2

We have a client who has two webhooks defined in Mandrillapp - both of them reacting to the same events (click, open, etc). These webhooks have a post url of two different sites(dev and live). Eg.

Post url of dev = http://devsite.com/civicrm/ajax/mte/callback?mandrillSecret=devkey

Post URL of live - http://livesite.com/civicrm/ajax/mte/callback?mandrillSecret=livekey

My guess is that - when an email is sent from the live site, these both urls are triggered(on open or click event) and dev site also gets the response which creates a mandrill activity on dev site.

This is what is happening for us - when a bulk email is sent from the live site, dev also creates a mandrill activity.

Can we conclude that we need to use two different mandrill accounts for two different sites OR there is a way to avoid this (rules, etc)?


UPDATE after Chris Answer -

The posted answer seems to be something which is already present in Mandrill extension?

Readme file asks user to save the secret key as a value of an option group which we've done for dev and live sites.

Problem arises when DEV webhook is triggered by an event(open/click) of LIVE mails(note both above URLs react on the same event). As dev secret key is same(url param and option grp value) matches the option value stored on the dev site, this checking of key match doesn't help us.

In short, a dev Post URL need to be avoided to be triggered after an event has occurred for emails sent from live site. Maybe this could to be done on the MandrillApp side?

  • I've split my two answers and expanded the one about Mandrill's Test Mode – Chris Burgess Nov 12 '17 at 19:58
1

If you must use the same account on both environments, Drupal/CiviCRM hooks could potentially support this? (All of this answer is likely more work than just using the provider's supported test mode, though!)

You can pick any hook that fires before Mte.callback gets fired, and trigger rejection / invalidation based on any of the incoming data including the secret key or contact details in the request.

CMS boot hooks (eg Drupal hook_init) or CRM config hook (hook_civicrm_config) happen early but on many requests so will add overhead; if possible I'd do this as late and specifically as possible - hook_civicrm_apiWrappers could be just the ticket if it works for this usage? Alternatively you could just throw some interception in settings.php / civicrm.settings.php / environment-specific settings.development.php.

If the secret keys aren't suitable, you could look for test-specific properties of the submitted contact data.

That might look like,

// Lives in settings.php so it's not in your committed code.
$mandrill_secrets = [
  'development' => 'devkey',
  'production' => 'livekey'
];

Boot time: obtain current environment, put in $environment:

Before CiviCRM has a chance to respond to civicrm/ajax/mte/callback: If the supplied secret doesn't match the current environment, unset it or make it invalid.

if (isset($_GET['mandrillSecret']) && $_GET['mandrillSecret'] != $mandrill_secrets[$environment]) {
  $_GET['mandrillSecret'] = 'invalid';
}
  • Hey Chris, glad to see you and thankyou for the answer :-). Word limit here, so i've updated the question. – jitendra - fuzion Nov 12 '17 at 4:40
  • Are the "secret codes" on live and dev the same or different? Your question has livekey / devkey so I figured they weren't the same. EDIT: ah, I see your updated question says they are the same. – Chris Burgess Nov 12 '17 at 4:53
  • Yeah, I think you need to separate this Mandrill side then. Will using a test key help? mandrill.zendesk.com/hc/en-us/articles/… – Chris Burgess Nov 12 '17 at 5:04
  • No, the secret key is different for both the URL as mentioned in the post(devkey/livekey). The same word the updated question is dev url secret key and the option group value stored on the dev site. – jitendra - fuzion Nov 12 '17 at 5:28
1

It sounds like what you want is to switch your dev environment to use Mandrill's Test Mode?

You can then make your site environment aware to switch the Mandrill account details each time you refresh data on your dev environment, preventing live webhooks from affecting dev environment and vice versa.

Mandrill's test mode is API key specific; on your dev site you'll need to switch the API key used, and then send emails to certain addresses to test bounce, rejection etc.

  • Mandrill Zendesk: Test mode / sandbox
  • reject@test.mandrillapp.com => Rejected email
  • hard_bounce@test.mandrillapp.com => Hard-bounced email
  • soft_bounce@test.mandrillapp.com => Soft-bounced email
  • spam@test.mandrillapp.com => Spam complaint

(Your tests will also need to ensure that they are idempotent, ie reset the DB to a known state that ensures the hard_bounce contact is newly created or has not been marked undeliverable in CiviCRM.)

You can then use Mandrill's Rules Engine to send webhook requests to the appropriate site based on the API key in use for the generated email.

  • Great info. Tested this by removing all the default triggers from dev webhook and replaced it with rules. This seems to be working when the mail are sent from live site(they don't create any new contacts or activity on dev now). But sending mails from dev site also don't create any activity on dev. Pretty sure the rules are configured correctly to react on dev api key match. – jitendra - fuzion Nov 13 '17 at 14:29
  • Also, as live webhook is meant to trigger on default open/click event, mails sent from dev site created a new activity on live... yikes. – jitendra - fuzion Nov 13 '17 at 14:32
1

The Mandrill extension was not designed to support multiple sites.

It is a reasonable use case to enhance it to support dev and prod instances of the same site.

@Chris Burgess workarounds are likely best approach in absence of funding to do this.

Without reviewing Mandrill docs etc I think the approach needed is to figure out somehow whether the instance receiving a callback is the one that sent out the mailing. One way might be to add another field containing the baseurl of the sending instance to each email, then check that value which you can get on the webhook callback.

Note: code contributions are welcome!

  • One way might be to add another field containing the baseurl of the sending instance to each email - I did this as a first trial before posting this question by adding CIVICRM_SITE_KEY to the headers created in altermailparam() hook, but most of the click or open event wasn't containing this headers information(not even civicrm mandrill id) in response :( – jitendra - fuzion Nov 15 '17 at 4:27

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.