From 4742f1f39716d4d1361f246e4fd0129c6cdbb3c1 Mon Sep 17 00:00:00 2001 From: Brett Meyer Date: Sun, 18 Dec 2022 13:03:19 -0500 Subject: [PATCH] pulled logic into MessagingService, convering the controller endpoint into a generic conversations webhook --- .../nucleus/controller/TwilioController.java | 73 +++---------------- .../controller/TwilioFrontlineController.java | 2 +- .../service/logic/MessagingService.java | 30 ++++++++ 3 files changed, 42 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/impactupgrade/nucleus/controller/TwilioController.java b/src/main/java/com/impactupgrade/nucleus/controller/TwilioController.java index b6ac24b35..4b8ec04b7 100644 --- a/src/main/java/com/impactupgrade/nucleus/controller/TwilioController.java +++ b/src/main/java/com/impactupgrade/nucleus/controller/TwilioController.java @@ -4,8 +4,6 @@ package com.impactupgrade.nucleus.controller; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.impactupgrade.nucleus.entity.JobType; import com.impactupgrade.nucleus.environment.Environment; @@ -13,9 +11,7 @@ import com.impactupgrade.nucleus.model.ContactSearch; import com.impactupgrade.nucleus.model.CrmContact; import com.impactupgrade.nucleus.model.CrmOpportunity; -import com.impactupgrade.nucleus.model.CrmTask; import com.impactupgrade.nucleus.security.SecurityUtil; -import com.impactupgrade.nucleus.service.logic.MessagingService; import com.impactupgrade.nucleus.util.Utils; import com.twilio.twiml.MessagingResponse; import com.twilio.twiml.VoiceResponse; @@ -38,12 +34,8 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; import static com.impactupgrade.nucleus.util.Utils.noWhitespace; @@ -258,13 +250,14 @@ public Response proxyVoice( } /** - * This webhook handles 'onMessageAdded' event + * This webhook handles 'onMessageAdded' event for Conversations, creating CRM activities. However, note that + * tracking of one-off messages is instead handled by inboundWebhook! */ - @Path("/webhook/message/onMessageAdded") // TODO: replace with the correct url + @Path("/callback/conversations") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) - public Response onMessageAddedWebhook( + public Response conversationsWebhook( @FormParam("EventType") String eventType, @FormParam("ConversationSid") String conversationSid, @FormParam("MessageSid") String messageSid, @@ -281,58 +274,14 @@ public Response onMessageAddedWebhook( Environment env = envFactory.init(request); SecurityUtil.verifyApiKey(env); - CrmTask crmTask = getOrCreateCrmTask(env, conversationSid); - addMessage(crmTask, messageSid); - upsertCrmTask(env, crmTask); - - return Response.ok().build(); - } - - private CrmTask getOrCreateCrmTask(Environment env, String conversationId) throws Exception { - CrmTask crmTask = null; - String subject = "SMS_CONVERSATION"; - String assignTo = env.getConfig().salesforce.defaultTaskAssignee; - - if (!Strings.isNullOrEmpty(conversationId)) { - // SMS Conversation - subject = subject + ":" + conversationId; - crmTask = env.primaryCrmService().getTaskBySubject(subject).orElse(null); - } - if (crmTask == null) { - // Conversation id not defined (single message) - // or conversation not yet exists - crmTask = new CrmTask(); - crmTask.subject = subject; - crmTask.assignTo = assignTo; - crmTask.type = CrmTask.Type.CALL; - crmTask.status = CrmTask.Status.TO_DO; - crmTask.priority = CrmTask.Priority.MEDIUM; - } - return crmTask; - } - - private void addMessage(CrmTask crmTask, String messageId) { - Set ids = new HashSet<>(); - if (!Strings.isNullOrEmpty(crmTask.description)) { - List messageIds = - Splitter.on(",") - .trimResults() - .splitToList(crmTask.description); - ids.addAll(messageIds); - } - ids.add(messageId); - crmTask.description = ids.stream() - .collect(Collectors.joining(",")); - } - - private String upsertCrmTask(Environment env, CrmTask crmTask) throws Exception { - String taskId; - if (Strings.isNullOrEmpty(crmTask.id)) { - taskId = env.primaryCrmService().insertTask(crmTask); - } else { - taskId = env.primaryCrmService().updateTask(crmTask); + switch (eventType) { + case "onMessageAdded": + env.messagingService().upsertCrmConversation(body, messageSid, conversationSid); + return Response.ok().build(); + default: + log.warn("unexpected eventType: " + eventType); + return Response.status(422).build(); } - return taskId; } // TODO: Temporary method to prototype an MMS replacement of the mobile app. In the future, diff --git a/src/main/java/com/impactupgrade/nucleus/controller/TwilioFrontlineController.java b/src/main/java/com/impactupgrade/nucleus/controller/TwilioFrontlineController.java index 765b2293f..b2ea589f8 100644 --- a/src/main/java/com/impactupgrade/nucleus/controller/TwilioFrontlineController.java +++ b/src/main/java/com/impactupgrade/nucleus/controller/TwilioFrontlineController.java @@ -338,7 +338,7 @@ public Response conversationsCallback( return Response.ok().build(); default: - log.error("unexpected eventType: " + eventType); + log.warn("unexpected eventType: " + eventType); return Response.status(422).build(); } } diff --git a/src/main/java/com/impactupgrade/nucleus/service/logic/MessagingService.java b/src/main/java/com/impactupgrade/nucleus/service/logic/MessagingService.java index caff578d4..6b38d201d 100644 --- a/src/main/java/com/impactupgrade/nucleus/service/logic/MessagingService.java +++ b/src/main/java/com/impactupgrade/nucleus/service/logic/MessagingService.java @@ -9,6 +9,7 @@ import com.impactupgrade.nucleus.environment.Environment; import com.impactupgrade.nucleus.model.ContactSearch; import com.impactupgrade.nucleus.model.CrmContact; +import com.impactupgrade.nucleus.model.CrmTask; import com.impactupgrade.nucleus.service.segment.CrmService; import com.impactupgrade.nucleus.util.Utils; import com.twilio.exception.ApiException; @@ -17,6 +18,7 @@ import org.apache.logging.log4j.Logger; import java.util.Objects; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -230,4 +232,32 @@ public void optOut(CrmContact crmContact) throws Exception { crmContact.smsOptOut = true; crmService.updateContact(crmContact); } + + public void upsertCrmConversation(String messageBody, String messageSid, String conversationId) throws Exception { + String subject = "SMS CONVERSATION: " + conversationId; + + Optional _crmTask = env.primaryCrmService().getTaskBySubject(subject); + CrmTask crmTask; + + if (_crmTask.isEmpty()) { + crmTask = new CrmTask(); + crmTask.subject = subject; + crmTask.type = CrmTask.Type.CALL; + crmTask.status = CrmTask.Status.DONE; + crmTask.priority = CrmTask.Priority.MEDIUM; + } else { + crmTask = _crmTask.get(); + } + + if (!Strings.isNullOrEmpty(crmTask.description)) { + crmTask.description += "\n"; + } + crmTask.description += messageSid + ": " + messageBody; + + if (Strings.isNullOrEmpty(crmTask.id)) { + env.primaryCrmService().insertTask(crmTask); + } else { + env.primaryCrmService().updateTask(crmTask); + } + } }