Shopify Customer Care powered by GenAI
Building a Shopify Customer Care Agent powered by GenAI with Amazon Bedrock
How does the application work?
๐ค What are Amazon Bedrock Agents?
โ๏ธ Build an Amazon Bedrock Agent in 4 steps
๐ Step 1: Generate Shopify Credentials
Install the app and get credentials:ย ย ๐ Step 2: Create OpenAPI 3.0 spec
๐งโ๐ป Step 3: Create a Lambda Function
๐ Step 4: Creating a Bedrock Agent
๐ฑ The Bedrock Agent is not working: Lambda Function missing permissions
- Create an Amazon Bedrock Agent using one of the foundational models available: Claude Instant V1.
- Create an openAPI 3.0 spec that works with an Amazon Bedrock Agent.
- Create a Lambda Function that meets the requirements to reply an Amazon Bedrock Agent request.
- Create Shopify credentials. Given that we're going to use Shopify for this tutiral we need an Access Token to query its API.
- Write an OpenAPI 3.0 spec that contains all the documentation about our API to instruct the Agento n how to use it.
- Create a Lambda function that will be in charge of querying the order status in Shopify.
- Create and setup the Agent.
- Create a Custom App in Shopify:
- Define permissions:ย
- We only need read_orders permission: https://help.shopify.com/en/manual/apps/app-types/custom-apps#get-the-api-credentials-for-a-custom-appย
- API Endpoints
- HTTP Request Methods accepted
- Parameters for each endpoint and its formatting
- Expected responses.
1
2
3
4
5
6
7
8
9
{
"openapi": "3.0.0",
"info": {
"title": "Order Info API",
"version": "1.0.0",
"description": "API that provides and identifies order details"
},
"paths":{}
}
- /orders/{orderId}: It will receive GET requests and returns the order information. orderId is a required parameter passed in the URL.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"paths": {
"/orders/{orderNumber}": {
"get": {
"summary": "Gets information about an order",
"description": "Gets the entire information about an order based on its number",
"operationId": "getOrderInfo",
"parameters": [
{
"name": "orderNumber",
"in": "path",
"description": "ID of the order that needs to be fetched",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"paths": {
"/orders/{orderNumber}": {
"get": {
"summary": "Gets information about an order",
"description": "Gets the entire information about an order based on its number",
"operationId": "getOrderInfo",
"parameters": [
{
"name": "orderNumber",
"in": "path",
"description": "ID of the order that needs to be fetched",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {}
}
- Build a response that meets Bedrock Agent requirements.
- Status Code: 200
- An object with a property named content: application/json
- Enum of object properties.
- Object properties:
- Id: Order Number
- Status: Order Status
- MoreInfo: If the order is fulfilled, info about the tracking number, url, etc.
1
2
3
4
5
6
7
8
9
{
'application/json': {
'body': JSON.stringify({
"id": orderNumber,
"status": orderStatus,
"moreInfo": moreInfo
})
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
"responses": {
"200": {
"description": "Object with the order information",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"status": {
"type": "string",
"description": "Status of the order"
},
"moreInfo": {
"type" :"string",
"description": "More information about the order usually the tracking URL"
}
}
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
"openapi": "3.0.0",
"info": {
"title": "Order Info API",
"version": "1.0.0",
"description": "API that provides and identifies order details"
},
"paths": {
"/orders/{orderNumber}": {
"get": {
"summary": "Gets information about an order",
"description": "Gets the entire information about an order based on its number",
"operationId": "getOrderInfo",
"parameters": [
{
"name": "orderNumber",
"in": "path",
"description": "ID of the order that needs to be fetched",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"200": {
"description": "Object with the order information",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"status": {
"type": "string",
"description": "Status of the order"
},
"moreInfo": {
"type" :"string",
"description": "More information about the order usually the tracking URL"
}
}
}
}
}
}
}
}
}
}
}
- Go to AWS Console - Lambda: https://console.aws.amazon.com/lambda/home#/functions
- Create Function
- Author from Scratch
- Set a name
- Runtime: NodeJS (you can use Python or any programming language you feel comfortable with)
- Architecture: X86_64
- URL
- Headers
- Shopify requires a special header to authenticate the requests, named X-Shopify-Access-Token
- Content-Type
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const axios = require('axios');
/**
Let's create the axios request to Shopify
In order to get the Shopify-Access Token we'll need to create a custom app in Shopify to use the token
*/
const shopifyRequest = axios.create({
baseURL: `https://your-shopify-store.myshopify.com/admin/api/2024-01/graphql.json`,
headers: {
'X-Shopify-Access-Token': '[HERE GOES YOUR ACCESS TOKEN]',
'Content-Type': 'application/json'
}
});
exports.handler = async (event) => {
// Lambda Function Code GOES here
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const orderNumber = event.parameters[0].value;
const query = `{
orders(first:1,query: "name:${orderNumber}") {
edges {
node {
name
displayFulfillmentStatus
fulfillments {
trackingInfo {
number
url
}
}
}
}
}
}`;
// Let's get the response from Shopify
const shopifyResponse = await shopifyRequest.post('', { query: query });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Let's get the order fulfillment status from the response
const orderStatus = shopifyResponse.data.data.orders?.edges[0]?.node.displayFulfillmentStatus;
const moreInfo = shopifyResponse.data.data.orders?.edges[0]?.node.fulfillments[0]?.trackingInfo[0]?.url;
// Let's return the response
let responseBody = {
'application/json': {
'body': JSON.stringify({
"id": orderNumber,
"status": orderStatus,
"moreInfo": moreInfo
})
}
}
- ActionGroup
- Path
- HTTP Method
- Status Code
- Body (responseBody)
1
2
3
4
5
6
7
8
let actionResponse = {
actionGroup: event.actionGroup,
apiPath: event.apiPath,
httpMethod: event.httpMethod,
httpStatusCode: 200,
responseBody: responseBody,
}
1
2
3
4
5
6
let response = {
messageVersion: '1.0',
statusCode: 200,
response: actionResponse,
};
return response;
- Give your agent a name: OrderInfoAgent
- Require User Input: YES
- Check if you would like to use an existing role or create a new one, encription and timeout (how long the session will last), and tags.
- Select the FM (Foundational Model):
- Here's a guide about how to choose a LLM : https://community.aws/posts/how-to-choose-your-llm
- If you don't see any LLM in the dropdown, this is because you need to enable them: (https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html).
- Write the instructions for your agent: It is super important to write an excellent prompt, even though the Foundational Model might be capable of understanding multiple languages, writing the prompot in English will make thigs easier, ie: You're a kind customer care agent that is here to provide order status information to our customers, on each response you'll provide as much information as you can grab about the order and you'll always thank our customer for being a loyal customer, if you don't know the answer tell the customer to contact customercare@mycompany.com
- Name: GetOrderInformation
- Select the Lambda Function created in the previous step
- Select the OpenAPI spec
4) Don't create a knowledgebase, click Next, review all the information and click Create Agent.
- In the Lambda Function go to Configurations -> Permissions
- In the section resource based policy statements click "Add Permissions"
ย 3. Select AWS Service and open the services list. Unfortunately, Amazon Bedrock (at the moment of writing this article) is not part of this list. Select: Other
- Fill in the information
- Understand what customer wants
- Look for the information needed, invoke an API to execute an action.
- Provide the answer to the customer.
ย