CRM-20238 Hook for inbound SMS messages

    Details

    • Type: New Feature
    • Status: Done/Fixed
    • Priority: Trivial
    • Resolution: Fixed/Completed
    • Affects Version/s: 4.7.16
    • Fix Version/s: 4.7.21
    • Component/s: None
    • Versioning Impact:
      Minor (add functionality in backwards-compatible manner)
    • Documentation Required?:
      Developer Doc
    • Funding Source:
      Needs Funding
    • Verified?:
      No

      Description

      It would be beneficial to have a callable hook when an inbound SMS is received.

      Potential use cases include:

      • Applying custom logic to match the From phone number to contacts
      • Reformatting the From phone number to match the structure in the database (for example, replacing +614 with 04 for Australian mobile numbers)
      • Taking actions based on incoming SMS (such as adding the contact to a group if the message includes a specific keyword)
      • Sending an automatic reply SMS back to the sender

        Attachments

          Activity

          [CRM-20238] Hook for inbound SMS messages
          Jon K Goldberg added a comment -

          Hi Effy Elden,

          This seems useful for the first use case you provided. I've actually implemented most of the other three use cases using existing hooks. Since inbound SMS creates an activity, I've had good success with hook_civicrm_pre and hook_civicrm_post to implement what you're describing. I don't know if that influences your hook design at all.

          For instance, this is the code at the heart of an extension I wrote. This is an "SMS forwarder" - when someone with an open CiviCase sends an inbound SMS, automatically send an outgoing SMS to their case manager(s) to copy what they said:

          function smsredirect_civicrm_post($op, $objectName, $objectId, &$objectRef) {
            // "From" and "To" refer to the outgoing SMS.
            // Therefore, an incoming SMS comes from the "From" person.
            // It goes to the case manager, who is the "To" person.
            if ($op == 'create' && $objectName == 'Activity') {
              $inboundId = smsredirect_getActivityTypeId('Inbound SMS');
              if ($objectRef->activity_type_id == $inboundId) {
                $fromInfo = smsredirect_getTargetInfo($objectId);
                $displayName = $fromInfo['contact_id.display_name'];
                $caseManagerInfo = smsredirect_getCaseManagerInfo($fromInfo['contact_id']);
                $body = "From $displayName: $objectRef->details";
                //Make sure we're not going over 460 characters.
                $body = substr($body, 0, 459);
                foreach ($caseManagerInfo as $toId => $phone) {
                  smsredirect_send($body, $toId, $phone);
                }   
              }   
            }
          }
          
          Effy Elden added a comment - - edited

          Interesting. The motivation for this came about from my second example - needing to reformat phone numbers coming in. This is because my organisation stores our mobile numbers in local format (10 digit, starting with 04), but Twilio and other SMS providers provide the number in international format (+614). Without custom code, Civi fails to match and creates a new contact. To my knowledge there's not a way to do that with current hooks.

          I can see how that would work - that said, I like the idea of decoupling CiviSMS from activities and providing more flexibility, which I think having explicit hooks for inbound (and outbound hopefully) messages will provide.

          Jon K Goldberg added a comment -

          Ah - you're right Effy Elden, I've changed phone numbers using hooks in non-SMS situations (much like Cividesk Normalize extension does) but that's not going to cut it here.

          I saw Tim's comment on the PR to pass an object rather than individual variables, which I think addresses my concern by future-proofing this hook.

          Effy Elden added a comment -

          It's also worth noting that a hook for outbound SMS messages that allowed altering phone numbers would allow more flexibility and [avoid issues such as requiring patched versions of SMS providers depending on country](https://wiki.civicrm.org/confluence/display/CRMDOC/Setting+up+a+SMS+Provider+for+CiviSMS).

          Unfortunately, from what I can tell, the way the send function is currently implemented means that the SMS provider extensions themselves would need to be patched (to call the parent function at the start), which seemed like an irritation, and so I didn't want to bundle that in with this issue/PR.

            People

            • Assignee:
              Unassigned
              Reporter:
              Effy Elden

              Dates

              • Created:
                Updated:
                Resolved: