Introduction #
Developers can enhance Sidekick Threads with integrations to external systems utilizing the App Platform. In particular, developers can build custom applications that:
- Retrieve data from external systems in order to present external information to customers within Sidekick, or trigger behavior in Sidekick based on data retrieved. Examples include, but are not limited to:
- Retrieving an order and showing the order status to a customer
- Retrieving an order. If the order was created in the past 30 days, then tell the user that the order can still be canceled. Otherwise, tell the user the order cannot be canceled.
- Perform actions in an external system from within Sidekick. Examples include, but are not limited to:
- Canceling an order
- Creating a Task in Gladly with the Gladly Task API
Tips and Tricks #
There are two important keys to designing a successful Sidekick app.
Experience Design #
Understand what experience you want to build for your users and design a logical flow chart.
For example, if you would like to build an enhancement to cancel an order, think of the following:
- Should Sidekick be allowed to cancel all orders? If not- what criteria makes an order non-cancelable? For example:
- Orders should not be cancelable if some items are on final sale
- Orders should not be cancelable if they were placed ≥ 100 days ago
- Orders should not be cancelable if they are already canceled
- If an order is not cancelable, what should Sidekick do? For example:
- If an order is non cancelable, state the cancellation policy and close the Conversation
- If an order is cancelable, what should Sidekick do? For example:
- If an order contains multiple items, ask the customer if they want to fully cancel the order – or partial. If they want to cancel partial, then hand off to an Agent
- If an order only contains one item, then cancel the order
- If a cancelation fails, what should Sidekick do? For example:
- Upon failed cancelation, let customer know order could not be canceled and transfer Conversation to an Agent
- If a cancelation succeeds, what should Sidekick do? For example:
- Upon successful cancelation, let customer know order has been canceled and ask if there is anything else they need help on.
Understand your systems #
When building an integration, there are 2 key pieces of information you need to know:
- If you need to retrieve external data and communicate it to an end customer / make decisions based on what it returns:
- How will you retrieve this data (e.g.: a REST API to Get Orders)
- What information do you need to provide to the external system to retrieve this data (e.g.: credentials, an order ID)
- How will you supply the information to the external system to be able to retrieve the data (e.g.: ask the customer for an order ID)
- If you need to perform an action in an external system:
- How will you perform the action (e.g.: a REST API to Cancel Orders)
- What information do you need to provide to the external system to conduct the action (e.g.: an order ID)
- How will you supply the information to the external system to be able to conduct the action (e.g.: collect order ID from the customer)
Goal #
The goal of this tutorial is to build a Thread in Sidekick that tells customers the status of their latest order via Chat.
How To #
Scoping #
Experience Design
In this tutorial, we will design the following experience:
- Customer initiates a Chat session via Glad App
- Customer types in “what is the status of my order?”
- This triggers Sidekick to do the following:
- Retrieve customer’s latest order
- If order is found, send a message that tells them the status of their latest order and close the Conversation
- If order is not found, send a message that tells them the order cannot be found, and then transfer the Conversation
Understand Your Systems
Understand your APIs
Let’s say that you have an OMS, and that OMS has 2 APIs available:
- GET customer: https://gladly-sample-oms.vercel.app/api/customers?emailAddress=
{{email_address}}
- Upon successful retrieval, retrieves an object that looks like this:
{
"id": "YW5kcmV3QGV4YW1wbGUub3Jn",
"fullName": "Lamont Russel",
"phones": [
"+644938853685"
],
"emails": [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
],
"ltv": "$142.11"
}
- GET customer orders: https://gladly-sample-oms.vercel.app/api/orders?customerId=
{{oms_customer_id}}
- Upon successful retrieval, retrieves an object that looks like this, where orders are sorted by
orderDate
descending:
- Upon successful retrieval, retrieves an object that looks like this, where orders are sorted by
{
"id": "1f85eb0a-caa8-42ee-ad10-1dcfd09d01e2",
"orderNumber": "sGMtsfUf",
"status": "pending",
"shippingAddress": "64389 Sienna Village Apt. 296",
"billingAddress": "",
"orderDate": "2021-08-19T06:42:30.609Z",
"customerId": "YW5kcmV3QGV4YW1wbGUuY29t",
"lineItems": [
{
"id": "f9930951-ff95-4e34-8ce4-e7320e01f538",
"quantity": 2,
"productId": "ab30f03a-be65-4b97-81f6-8f3157b13fbc",
"status": "return_initiated"
},
{
"id": "8e8a31b8-75e0-4edc-8a98-98fd29a6a18a",
"quantity": 3,
"productId": "5d2ba910-fd1b-4939-8f57-f71199964e95",
"status": "return_initiated"
},
{
"id": "e6f76583-40ca-4284-9baa-518a8a4e52e5",
"quantity": 4,
"productId": "38af722b-14be-40f1-a7fd-26b84bb46d15",
"status": "pending"
}
],
"shippingSpeed": "expedited",
"totalPrice": "697.00",
"shippingAndHandling": "816.00"
}
Understand your authentication requirements
In addition, authentication-wise, your OMS just needs the following static header to be supplied across all requests:
apiToken
How do I retrieve the data I need?
For this experience, you need to retrieve a customer’s most recent order’s status.
To retrieve this data, you will first need to:
- Call the GET customer API to retrieve the customer’s ID
- Call the GET customer orders API to retrieve the list of customer’s orders – where the most recent order placed is the first order in the response Array
What information do I need to supply to my external system to retrieve this data?
- For the GET customer API:
- I must supply the customer’s email to the API
- For the GET customer orders API:
- I must supply the OMS customer ID
How will I supply this information to the external system using Glad App and Sidekick?
- For the GET customer API:
- I can collect the customer’s email via the Glad App onboarding process
- For the GET customer orders API:
- I can collect the OMS customer ID upon successful retrieval of a customer profile using the GET customer API
Pre-requisites #
In order to build the above experience, I must ensure:
- I have an
apiToken
to access my OMS APIs - I have a Glad App created that is connected to Sidekick
- Glad App has quick replies turned off
- Glad App has onboarding turned on
Build App #
An App is folder containing files that define how your APIs behave.
Therefore, in this section, we will create an App that has the two APIs we defined above:
• GET customer
• GET customer orders
Install Tools
Install appcfg
- Go to https://github.com/gladly/app-platform-appcfg-cli/releases
- Scroll down to the
Assets
section and download the version that is most relevant to your machine - Unzip the downloaded folder – you should see a file that is named
appcfg
- Drag this file to your Desktop
- Open up Terminal on your Mac
cd ~/Desktop
chmod a+rx appcfg
./appcfg
- Click on the “OK” button
- Open up System Settings > Privacy and Security and click “Allow Anyway”
- Open up Terminal on your Mac
cd ~/Desktop
./appcfg
- Click OK
./appcfg
- After running this, you should now see a help guide
Build App
• This tutorial for an overview of concepts: https://connect.gladly.com/docs/developer-tutorials/article/draft-app-platform-tutorial/
• This tutorial for how the Sample OMS App we are installing is built: https://connect.gladly.com/docs/developer-tutorials/article/draft-app-platform-tutorial/
- Download https://github.com/gladly/app-platform-examples and drag the
SampleOMS
folder to your Desktop - Open up the following files in your favorite code editor. Let’s cover some key concepts – these are all specified in the more in-depth App Platform tutorial, so think of the following as a cheat sheet for a robust application.
app/authentication/headers/apiToken.gtpl
- Each file name in the
/headers/
folder represents the key of a header we send for every API request to the Sample OMS - In this particular case, we only need to send the header name
apiToken
, which is why we only have one file in this folder - The
.gtpl
extension represents the Go templating language, which you can find documented here: https://masterminds.github.io/sprig/ - The file contains the following:
{{.integration.secrets.apiToken}}
–integration.secrets
is a reserved object in App Platform that contains all the secrets associated with your application. This is a great place to put things like API tokens, secrets, credentials that you don’t want to make public. In this case, we are accessingapiToken
, a secret we store in theintegration.secrets
object. - The
integration.secrets
values get set during the App installation process we will go through in the next section
- Each file name in the
app/data/pull/customer/request_url.gtpl
- Data pulls are stored in the
/data/
folder, whereas actions are stored in the/actions/
folder - Each API you need access to should be stored in its own subfolder (e.g.: customers) within
/data/
. In this tutorial, we only need access to two APIs:customer
andorders
, though the Sample OMS app you downloaded defines more. request_url.gtpl
is the file that is utilized to build the request URL for the API you need to call..customer
is a reserved object that you can access in API calls – it represents the customer object that is undergoing the Sidekick experience. For more information on what values are available in the customer object, see the “Gladly Customer Profile data” section here
- Data pulls are stored in the
app/data/pull/customer/config.json
- In this file, we specify that the object name for the customer API response is called
sample_oms_customer
- We also specify that the request is a
GET
request
- In this file, we specify that the object name for the customer API response is called
app/data_schema.graphql
- You’ll see here that we define an object called
Customer
– which is based off of the data pull forcustomer
that we saw above - Importantly, you’ll see that an
orders
Array is present in the customer object:orders: [Order] @parentId(template: "{{.id}}")
. This means that for each request to get a customer, we also trigger a request to get this customer’s orders.
- You’ll see here that we define an object called
app/data/pull/orders/config.json
- You’ll see in this configuration file a value called
dependsOnDataTypes
– this field ensures that we get the customer data first before we execute this API request
- You’ll see in this configuration file a value called
app/data/pull/orders/request-url.gtpl
- You’ll see here that the customerId query is built using this template
{{urlquery (index .externalData.sample_oms_customer 0).id}}
- In the above,
externalData
is a reserved object in the App Platform - Since this call is dependent on the
customers
call succeeding, and we know that the customer object is saved in thesample_oms_customer
object based on this file – we can usesample_oms_customer
to build thecustomerId
parameter in this API request
- You’ll see here that the customerId query is built using this template
- Once you’re done inspecting the application, open up Terminal
export GLADLY_APP_CFG_ROOT=~/Desktop/SampleOMS
./appcfg build
- The above will build a zip file
Install App
Send your zip file to the PS Engineer you are working with and ask them to install it. Make sure to specify the secrets that you want the PS Engineer to configure (e.g.: set apiToken to 12345)
Build Sidekick Thread #
Once your PS Engineer has installed the application, you can build your Sidekick Thread:
- Go to your Sidekick dashboard and click on “Create Thread”
- Name the Thread “Track” – this will auto-trigger if Sidekick detects the interaction is of type “Track”
- Click on + and then add an action called
customer - Sample OMS
– this corresponds to the customer data pull you built above! Name this memorysample_oms_customer
- Then, click on + and then add an action called
Add Rules
- Add a rule and call it “Order Not Found” with the following properties
- If
sample_oms_customer
>orders
>status
>Does Not Exist
- Here, we are determining that if sample_oms_customer.orders[n].status does not exist, we should proceed forward with this rule as no orders have been found
- Then
Action
>Update Conversation
- Click on Edit Update Conversation
- Add a
Send Reply
action with the following text:We are unable to find your order. We will transfer you to an Agent.
- Add a
Transfer Conversation
Action
- Add a
- Click on Back to Thread
- If
- Add a rule called “Order Found” with the following properties
- If
sample_oms_customer
>orders
>status
>Exists
- Here, we are determining that if sample_oms_customer.orders[n].status does exist, we should proceed forward with this rule as an order has been found
- Then
Action
>Send Reply
- Set the reply to
Hi {{sample_oms_customer.fullName}} - your order ID {{sample_oms_customer.orders[0].id}} is currently {{sample_oms_customer.orders[0].status}}
- Here, we are accessing the
fullName
property of thesample_oms_customer
object - We are also accessing the first order in the list of orders associated with this customer and communicating its status
- Since we are not transferring this conversation, and there are no further actions, Sidekick will close the interaction
- Here, we are accessing the
- If
- Add a rule and call it “Order Not Found” with the following properties
Test #
- Go to Gladly and then go to Settings > Glad App and preview your Glad App
- Onboard (i.e.: supply email and password)
- Type in “what is the status of my order”
- View the response!