资讯专栏INFORMATION COLUMN

如何用AWS编写一个“无服务器”的Slack 聊天机器人?

piapia / 2889人阅读

摘要:提供任何功能的打包服务,比如我们即将去构建的聊天机器人。而聊天机器人的工作方式如下用户向聊天机器人发送一个直接聊天消息表示该消息的事件已发布如果机器人订阅了该类型的事件,则将包含该聊天消息相关信息的请求发送到位于给定上的资源中。

最近,围绕“Serverless”架构的讨论不绝于耳……

即使你以前从未听说过这个词汇,没关系,这并不会有什么影响。其实,“serverless”就是指专门使用云服务构建的应用程序。现如今,随着AWS Lambda的引入以及亚马逊竞争对手的类似产品的出现,使构建和部署不需要维护操作且可以提供无限规模的应用程序成为可能。最关键的是,你不再需要去管理应用程序服务器,从而减少了大量的复杂性和成本开销。

在本教程中,我们将通过构建一个可以回复我们私人聊天消息的简单Slack聊天机器人来将我们的技术付诸实践。

创建Slack机器人

首先,如果你还没有组队的话,赶紧创建你的Slack团队吧。

点击左上角的主菜单,然后选择“Apps & integrations”。

 

选择构建。

 

然后,点击绿色的开始构建按钮。紧接着会弹出一个名为“Create an app”的新窗口。

Slack apps提供任何功能的打包服务,比如我们即将去构建的聊天机器人。然后可以通过Slack APP目录来分发APP。

为你的app输入一个合适的名称,并将其分配到你团队中的“开发团队”。而我就将我的机器人命名为Gort。

 

单击创建应用程序,然后你的面前就会呈现出你的应用程序的配置页面。

我们现在需要做的是启用事件订阅。而聊天机器人的工作方式如下:

•用户向聊天机器人发送一个直接聊天消息;

•表示该消息的事件已发布;

•如果机器人订阅了该类型的事件,则将包含该聊天消息相关信息的HTTP POST请求发送到位于给定URL上的Web资源中。

该URL可以由Web应用程序进行处理,而我们可以通过使用几个“serverless”AWS云技术来轻松构建该Web应用程序:

•位于该URL处的API网关资源处理传入的POST请求;

•AWS Lambda函数处理POST请求的有效负载,并采取适当的操作,如向Slack API发出新请求(比如回复消息);

这是一个交互图,可以充分显示每次当我们的机器人收到一条直接消息时会有哪些情况发生:

我们继续接下来的工作:我们需要告诉机器人去订阅一个名为im.message的特定事件类型。

转到事件订阅页面并启用事件:

切换开/关按钮启用/禁用事件订阅

向下滚动到“订阅机器人事件(Subscribe to Bot Events)”部分,然后单击添加机器人用户文本超链接。

你可以重新定义机器人在与频道和用户交互时使用的昵称。不要忘记启用“始终显示我的机器人在线”选项,因为我们不能一直使用RTM API来完成这一点。除此之外,AWS基础设施是始终处于开启状态的,不相信吗?这就是使用“serverless”架构的优点之一:不存在停机时间。

你可以通过单击“添加Bot用户”按钮完成此部分。返回到“事件订阅部分”并切换“开/关”按钮。你是否注意到刚刚出现的请求URL?这就是机器人将收到的直接消息通过HTTPS POST请求来发送去往的地方。

我们现在需要设置该Web资源,但在我们进行此操作之前,请转到“OAuth和权限(Permissions)”页面,然后单击“安装应用程序到团队”按钮。为机器人授权,然后你将获得一组OAuth访问令牌,要记得将Bot用户OAuth访问令牌复制到剪贴板,因为我们稍后将用到这些。

创建API网关web资源

登录到你的AWS管理控制台。由于我们即将开始创建API网关资源,所以请转到其信息中心。

点击“Create API”按钮,选择新的API并输入一个好的名称,我称其为“gort-brains”。

预定义的资源是root(/),因此我们将创建一个名为/ event-handler的新资源。单击“操作”按钮,然后从下拉菜单中选择“创建资源”。

输入“Event Handler(事件处理程序)”作为资源名称,“event-handler”作为资源路径。我们不需要启用CORS,因为客户端不会是浏览器,而是有Slack运行的任何后端应用程序来分派这些请求。最后,不要忘记点击“Create Resource”按钮。

 

在完成新的API网关资源之前,我们需要创建它将触发的Lambda函数。单击顶部菜单中的“Services”,并在另一个浏览器选项卡中打开Lambda管理控制台。

创建Lambda函数

转到Lambda控制板并创建一个Lambda函数。

选择空白函数作为操作蓝图:我们将从零开始。当出现“配置触发器(Configure Triggers)”部分时,单击“下一步”。

当你感到疑惑甚至忍不住询问之前,我可以明确的告诉你:是的,我们可以一举创建Gateway资源和Lambda函数,但是在本教程中,我会逐步向大家解释这个过程。

我们将使用Python 3来编写我们的Lambda函数,并将其称为“handleBotEvent”。

Lambda函数将编码以下过程:

1.处理来自传入的POST请求数据,并提取与事件相关的部分;

2.检查消息是否是来自用户的;

3.反转消息的文本,例如“Hello”变成“olleH”;

4.通过向适当的Slack API资源提交新的GET请求,向用户发送响应文本:chat.postMessage。

Lambda函数的行为就像简单的CGI(或WSGI)处理程序。使用Python 3类型注释的Python Lambda函数签名是:

 

event对象是我们需要挖掘多个少量消息数据的地方。而你通常得到是这样的:

 

你会在那里获得很多有趣的信息。我已经强调了与我们的用例非常相关的部分:

•用户(user):将消息发送到我们聊天机器人的用户的ID;

•文本(text):消息的文本;

•频道(channel):发送消息的频道的ID,基本上是用户和机器人之间的私人聊天流。

我希望在函数中包含上述两个功能,我可以通过下面的代码来实现:

"""

Slack chat-bot Lambda handler.

"""

Import os

import logging

import urllib

# Grab the Bot OAuth token from the environment.

BOT_TOKEN = os.environ["BOT_TOKEN"]

# Define the URL of the targeted Slack API resource.

# We"ll send our replies there.

SLACK_URL = "https://slack.com/api/chat.postMessage"

Def lambda_handler(data, context):

    """Handle an incoming HTTP request from a Slack chat-bot.

    """

    # Grab the Slack event data.

slack_event = data["event"]

    # We need to discriminate between events generated by 

    # the users, which we want to process and handle, 

    # and those generated by the bot.

if "bot_id" in slack_event:

logging.warn("Ignore bot event")

else:

        # Get the text of the message the user sent to the bot,

        # and reverse it.

text = slack_event["text"]

reversed_text = text[::-1]

        # Get the ID of the channel where the message was posted.

channel_id = slack_event["channel"]

# We need to send back three pieces of information:

#     1. The reversed text (text)

#     2. The channel id of the private, direct chat (channel)

#     3. The OAuth token required to communicate with 

#        the API (token)

# Then, create an associative array and URL-encode it, 

# since the Slack API doesn"t not handle JSON (bummer).

data = urllib.parse.urlencode(

   (

        ("token", BOT_TOKEN),

        ("channel", channel_id),

        ("text", reversed_text)

)

)

data = data.encode("ascii")

# Construct the HTTP request that will be sent to the Slack API.

request = urllib.request.Request(

            SLACK_URL, 

data=data, 

method="POST"

 )

# Add a header mentioning that the text is URL-encoded.

request.add_header(

            "Content-Type", 

            "application/x-www-form-urlencoded"

 )

        # Fire off the request!

urllib.request.urlopen(request).read()

    # Everything went fine.

return "200 OK"

请注意:生产代码必须验证Slack在请求中发送的令牌。出于简单性的考虑,我在代码中省略了这一点,但是我认为你应该看看尼古拉斯的评论从而获得更多的信息。

我们引用了机器人OAuth令牌的环境变量,所以让我们在编辑器下对它进行定义:

最后,我们还要为函数创建一个适当的角色。向下滚动到Lambda函数处理程序和角色部分,然后从“角色”下拉列表中选择“创建自定义角色”。打开一个浏览器标签,然后你可以在这个新页面上创建一个新的非常基本的角色:

单击“允许”,则上一个表单将自动填充:

 

这就是我们的Lambda函数。那么让我们回到API网关资源中去进行相应的操作。

Joining the dots

我们需要配置资源,以便它处理POST请求。再次单击“操作”按钮,继而选择“创建方法”,然后单击已出现的新下拉字段并选择“POST”。最后点击勾号图标。

选择“Lambda函数”作为集成类型(如果尚未成功),那就在“Lambda Region”中选择最适合你的。当我在爱尔兰居住时选择了“eu-west-1”。输入“handleBotEvent”作为Lambda函数的名称。

单击“保存”。一个即将出现的弹出窗口会通知你为新的Lambda函数给出API网关权限。到这里,我们的工作就做的差不多了。

你应该结束以下工作流程:

 

部署API,它将通过特定的网址来获得。单击“操作”,然后单击“部署API”。

 

在被要求选择部署阶段时,创建一个新的名为“dev”并进行部署!

一旦你这样做了之后,我们就最终可以得到我们真正想要的:“请求URL”,这里被称为“Invoke URL”:

我们默认启用HTTPS

重要:你需要“事件处理程序”资源的URL,而不是根资源!展开树形图,然后点击绿色的POST链接即可。

复制链接网址。

我们的工作差不多完成了。方程的AWS部分已经得到妥善处理。现在我们需要将机器人订阅到正确类型的事件,返回到Slack API事件订阅页面。

启用Slack直接邮件事件并将URL粘贴到“请求URL”字段中。你可能会立即收到一条警告消息,称该网址没有正确回复由Slack API发起的挑战。

 

到底是怎么回事? Slack API谨慎地向你刚刚定义为“请求URL”的新网址发送一次性挑战请求。该挑战包含一段随机的字符串,而我们的API预期在响应中使用相同的字符串进行响应。看来我们需要修改代码,以便处理这种情况。

我们应该回到Lambda函数的代码部分,并在函数的词法顶部添加以下条件语句(标粗部分):

 

这部分应该妥善处理。保存该函数并返回到“启用事件”页面,然后单击“重试”。现在进行的验证应该成功了:

向下滚动到“订阅机器人事件”部分,然后单击“添加机器人用户事件”按钮。选择message.im作为事件类型:

保存你的更改并返回到Slack团队频道。机器人应该耐心等待:

发送一条直接消息,而你应该会从机器人那里获取反转的文本。

点击这里获得本教程的完整代码。

结论

我不得不说我不喜欢在Lambda的受限编辑器中编写Python代码。这可能就是为什么最近推出了一个更全面的Web IDE和开发工具包。不过,我想说的是,一旦你脑海里有了想法和思路(如Slack API不接受JSON有效载荷等)之后,创建一个基本的机器人,也就是一件非常简单的事情了。

那么该从哪里着手呢?我可能会看看Lex,观察它是如何进行集成的,也可能会得到一个数据存储,从而给机器人一个记忆。在接下来的日子里,我还打算尝试由AWS赞助的,用于AWS的Python微框架Chalice。

我希望这个教程对你来说是有用的。

欢迎加入本站公开兴趣群

软件开发技术群

兴趣范围包括:Java,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流

QQ群:26931708

Hadoop源代码研究群

兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop

QQ群:288410967 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/4238.html

相关文章

  • 何用AWS编写一个服务器Slack 聊天器人

    摘要:提供任何功能的打包服务,比如我们即将去构建的聊天机器人。而聊天机器人的工作方式如下用户向聊天机器人发送一个直接聊天消息表示该消息的事件已发布如果机器人订阅了该类型的事件,则将包含该聊天消息相关信息的请求发送到位于给定上的资源中。最近,围绕Serverless架构的讨论不绝于耳…… 即使你以前从未听说过这个词汇,没关系,这并不会有什么影响。其实,serverless就是指专门使用云服务构...

    instein 评论0 收藏0
  • 来 DIY 个器人 - 收藏集 - 掘金

    摘要:能不能省掉这些烦琐的步骤,让开发人员自己完成呢现在好了,你可以用和把聊天机器人接入微信工具资源掘金今晚看了个电影,回得有点迟。 小花猫-网页聊天机器人 - 前端 - 掘金 基于图灵机器人API的网页聊天机器人,输入二维码+你要说的话有惊喜哦~~~(菜单中的功能尚未开发完成,玩玩聊天功能就好了~)代码开源在https://github.com/ColorfulCa... 了~... (英...

    mrli2016 评论0 收藏0
  • 前端每周清单第 38 期: Node 9 发布,Kotlin 与 React,Netflix 架构解

    摘要:发布本周正式发布,包含了一系列的特性提升与问题修复,同时也在不断致力于将打造地更为轻巧与高性能。当然,姜振勇老师还会介绍的多种服务,包括大数据网络和安全,展现弹性安全和高可扩展性的全方位能力。 showImg(http://upload-images.jianshu.io/upload_images/1647496-2ce7598e6987d9af.jpg?imageMogr2/aut...

    Carbs 评论0 收藏0
  • 系统架构

    强力推荐!那些你不能错过的 GitHub 插件和工具 以代码托管平台起家的 GitHub 网站,已然成为全球程序员工作和生活中不可或缺的一份子。从优秀的企业,到优秀的程序员,都将自己最优秀的代码作品存放在这片开源净土里,供彼此学习交流。 GitHub Trending 栏目甚至已经成为 IT 从业人员的新闻日报,每日必读。在之前的一… PostgreSQL 数据库的前世今生 编辑:IT大咖说阅读字...

    Gilbertat 评论0 收藏0
  • 系统架构

    强力推荐!那些你不能错过的 GitHub 插件和工具 以代码托管平台起家的 GitHub 网站,已然成为全球程序员工作和生活中不可或缺的一份子。从优秀的企业,到优秀的程序员,都将自己最优秀的代码作品存放在这片开源净土里,供彼此学习交流。 GitHub Trending 栏目甚至已经成为 IT 从业人员的新闻日报,每日必读。在之前的一… PostgreSQL 数据库的前世今生 编辑:IT大咖说阅读字...

    k00baa 评论0 收藏0

发表评论

0条评论

piapia

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<