Skip to content

Commit 01910a5

Browse files
authored
Merge pull request #2344 from ragibmahsan/edit-ragibmahsan-feature-shopify-eventbridge-lambda
Edit ragibmahsan feature shopify eventbridge lambda
2 parents b14c0f7 + c8f3368 commit 01910a5

14 files changed

+474
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Shopify Amazon EventBridge Partner Integration to AWS Lambda
2+
3+
This pattern demonstrates how to use the Shopify Amazon EventBridge SaaS integration and AWS Lambda to process events from Shopify. This pattern is leveraging the Shopify Amazon EventBridge webhook integration to send product updated events from the customer's Shopify account to their AWS account, via an Amazon EventBridge Partner event bus. Once the Shopify events are in the customer's account, an Amazon EventBridge rule routes updated product events to a downstream Lambda function. In production cases, the Lambda function could transform the event, send it to a downstream application, archive it in a warehouse service, or send a notification email to a customer using SES. Amazon CloudWatch Log Groups are provisioned for debugging and auditing. This pattern deploys two EventBridge rules, one Lambda function, and two CloudWatch Log Groups.
4+
5+
Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/shopify-eventbridge-lambda
6+
7+
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
8+
9+
## Requirements
10+
11+
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
12+
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
13+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
14+
* [AWS CDK CLI](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) (AWS CDK) installed
15+
* [Create a Shopify Account](https://accounts.shopify.com/signup?rid=645a3a17-4ed1-4d68-94ab-de416384059a) if you do not already have one and log in.
16+
* [Set up the Shopify Amazon EventBridge webhook integration](https://shopify.dev/docs/apps/build/webhooks/configuration/eventbridge) if you have not already configured the integration.
17+
18+
19+
## Deployment Instructions
20+
21+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
22+
```
23+
git clone https://github.com/aws-samples/serverless-patterns
24+
```
25+
2. Change directory to the pattern directory:
26+
```
27+
cd shopify-eventbridge-lambda
28+
```
29+
3. From the command line, use AWS CDK to deploy the AWS resources for the pattern as specified in the app.py file. A command-line argument is needed to deploy the CDK stack, "shopifyEventBusName". This argument should be the name of the **SaaS event bus** associated with your Shopify [partner event source](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-saas.html).
30+
```
31+
cdk deploy --parameters shopifyEventBusName=SAAS_EVENT_BUS_NAME_HERE
32+
```
33+
34+
4. Note the outputs from the CDK deployment process. These contain the resource names and/or ARNs which are used for testing. This stack will output the name of the Lambda function deployed for testing to the CLI. See the example below.
35+
36+
```
37+
Outputs:
38+
ShopifyIntegrationStack.ShopifyProcessFailedLoginLambdaOutput = ShopifyIntegrationStack-ShopifyProcessFailedLoginLambd....
39+
```
40+
41+
## How it works
42+
43+
This service interaction uses an existing Shopify SaaS integration in the customer's AWS account. If you do not have the Shopify SaaS integration set up in your AWS account, please set it up before deploying this pattern. View the [integration on Shopify's developer site](https://shopify.dev/docs/apps/build/webhooks/configuration/eventbridge#eventbridge-payload-structure).
44+
45+
This pattern demonstrates how to:
46+
1. Write EventBridge rules that match Shopify's event pattern
47+
2. Send events from Shopify's EventBridge webhook integration to Amazon CloudWatch for logging and debugging
48+
3. Transform Shopify events using AWS Lambda and allows you to connect to other services going forward
49+
50+
See the below architecture diagram from the data flow of this pattern.
51+
52+
![Architecture Diagram](./img/readme-arch-diagram.png)
53+
54+
## Testing
55+
56+
### Test the AWS Lambda Function
57+
58+
The event.json file included in this pattern is a sample EventBridge event from Shopify. This event can be used to test the Lambda function and EventBridge rules deployed by this pattern.
59+
60+
To test the Lambda function via the CLI, copy and paste the following command, replacing the variables in <> with your own values:
61+
```
62+
aws lambda invoke --function-name <ShopifyIntegrationStack-ShopifyProcessProductUpdatedLambd-....> --payload file://event.json --cli-binary-format raw-in-base64-out response.json
63+
```
64+
65+
You should receive a response that looks like:
66+
```
67+
{
68+
"StatusCode": 200,
69+
"ExecutedVersion": "$LATEST"
70+
}
71+
```
72+
73+
The command should have create a response.json file in your directory. If you open this file, you see the output of the Lambda function.
74+
75+
### Test the EventBridge Rule
76+
77+
You cannot put events on the Shopify event bus, only Shopify can publish events to this event bus. To test that the EventBridge rules deployed by this pattern were successfully deployed, follow these instructions:
78+
79+
1. Navigate to the Amazon EventBridge console. Select "Rules".
80+
81+
2. From the Event bus list, choose the SaaS event bus associated with your Shopify partner event source.
82+
83+
3. From the Rules list, select the "ShopifyIntegrationStack-ShopifyProductUpdatedEventsRule54D..."
84+
85+
![EventBridge Console](./img/EBconsole-rules.png)
86+
87+
4. Choose "Edit" to enter the rule editor. Click through to "Step 2. Build Event Pattern."
88+
89+
![EventBridge Console](./img/BuildEvent.png)
90+
91+
5. Scroll down to "Sample event - optional." Select "Enter my own," and delete the pre-populated event. Copy the contents of event.json into the event editor.
92+
93+
![EventBridge Console](./img/SampleEvent.png)
94+
95+
6. Scroll down to "Event pattern." Choose "Test Pattern."
96+
97+
![EventBridge Console](./img/TestEvent.png)
98+
99+
You should see a green box appear that says "Sample event matched the event pattern." This means that the rule will successfully route incoming events to the AWS Lambda function.
100+
101+
![EventBridge Console](./img/TestEventSuccessful.png)
102+
103+
104+
## Cleanup
105+
106+
1. Delete the stack
107+
```bash
108+
cdk destroy
109+
```
110+
111+
----
112+
Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
113+
114+
SPDX-License-Identifier: MIT-0

shopify-eventbridge-lambda/app.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env python3
2+
import os
3+
4+
import aws_cdk as cdk
5+
from aws_cdk import (
6+
Stack,
7+
aws_s3 as s3,
8+
aws_lambda as _lambda,
9+
RemovalPolicy,
10+
aws_events as events,
11+
aws_events_targets as targets,
12+
aws_iam as iam,
13+
aws_logs as logs,
14+
Duration,
15+
CfnParameter,
16+
CfnOutput
17+
)
18+
19+
from constructs import Construct
20+
21+
class ShopifyIntegrationStack(Stack):
22+
23+
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
24+
super().__init__(scope, construct_id, **kwargs)
25+
26+
# Stack inputs
27+
SHOPIFY_PARTNER_EVENT_BUS = CfnParameter(self, id="shopifyEventBusName", type="String",
28+
description="The name of event bus the Shopify Partner EventSource is associated with.")
29+
30+
# Turn partner event bus from string to IEventBus object
31+
partner_event_bus = events.EventBus.from_event_bus_name(scope=self, id='partner-event-bus', event_bus_name=SHOPIFY_PARTNER_EVENT_BUS.value_as_string)
32+
33+
# CloudWatch Logs Group that stores all events sent by Shopify for debugging or archive
34+
log_group = logs.LogGroup(
35+
self, "Shopify-all-events",
36+
retention=logs.RetentionDays.ONE_DAY,
37+
removal_policy=RemovalPolicy.DESTROY
38+
)
39+
40+
# CloudWatch Logs Group that stores specific events from Shopify for debugging or archive
41+
log_group_product_updated = logs.LogGroup(
42+
self, "Shopify-product-updated-events",
43+
retention=logs.RetentionDays.ONE_DAY,
44+
removal_policy=RemovalPolicy.DESTROY
45+
)
46+
47+
lambda_role = iam.Role(scope=self, id='shopify-cdk-lambda-role',
48+
assumed_by=iam.ServicePrincipal('lambda.amazonaws.com'),
49+
managed_policies=[
50+
iam.ManagedPolicy.from_aws_managed_policy_name(
51+
'service-role/AWSLambdaBasicExecutionRole')
52+
]
53+
)
54+
55+
# A Lambda function to consume and process specific events
56+
shopify_process_product_updated_events_lambda = _lambda.Function(
57+
self,
58+
id='ShopifyProcessProductUpdatedLambda',
59+
runtime=_lambda.Runtime.PYTHON_3_8,
60+
code=_lambda.Code.from_asset('src'),
61+
handler='ShopifyProcessProductUpdated.handler',
62+
role=lambda_role,
63+
timeout=Duration.seconds(15)
64+
)
65+
66+
# EventBridge Shopify all events rule
67+
shopify_all_events_rule = events.Rule(
68+
self,
69+
id="ShopifyAllEventsRule",
70+
event_bus=partner_event_bus
71+
)
72+
73+
# Add event pattern to rule
74+
shopify_all_events_rule.add_event_pattern(
75+
source=events.Match.prefix('aws.partner/shopify.com'),
76+
)
77+
78+
# CloudWatch Log Group as target for EventBridge Rule
79+
shopify_all_events_rule.add_target(targets.CloudWatchLogGroup(log_group))
80+
81+
# EventBridge Shopify product updated events
82+
shopify_product_updated_rule = events.Rule(
83+
self,
84+
id="ShopifyProductUpdatedEventsRule",
85+
event_bus=partner_event_bus
86+
)
87+
88+
# Add rule to the event bus for specific events
89+
shopify_product_updated_rule.add_event_pattern(
90+
source=events.Match.prefix('aws.partner/shopify.com/shop-event-bus'),
91+
detail_type=["shopifyWebhook"],
92+
detail={
93+
"metadata": {
94+
"X-Shopify-Topic": ["products/update"]
95+
}
96+
}
97+
)
98+
99+
# Lambda as target for EventBridge Rule
100+
shopify_product_updated_rule.add_target(targets.LambdaFunction(shopify_process_product_updated_events_lambda))
101+
102+
# CloudWatch Log Group as target for EventBridge Rule
103+
shopify_product_updated_rule.add_target(targets.CloudWatchLogGroup(log_group_product_updated))
104+
105+
# Print the Lambda function name
106+
CfnOutput(self, "ShopifyProductUpdatedEventsLambdaOutput", value=shopify_process_product_updated_events_lambda.function_name)
107+
108+
app = cdk.App()
109+
description = (
110+
"Shopify EventBridge Integration (uksb-1tthgi812) (tag:shopify-eventbridge-lambda)"
111+
)
112+
ShopifyIntegrationStack(app, "ShopifyIntegrationStack", description=description)
113+
app.synth()
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"app": "python3 app.py",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"requirements*.txt",
11+
"source.bat",
12+
"**/__init__.py",
13+
"python/__pycache__",
14+
"tests"
15+
]
16+
},
17+
"context": {
18+
"@aws-cdk/core:stackRelativeExports": true,
19+
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
20+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
21+
"@aws-cdk/core:target-partitions": [
22+
"aws"
23+
]
24+
}
25+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"version": "0",
3+
"id": "1b8e2e75-b771-e964-f0e6-fbca6a21dad8",
4+
"detail-type": [
5+
"shopifyWebhook"
6+
],
7+
"source": "aws.partner/shopify.com/shop-event-bus",
8+
"account": "123456789",
9+
"resources": [
10+
""
11+
],
12+
"time": "2024-04-02T12:47:58Z",
13+
"region": "ca-central-1",
14+
"detail": {
15+
"payload": {
16+
"product": {
17+
"id": 1,
18+
"title": "Columbia Las Hermosas",
19+
"body_html": "",
20+
"vendor": "Reunion Island",
21+
"product_type": "Coffee",
22+
"created_at": "2024-04-07T14:55:00-05:00",
23+
"handle": "columbia-las-hermosas"
24+
}
25+
},
26+
"metadata": {
27+
"X-Shopify-Topic": "products/update",
28+
"X-Shopify-API-Version": "2024-04",
29+
"X-Shopify-Hmac-SHA256": "rncNozYG6CCjmFJjEgUWowYJ60X+oUtsqul1sTwJMpU=",
30+
"X-Shopify-Shop-Domain": "{shop}.myshopify.com",
31+
"X-Shopify-Order-Id": 1
32+
}
33+
}
34+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"title": "Shopify EventBridge Webhook Integration to AWS Lambda",
3+
"description": "Use the Amazon EventBridge Shopify webhook integration to process updated product events with AWS Lambda, and notify users with Amazon SES or store the data elsewhere.",
4+
"language": "Python",
5+
"level": "200",
6+
"framework": "CDK",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This sample project demonstrates how to use the Shopify webhook integration with Amazon EventBridge and AWS Lambda to process events from Shopify. This pattern is leveraging the Shopfy Amazon EventBridge webhook integration to send events from the customer's Shopify account to their AWS account, via an Amazon EventBridge Partner event bus.",
11+
"Once the Shopify events are in the customer's account, an Amazon EventBridge rule routes updated product events to a downstream Lambda function. The Lambda function could transform the event, send it to a downstream application, archive it in a warehouse service, or send a notification email to a customer using SES.",
12+
"Amazon CloudWatch Log Groups are provisioned for debugging and auditing.",
13+
"This pattern deploys two EventBridge Rules, one Lambda function, and two CloudWatch Log Groups."
14+
]
15+
},
16+
"gitHub": {
17+
"template": {
18+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/shopify-eventbridge-lambda",
19+
"templateURL": "serverless-patterns/shopify-eventbridge-lambda",
20+
"projectFolder": "shopify-eventbridge-lambda",
21+
"templateFile": "app.py"
22+
}
23+
},
24+
"resources": {
25+
"bullets": [
26+
{
27+
"text": "Amazon EventBridge SaaS Integrations",
28+
"link": "https://aws.amazon.com/eventbridge/integrations/"
29+
},
30+
{
31+
"text": "Amazon EventBridge SaaS Integrations Documentation",
32+
"link": "https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-saas.html"
33+
},
34+
{
35+
"text": "Shopify's Amazon EventBridge Webhook Integration",
36+
"link":"https://shopify.dev/docs/apps/build/webhooks/configuration/eventbridge#eventbridge-payload-structure"
37+
}
38+
]
39+
},
40+
"deploy": {
41+
"text": [
42+
"cdk deploy"
43+
]
44+
},
45+
"testing": {
46+
"text": [
47+
"See the GitHub repo for detailed testing instructions."
48+
]
49+
},
50+
"cleanup": {
51+
"text": [
52+
"cdk destroy"
53+
]
54+
},
55+
"authors": [
56+
{
57+
"name": "Ragib Ahsan",
58+
"image": "https://media.licdn.com/dms/image/D4E03AQHKVYkUoGROvA/profile-displayphoto-shrink_800_800/0/1699650399893?e=1723680000&v=beta&t=A08_HJD38AAs5NdDzBsWzZksHIfztFW1ong3EJJodWA",
59+
"bio": "AWS Partner Solutions Architect based in NYC. Huge advocate for serverless architectures!",
60+
"linkedin": "ragibmahsan"
61+
}
62+
]
63+
}
219 KB
Loading
238 KB
Loading
412 KB
Loading
227 KB
Loading
243 KB
Loading

0 commit comments

Comments
 (0)