6

Is it possible for CiviMail to track embedded URLs? For eg, I've a URL which contains contact id and checksum tokens in it. I need to check how many users have clicked the URL from the email.

URL to track - https://site-name/info?cid1=<contact_id_token>&cs=<contact_checksum>

Currently, the code in CiviMail don't consider such tokenized URL from tracking and don't insert it in civicrm_mailing_trackable_url table.

There is a similar question on SE - Tracking links that have been added via tokens but it seems to provide different track links for each tokenised URL which is a pain when number of recipients is large in number. Eg 10k contacts would have 10k trackable links and will considerably increase the size of the database.

Our thought now is to cut the URL till a token is reached and consider this for tracking. For eg, if the original URL is https://site-name/info?cid1=<contact_id_token>&cs=<contact_checksum>, we need to modify the functionality to track only https://site-name/info and if such url is hit by the user, the click counter should be incremented.

To proceed with the above, we can store the partial link in civicrm_mailing_trackable_url table and replace the main html URL with the trackable link. Now, when the user hits this url in the mail, the main problem arises as we don't have any data of what should be appended to the partial URL to navigate user the original page.

Is there any another solution possible?

6

We've accomplished this by modifying the core function getTokenData() to track non-tokenised part of the URL string. For eg. with the url posted in the question -

https://site-name/info?cid1=<contact_id_token>&cs=<contact_checksum>

  • Grab the main URL before the ? (https://site-name/info) and get the trackable url of this string from CRM_Mailing_BAO_TrackableURL::getTrackerURL() function.
  • This enters the URL in civicrm_mailing_trackable_url table.
  • Replace the HTML with this trackable URL so that main URL that is sent is in the form - http://site-name/sites/all/modules/civicrm/extern/url.php?u=13&qid=17&cid1=<contact_id_token>&cs=<contact_checksum>, i.e, trackable url + query string from the original URL string.
  • When the user clicks the link in the mail, user gets navigated to trackable URL and is redirected to the original URL from civicrm_mailing_trackable_url table.
  • The extra query string automatically gets appended to the main URL.

The above is working correctly for us and tracks each click when the URL https://site-name/info is loaded.

Overriden the file in an extension. Sample Code diff looks like -

$ git diff CRM/Mailing/BAO/Mailing.php
diff --git a/CRM/Mailing/BAO/Mailing.php b/CRM/Mailing/BAO/Mailing.php
index 3a0f08048c..f2501a0b91 100644
--- a/CRM/Mailing/BAO/Mailing.php
+++ b/CRM/Mailing/BAO/Mailing.php
@@ -1348,6 +1348,21 @@ ORDER BY   civicrm_email.is_bulkmail DESC
       elseif (preg_match('/^href[ ]*=[ ]*\"/', $url)) {
         $url .= '"';
       }
+      if (!empty($token_a['embed_parts'][0])) {
+        $string = ' ' . $token_a['embed_parts'][0];
+        $start = 'http';
+        $end = '?';
+
+        $ini = strpos($string, $start);
+        if ($ini != 0) {
+          $ini += strlen($start);
+          $len = strpos($string, $end, $ini) - $ini;
+
+          $partialLink = "http" . substr($string, $ini, $len);
+          $trackableLink = CRM_Mailing_BAO_TrackableURL::getTrackerURL($partialLink, $this->id, $event_queue_id);
+          $url = str_replace("{$partialLink}?", "{$trackableLink}&", $url);
+        }
+      }
       $data = $url;
       // CRM-20206 Fix ampersand encoding in plain text emails
       if (empty($html)) {
0

I wrote this actiontracker extension a few months ago, but I have to admit that I do not use it often, so your mileage may vary.

It generates tracking URLs for every link in the email that has a checksum. It has only been tested with flexmailer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.