作者选择了(https://www.brightfunds.org/funds/tech-education)作为 写给捐款计划的一部分的捐款。
介绍
Slack是一个专为工作场所生产力而设计的通信平台,包括直接消息、公共和私人渠道、语音和视频通话以及机器人集成等功能。
在此教程中您将在 [Python] (https://www.python.org/] 编程语言中构建 Slackbot 。 Python是一种流行语言,以简单和可读性为傲. Slack提供了丰富的Python Slack API,用于与Slack的集成,以完成发送消息等共同任务,在消息中加入emojis,以及更多. Slack还提供了一个Python Slack Events API,用于与Slack中的事件相融合,允许您对消息和提及等事件进行动作.
作为一个有趣的概念证明,这将展示Python及其Slack API的力量,你将建立一个CoinBot
,一个Slackbot监控一个频道,当它被触发时,会为你扭转一个硬币。
请注意,本教程使用Python 3并且与Python 2不兼容。
前提条件
为了遵循这个指南,你需要:
如果你创建了工作空间,你有这个能力. 如果你没有这个能力,你可以在Slack网站上创建一个工作空间(https://slack.com/create)。 * (可选) 一个服务器或计算机具有公共IP地址进行开发。 我们建议新安装Ubuntu 20.04,一个非根用户具有sudo
特权,并启用SSH。
<$>[注]您可能想在具有公共 IP 地址的服务器上测试此教程. Slack 需要能够向您的机器发送消息等事件. 如果您在本地机器上测试,则需要将流量通过防火墙传输到本地系统。
步骤 1 — 在 Slack UI 中创建 Slackbot
首先在 Slack API 控制面板上创建 Slack 应用程序. 通过 Web 浏览器登录 Slack 中的工作区,然后导航到 API 控制面板。
接下来,您将被提示为您的应用程序的名称,并选择一个开发 Slack 工作区. 对于本教程,命名您的应用程序 CoinBot
,并选择您有管理员访问的工作区。
创建应用后,您将看到以下默认应用程序仪表板. 此仪表板是您通过设置权限、订阅事件、在工作区中安装应用程序等来管理应用程序的位置。
为了让您的应用能够向频道发布消息,您需要授予该应用程序发送消息的权限。
当您到达 OAuth & Permissions 页面时,向下滚动,直到您找到页面的 ** Scopes** 部分,然后在范围中找到 ** Bot Token Scopes** 子部分,然后单击 ** Add an OAuth Scope** 按钮。
点击该按钮,然后键入chat:write
。选择该权限以将其添加到您的机器人中。这将允许应用程序向其可以访问的渠道发布消息。有关可用的权限的更多信息,请参阅Slack的文档(https://api.slack.com/scopes)。
现在您已经添加了适当的权限,现在是时候将应用程序安装到您的 Slack 工作区了。 滚动在 OAuth & Permissions 页面上,然后点击顶部的 ** Install App to Workspace** 按钮。
点击此按钮,查看应用程序可以在渠道中执行的操作.一旦您满意,请点击允许
按钮来完成安装。
一旦机器人安装,您将收到一个 Bot 用户 OAuth 访问令牌 ,让您的应用程序在尝试在工作空间中执行操作时使用。
最后,将您新安装的机器人添加到您工作区内的一个频道中。如果您还没有创建一个频道,您可以使用 Slack 工作区的默认创建的 # general 频道。在 Slack 客户端导航栏的 Apps 部分中找到该应用程序,然后点击它。
要完成将应用程序添加到频道中,请点击详细信息页面中的三个点表示的 ** 更多** 按钮,然后选择 ** 将此应用程序添加到频道中...** 。
您现在已经成功创建了您的应用程序,并将其添加到您的 Slack 工作区内的一个频道中。在您为您的应用程序编写代码后,它将能够在该频道中发布消息。
步骤2 — 设置您的Python开发环境
首先,让我们设置您的Python环境,以便您可以开发Slackbot。
打开终端并在您的系统上安装python3
和相关工具:
1sudo apt install python3 python3-venv
接下来,您将创建一个虚拟环境,将您的Python包从Python的系统安装中分离出来。 要做到这一点,首先创建一个目录,您将创建您的虚拟环境。
1mkdir ~/.venvs
现在创建您的Python虚拟环境:
1python3 -m venv ~/.venvs/slackbot
接下来,激活您的虚拟环境,以便您可以使用其Python安装和安装包:
1source ~/.venvs/slackbot/bin/activate
您的壳提示将现在显示虚拟环境,它将看起来像这样:
现在使用pip
将必要的Python包安装到您的虚拟环境中:
1pip install slackclient slackeventsapi Flask
slackclient
和slackeventsapi
有助于Python与Slack的API进行互动。
现在你已经设置了开发人员环境,你可以开始写你的Python Slackbot:
步骤 3 —在Python中创建Slackbot消息类
Slack 中的消息是通过 专门格式化的 JSON 效能负载发送的。
1{
2 "channel":"channel",
3 "blocks":[
4 {
5 "type":"section",
6 "text":{
7 "type":"mrkdwn",
8 "text":"Sure! Flipping a coin....\n\n"
9 }
10 },
11 {
12 "type":"section",
13 "text":{
14 "type":"mrkdwn",
15 "text":"*flips coin* The result is Tails."
16 }
17 }
18 ]
19}
你可以手动创建这个 JSON 并发送它,但相反,让我们构建一个 Python 类,不仅可以创建这个负载,还可以模拟硬币转换。
首先使用触摸
命令创建一个名为coinbot.py
的文件:
1touch coinbot.py
接下来,使用nano
或您最喜欢的文本编辑器打开此文件:
1nano coinbot.py
现在添加以下代码行来导入适用于您的应用程序的相关库. 您为此类所需的唯一库是来自 Python 标准库的随机
库。
将下列行添加到coinbot.py
以导入所有必要的库:
1[label coinbot.py]
2# import the random library to help us generate the random numbers
3import random
接下来,创建你的CoinBot
类和这个类的实例来创建消息的负载. 添加以下行到coinbot.py
来创建CoinBot
类:
1[label coinbot.py]
2...
3class CoinBot:
现在,单独编入并创建类所需的常数、构造器和方法。 首先,让我们创建一个将保持消息负载的基础的常数。 本节规定了这个常数是部分类型,并且文本是通过标记格式化。
将下列行附加到coinbot.py
中,以创建有效负载的基本模板:
1[label coinbot.py]
2...
3 # Create a constant that contains the default text for the message
4 COIN_BLOCK = {
5 "type": "section",
6 "text": {
7 "type": "mrkdwn",
8 "text": (
9 "Sure! Flipping a coin....\n\n"
10 ),
11 },
12 }
接下来,为您的类创建一个构建器,以便您可以为每个请求创建一个单独的机器人实例。不要担心这里的内存过剩;Python垃圾收集器将清理这些实例,一旦它们不再需要。
将下列行附加到coinbot.py
来创建构建器:
1[label coinbot.py]
2...
3 # The constructor for the class. It takes the channel name as the a
4 # parameter and sets it as an instance variable.
5 def __init__(self, channel):
6 self.channel = channel
现在写下模拟翻转硬币的代码. 我们将随机生成一个或零,分别代表头或尾巴。
将下列行附加到coinbot.py
中,以模拟硬币转换并返回编造的负载:
1[label coinbot.py]
2...
3 # Generate a random number to simulate flipping a coin. Then return the
4 # crafted slack payload with the coin flip message.
5 def _flip_coin(self):
6 rand_int = random.randint(0,1)
7 if rand_int == 0:
8 results = "Heads"
9 else:
10 results = "Tails"
11
12 text = f"The result is {results}"
13
14 return {"type": "section", "text": {"type": "mrkdwn", "text": text}},
最后,创建一种方法,通过调用你的 _flip_coin
方法来制作并返回整个消息效用负载,包括你的构建器的数据。
将下列行附加到coinbot.py
中,创建将生成完成的有效负载的方法:
1[label coinbot.py]
2...
3 # Craft and return the entire message payload as a dictionary.
4 def get_message_payload(self):
5 return {
6 "channel": self.channel,
7 "blocks": [
8 self.COIN_BLOCK,
9 *self._flip_coin(),
10 ],
11 }
现在你已经完成了CoinBot
类,它已经准备好进行测试,然后再继续前,请验证你的已完成的文件coinbot.py
是否包含以下内容:
1[label coinbot.py]
2# import the random library to help us generate the random numbers
3import random
4
5# Create the CoinBot Class
6class CoinBot:
7
8 # Create a constant that contains the default text for the message
9 COIN_BLOCK = {
10 "type": "section",
11 "text": {
12 "type": "mrkdwn",
13 "text": (
14 "Sure! Flipping a coin....\n\n"
15 ),
16 },
17 }
18
19 # The constructor for the class. It takes the channel name as the a
20 # parameter and then sets it as an instance variable
21 def __init__(self, channel):
22 self.channel = channel
23
24 # Generate a random number to simulate flipping a coin. Then return the
25 # crafted slack payload with the coin flip message.
26 def _flip_coin(self):
27 rand_int = random.randint(0,1)
28 if rand_int == 0:
29 results = "Heads"
30 else:
31 results = "Tails"
32
33 text = f"The result is {results}"
34
35 return {"type": "section", "text": {"type": "mrkdwn", "text": text}},
36
37 # Craft and return the entire message payload as a dictionary.
38 def get_message_payload(self):
39 return {
40 "channel": self.channel,
41 "blocks": [
42 self.COIN_BLOCK,
43 *self._flip_coin(),
44 ],
45 }
保存并关闭文件。
现在你有一个Python类准备好为你的Slackbot工作,让我们确保这个类产生有用的消息负载,你可以将其发送到你的工作区。
步骤 4 — 测试您的消息
现在让我们来测试这个类会产生合适的负载,创建一个名为coinbot_test.py的文件:
1nano coinbot_test.py
现在添加以下代码: ** 请确保在 coinbot 类的实例中更改频道名称:coin_bot = coinbot(# YOUR_CHANNEL_HERE
)** . 此代码将创建 Python 中的 Slack 客户端,该代码将向您指定已安装应用程序的频道发送消息:
1[label coinbot_test.py]
2from slack import WebClient
3from coinbot import CoinBot
4import os
5
6# Create a slack client
7slack_web_client = WebClient(token=os.environ.get("SLACK_TOKEN"))
8
9# Get a new CoinBot
10coin_bot = CoinBot("#YOUR_CHANNEL_HERE")
11
12# Get the onboarding message payload
13message = coin_bot.get_message_payload()
14
15# Post the onboarding message in Slack
16slack_web_client.chat_postMessage(**message)
保存并关闭文件。
在运行此文件之前,您需要将您在步骤 1 中保存的 Slack 代币导出为环境变量:
1export SLACK_TOKEN="your_bot_user_token"
现在测试这个文件,并通过在您的终端运行下面的脚本来验证使用量被生成和发送。 确保您的虚拟环境被激活。 您可以通过看到 bash 提示前面的 (slackbot)
文本来验证。 运行此命令,您将收到来自您的 Slackbot 的消息,其中包含硬币转换的结果:
1python coinbot_test.py
检查您安装应用程序的渠道,并验证您的机器人确实发送了硬币转换消息。
现在你已经验证了你的Slackbot可以扭转硬币,创建消息,并传递消息,让我们创建一个 Flask永久运行这个应用程序,让它模拟一个硬币扭转,并分享结果,每次它看到某些文本在发送在渠道中的消息。
步骤5 —创建一个Flask应用程序来运行您的Slackbot
现在你有一个可以发送消息到你的Slack工作区的应用程序,你需要创建一个漫长的流程,以便你的机器人可以听到在频道中发送的消息,并回复它们,如果文本符合某些标准。
在本节中,您将从具有公共 IP 地址的服务器运行您的 Flask 应用程序,以便 Slack API 可以向您发送事件。如果您在个人工作站上本地运行此功能,则需要将端口从个人防火墙传输到工作站上运行的端口。
首先调整防火墙设置以允许通过端口3000
的流量:
1sudo ufw allow 3000
现在检查UFW
的状态:
1sudo ufw status
你会看到这样的输出:
1[secondary_label Output]
2Status: active
3
4To Action From
5-- ------ ----
6OpenSSH ALLOW Anywhere
73000 ALLOW Anywhere
8OpenSSH (v6) ALLOW Anywhere (v6)
93000 (v6) ALLOW Anywhere (v6)
现在为您的 Flask 应用程序创建文件. 命名此文件 app.py
:
1touch app.py
接下来,在您最喜欢的文本编辑器中打开此文件:
1nano app.py
现在添加以下导入陈述
,您将因以下原因导入以下库:
import os
- 访问环境变量 *import logging
- 登录应用程序的事件 *from flask import Flask
- 创建一个Flask应用程序 *from slack import WebClient
- 通过Slack发送消息 *from slackeventsapi import SlackEventAdapter
- 接收来自Slack的事件并处理它们 *from coinbot import CoinBot
- 创建您的CoinBot实例并生成消息负载。
将下列行附加到app.py
以导入所有必要的库:
1[label app.py]
2import os
3import logging
4from flask import Flask
5from slack import WebClient
6from slackeventsapi import SlackEventAdapter
7from coinbot import CoinBot
现在创建你的Flask应用程序,并在/slack/events
终端点注册Slack事件适配器到Slack应用程序,这将创建Slack应用程序中的路线,在那里Slack事件将被发送和摄入。 要做到这一点,你需要从Slack应用程序中获得另一个代币,你将在教程中稍后进行。 一旦你获得这个变量,你将将其导出作为一个名为SLACK_EVENTS_TOKEN
的环境变量。 继续写下你的代码,在创建SlackEventAdapter
时读取它,即使你还没有设置代币。
将下列行附加到app.py
中,创建 Flask 应用程序并将事件适配器注册到该应用程序中:
1[label app.py]
2...
3# Initialize a Flask app to host the events adapter
4app = Flask(__name__)
5
6# Create an events adapter and register it to an endpoint in the slack app for event ingestion.
7slack_events_adapter = SlackEventAdapter(os.environ.get("SLACK_EVENTS_TOKEN"), "/slack/events", app)
接下来,创建一个 Web 客户端对象,该对象将允许您的应用程序在工作区中执行操作,特别是发送消息。
将下列行附加到app.py
,以创建此slack_web_client
:
1[label app.py]
2...
3# Initialize a Web API client
4slack_web_client = WebClient(token=os.environ.get("SLACK_TOKEN"))
现在创建一个可调用的函数,将创建一个CoinBot
的实例,然后使用该实例创建一个消息的有效载荷,并将消息的有效载荷传送到Slack Web客户端进行交付。
将下列行附加到app.py
来创建此函数:
1[label app.py]
2...
3def flip_coin(channel):
4 """Craft the CoinBot, flip the coin and send the message to the channel
5 """
6 # Create a new CoinBot
7 coin_bot = CoinBot(channel)
8
9 # Get the onboarding message payload
10 message = coin_bot.get_message_payload()
11
12 # Post the onboarding message in Slack
13 slack_web_client.chat_postMessage(**message)
现在你已经创建了一个功能来处理你的应用程序的消息方面,创建一个监控Slack事件的特定行动,然后执行你的机器人。
首先,用@slack_events_adapter.on
语法来装饰您的函数,使您的函数能够接收事件。 指定您只想要消息
事件,并让您的函数接受包含所有必要的Slack信息的负载参数。 一旦您有这个负载,您将对文本进行分析并分析。
将下列代码附加到 app.py 以接收、分析和对接收消息采取行动:
1[label app.py]
2# When a 'message' event is detected by the events adapter, forward that payload
3# to this function.
4@slack_events_adapter.on("message")
5def message(payload):
6 """Parse the message event, and if the activation string is in the text,
7 simulate a coin flip and send the result.
8 """
9
10 # Get the event data from the payload
11 event = payload.get("event", {})
12
13 # Get the text from the event that came through
14 text = event.get("text")
15
16 # Check and see if the activation phrase was in the text of the message.
17 # If so, execute the code to flip a coin.
18 if "hey sammy, flip a coin" in text.lower():
19 # Since the activation phrase was met, get the channel ID that the event
20 # was executed on
21 channel_id = event.get("channel")
22
23 # Execute the flip_coin function and send the results of
24 # flipping a coin to the channel
25 return flip_coin(channel_id)
最后,创建一个主要
部分,将创建一个日志器,以便您可以查看您的应用程序的内部信息,以及在端口3000
上的外部IP地址上启动应用程序。
将下列行附加到app.py
以设置您的主要部分:
1[label app.py]
2if __name__ == "__main__":
3 # Create the logging object
4 logger = logging.getLogger()
5
6 # Set the log level to DEBUG. This will increase verbosity of logging messages
7 logger.setLevel(logging.DEBUG)
8
9 # Add the StreamHandler as a logging handler
10 logger.addHandler(logging.StreamHandler())
11
12 # Run your app on your externally facing IP address on port 3000 instead of
13 # running it on localhost, which is traditional for development.
14 app.run(host='0.0.0.0', port=3000)
您现在已经完成了Flask应用程序,它已经准备好进行测试。在您继续之前,请验证您的已完成的文件,‘app.py’包含以下内容:
1[label app.py]
2import os
3import logging
4from flask import Flask
5from slack import WebClient
6from slackeventsapi import SlackEventAdapter
7from coinbot import CoinBot
8
9# Initialize a Flask app to host the events adapter
10app = Flask(__name__)
11# Create an events adapter and register it to an endpoint in the slack app for event injestion.
12slack_events_adapter = SlackEventAdapter(os.environ.get("SLACK_EVENTS_TOKEN"), "/slack/events", app)
13
14# Initialize a Web API client
15slack_web_client = WebClient(token=os.environ.get("SLACK_TOKEN"))
16
17def flip_coin(channel):
18 """Craft the CoinBot, flip the coin and send the message to the channel
19 """
20 # Create a new CoinBot
21 coin_bot = CoinBot(channel)
22
23 # Get the onboarding message payload
24 message = coin_bot.get_message_payload()
25
26 # Post the onboarding message in Slack
27 slack_web_client.chat_postMessage(**message)
28
29# When a 'message' event is detected by the events adapter, forward that payload
30# to this function.
31@slack_events_adapter.on("message")
32def message(payload):
33 """Parse the message event, and if the activation string is in the text,
34 simulate a coin flip and send the result.
35 """
36
37 # Get the event data from the payload
38 event = payload.get("event", {})
39
40 # Get the text from the event that came through
41 text = event.get("text")
42
43 # Check and see if the activation phrase was in the text of the message.
44 # If so, execute the code to flip a coin.
45 if "hey sammy, flip a coin" in text.lower():
46 # Since the activation phrase was met, get the channel ID that the event
47 # was executed on
48 channel_id = event.get("channel")
49
50 # Execute the flip_coin function and send the results of
51 # flipping a coin to the channel
52 return flip_coin(channel_id)
53
54if __name__ == "__main__":
55 # Create the logging object
56 logger = logging.getLogger()
57
58 # Set the log level to DEBUG. This will increase verbosity of logging messages
59 logger.setLevel(logging.DEBUG)
60
61 # Add the StreamHandler as a logging handler
62 logger.addHandler(logging.StreamHandler())
63
64 # Run our app on our externally facing IP address on port 3000 instead of
65 # running it on localhost, which is traditional for development.
66 app.run(host='0.0.0.0', port=3000)
保存并关闭文件。
现在,您的 Flask 应用已经准备好为您的应用程序服务,让我们测试它。
步骤6 —运行您的Flask应用程序
最后,把一切都汇集在一起,并运行您的应用程序。
首先,添加您的运行应用程序作为您的Slackbot的授权处理器。
在 Slack UI中,导航到应用程序的 基本信息 部分。
复制签名秘密
并将其导出为环境变量SLACK_EVENTS_TOKEN
:
1export SLACK_EVENTS_TOKEN="MY_SIGNING_SECRET_TOKEN"
有了这个,你有所有必要的API代币来运行你的应用程序. 请参阅步骤 1 如果你需要一个更新如何导出你的SLACK_TOKEN
。 现在你可以启动你的应用程序,并验证它确实在运行。 确保你的虚拟环境是激活的,并运行以下命令来启动你的Flask应用程序:
1python3 app.py
你会看到这样的输出:
1(slackbot) [20:04:03] sammy:coinbot$ python app.py
2 * Serving Flask app "app" (lazy loading)
3 * Environment: production
4 WARNING: This is a development server. Do not use it in a production deployment.
5 Use a production WSGI server instead.
6 * Debug mode: off
7 * Running on http://0.0.0.0:3000/ (Press CTRL+C to quit)
要验证您的应用程序是否已启动,请打开一个新的终端窗口,并在/slack/events
的正确端口弯曲
您的服务器的 IP 地址:
1curl http://YOUR_IP_ADDRESS:3000/slack/events
curl
将返回如下:
1[secondary_label Output]
2These are not the slackbots you're looking for.
收到这些不是您正在寻找的 slackbots
消息表示您的应用已启动和运行。
现在,让这个 Flask 应用程序在您在 Slack UI中完成配置应用程序时运行。
首先,授予您的应用程序适当的权限,以便它可以听取消息并相应地响应。
完成此操作后,输入您的 IP 地址、端口和/slack/events
终端点到Request URL**
字段中。 不要忘记HTTP
协议前缀。 Slack 将尝试连接到您的终端点。 一旦成功完成,您将看到一个绿色标记,旁边有Verified
字。
接下来,扩展 **订阅机器人事件 ** ,并将message.channels
权限添加到您的应用程序中,这将允许您的应用程序从您的频道接收和处理消息。
完成此操作后,您将看到您的 ** 订阅 bot 事件 ** 部分中列出的事件,然后在右下角点击绿色 ** 保存更改 ** 按钮。
一旦您这样做,您将看到屏幕顶部的黄色标签,告知您需要重新安装您的应用程序,以便下列更改适用。
您将收到一个确认屏幕,概括您的机器人将有权限,并询问您是否想要允许其安装。
现在你已经完成了,你的应用程序应该准备好了。回到你安装了CoinBot
的渠道,并发送一个含有短语 Hey Sammy, Flip a coin 的消息。
结论
一旦你完成了开发你的应用程序,你已经准备好将其迁移到生产中,你需要部署到服务器上。这是必要的,因为Flask开发服务器不是一个安全的生产环境。如果你使用 WSGI部署你的应用程序,甚至可以确保域名并为你的服务器提供DNS记录,你将得到更好的服务。
- 使用 Gunicorn 和 Nginx 部署您的 Flask 应用程序到 Ubuntu 20.04 * 使用 uWSGI 和 Nginx 部署您的 Flask 应用程序到 Ubuntu 20.04 * 在 Ubuntu 18.04 上使用 Docker 部署您的 Flask 应用程序
有更多的方法来部署你的应用程序,而不仅仅是这些. 就像往常一样,当涉及到部署和基础设施时,做什么最适合 you。
无论如何,你现在有一个Slackbot,你可以使用它来扭转一枚硬币,以帮助你做出决定,比如吃什么午餐。
您还可以采取这个基本代码,并修改它以满足您的需求,无论是自动支持,资源管理,猫的图像,或任何你可以想到的。