如何用 Python 打造你的第一个 Slack Bot

阅读 3678
收藏 45
2016-07-13
原文链接:www.sdk.cn

在与Slack等聊天服务进行互动的时候,Bot是一种非常使用的手段。如果你以前从来没有开发过Bot,这篇文章为你提供了一个简单的新手教程,让你可以用Python和Slack API结合在一起,创建你的第一个Bot。

我们将会介绍开发环境、获取Slack API bot token,以及在Python中进行编程,创建一个简单的Bot。

所需工具

我们将会创建一个名叫“StarterBot”的项目,这个Bot需要你拥有Python和Slack API。要想使用Python,你将会需要:

• Python2或3版本

• 用于处理Python依赖的pip和vertualenv

• 免费的Slack账户,但是你的团队必须能够获取API,你也可以注册Slack Developer Hangout团队

• Slack团队推出的官方Python slackclient代码库

• Slack API测试token

在开发过程中,Slack API的说明文件也会给你提供很多的帮助。

部署环境

在准备好上述工具之后,我们将会部署开发环境。打开Mac上控制台(Windows系统上为命令提示符),更改你想要保存这个项目的目录。在这个目录下,创建一个新的虚拟沙箱,让这个程序的依赖于其他Python项目隔离开。

virtualenv starterbot

激活虚拟沙箱:

source starterbot/bin/activate

现在你的命令提示符看起来应该像是下面截图中这样:

 

Slack开发的官方slackclient API助手库能够从Slack频道中获取信息,也能将信息发送到Slack频道中。使用pip命令安装slackclient库:

 pip install slack client

在pip命令完成之后,你应该看到下面的内容,然后你会回到命令提示符中:

 

我们还需要给Slack团队获得一个access token,让Bot可以通过它来连接Slack API。

Slack Real Time Messaging (RTM) API

Slack所提供的一个API允许我们对他们的消息频道进行程序访问。代开Slack web API野蛮,然后注册,创建你自己的Slack团队。如果你以前注册过,直接登录就可以了。

 

登录之后,打开Bot Users页面。

 

给Bot命名为“starterbot”,然后点击“添加Bot整合”按钮。

 

页面会重新加载,然后你会看到一个新生成的access token。你也可以改变logo。例如,我给我的Bot换了一个Full Stack Python的logo。

 

点击页面下方的“保存整合”按钮。现在你的Bot已经最好连接Slack API的准备了。

一般情况下,Python开发人员会导出secret token为环境变量。将导出的Slack token命名为SLACK_BOT_TOKEN:

export SLACK_BOT_TOKEN='your slack token pasted here’

好的,我们现在已经拿到将Slack API当做Bot使用的授权了。

现在还差一条信息:Bot的ID。接下来,我们将要写一个短的代码段,来从Slack API那里获得这个ID。

终于要用Python写代码了!先来热热身,通过Python代码段来获取Bot ID。

这个ID的意义在于,它可以让我们的程序判断 Slack RTM所生成的信息,是否是发送给StarterBot的。我们的代码段也会对SLACK_BOT_TOKEN环境变量进行测试,确定它是否可用。

创建一个名为print_bot_id.py的新文件,然后用下面的代码进行填充:

 import os

from slackclient import SlackClient

 

 

BOT_NAME = 'starterbot'

 

slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))

 

 

if __name__ == "__main__":

    api_call = slack_client.api_call("users.list")

    if api_call.get('ok'):

        # retrieve all users so we can find our bot

        users = api_call.get('members')

        for user in users:

            if 'name' in user and user.get('name') == BOT_NAME:

                print("Bot ID for '" + user['name'] + "' is " + user.get('id'))

    else:

        print("could not find bot user with the name " + BOT_NAME)

我们的代码导入了SlackClient,并且给它指定了SLACK_BOT_TOKEN这个环境变量。当这个代码段被python命令执行的时候,我们就调用了Slack API,列出所有Slack用户,并且得到了匹配 “starterbot”这个名字的ID。

只需要再运行一次下面这个代码段,就可以获得Bot的ID:

python print_bot_id.py

这个代码段会只生成一行输出,里面就包含了Bot的ID:

 

复制这个ID,将其导出为环境变量,并且命名为BOT_ID。

 (starterbot)$ export BOT_ID='bot id returned by script’ 

编写StarterBot代码

现在一切准备都做好了。创建一个名为starterbot.py的文件,然后输入下面的代码:

import os

import time

from slackclient import SlackClient

os和SlackClient的导入看上去很熟悉,因为我们在print_bot_id.py项目中使用过它们。

在导入了依赖之后,我们可以用它们来获取环境变量值,然后对Slack客户端进行实例化。

 # starterbot's ID as an environment variable

BOT_ID = os.environ.get("BOT_ID")

 

# constants

AT_BOT = "<@" +="" bot_id="" "="">:"

EXAMPLE_COMMAND = "do"

 

# instantiate Slack & Twilio clients

slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))

 

 

if __name__ == "__main__":

    READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose

    if slack_client.rtm_connect():

        print("StarterBot connected and running!")

        while True:

            command, channel = parse_slack_output(slack_client.rtm_read())

            if command and channel:

                handle_command(command, channel)

            time.sleep(READ_WEBSOCKET_DELAY)

    else:

        print("Connection failed. Invalid Slack token or bot ID?”)

Slack客户端连接了Slack RTM API WebSocket,然后在从firehose那里获取信息的时候进行不断的循环。如果信息是发送给StarterBot,一个名为handle_command的函数会决定下一步做什么。

之后,添加两个新的函数来对Slack的输出进行分析,并且处理命令。

 def handle_command(command, channel):

    """

        Receives commands directed at the bot and determines if they

        are valid commands. If so, then acts on the commands. If not,

        returns back what it needs for clarification.

    """

    response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \

               "* command with numbers, delimited by spaces."

    if command.startswith(EXAMPLE_COMMAND):

        response = "Sure...write some more code then I can do that!"

    slack_client.api_call("chat.postMessage", channel=channel,

                          text=response, as_user=True)

 

 

def parse_slack_output(slack_rtm_output):

    """

        The Slack Real Time Messaging API is an events firehose.

        this parsing function returns None unless a message is

        directed at the Bot, based on its ID.

    """

    output_list = slack_rtm_output

    if output_list and len(output_list) > 0:

        for output in output_list:

            if output and 'text' in output and AT_BOT in output['text']:

                # return text after the @ mention, whitespace removed

                return output['text'].split(AT_BOT)[1].strip().lower(), \

                       output['channel']

    return None, None 

parse_slack_output这个函数会从Slack那里获取消息,并且判断这些信息是否是发送给StarterBot的。

再将所有东西整合在一起后,这个系统看上去应该是这样的:

 import os

import time

from slackclient import SlackClient

 

 

# starterbot's ID as an environment variable

BOT_ID = os.environ.get("BOT_ID")

 

# constants

AT_BOT = "<@" +="" bot_id="" "="">:"

EXAMPLE_COMMAND = "do"

 

# instantiate Slack & Twilio clients

slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))

 

 

def handle_command(command, channel):

    """

        Receives commands directed at the bot and determines if they

        are valid commands. If so, then acts on the commands. If not,

        returns back what it needs for clarification.

    """

    response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \

               "* command with numbers, delimited by spaces."

    if command.startswith(EXAMPLE_COMMAND):

        response = "Sure...write some more code then I can do that!"

    slack_client.api_call("chat.postMessage", channel=channel,

                          text=response, as_user=True)

 

 

def parse_slack_output(slack_rtm_output):

    """

        The Slack Real Time Messaging API is an events firehose.

        this parsing function returns None unless a message is

        directed at the Bot, based on its ID.

    """

    output_list = slack_rtm_output

    if output_list and len(output_list) > 0:

        for output in output_list:

            if output and 'text' in output and AT_BOT in output['text']:

                # return text after the @ mention, whitespace removed

                return output['text'].split(AT_BOT)[1].strip().lower(), \

                       output['channel']

    return None, None

 

 

if __name__ == "__main__":

    READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose

    if slack_client.rtm_connect():

        print("StarterBot connected and running!")

        while True:

            command, channel = parse_slack_output(slack_client.rtm_read())

            if command and channel:

                handle_command(command, channel)

            time.sleep(READ_WEBSOCKET_DELAY)

    else:

        print("Connection failed. Invalid Slack token or bot ID?”)

现在所有的代码都已经就位,使用python starterbot.py这个命令,我们就可以运行StarterBot了。

 

在Slack中,创建一个新的频道,邀请StarterBot,或是将它邀请到你以前的频道中。

 

现在开始在频道中给StarterBot设定命令吧。

 

好了,你已经有了一个简单的StarterBot了,你可以给它添加任何你想要的功能。

使用Slack RTM API和Python,你其实还可以完成很多其他的事情。

354523313711495915.jpg

原    文:How to Build Your First Slack Bot with Python Posted by Matt Makai on June 04, 2016.
译    文:SDK.cn
作    者:Christian(编译)

「Slack」都使用了那些技术和工具?他又是怎样从0到1发展起来的?
点击查看「Slack」-- 技术栈
评论