Recording url click-throughs in civimail as activity records in civicrm 3.x

admin Profile Photo
A. J. Roach

on

January 24, 2010

Recording url click-throughs in civimail as activity records in civicrm 3.x

Recently, during a civicrm upgrade to 3.x, a client asked for each civiMail click-through to not only be tracked for mailing reports, but to show up as an activity record for the user that clicks through. The main problem with doing this out of the box is that when civimail sends an email, it doesn't send any record (other than the email address) of who is receiving that email. That is to say that no links in the email -- while they are rewritten to be directed through the civicrm server in order to count the click-throughs -- contain any information to tell the civicrm server which user is clicking-through on the link. To fix this I added a new Activity type and made some minor changes to a few files. First, add an activity type called 'Click-through': - Go to Administer Civicrm => Option Values => Activity Types - Add a new activity type: - Name: Click-through - Description: This type represents a click-through by a user for a link embedded in a civicrmail message - Click save Now for the minor code changes... First in CRM/Mailing/BAO/TrackableURL.php: In 'getTrackerURL($url, $mailing_id, $queue_id)' where the link is rewritten add:

global $user;
$umail = $user->mail;
at the top. Then near the bottom where the url is rewritten to direct it back through the civicrm server, add:
'&umail=$umail'
to the end of the rewritten url. We'll use this information in extern/url.php in order to get the contact_id of the user who clicks-through on this link

Now, in extern/url.php: Add

require_once '../api/v2/Contact.php';
To the top of the file and then added this block of code:
if (isset($_GET['umail'])) {
  $umail_address = CRM_Utils_Array::value( 'umail', $_GET );
  $params = array('email' => $umail_address,
                  'return.contact_id' => 1
                 );
  $result = civicrm_contact_search($params);
  if (civicrm_error($result)) {
    echo $result['error_message'];
  }
  else if(count($result) > 1) {
    $cid = "";
  }
  else {
    foreach ($result as $id => $data) {
      $cid = $id;
    }
  }
}
What this does is check for the umail variable on the query string (remember we added this variable in getTrackerURL(). Once found it pulls the email address and uses civicrm_contact_search() to get the contact that the email address belongs to. Then it pulls out the $cid. We then add the $cid to the CRM_Mailing_Event_BAO_TrackableURLOpen call near the end of the file, like so:
require_once 'CRM/Mailing/Event/BAO/TrackableURLOpen.php';
$url = CRM_Mailing_Event_BAO_TrackableURLOpen::track($queue_id, $url_id, $cid);

Lastly, we'll need to alter the CRM/Mailing/Event/BAO/TrackableURLOpen.php file: Add the $cid variable to the public static declaration of the track() method. Make sure to give it a default value of "" so that calls to this method that don't include $cid won't break:

public static function track($queue_id, $url_id, $cid = "") {
Now add the code to this method that will create a click-through activity record for the contact who has an id matching $cid:
// Save this click through as an activity for this contact
if ($cid != "") {
  $params = array(
    'activity_type_id' => CLICK_THROUGH_ID,
    'source_contact_id' => $cid,
    'assignee_contact_id' => $cid,
    'target_contact_id' => $cid,
    'subject' => 'Click-through',
    'status_id' => STATUS_ID,
    'activity_date_time' => date('YmdHis')
  );
  $activity = civicrm_activity_create($params);
}
Of course, you'll need to define CLICK_THROUGH_ID and STATUS_ID to be their appropriate values. My click-through activity type_id was 33 and I used 2 as the status_id.

I've attached patch files for these files as .txt files below.

AttachmentSize
TrackableURL.txt813 bytes
url.txt1.26 KB
TrackableURLOpen.txt1.48 KB

Share it!

Had to update mailing.php and TrackableURL.php to feed over the email address.

 

Thanks,

 

John

Most of the code matches up but I'm not getting the $umail variable populated in

TrackableURL.php.  It seems the $user global does not exist.

This seems like a great addition to CiviCRM! Might it be built into core in the future?

Just a quick note: it looks like your > symbols inside the code blocks are displaying as > (their escaped character codes) instead of as the true sideways carats you want. (On a Mac in Safari 4.x, at least.)

Yes, I've just noticed those >s...  Yes, I do intend on contributing this functionality to the civicrm team.  I'd love to see it considered for core in a future version.  

 

Thanks,

aj