Helpful utility functions for notifying users about inbound emails

Here is another Francesca Shiekh guest post! She is a Sugar Developer from Wolfram Research.

We had the need to notify the assigned user when an email was received that was related to a Case record. To make our application more flexible we extended this concept to be reusable for email received that was related to any module. We then further broke out the notification functions to be reusable in other scenarios.

Notifying an Assigned User that an Email was received

The following concept can be used to notify the Assigned user on a Case, Contact, Account, or basically any module that has related Emails.

For example, suppose that we wish to notify the Assigned User that an email has been logged on a Contact record assigned to them.

Detecting inbound Emails using an after_relationship_add logic hook

First, we can add an after_relationship_add logic hook on Contacts:

In ./custom/modules/Contacts/logic_hooks.php

<?php

$hook_version = 1;

$hook_array = Array();

$hook_array['after_relationship_add'] = Array();

$hook_array['after_relationship_add'][] = Array(1, 'email_contact_relationship', 'custom/modules/Contacts/email_contact_handling.php','email_contact_handling', 'update_on_relationship'); ?>

The logic hook checks if the related record is an Email then calls a custom utility function to handle the notification../custom/modules/Contacts/email_contact_handling.php

class email_contact_handling

{

   // Email RELATED to a Contact

   function update_on_relationship ($bean,$event,$arguments){

        require_once('custom/entry_points/Utils/notifyAssignedUser.php'); //choose your own path for your custom utility functions

        //bean = Contact

        //related_module = Emails

        if ($arguments['related_module'] =='Emails'){ //check that you are indeed relating an Email to this Contact

           notifyAssignedUser($bean, $arguments['related_id']); //related_id is the email id in this case

        }

    }

}

Notifying an Assigned User that an Email was received

We can also define a reusable utility function to notify the Assigned User. We choose to store our reusable functions in in ./custom/entry_points/Utils/ but you can put yours inside another custom directory.

In /custom/entry_points/Utils/notifyAssignedUser.php

<?php

//given a bean and an Email id notify the

//Assigned user on the bean that the email was received.

function notifyAssignedUser($bean, $email_id){

$email = BeanFactory::retrieveBean('Emails',$email_id);

$module = $bean->module_name;

    $u = new User();

    $u->retrieve($c->assigned_user_id);

    $user_email = $u->emailAddress->getPrimaryAddress($u);

    if (filter_var($user_email, FILTER_VALIDATE_EMAIL)) {

      include_once('custom/entry_points/Utils/sendEmail.php');

      $email_text = !empty($email->description_html)?$email->description_html:$email->description;

      $EmailBody=<<<BODY New email received for $bean->name

Assigned to: $u->user_name

From: {$email->from_addr_name} ( {$email->from_addr} )

To: {$email->to_addrs}

Cc: {$email->cc_addrs}

Subject: $email->name

See: {$sugar_config['site_url']}/#{$module}/{$bean->id}

{$email_text}

BODY;

      $to_address = $u->emailAddress->getPrimaryAddress($u);

      $subject = "New Email received for $c->name";

      if(!empty($to_address)&&$u->user_name!='tsreception'){

        sendEmail($to_address, '<your sugar email address>', $from, $subject,$EmailBody);

      }

    }

  return;

}

?>

Notifying a Group of Users based on criteria from the Users module

You can also choose to retrieve a group of users based on some criteria for User records.

For example, we have a custom field support_group_c which we use for group notifications on Case records.

<?php

// Copyright 2016 Wolfram Research, Inc.

// Given a support group and a Case bean, then notify the support group users that the case was created.

function notify_support_group_users($c, $support_group, $email=null){

$GLOBALS['log']->debug("Inbound Email: Prepare to notify " . $support_group);

  require_once('include/SugarQuery/SugarQuery.php');

  $sugarQuery = new SugarQuery();

  $sugarQuery->select(array('id'));

  $bean = BeanFactory::newBean('Users');

  $sugarQuery->from($bean, array('team_security' => false));

  $sugarQuery->where()->equals('support_group_c', $support_group);

  $result = $sugarQuery->execute();

  $GLOBALS['log']->debug("Inbound Email: Prepare to notify " . print_r($result,true));

  foreach($result as $user){

    $GLOBALS['log']->debug("Inbound Email: Prepare to notify " . print_r($user,true));

    $user = BeanFactory::getBean('Users', $user['id']);

    $user_email = $user->emailAddress->getPrimaryAddress($user);

    if (filter_var($user_email, FILTER_VALIDATE_EMAIL)) {

      $user_emails[] = $user_email;

    }

  }

  if(!empty($user_emails)){

    $GLOBALS['log']->debug("Inbound Email: Will notify " . print_r($user_emails,true));

    include_once('custom/entry_points/Utils/send_group_email.php');

    global $sugar_config;

    $toAddresses = implode(';',$user_emails);

    if(!empty($email)){

        $email_text = !empty($email->description_html)?$email->description_html:$email->description;

        $EmailBody=<<<BODY New email on [CASE:{$c->case_number}] $c->name

Current Case Status: $c->status

Assigned to: $user->user_name

From: {$email->from_addr_name} ( {$email->from_addr} )

To: {$email->to_addrs}

Cc: {$email->cc_addrs}

Subject: $email->name

See: {$sugar_config['site_url']}/#Cases/{$c->id}

{$email_text}

BODY;

    }else{

        $EmailBody=<<<BODY New Correspondence on  Case: [CASE:{$c->case_number}] $c->name

See: {$sugar_config['site_url']}/#Cases/{$c->id}

BODY;

    }

    // sendEmail($ToEmailAdd, $FromEmailAdd, $FromEmailName, $EmailSubject, $EmailBody)

    // defined in custom/entry_points/send_email.php

    $GLOBALS['log']->debug("Inbound Email: Will notify " . $toAddresses);

    if($c->status == 'New'){

      $subject = "New Case Created [CASE:{$c->case_number}] $c->name";

      $from = 'SugarCRM Case New';

    }else{

      $subject = "New Correspondence on Case [CASE:{$c->case_number}] $c->name";

      $from = 'SugarCRM Case Update';

    }

    if(!empty($toAddresses))  sendGroupEmail($toAddresses, 'sugarCRM@wolfram.com', $from, $subject,$EmailBody);

  }

  return;

}

?>

Sending an Email to a given set of addresses, one per addressee

Finally, we have a sendEmail() utility function../custom/entry_points/Utils/sendEmail.php

<?php

// Copyright 2016 Wolfram Research, Inc.

// Function to send Email message

// one email per recipient

function sendEmail($ToEmailAdd, $FromEmailAdd, $FromEmailName, $EmailSubject, $EmailBody) {

global $sugar_config;

$GLOBALS['log']->debug('PREPARE EMAIL to ' . print_r($ToEmailAdd, true));

  require_once ('modules/Emails/Email.php');

  if(is_array($ToEmailAdd)){

    $To = $ToEmailAdd;

  }else{

    $To = explode(';',$ToEmailAdd);

  }

  foreach ($To as $to_addr){

    $GLOBALS['log']->debug('PREPARE EMAIL TO:' . $to_addr);

    if (filter_var($to_addr, FILTER_VALIDATE_EMAIL)){

      try{

        $phpMailer = MailerFactory::getSystemDefaultMailer();

        $mailTransmissionProtocol = $phpMailer->getMailTransmissionProtocol();

        $FromEmailIdentity = new EmailIdentity($FromEmailAdd, $FromEmailName);

        $header_array = array(

          'From'=>$FromEmailIdentity,

          'ReplyTo'=>'',

          'Sender'=>$FromEmailIdentity, //mandatory

          'Subject'=>$EmailSubject,

        );

        $phpMailer->constructHeaders($header_array);

        $phpMailer->addRecipientsTo(new EmailIdentity($to_addr, $to_addr));

        $phpMailer->setHtmlBody($EmailBody);

        $phpMailer->send();

      }catch(MailerException $me) {

        $message = $me->getMessage();

        $GLOBALS["log"]->warn(

          "SendEmail: error sending e-mail (method: {$mailTransmissionProtocol}), (error: {$message})"

        );

      }

    }

  }

  return;

}

Send Email to a set of addresses as multiple To and/or CC

We can also modify the sendEmail() function above to send one email to the whole group with multiple recipients instead of individual emails.

<?php

// Copyright 2016 Wolfram Research, Inc.

//Function to send Email message

//Multiple recipients => multiple addresses in the To, and/or Cc

function sendGroupEmail($ToEmailAdd, $FromEmailAdd, $FromEmailName, $EmailSubject, $EmailBody, $CcEmailAdd = array()) {

  include_once('modules/Mailer/MailerFactory.php');

  global $sugar_config;

  $ToAddrs = array();

  $CcAddrs = array();

  if(is_array($ToEmailAdd)){

    $To = $ToEmailAdd;

  }else{

    $To = explode(';',$ToEmailAdd);

  }

  if(is_array($CcEmailAdd)){

    $Cc = $CcEmailAdd;

  }else{

    $Cc = explode(';',$CcEmailAdd);

  }

  try{

    $phpMailer = MailerFactory::getSystemDefaultMailer();

    $mailTransmissionProtocol = $phpMailer->getMailTransmissionProtocol();

    $FromEmailIdentity = new EmailIdentity($FromEmailAdd, $FromEmailName);

    $headers = new EmailHeaders();

    $header_array = array(

      'From'=>$FromEmailIdentity,

      'ReplyTo'=>'',

      'Sender'=>$FromEmailIdentity, //mandatory

      'Subject'=>$EmailSubject,

    );

    $headers->buildFromArray($header_array);

    $phpMailer->setHeaders($headers);

    //$phpMailer->setHtmlBody($EmailBody);

    $phpMailer->setTextBody($EmailBody);

    foreach($To as $to_addr){

      //note should be new EmailIdentity(<email_address>, <name>)

      //we don't have a name for these

      $phpMailer->addRecipientsTo(new EmailIdentity($to_addr, $to_addr));

    }

    foreach($Cc as $cc_addr){

      //note should be new EmailIdentity(<email_address>, <name>)

      //we don't have a name for these

      $phpMailer->addRecipientsCc(new EmailIdentity($cc_addr, $cc_addr));

    }

    $phpMailer->send();

  }catch(MailerException $me) {

    $message = $me->getMessage();

    $GLOBALS["log"]->warn(

      "SendGroupEmail: error sending e-mail (method: {$mailTransmissionProtocol}), (error: {$message})"

    );

  }

  return;

}

?>