Send Shopify Order Confirmation on Whatsapp

 

One of our existing customer came back to us with the requirement to send Order Confirmation on Whatsapp. They tried certain existing Shopify Plugin but they found them expensive with monthly subscription plan for the feature they dont intend to use. They ask us for some cheap alternative with the simple feature of just sending the Order confirmation once the Order is placed.

We brainstorm with the customer to find the best alternative way to send Whatsapp Order Confirmation and decided to use AWS Lambda function which will be executed via the Shopify Webhook. For Whatsapp API, we decided to use Wati. Since, we are a affliate partner of Wati, customer signed up with Whatsapp with official mobile number using our affliate link: https://www.wati.io?ref=tirnavsolutions

Here is how we implemented the requirement:

Step 1: Create Order Webhook in Shopify Admin

Go to your Shopify Admin -> Settings -> Notifications -> Webhooks -> Create Webhooks 

Add a new Webhook like below screenshot:

Step 2: Create a AWS lambda function:

You can create AWS lambda function using AWS supported programming language. Currently, AWS support Java, NodeJS, Python, Go, C# and Ruby. Read more here.

We decided to use Java.

				
					@Override
    public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
    	LambdaLogger logger = context.getLogger();
        
        String waTemplateName = System.getenv("whatsappTemplateName");
        String watiEndpointURL = System.getenv("watiEndpointURL");
        String bearerToken = System.getenv("bearerToken");
        
        String orderJson = new String(input.readAllBytes(), StandardCharsets.UTF_8);
        //logger.log("Raw Order from Shopify: " + orderJson);
        
        if(StringUtils.isNullOrEmpty(watiEndpointURL) || StringUtils.isNullOrEmpty(waTemplateName) || StringUtils.isNullOrEmpty(bearerToken)) {
        	logger.log("Environment variable missing.");
        	return;
        }
        
        JsonNode data = mapper.readTree(orderJson);
        String customerName = data.get("shipping_address").get("name").asText();
        String orderNumber = data.get("order_number").asText();
        String phoneNumber = data.get("shipping_address").get("phone").asText();
        String orderURL = data.get("order_status_url").asText();
        if(orderURL.indexOf("authenticate")>-1) {
        	orderURL = orderURL.substring(0,orderURL.indexOf("authenticate")-1);
        }
        
        logger.log("New Shopify Order received for Customer "+ customerName + " for Shopify Order #: " + orderNumber);
		
        try {
        	if(!StringUtils.isNullOrEmpty(phoneNumber)) {
        		GDWhatsappModel payloadData = new GDWhatsappModel();
        		payloadData.setTemplateName(waTemplateName);
        		payloadData.setBroadcastName(customerName+"-"+orderNumber);
            	
            	Receiver receiver = new Receiver();
            	receiver.setWhatsappNumber(phoneNumber.replaceAll("[+]", ""));
            	
            	List<CustomParam> customParamList = new ArrayList<>();
            	CustomParam customerNameParam = new CustomParam();
            	customerNameParam.setName("customername");
            	customerNameParam.setValue(customerName);
            	customParamList.add(customerNameParam);

            	CustomParam orderURLParam = new CustomParam();
            	orderURLParam.setName("orderurl");
            	orderURLParam.setValue(orderURL);
            	customParamList.add(orderURLParam);

            	CustomParam orderNumberParam = new CustomParam();
            	orderNumberParam.setName("ordernumber");
            	orderNumberParam.setValue(orderNumber);
            	customParamList.add(orderNumberParam);
            	
            	receiver.setCustomParams(customParamList);
            	payloadData.setReceivers(Arrays.asList(receiver));
            	
            	String payload = mapper.writeValueAsString(payloadData);
            	logger.log("Sending Whatsapp notification with paylod: "+ payload);
    			HttpRequest request = HttpRequest.newBuilder()
    					  .uri(new URI(watiEndpointURL))
    					  .header("Content-Type", "application/json;charset=UTF-8")
    					  .header("Authorization", "Bearer "+bearerToken)
    					  .POST(HttpRequest.BodyPublishers.ofString(payload))
    					  .build();
    			
    			HttpResponse<String> response = HttpClient.newBuilder()
    					  .build()
    					  .send(request, BodyHandlers.ofString());
    			
    			if(response.statusCode() == 200) {
    				logger.log("Whatsapp notification succesfully sent to phone: "+ phoneNumber + " for Shopify Order #: " + orderNumber+". Whatsapp template used:"+waTemplateName);
    			}else {
    				logger.log("Whatsapp notification failed sent to phone: "+ phoneNumber + " for Shopify Order #: " + orderNumber+". Error message: " + response.body());
    			}
        	}
		} catch (URISyntaxException | InterruptedException e) {
			logger.log("Error while sending Whatsapp notification failed sent to phone: "+ phoneNumber + " for Shopify Order #: " + orderNumber+". Error message: " + e.getMessage());
			e.printStackTrace();
		} 
    }
				
			

 

Since, Shopify webhook sends the POST API with the JSON body, we need to use API Gateway to call the lambda function. We configured the AWS API Gateway from this Amazon AWS tutorial: Tutorial: Build a Hello World REST API with Lambda proxy integration – Amazon API Gateway.

Step 3: Deploy and test

We manually created the Order in Shopify and waited for Webhook to be executed.  Bingo, we received the Whatsapp notification with few seconds after the order creation.

shopify_whatsapp_message

But, we found that the webhook was executed twice and we received 2 Whatsapp Order Confirmation message with 1 minutes interval. We found about Shopify Webhook retry policy wherein Shopify will re-send the webhook request if they dont received the 200 OK response within 5 seconds of the webhook call.

We checked the AWS Lambda function logs for some hint and we found there were indeed 2 request and the 1st execution took around 8 seconds to execute.

We found the issue with AWS Lambda Cold start. Read here more on AWS Lambda Cold Start:  Operating Lambda: Performance optimization – Part 1 | AWS Compute Blog (amazon.com). In order to fix Cold Start issue, we added a environment in AWS Configuration to prevent Cold Start issue.

As we can see here that the changes worked and the function was executed within 2 seconds.

This is how we fulfilled the customer requirement within thier budget using AWS Lambda function and Wati Whatsapp API. You can start using Wati Whatsapp API using our referral link: https://www.wati.io?ref=tirnavsolutions

Leave A Comment