Slack正迅速成为团队沟通的新行业标准。事实上,它是如此受欢迎,以至于当我在谷歌中输入 slack 时,正如我所期望的那样,第一个结果是字典中单词的定义。紧随其后的是 Slack 的网站!
对于英语词典中最常见的单词,这几乎是闻所未闻的。通常,谷歌的定义后面有几个顶级词典网站的链接。
什么是松弛?
最基本的,Slack 是一个消息传递系统。它允许直接向团队成员发送消息,并创建允许轻松实时团队沟通和协作的渠道(私人或公共)。有关 Slack 的更多信息,您可以查看Slack 的功能。
在这一点上,您可能想知道 node.js 的用武之地。正如我所提到的,在最基本的情况下,Slack 是一个消息传递系统;但是,它可以无限扩展和定制。Slack 提供了一个非常灵活的系统来定制您的团队的集成,包括:
在本文中,我将演示如何使用 Node.js 创建一个可添加到团队的 Slack 配置中的 Slack 机器人。
定义的 Slack 机器人
Slack Bot 的工作是接收Slack 发送的事件并进行处理。有大量事件将发送到您的 Bot,这就是 Node.js 的用武之地。我们不仅要决定要处理哪些事件,还要决定如何处理每个单独的事件。
例如,机器人将处理的一些常见事件是:
member_joined_channel
member_left_channel
message
在本文中,我将创建一个 Node.js 应用程序和一个 Slack Bot,可以将它们添加到您的团队项目中,以根据它接收到的事件执行特定操作。
首先,我需要在 Slack 上创建一个机器人。可以创建两种类型的机器人:
自定义机器人
创建应用程序并添加机器人用户
本文将创建一个自定义机器人,因为如果您打算在 Slack 上编写和发布应用程序,应用程序机器人用户会更合适。鉴于我希望这个机器人对我的团队来说是私有的,一个自定义机器人就足够了。
创建自定义 Slack 机器人
可以在此处创建自定义机器人: https ://my.slack.com/apps/A0F7YS25R-bots 。如果您已经登录到您的 Slack 帐户,请在左侧选择 添加配置按钮;否则,请先登录您的 Slack 帐户,然后再继续。如果您没有 Slack 帐户,您可以免费注册。
这会将您带到一个新页面,该页面要求您为您的机器人提供用户名。现在输入您的用户名,确保您遵循 Slack 的命名准则。一旦您选择了一个很棒的机器人名称,请按 Add bot configuration。
成功创建机器人后,Slack 会将您重定向到允许进一步自定义机器人的页面。我会把这部分留给你有创造力的自己。此页面唯一需要 的是以 xoxb-
. 我要么将此令牌复制到一个安全的地方供以后使用,要么只是让此页面保持打开状态,直到我们需要 Node.js 应用程序的令牌。
配置
在继续编写代码之前,还需要两个 Slack 配置:
创建或选择您的机器人将与之交互的现有频道。在测试我的新机器人时,我选择创建一个新频道。请务必记住通道名称,因为您很快就会在应用程序中使用它。
将您的机器人添加/邀请到频道,以便它可以与之交互。
现在我已经配置了我的 Slack Bot,是时候转到 Node.js 应用程序了。如果您已经安装了 Node.js,则可以继续下一步。如果您没有安装 Node.js,我建议您首先访问Node.js 下载页面并为您的系统选择安装程序。
对于我的 Slack Bot,我将通过运行该npm init
过程来创建一个新的 Node.js 应用程序。使用设置为您希望安装应用程序的位置的命令提示符,您可以运行以下命令:
mkdir slackbot cd slackbot npm init
如果您不熟悉npm init
,这将启动一个实用程序来帮助您配置新项目。它要求的第一件事是名称。它默认我的slackbot
,我很满意。如果您想更改您的应用程序名称,现在是机会;否则,按 Enter继续下一个配置步骤。下一个选项是版本和描述。我将两者都保留为默认设置,只需按 Enter 键即可继续使用这两个选项。
入口点
接下来要求的是 入口点。这默认为index.js
; 但是,很多人喜欢使用app.js
. 我不想参加这场辩论,并且鉴于我的申请不需要密集的项目结构,我将把我的默认设置为index.js
.
在您从可能与制表符与空格一样激烈的辩论中恢复过来后,配置继续进行,并提出了几个问题:
测试命令
git仓库
关键词
作者
执照
出于本文的目的,我将所有选项都保留为默认选项。最后,一旦配置了所有选项,在创建文件之前会显示文件的确认package.json
。按 Enter 键完成配置。
进入SDK
为了使与 Slack 的交互更容易,我还将安装Slack Developer Kit 包,如下所示:
npm install @slack/client --save
你终于准备好使用一些代码了吗?我当然是。首先,我将使用 Slack Developer Kit 网站上的示例代码,该代码使用实时消息传递 api (RTM)发布一条 Slack 消息, 并进行一些调整。
鉴于 我选择的入口点index.js
是,是时候创建这个文件了。Slack Developer Kit 网站上的示例大约有 20 行代码。我将一次将其分解为几行,只是为了解释这些行的作用。但请注意,所有这些行都应包含在您的index.js
文件中。
代码首先包含 Slack Developer Kit 中的两个模块:
var RtmClient = require('@slack/client').RtmClient; var CLIENT_eventS = require('@slack/client').CLIENT_EVENTS;
实例化RtmClient
后,将成为我们引用 RTM API 的机器人对象。这些CLIENT_EVENTS
是机器人将要监听的事件。
包含这些模块后,就可以实例化并启动机器人了:
var rtm = new RtmClient('xoxb-******************************************');rtm.start();
请务必将上面混淆的 API 令牌替换为您在创建 Slack Bot 期间获得的令牌。
调用start
my 上的函数RtmClient
将初始化机器人的会话。这将尝试验证我的机器人。当我的机器人成功连接到 Slack 时,将发送事件以允许我的应用程序继续。这些事件将立即显示。
实例化客户端后,将channel
创建一个变量以在其中一个CLIENT_EVENTS
事件中临时填充。
let channel;
该channel
变量将用于执行特定操作,例如向机器人连接的通道发送消息。
当 RTM 会话启动 ( ) 并为机器人rtm.start();
提供有效的 API 令牌RTM.AUTHENTICATED
时,将发送一条消息。接下来的几行监听这个事件:
rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartdata) => { for (const c of rtmStartData.channels) { if (c.is_member && c.name ==='jamiestestchannel') { channel = c.id } } console.log(`Logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}`); });
当 RTM.AUTHENTICATED
收到事件时,前面的代码会在 Slack 团队频道列表中执行for
循环。就我而言,我专门寻找 jamiestestchannel并确保我的机器人是该频道的成员。当满足该条件时,通道 ID 将存储在channel
变量中。
调试
为了帮助调试,会记录一条控制台消息,其中显示一条消息,表明机器人已通过显示其名称 ( ) 和它所属${rtmStartData.self.name}
的团队名称 ( ) 成功进行身份验证。${rtmStartData.team.name}
机器人通过身份验证后,会触发另一个事件 ( RTM.RTM_CONNECTION_OPENED
),这表示机器人已完全连接并可以开始与 Slack 交互。接下来的代码行创建事件监听器;成功后, 您好!消息被发送到频道(在我的例子中是 jamiestestchannel)。
rtm.on(CLIENT_EVENTS.RTM.RTM_CONNECTION_OPENED, function () { rtm.sendMessage("Hello!", channel); });
此时,我现在可以运行我的 Node 应用程序并观察我的机器人自动向我的频道发布一条新消息:
node index.js
运行此命令(成功时)的结果是双重的:
我收到调试消息,表明我的机器人已成功登录。这源于
RTM.AUTHENTICATED
启动 RTM 客户端后被触发。我收到一个 你好!我的 Slack 频道中的消息。这发生在
RTM.RTM_CONNECTION_OPENED
应用程序接收和处理事件消息时。
在继续并进一步增强我的应用程序之前,现在是回顾一下我为实现这一目标所做的工作的好时机:
创建了一个自定义 Slack Bot。
创建了一个自定义 Slack 频道并邀请我的机器人加入其中。
创建了一个名为slackbot的新 Node.js 应用程序 。
将 Slack Developer Kit 包安装到我的应用程序中。
创建了我的
index.js
文件,该文件RtmClient
使用我的自定义机器人中的API 令牌创建了一个文件。创建了一个事件***器,用于
RTM.AUTHENTICATED
查找我的机器人所属的 Slack 频道。RTM.RTM_CONNECTION_OPENED
为发送 Hello!创建了一个事件***器。消息到我的 Slack 频道。调用 RTM Start Session 方法以开始由我的事件***器处理的身份验证过程。
构建机器人
现在是时候开始真正的乐趣了。Slack 提供(我没有计算在内)至少50 种不同的事件可供我的自定义机器人监听和选择性处理。从 Slack Events 列表中可以看出,一些事件是 RTM API(我们正在使用)自定义的,而其他事件是Events API自定义的。在写这篇文章的时候,我的理解是 Node.js SDK 只支持 RTM。
为了完成我的机器人,我将处理message
事件;当然,这可能是最复杂的事件之一,因为它支持大量子类型,我稍后将探讨。
message
以下是Slack中最基本事件的示例:
{ "type": "message", "channel": "C2147483705", "user": "U2147483697", "text": "Hello world", "ts": "1355517523.000005" }
在这个基本对象中,我最关心的三件事是:
channel
。_ 我将要确保此消息属于我的机器人所属的频道。user
。_ 这将允许我直接与用户交互或根据用户身份执行特定操作。text
。_ 这可能是最重要的部分,因为它包含消息的内容。我的机器人将只想响应某些类型的消息。
有些消息更复杂。它们可以包含许多子属性,例如:
edited
: 一个子对象,描述了哪个用户编辑了消息以及它何时发生。subtype
: 定义多种不同类型之一的字符串,例如 channel_join、channel_leave 等。is_starred
: 一个布尔值,指示此消息是否已加星标。pinned_to
:已固定此消息的频道数组。reactions
:一组反应对象,定义了反应是什么(例如,facepalm)、发生了多少次,以及以这种方式对消息做出反应的用户数组。
我将扩展我之前创建index.js
的监听message
事件。为了减少代码冗余,以下示例将仅包含与message
事件增强相关的部分代码。
必须做的第一件事是为RTM_EVENTS
我将要收听的新模块添加一个新模块。我把它放在我之前的两个模块下面,包括:
var RTM_EVENTS = require('@slack/client').RTM_EVENTS;
message
我将放置在文件底部的用于处理事件的代码。为了测试message
事件是否正常工作,我创建了一个新的事件***器,将 message
对象记录到控制台,如下所示:
rtm.on(RTM_EVENTS.MESSAGE, function(message) { console.log(message); });
我现在可以重新运行我的 Node 应用程序 ( node index.js
)。当我在频道中输入消息时,控制台会记录以下内容:
{ type: 'message', channel: 'C6TBHCSA3', user: 'U17JRET09', text: 'hi', ts: '1503519368.000364', source_team: 'T15TBNKNW', team: 'T15TBNKNW' }
到目前为止,一切都很好。我的机器人正在成功接收消息。下一个增量步骤是确保消息属于我的机器人所在的频道:
rtm.on(RTM_EVENTS.MESSAGE, function(message) { if (message.channel === channel) console.log(message); });
现在,当我运行我的应用程序时,如果message
事件是针对channel
我的机器人所属的事件,我只会看到我的调试消息。
我现在将扩展应用程序以向通道发送自定义消息,以演示如何在消息中标记用户:
rtm.on(RTM_EVENTS.MESSAGE, function(message) { if (message.channel === channel) rtm.sendMessage("Stop, everybody listen, <@" + message.user + "> has something important to say!", message.channel); });
现在,当有人在频道中键入消息时,我的机器人会发送自己的消息,类似于:“停止,每个人都听着,@endyourif 有重要的事情要说!”
好的,不是很有用。相反,我将通过增强message
事件***器以响应特定命令来完成我的机器人。这将通过执行以下操作来完成:
根据空格
text
将 a 的部分拆分为数组。message
检查第一个索引是否与我的机器人的用户名匹配。
如果是这样,我将查看第二个索引(如果存在)并将其视为 我的机器人应该执行的命令。
为了便于检测是否提到了我的机器人,我需要创建一个新变量来存储我的机器人用户 ID。下面是更新的代码部分,我之前在其中设置了channel
变量。它现在还将我的机器人的用户 ID 存储在一个名为bot
.
let channel; let bot; rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => { for (const c of rtmStartData.channels) { if (c.is_member && c.name ==='jamiestestchannel') { channel = c.id } } console.log(`Logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}`); bot = '<@' + rtmStartData.self.id + '>'; });
使用我的bot
变量集,我通过充实先前创建的 message
事件***器来完成我的机器人,如下所示:
rtm.on(RTM_EVENTS.MESSAGE, function(message) { if (message.channel === channel) { if (message.text !== null) { var pieces = message.text.split(' '); if (pieces.length > 1) { if (pieces[0] === bot) { var response = '<@' + message.user + '>'; switch (pieces[1].toLowerCase()) { case "jump": response += '"Kris Kross will make you jump jump"'; break; case "help": response += ', currently I support the following commands: jump'; break; default: response += ', sorry I do not understand the command "' + pieces[1] + '". For a list of supported commands, type: ' + bot + ' help'; break; } rtm.sendMessage(response, message.channel); } } } } });
以下代码基于空格text
将对象的属性拆分为数组。message
接下来,我确保数组中至少有两个元素,理想情况下是我的机器人和要执行的命令。
当数组中的第一个元素与我的机器人匹配时,我对数组中switch
的第二个元素执行语句:命令。当前支持的命令是 jump和 help。当一条消息发送到看起来像“@jamiestest jump”的频道时,我的机器人将向原始用户发送一条特殊消息。
如果无法识别该命令,它将属于我的默认 case 语句,switch
并以如下所示的通用命令响应:“@endyourif,对不起,我不理解命令“hi”。有关支持的命令列表,输入:@jamiestest 帮助”。
结论
至此,我的机器人就完成了!如果您有兴趣进一步增强您的机器人,这里有一个想法列表:
通过收听
team_join
事件来处理新的团队成员加入。当新团队成员加入时,向他们发送各种入职信息和/或文档以欢迎他们加入您的团队是一个好主意。增强我已启动的受支持命令列表。
通过搜索数据库、Google、YouTube 等使命令具有交互性。
在应用程序上创建机器人用户并创建您自己的自定义斜杠命令。
- 配置
- 入口点
- 进入SDK
- 调试
- 构建机器人