Implement Slack chatbot in Python

A generic implementation of bots for Slack's Outgoing Webhooks in Python, "djehuty/[djehuty-slack](https://github.com/xica/ djehuty-slack) "has been released so I'll share it.

With Hubot?

I wanted to use an in-house, Python-implemented server-side module directly from the bot.

Set up Slack's Outgoing Webhooks integration

Add integration

Before preparing a bot, it is necessary to make settings for interacting with the bot on the Slack side in the first place. One of Slack's integrations is "Outgoing Webhooks", which is a mechanism for POST requesting input starting with a specific word to a specified URL. djehuty uses this integration.

In the Outgoing Webhooks settings, you can set the channel, trigger word, etc. to enable this integration. If you have a Slack account, you can probably choose to add an integration from here.

Outgoing Webhooks are near the bottom of the list.

slackOutgoing.png

integration settings

djehuty recognizes the first ASCII string found after the trigger word set here as the command line. For example, if you set "mybot:" in the trigger word, then in Slack

mybot:yo -g hello

If you enter, etc., djehuty will recognize it as the command line "yo -g hello". For the URL, you can set the URL of the application server you prepared with'/ slack' added later.

slackIntegrationSettings.png

Check Outgoing Webhooks Token

You can also see the token on this screen to indicate that it's from a request from your Slack account. Since the implementation of djehuty-slack also checks this token and checks the request, it is good to check the token in advance here.

djehuty

djehuty (Jeffty) is a Python package to help implement application servers that specialize in supporting so-called web hooks. Currently, it has very low functionality, but as a feature,

Djehuty-slack is already implemented as a service, so if you use this, you can easily make a bot that returns some response corresponding to Slack's Outgoing Webhooks. Can be prepared in.

Regarding the package name, since it was implemented based on pyramid, I decided to make it an Egyptian (mythology) related name [thoth](http://ja.wikipedia.org/wiki/%E3%83%88%E3%83% BC% E3% 83% 88) was being implemented as if it was the most suitable, but since the package with the same name was already registered in PyPI, it ended up being another name djehuty.

Prepare a djehuty server

Stand by yourself

Basically it is not recommended because the documents are not available.

For the time being, djehuty implements pyramid scaffold, so you can easily create a project using it and start it as a pyramid app.

$ pip install djehuty
$ pcreate -s djehuty_server PROJECT_NAME
$ cd PROJECT_NAME
...
$ pserve development.ini

In order to run as a Slack bot, it is necessary to set the corresponding service and environment variables as described in the djehuty and djehuty-slack README.

Run on Heroku

The files generated by djehuty's scaffold also include settings for Heroku (requirements.txt, Procfile, ini file for Heroku), so this is your own on the assumption that you will support SSL etc. It's easier than preparing an environment with.

$ pip install djehuty
$ pcreate -s djehuty_server PROJECT_NAME
$ cd PROJECT_NAME
$ heroku create
...
$ git push heroku master

I will omit the deployment to Heroku and the setting of environment variables.

Use the djehutysample Heroku Button

The djehuty-sample repository for the sample is [Heroku Button](https://blog.heroku.com/archives/2014/8/7/heroku- button) is supported, and djehuty-sample has already specified djehuty-slack as a service to use, so if you have a Heroku account, you can prepare a chat bot server for Slack with the touch of a button. However, considering that you will edit the code later to add commands etc., it is better to fork once before deploying.

When deploying with Heroku Button, you will be asked to set environment variables for djehuty-slack, so set the token that can be confirmed in the Outgoing Webhooks settings here.

Regardless of which method you use to prepare the server, don't forget to specify the URL of the server you prepared with'/ slack' added to the URL setting of Outgoing Webhooks.

Try the bot

If Slack is set up and the djehuty server is set up correctly, the command should work. If you have tried djehuty-sample, the yo command and lgtm command should be enabled, so enter the following on the channel specified in the settings, and the character string yo will be returned [LGTM]( If the image of http://www.lgtm.in/) is returned randomly, it is successful.

YOUR_TRIGGER_WORD yo
YOUR_TRIGGER_WORD lgtm

Implement the command

Regardless of which method you use to prepare the server, the Python package for the application server is at hand, so you can add bot functionality by implementing commands in it.

The command implementation inherits the class provided by djehuty and implements the command class and uses it as setuptools entry_points It is enabled by registering in -and-plugins).

djehuty.command.Command

A class called djehuty.command.Command is defined in djehuty. djehuty uses a framework called cliff for command line management, and djehuty.command.Command is considered to be almost the same as cliff.command.Command. You can. So basically the command class implementation follows cliff's documentation.

Since the actual command name is specified in the entry_points registration described later, the name of the class to be implemented by yourself does not have to be the same.

Implementation of command contents

The concrete class of djehuty.command.Command is expected to implement a method called take_action, and djehuty uses the value returned by this method as a response message to Slack (this is what cliff expects). Different). For example, the implementation that returns the string "yo" with a mention to the input user is as follows.

from djehuty.command import Command


class Yo(Command):
    '''echo yo'''  #cliff uses class documentation as help

    def take_action(self, parsed_args):
        return '@{} yo'.format(self.app_args.user)

parsed_args will be described later. self.app_args contains arguments common to services, in the case of Slack, the name of the user entered in user and the name of the channel entered in room.

Basically, this is the only command implementation.

Implementation of command arguments

Commands come with arguments so that they can be given dynamic values. djehuty (or cliff) also supports argument implementation, so you can declaratively add arguments to your own commands.

from djehuty.command import Command


class Yo(Command):
    '''echo yo'''

    def get_parser(self, prog_name):
        parser = Command.get_parser(self, prog_name)
        parser.add_argument('-g', '--greeting',
                            default='yo',
                            help='greeting message')
        return parser

    def take_action(self, parsed_args):
        return '@{} {}'.format(self.app_args.user, parsed_args.greeting)

If you implement a method called get_parser in the concrete class of djehuty.command.Command, the input string is evaluated according to the implementation, and the argument is passed to take_action as parsed_args and can be used.

get_parser is basically

It is in the form of. Since parser is an instance of argparse.ArgumentParser and parsed_args is argparse.Namespace, refer to the argparse documentation for the argument definition and how to get the value itself. thing. I think you can get a basic idea of how to use it with just the above code, but there are many more advanced definitions.

Command registration

djehuty.command.Command is recognized and enabled by djehuty by registering it in the entry_points mechanism of setuptools as described above. Registration simply adds the description to setup.py, so if you implement the Misawa and Hartman commands in commands.py in a package called mydjehuty, the entry_points argument for setup in mydjehuty / setup.py is: become that way.

setup(
    name='mydjehuty',
    # ...
    entry_points={
        'djehuty.commands': [
            'misawa = mydjehuty.commands:Misawa',
            'hartman = mydjehuty.commands:Hartman',
        ],
    },
)

As the value of list with'djehuty.commands' as the key

'Command name when actually using=Modules implemented(file name):Implemented class name'

You just have to add the character string.

Operation on the console

Installing djehuty installs not only the framework code and pyramid scaffold, but also a CLI called djehuty. Since this is a CLI that takes over only the POST request and response parts, the behavior of the implemented command can be emulated on the console.

$ djehuty yo
yo

However, you need to explicitly specify the arguments common to services such as those implemented in services such as djehuty-slack.

$ djehuty -u kiri yo
@kiri yo

Command-only package

It is possible to implement a Python package that implements only commands as well as within your own application server, and scaffold is also available for that purpose.

$ pcreate -s djehuty_command YOUR_COMMAND_PROJECT_NAME

If the implementation can be published with functions that do not depend on a specific organization, it can also be published as a command package using this.

the end

If you can deploy the package containing the implemented command to the application server and run the implemented command from Slack, it will be successful. Feel free to implement your favorite features in Python for a good Slack life.

Recommended Posts

Implement Slack chatbot in Python
Implement Enigma in python
Implement recommendations in Python
Implement XENO in python
Slack chatbot creation Python
Implement sum in Python
Implement Traceroute in Python 3
Implement naive bayes in Python 3.3
Implement ancient ciphers in python
Implement Redis Mutex in Python
Implement extension field in Python
Implement fast RPC in Python
Post to Slack in Python
Implement stacking learning in Python [Kaggle]
Implement the Singleton pattern in Python
Quickly implement REST API in Python
Quadtree in Python --2
Python in optimization
CURL in python
I tried to implement PLSA in Python
Metaprogramming in Python
Python 3.3 in Anaconda
Geocoding in python
SendKeys in Python
Implement __eq__ etc. generically in Python class
I tried to implement permutation in Python
Meta-analysis in Python
Unittest in python
Collectively implement statistical hypothesis testing in Python
I tried to implement PLSA in Python 2
Epoch in Python
Discord in Python
Sudoku in Python
DCI in Python
quicksort in python
Log in to Slack using requests in Python
nCr in python
Plink in Python
I tried to implement ADALINE in Python
Constant in python
Develop slack bot in python using chat.postMessage
I tried to implement PPO in Python
Lifegame in Python.
FizzBuzz in Python
Sqlite in python
StepAIC in Python
N-gram in python
LINE-Bot [0] in Python
Disassemble in Python
Reflection in Python
Constant in python
nCr in Python.
format in python
Scons in Python3
Puyo Puyo in python
python in virtualenv
PPAP in Python
Quad-tree in Python
Reflection in Python
Chemistry in Python
Hashable in python