Integrating Shopify with Slack for Quick Order Processing in Choreo

Chameera Rupasinghe
Choreo Tech Blog
Published in
11 min readAug 21, 2023

Introduction

Real-time Order Notifications and Customer Support

In the fast-paced world of e-commerce, staying informed about new orders and being able to provide excellent customer service are crucial for maintaining customer satisfaction and driving sales. Integrating Shopify with Slack and email notifications can streamline these processes and enhance the overall customer experience.

How it works

Order Notifications: When a new order is placed on your Shopify store or an existing order is canceled, an automated notification can be sent to a designated Slack channel and to a given email address. This immediate alert allows your team to quickly acknowledge and process orders, reducing the risk of delays or oversights.

In this tutorial we will learn how to create an integration that will send a notification to a Slack channel along with an email for order creations and cancellations in your Shopify store to make the order handling process efficient. For the integration we will create a development store, an app in the development store, set up permissions for the app, obtain API secrets, and create webhooks for the triggers Order Create and Order Cancel.

Prerequisites

  1. Shopify Partner Account. (You can create one here).
  2. Slack subscription.
  3. Ballerina (Version 2201.7.1 is preferred).

Step 1: Setting Up Shopify

1.1 Creating a Development Store

To start the integration, let’s create a development store in Shopify using your Shopify Partner account.

Fig 1.1 Creating a development store

Navigate to the newly created development store and log in with the same credentials you used for setting up the Shopify Partner account.

1.2 Creating a Developer App

To create a trigger for order creation and order deletion, we need a Shopify App. In your development store, navigate to Settings -> Apps and sales channels -> Develop Apps to create a new app. Let’s name this app, order-manager.

Fig 1.2 Creating a Shopify App

1.3 Obtaining App Secrets

Now our app is ready. To add triggers for Order Create and Order Cancel, we need to set up permissions for the app. Navigate to the newly created app and click on “Configure Admin API Scopes” to set up permissions.

Fig 1.3 App overview

We will need “read_orders” permission. Select “read_orders’’ from the list. Before saving the configuration, we need to be mindful about the “Event version” under the “Webhook subscriptions” as we are going to create a webhook for this trigger. This version states the API version of the Shopify Webhook API. Let’s go with the Latest stable version 2023–07.

Fig 1.4 Webhook event version selection

After saving the configurations, our app is ready to be installed. Click on “Install app” and confirm the prompted message.

Once the app is installed, it will reveal the API credentials. Make sure to copy the “Admin API access token” and the “API secret key” as these are needed for the Slack Webhook creation and implementation of our integration.

We are all set to move to the next step of setting up the Slack channel. We’ll re-visit Shopify to create webhooks.

Step 2: Setting up Slack

We need a Slack workspace, a channel to post updates on orders and an app associated with the workspace with relevant permissions. To interact with the app we need to obtain an OAuth token with required permissions.

2.1 Creating an App with relevant permissions

I have a “Shopify Slack” Slack workspace. Let’s create an app for this. Go to Slack API and create a new app from the “Your Apps” section. Name the app, select the workspace, and create the app.

Fig 1.5 Creating a Slack App

To obtain the OAuth token, navigate to the “OAuth & Permissions” section.

Fig 1.6 OAuth & Permissions

Let’s setup scopes and get the Bot OAuth token. We are going to need the “channels:write”, “channels:read”, “chat:write”, and “chat:write.public” Bot Token scopes. Now install the OAuth Token to the workspace using the “Install to Workspace” button. Copy the Bot User OAuth Token to use it in the integration.

Step 3: Implementing Shopify-Slack connection using Ballerina Shopify Trigger

Let’s start integrating. We are going to write the integration using Ballerina. To get started with a project, let’s run the command below in the terminal.

bal new shopify-slack-order-notification-service

This will generate the main.bal file and the Ballerina.toml file. The main.bal file is the file in which we write our integration logic. The Ballerina.toml identifies the directory as a Ballerina project (package). It contains all the meta information that is needed to build your package. We can remove all the content from the main.bal file and start coding.

3.1 Integrating Shopify Listener

First, let’s implement the Shopify trigger. Starting with importing the ballerinax/trigger.shopify module.

import ballerinax/trigger.shopify;

Next we need a Shopify ListenerConfig, to configure the Shopify API secret key obtained from the Shopify app we created. Let’s declare a configurable “shopifyApiSecretKey” and assign it as the “apiSecretKey” in the ListenerConfig.

configurable string shopifyApiSecretKey = ?;

shopify:ListenerConfig listenerConfig = {
apiSecretKey: shopifyApiSecretKey
};

Next, let’s create a Listener using the Listener config.

listener shopify:Listener shopifyListener = new(listenerConfig, 8090);

I’m using port 8090 here. This can be changed as per the requirement.

To receive Order Create and Order Cancel notifications, we need to implement the OrdersService.

service shopify:OrdersService on shopifyListener {
remote function onOrdersCreate(shopify:OrderEvent event) returns error? {
// Write your logic here
}
remote function onOrdersCancelled(shopify:OrderEvent event) returns error? {
// Write your logic here
}
remote function onOrdersFulfilled(shopify:OrderEvent event) returns error? {
// Write your logic here
}
remote function onOrdersPaid(shopify:OrderEvent event) returns error? {
// Write your logic here
}
remote function onOrdersPartiallyFulfilled(shopify:OrderEvent event) returns error? {
// Write your logic here
}
remote function onOrdersUpdated(shopify:OrderEvent event) returns error? {
// Write your logic here
}
}

The OrdersService has multiple built-in triggers for order related actions. Let’s implement only the “onOrdersCreate” and “onOrdersCancelled” methods for this tutorial. Let’s revisit the implementation details after we integrate the Slack Client.

3.2 Integrating Slack Client

To integrate the Slack Client we need import the “ballerinax/slack” module.

import ballerinax/slack;

Let’s create a configurable to add the OAuth token we generated for the Slack App. This OAuth token will be used as the token in the Slack ConnectionConfig to configure the Slack client.

configurable string slackOauthToken = ?;

slack:ConnectionConfig slackConfig = {
auth: {
token: slackOauthToken
}
};

Now create a Slack Client using the slackConfig we declared above.

slack:Client slackClient = check new(slackConfig);

Let’s use this “slackClient” to send messages to our #order slack channel upon order creation and cancellation. We can implement the “onOrdersCreate” and “onOrdersCancelled” methods.

service shopify:OrdersService on shopifyListener {
remote function onOrdersCreate(shopify:OrderEvent event) returns error? {

string odrerNumber = event?.name.toString();
string currency = event?.presentment_currency.toString();
string totalPrice = event?.total_price.toString();
string message = "Order No: " + odrerNumber + " Total Price: " + currency + totalPrice;
slack:Message messageParams = {
channelName: "orders",
text: "New order! " + message
};

string _ = check slackClient->postMessage(messageParams);
}
remote function onOrdersCancelled(shopify:OrderEvent event) returns error? {

string odrerNumber = event?.name.toString();
string currency = event?.presentment_currency.toString();
string totalPrice = event?.total_price.toString();
string message = "Order No: " + odrerNumber + " Total Price: " + currency + totalPrice;
slack:Message messageParams = {
channelName: "orders",
text: "Order Canceled! " + message
};

string _ = check slackClient->postMessage(messageParams);

log:printInfo("Message sent: " + messageParams.text);
}

//Other functions
}

I have composed a message to send to the slack channel with the order number, total and the currency.

3.3 Adding the Email Sender

To add the Choreo email sender to send an email for order creation and cancellation let’s import that sendemail module.

import wso2/choreo.sendemail;

Next declare a configurable to provide the recipient email address and create the sendemail client.

configurable string toEmail = ?;

sendemail:Client emailClient = check new ();

Let’s implement the email notification logic for the onOrdersCreate and onOrdersCancelled methods.

remote function onOrdersCreate(shopify:OrderEvent event) returns error? {

//exiting implementation

string emailResponse = check emailClient->sendEmail(toEmail, subject = "New Order Created: " + orderNumber, body = "Check on the newly created order. " + message);
log:printInfo("Email sent " + emailResponse);
}

remote function onOrdersCancelled(shopify:OrderEvent event) returns error? {
//exiting implementation

string emailResponse = check emailClient->sendEmail(toEmail, subject = "Order Cancelled: " + orderNumber, body = "Check on the cancelled order. " + message);
log:printInfo("Email sent " + emailResponse);
}

//Other functions

Finally your code should look like this.

import ballerinax/trigger.shopify;
import ballerinax/slack;
import wso2/choreo.sendemail;
import ballerina/log;


configurable string shopifyApiSecretKey = ?;
configurable string slackOauthToken = ?;
configurable string toEmail = ?;

slack:ConnectionConfig slackConfig = {
auth: {
token: slackOauthToken
}
};

slack:Client slackClient = check new(slackConfig);

shopify:ListenerConfig listenerConfig = {
apiSecretKey: shopifyApiSecretKey
};

sendemail:Client emailClient = check new ();

listener shopify:Listener shopifyListener = new(listenerConfig, 8090);

service shopify:OrdersService on shopifyListener {
remote function onOrdersCreate(shopify:OrderEvent event) returns error? {

string orderNumber = event?.name.toString();
string currency = event?.presentment_currency.toString();
string totalPrice = event?.total_price.toString();
string message = "Order No: " + orderNumber + " Total Price: " + currency + totalPrice;
slack:Message messageParams = {
channelName: "orders",
text: "New order! " + message
};

string _ = check slackClient->postMessage(messageParams);

log:printInfo("Message sent: " + messageParams.text);
string emailResponse = check emailClient->sendEmail(toEmail, subject = "New Order Created: " + orderNumber, body = "Check on the newly created order. " + message);
log:printInfo("Email sent " + emailResponse);
}
remote function onOrdersCancelled(shopify:OrderEvent event) returns error? {

string orderNumber = event?.name.toString();
string currency = event?.presentment_currency.toString();
string totalPrice = event?.total_price.toString();
string message = "Order No: " + orderNumber + " Total Price: " + currency + totalPrice;
slack:Message messageParams = {
channelName: "orders",
text: "Order Canceled! " + message
};

string _ = check slackClient->postMessage(messageParams);

log:printInfo("Message sent: " + messageParams.text);
string emailResponse = check emailClient->sendEmail(toEmail, subject = "Order Cancelled: " + orderNumber, body = "Check on the cancelled order. " + message);
log:printInfo("Email sent " + emailResponse);
}
remote function onOrdersFulfilled(shopify:OrderEvent event) returns error? {
// Write your logic here
}
remote function onOrdersPaid(shopify:OrderEvent event) returns error? {
// Write your logic here
}
remote function onOrdersPartiallyFulfilled(shopify:OrderEvent event) returns error? {
// Write your logic here
}
remote function onOrdersUpdated(shopify:OrderEvent event) returns error? {
// Write your logic here
}
}

I have imported the “ballerina/log” module to add some logs to each trigger as well.You can implement the other methods as per your requirement.

We are all set to deploy our integration in Choreo!

Step 4: Deploying in Choreo:

In order to deploy our integration in Choreo, the code needs to be in a GitHub or Bitbucket repository. I have already added my ballerina project to shopify-slack-order-notfication-service Github project.

4.1 Deploy in Choreo

Let’s create an event-triggered integration component in Choreo to deploy our project.

Navigate to the Create a New Component page in your Choreo Project and select Event-Triggered Integration.

Fig 1.7 Create a New Component page

Provide a name and a description. Make sure to keep the Access Mode as External since we are going to use this to get notifications over the internet.

Fig 1.8 General details in event-triggered integration creation

Next, authorize the version control vendor. Since we are using Github here, let’s go ahead and authorize Github. Here we can give permission for Choreo to view and work with our git repositories.

After successfully authorizing, we can connect our repository to this component. Make sure to select the Ballerina build preset and set the access mode to External.

Fig 1.9 Repository connect in event-triggered integration creation

Next we can select the trigger type. Choreo has a collection of triggers we can use to get a head start in webhook integrations. Let’s select Shopify option.

Fig 1.10 Trigger type selection in event-triggered integration creation

In the next page we can see the selected trigger type.

Fig 1.11 Trigger category selection in event-triggered integration creation

Click on create.

After the event-triggered integration component is created, navigate to the Deploy page to deploy the integration. Click on “Configure & Deploy” to start the deployment process. We have to provide values to the configurables that were declared in the code.

Fig 1.12 Setting values for configurations

Add the “API secret key” obtained from the Shopify App as the value for the shopifyApiSecretKey, “OAuth token” obtained from the Slack App as the value for the slackOauthToken, and the recipient email address as the toEmail. Click “Deploy” to proceed with the deployment. Wait for a few seconds for the deployment to be successful.

After the deployment is complete, we can see the “Invoke URL” for the component. Let’s copy this to use in the Shopify Webhook creation.

Fig 1.13 Invoke URL for the integration

4.2 Create Shopify webhook

To create Shopify webhooks, we will use the Shopify Webhook API and send a POST request to it.. We can use CURL or any other tool to send the request. The sample curl command will look like the following.

curl -d '{"webhook":{"address":"{invoke_url}","topic":"orders/create","format":"json"}}' \
-X POST "https://{developer_store_url}/admin/api/2023-04/webhooks.json" \
-H "X-Shopify-Access-Token: {access_token}" \
-H "Content-Type: application/json"

Let’s use Postman to send the request. First, let’s create a webhook for the order/create topic.

Fig 1.14 Using Postman to create Shopify webhook

Example payload;

{
"webhook": {
"topic": "orders/create",
"address": "{{invoke-url}}",
"format": "json"
}
}

Make sure to replace the {{developer-store-url}} with your developer store URL and {{invoke-url}} with the invoke URL obtained from Choreo. Add the “X-Shopify-Access-Token” header and set the “Admin API access token” obtained from the Shopify app as the value.

Sending this request will create a webhook for orders/create topic. Similarly create another webhook for orders/cancelled using the same method. Sample payload for order cancellation webhook is shown below.

{
"webhook": {
"topic": "orders/cancelled",
"address": "{{invoke-url}}",
"format": "json"
}
}

We can now test our integration.

Step 5: Testing the Integration

To test the integration, let’s create an order in the Shopify development store and observe our slack channel.

Fig 1.15 Order creation in Shopify Store

You can now see the message in the slack channel.

Fig 1.16 Order creation notification received in Slack channel

You can see the email notification in the inbox of the email you provided.

Fig 1.17 Order creation notification received via email

We can test order cancellation by canceling an order in the Shopify development store.

Fig 1.18 Order cancellation in Shopify store

You can now see the message for the canceled order in the slack channel

Fig 1.19 Order cancellation notification received in Slack channel

The email notification for cancellation received.

Fig 1.20 Order cancellation notification received via email

The integration is working perfectly!

Conclusion

Shopify to slack integration is a useful tool in managing orders and user queries efficiently. Integration logic can be easily implemented with Ballerina using the available Ballerina Shopify and Slack packages. Using Choreo as the integration platform with native support for Ballerina makes the integration process easy and reliable.

References

--

--

Chameera Rupasinghe
Choreo Tech Blog

Senior Software Engineer | Computer Science and Engineering graduate