I am using a custom heartbeat activity message that includes a teaser of a node.
If the node is edited and the teaser changes, unfortunately the heartbeat message stays the same.

Is there a simple way (or any way) to modify the heartbeat message once it's created? Seems like if there's no automatic way to do it, I can do a hook_nodeapi on this particular node type and, if there's any heartbeat logged messages related to it, I could have it edit them. If that's not possible, maybe I could have it delete the previous heartbeat message and create a new one with the same date? Can it be done with rules?

Any insight is greatly appreciated!

Comments

Stalski’s picture

Status: Active » Closed (won't fix)

Yes, you can do that in a nodeapi hook. I did this too once. I even promoted an edited article (deleting it while copying it to the most recent activity).
The reason why i suggest this, is because it's seems like the only way? I would expect if you use rules to log the activity, and since heartbeat always shows the most recent of the "non-merged" messages, the teaser-token would be updated by rules, no?
How is it in the database? I don't think heartbeat can do anything to change the behavior, no?

Reopen this ticket if the problem is not solved or you are of the opinion heartbeat can take up the challenge.

sarav.din33’s picture

Status: Closed (won't fix) » Active

@ Stalski,

Can you please post the sample code to update the heartbeat activity message through hook_node_api??

Stalski’s picture

Status: Active » Closed (fixed)

Just do your action in the hook_node_api (delete, remove, insert, publishe, whatever).
The action could be to remove an activity log and insert another, or just update the activity record you want. This can be done since you know the actor and the node it's referring too. So plain simple

jienckebd’s picture

Thanks for a great module Stalski!

Could you provide example code from when you did this using hook_node_api? I'm also trying to do a mass update on all of my heartbeat activity.

jienckebd’s picture

Nevermind -- I got it working. My question was a little different from this. I added a new !body variable to an existing heartbeat template and I wanted my existing hearbeat entries to use the variable. I was able to update them by deleting all of the old entities and inserting new ones with the new variable values.

If anybody else is trying to do the same, here is an example script I ran to update them. Please let me know if there was a simpler method for future reference:

<?php

// retrieve all heartbeat entries for the heartbeat_liked_content template
$results = db_query("SELECT * FROM {heartbeat_activity} WHERE message_id = 'heartbeat_liked_content'");

foreach ($results as $result) {
	$activity = heartbeat_activity_load($result->uaid);

	// Check to make sure the activity doesn't have the new !body variable. I only want to run this update on old entities that don't have the variable.
	if (!$activity->variables['!body']) {

		// copy old values
		$message_id = $activity->message_id;
		$uid = $activity->uid;
		$uid_target = $activity->uid_target;
		$nid = $activity->nid;
		$nid_target = $activity->nid_target;

		// get timestamp of original activity to apply to the newly created one
		$timestamp = $result->timestamp;

		// load actor user and node target
		$account = user_load($uid);
		$node = node_load($nid_target);

		// This will be the new !body variable. It gets the first 300 characters of the target node's body and then sanitizes it.
		$body = $node->body['und'][0]['value'];
		$body = filter_xss(substr($body, 0, 300) . "...");

		// create variables array for the new heartbeat entity
		$variables = array();
		$variables['!username'] = l($account->realname, 'user/' . $account->uid);
		$variables['!node_type'] = $node->type;
		$variables['!node_title'] = l($node->title, 'node/' . $node->nid);
		$variables['!body'] = $body; // my new variable
		$variables['!types'] = $node->type;
		$variables['node_type'] = $node->type;
		$variables['node_status'] = 1;
		$variables['node_uid'] = 1;
		$variables['node_target_type'] = $node->type;
		$variables['node_target_status'] = 1;
		$variables['node_target_uid'] = 1;

		// Save the new heartbeat entity. This returns the new uaid.
		$activity_new = heartbeat_api_log($message_id, $uid, $uid_target, $nid, $nid_target, $variables);

		// delete original heartbeat entitity
		heartbeat_activity_delete(array($activity->uaid));

		// Set the timestamp of the new entity to match that of the original entity
		db_update('heartbeat_activity')
		  ->fields(
			array(
			  'timestamp' => $timestamp,
			)
		  )
		  ->condition('uaid', $activity_new)
		  ->execute();

	}
}

?>
mr.andrey’s picture

Issue summary: View changes

I ended up using custom PHP in Rules on Update content:

$nid = [node:nid];
$new_summary = <<< END_TITLE
[node:summary]
END_TITLE;
$new_node_title = <<< END_TITLE
[node:title]
END_TITLE;
$new_forum = <<< END_TITLE
[node:taxonomy_forums]
END_TITLE;
$new_type = <<< END_TITLE
[node:field_post_type]
END_TITLE;
$activity = db_query("SELECT variables FROM {heartbeat_activity} WHERE nid = :nid", array(':nid' => $nid))->fetchField();
$activity_array = explode('-|-', $activity);
foreach ($activity_array as $key => $variable) {
  if (substr($variable, 0, 11) == '!summary=|=') {
    $variable = "!summary=|=".$new_summary;
  }
  if (substr($variable, 0, 14) == '!node_title=|=') {
    $variable = "!node_title=|=<a href='/node/".$nid."'>".$new_node_title."</a>";
  }
  if (substr($variable, 0, 9) == '!forum=|=') {
    $variable = "!forum=|=".$new_forum;
  }
  if (substr($variable, 0, 8) == '!type=|=') {
    $variable = "!type=|=".$new_type;
  }
  $new_activity_array[$key] = $variable;
}
$new_activity = implode('-|-', $new_activity_array);
db_query("UPDATE {heartbeat_activity} SET variables = :new_activity WHERE nid = :nid", array(':nid' => $nid, ':new_activity' => $new_activity));

I have some custom fields, so you'll need to update it to your own setup.

Cheers,
Andrey.