在多伦多地区,去年(2020 年春季)COVID-19 大流行爆发时,后果之一(好处?)是所有员工可以合理在家工作的企业最终都被迫这样做。

这对餐馆和食品服务行业产生了有趣的影响。在郊区,食品店的销售额大幅增加,人们在家附近而不是在多伦多市中心购买午餐。不幸的是,这也意味着通常只需要 5 分钟的外卖排长队。

一些食品店只做网购,其中一家是一家名为“Chatime”的珍珠奶茶连锁店,你可能听说过,它显然是世界上最大的。这实际上给那些想要订购的人带来了一个非常令人沮丧的问题,包括我和我的妻子。

鉴于订单量的增加,我们附近的Chatime会“打开”他们的在线订购系统几分钟,等待它填满订单,然后再关闭它,拼命让他们保持up(订单显然仍然需要一个多小时才能完成)。一个星期以来,我和妻子尝试了很多次订购,每次我们进入订单提交页面...... Uber Eats 都会放弃并说商店不再营业,并且会很高兴同时清除我们的购物车(谢谢)。令人沮丧的是温和地说。

那么我们该怎么办?继续按 F5,直到它再次打开在线订购时希望赶上商店?谢天谢地没有。

进入 AWS。

像这样的情况是我喜欢云的原因之一,特别是无服务器技术。大约一天之内,我就能够构建一个快速而肮脏的无服务器应用程序,它会(有效地)为我们按下 F5,然后发送一条 SMS 消息让我们知道在线订购恢复的那一刻。

有效!第一次收到短信,下单成功!

[谷歌图片“泡泡茶模因”](https://res.cloudinary.com/practicaldev/image/fetch/s--BCkklkVv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// /dev-to-uploads.s3.amazonaws.com/uploads/articles/am4xc370s7qo5pm8qxs5.jpg)

进入 2021 年。

是时候清理我构建的东西并将其放在那里供其他人学习、重新利用等......

对于那些对冗长的演练和解释不感兴趣的人,请随意跳过其余部分并直接进入代码(如果您也觉得慷慨的话,在您离开之前鼓掌并跟随会很好:)

cdk-serverless-chatime-ordering-helper —https://github.com/aaronbrighton/cdk-serverless-chatime-ordering-helper

对于你们其他人,让我们深入了解它!


用于双向 SMS 的 Amazon Pinpoint

去年春天,无论出于何种原因(也许该功能实际上还不可用,请在评论中纠正我)我找不到一种在 AWS 上经济高效地处理入站 SMS 的方法。因此,最初的实现实际上利用了 Twilio 的带有 Webhook 的 SMS 和用于 SMS 接口的 API。

上周在清理代码时,我意识到我可以削减 Twilio 并直接使用 Amazon Pinpoint。这极大地简化了设置和解释。

Amazon Pinpoint 是... 一种灵活且可扩展的出站和入站营销通信服务。您可以通过电子邮件、短信、推送或语音等渠道与客户联系。

Pinpoint 是我无法使用 IaC(基础架构即代码)实现自动化的部分,因此如果您继续进行操作,则必须手动配置启用 SMS 的长代码电话号码。这在 AWS 管理控制台中非常简单。

[Amazon Pinpoint “电话号码”](https://res.cloudinary.com/practicaldev/image/fetch/s--Wg4wo4wF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// dev-to-uploads.s3.amazonaws.com/uploads/articles/fnlgiounfkq9f90733q5.png)


订阅者 Lambda 和亚马逊定位服务

一旦通过 Amazon Pinpoint 中的电话号码收到 SMS 消息,它就会通过Amazon SNS(简单通知服务)主题中继到一些自定义逻辑。这是双向短信如何与 Pinpoint 中的下游服务集成。

[摘自完整架构图](https://res.cloudinary.com/practicaldev/image/fetch/s--PZZc00dP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/qzrzf3jap3vzwi37e4ls.png)

亚马逊定位服务

作为清理工作的一部分,我最终替换的另一个外部服务是 Google Maps API。该应用程序需要做的一件事是将用户邮政编码 (Canadian) 转换为 LAT/LONG 坐标。在最初的实现中,我为此使用了谷歌地图。在 re:Invent 2020 上,亚马逊宣布了亚马逊定位服务——所以也是时候利用它了。

[摘自完整架构图](https://res.cloudinary.com/practicaldev/image/fetch/s--gCP7U-xA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// /dev-to-uploads.s3.amazonaws.com/uploads/articles/infl6t4efsn474yd42xh.png)

最终用户发送到此应用程序的第一条 SMS 消息将是他们的邮政编码。从上图中可以看出,我们随后点击了由 Chatime 托管的外部 API。他们的 API 要求用户提供 LAT/LONG 坐标,所以我们首先使用 Amazon Location 服务进行翻译,然后 POST 到 Chatime 的 Location API。我们会返回用户坐标附近的 Chatime 位置列表,以及 Uber Eats 在线订购 URL 等信息。代码摘录如下:

[TypeScript / AWS SDK for Javascript / Amazon Location Service “searchPlaceIndexForText”](https://res.cloudinary.com/practicaldev/image/fetch/s--htHbRiNR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto %2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdjt7b8qdhrf3qjq0fd5.png)

[TypeScript / Axios / Chatime Location API](https://res.cloudinary.com/practicaldev/image/fetch/s--4MSLJo38--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// /dev-to-uploads.s3.amazonaws.com/uploads/articles/pqhjq3v62hou79t1939p.png)

注册商店进行监控

在我们开始监控之前,应用程序和最终用户之间需要进行第二次交流。我们会向他们返回 3 个最近的拥有 Uber Eats 在线商店的 Chatime 地点的列表。然后,他们必须回复他们想要监控/订购的商店的商店 ID。

[摘自完整架构图](https://res.cloudinary.com/practicaldev/image/fetch/s--kKY3Xwai--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/dh8f0mt7vv9ogtfxljdh.png)

一旦应用程序接收到选定的商店 ID(它也会被抛出订阅者 Lambda)。我们为该 Chatime 商店创建了一个 Amazon SNS 主题,其中 Uber Eats URL 作为标签(用于“安全保存”)。最后,我们使用“sms”作为协议为最终用户订阅此 SNS 主题。


探测第 1 部分:Amazon EventBridge 和 Populator Lambda

[摘自完整架构图](https://res.cloudinary.com/practicaldev/image/fetch/s--dPL2LBPi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/msh2aoxc4dxvxycagi2l.png)

我们应用程序的下一部分是监控部分的前半部分。我们希望至少每分钟探测一次 Uber Eats Chatime 商店页面。因此,我们使用我们值得信赖的“无服务器 cron”AKAAmazon EventBridge(以前称为 CloudWatch 规则)。

[TypeScript / CDK / EventBridge](https://res.cloudinary.com/practicaldev/image/fetch/s--_hv3hZg4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/7go6mbb97eh0gevkd9yv.png)

**人口 Lambda **

填充器 Lambda 将扫描先前创建的代表要监控的 Chatime 商店的 SNS 主题,并将使用包含 Uber Eats URL(来自 SNS 主题标签)和 SNS 的消息填充Amazon SQS(简单排队服务)队列主题 ARN 本身。

[TypeScript / AWS SDK for Javascript / SQS “sendMessage”](https://res.cloudinary.com/practicaldev/image/fetch/s--LtQVl-eo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto %2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4omenf8izxeihk052yzi.png)


探测第 2 部分:Amazon SQS 和 Worker Lambda

[摘自完整架构图](https://res.cloudinary.com/practicaldev/image/fetch/s--wesYt8rz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/6imjwyloj7zjvpxlo5jp.png)

在最后的步骤中,我们的 Amazon SQS 被配置为将消息“扇出”到批量大小为 1 的 Worker Lambda(意味着一次只有 1 条 SQS 消息将发送到 Lambda — 我们不想过载;) 外部 Uber Eats 商店页面。

我们的 Worker Lambda 为商店页面抛出一个 GET,并检查是否出现“当前不可用”一词——这就是商店关闭其在线订购功能时发生的情况。

[TypeScript / AWS SDK for Javascript / SNS “发布”](https://res.cloudinary.com/practicaldev/image/fetch/s--dowQaGrP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880 /https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aur78ryrlasldzo9h7dn.png)

如果发现 is,则 Lambda 会退出并在大约 60 秒后再次尝试。如果 ** 没有找到*** ,那么我们将发布到我们之前创建的 SNS 主题——这将导致向任何想要在该商店的在线订单上线时收到通知的人发送 SMS 消息。


探索第 3 部分:AWS Step Functions 和取消订阅者 Lambda

[摘自完整架构图](https://res.cloudinary.com/practicaldev/image/fetch/s--s6qCBpj5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev -to-uploads.s3.amazonaws.com/uploads/articles/fkco86lbywodzxplo7tl.png)

最后,我们想删除最终用户的订阅,因为我们现在已经完成了我们的工作。 SNS 主题的“陷阱”之一是,如果您向它们发布然后立即尝试删除这些主题,则可能不会发送所有通知。

删除主题可能会阻止以前发送到该主题的某些消息传递给订阅者。 — 适用于 Javascript 的 AWS 开发工具包(“deleteTopic”)

所以我们有几个选择:

  • 让 Worker Lambda 休眠约 30 秒

  • AWS Step Functions

睡觉 Lambda 可能是人们第一个想到的想法,但出于多种原因,这并不是很好。其中之一是你是支付每毫秒Lambda 正在运行......所以这只是经济上的浪费。

使用 Step Functions,我们可以在执行其他自定义逻辑(我们的取消订阅者 Lambda)之前定义一个“等待”步骤,比如 30 秒。

[TypeScript / CDK / Step Functions / 状态机“等待”步骤](https://res.cloudinary.com/practicaldev/image/fetch/s--RPYFlghY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto %2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qr2tl6g9im8g7d1djgup.png)

退订 Lambda

这个应用程序的最后一步是完全删除 SNS 主题及其所有订阅,这就是这个 Lambda 所做的,代码非常简单。

[TypeScript / AWS SDK for Javascript / SNS “deleteTopic”](https://res.cloudinary.com/practicaldev/image/fetch/s--69QFtHya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880 /https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lb07zj8m38ul87iu75ab.png)

我如何自己部署这个?

我不会详细介绍,因为它大部分已经记录在cdk-serverless-chatime-ordering-helperrepo 的 README.md 中。

如果您有使用 CDK(AWS 云开发工具包)的经验,那么它应该相当简单。如果您没有使用 CDK 的经验,我强烈建议您熟悉它!它是云开发的游戏规则改变者,尤其是无服务器架构。

这里有一个非常棒的低时间投入 CDK 研讨会:https://cdkworkshop.com/


总而言之......对于最终用户来说是什么样的?

[与应用程序的短信对话](https://res.cloudinary.com/practicaldev/image/fetch/s--hpAwL-jM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// dev-to-uploads.s3.amazonaws.com/uploads/articles/fd51kkv9i8fglvxuh1vq.png)

谢谢阅读!

如果您发现内容有价值,请按下心形按钮并关注,评论您喜欢或不喜欢的内容,并让我知道接下来我应该介绍什么!

Logo

云原生社区为您提供最前沿的新闻资讯和知识内容

更多推荐