SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Elasticsearchと対話Botによる対話型の検索システム

使いたくなる検索システムのUIをSlackBotで実現する

Elasticsearchと対話Botによる対話型の検索システム 第4回

  • X ポスト
  • このエントリーをはてなブックマークに追加

SlackBotを設定する

 今回紹介するコードは以下のパートで構成されています。

  • 設定ファイル
  • 設定ファイルの値を保存するモデルのコード
  • Slackで対応するためのコード

[1]設定ファイル

 まず、YAML形式で設定ファイルを作成します。今回使用するパラメータはここで設定しておきます。固定値なのでコードに記述せず、設定ファイルに記述することでコードに影響がないようにします。

リスト1 SlackCode/enviroment_slack.yml
slack:
    api_token: {チャネルやユーザーの情報を取得するために使用したAPIトークン} 
    channel: {先ほどメモしたチャネルのid}
    user_name: {設定したいBotの名前}
    message: {設定したいBotが返答するメッセージ}
    icon_url: {先ほどメモした画像のリンク} 

[2]設定ファイルの値を保存するモデルのコード

 これは設定ファイルの値を保持することだけを目的としたモデルのコードです。このコードではSlackに対する操作は行いません。

リスト2 SlackCode/slack_model.py
self.Slack = namedtuple("slack", ["api_token", "channel", "user_name", "message", "icon_url"])

 リスト2では、YAMLファイルを読み込むための値に、名前をつけたタプル形式で保存するための設定を記述しています。

 名前付きタプルのメリットは以下の通りです。

  • 名前による明示性の向上
  • 設定した値を必ず設定する必要があること
  • 設定する値を増やせないこと

 今回はYAMLファイルから固定値を取得しているので、これがプログラム実行中に変更されることはなく、また項目が増えることもないので名前付きタプルが最適でした。

リスト3 SlackCode/slack_model.py
with open(self.config_file, encoding="utf-8") as cf:
   e = yaml.load(cf)
   slack = self.Slack(e["slack"]["api_token"], e["slack"]["channel"],
                      e["slack"]["user_name"], e["slack"]["message"],
                      e["slack"]["icon_url"])
   self.slack_channel = SlackClient(slack.api_token)
   self.chan = slack.channel
   self.user_name = slack.user_name
   self.message = slack.message
   self.icon_url = slack.icon_url

 リスト3では、YAMLファイルから各値を取得してモデルの値に設定しています。

slack:
    api_token:

 YAMLファイルが上記のような形式で、

e["slack"]["api_token"]

"slack"の次に"api_token"がネストされているため、このような形式で読み込みます。そして、先ほど設定したAPIトークンの値を"SlackClient"に設定し、SlackAPIを使用できるように設定します。

self.slack_channel = SlackClient(slack.api_token)

[3]Slackで対応するためのコード

 ここからはSlackを実際に操作するコードを説明します。

 リスト4ではSlackのチャネルに接続しているかをチェックし、チャネルから値を読み込み読み込んだ値に対して"self.__judge_call()"で返答するかどうか判断しています。

リスト4 SlackCode/app.py
    def call_method(self):
        """
        Slack api call
        1: read sentence
        2: return the sentence
        """
        if self.slack_channel.rtm_connect():
            while True:
                self.data = self.slack_channel.rtm_read()
                self.__judge_call()
                time.sleep(1)
        else:
            print("connection Fail")

 また、リスト5では、Botが反応するかどうか判定しています。

リスト5 SlackCode/app.py
    def __judge_call(self):
        """
        judge slack call for Slack
        Example:
            search_bot:{your sentence}
                return the sentence
        """
        if len(self.data) >= 1 and "text" in self.data[0]:
            if "search_bot:" in self.data[0]["text"]:
                word = self.message
                print(self.slack_channel.api_call("chat.postMessage", username=self.user_name, channel=self.chan, text=word, \
                                                  icon_url=self.icon_url))

 判定項目は以下の通りです。

  • データの長さが1以上か
  • データが"text"か
  • "search_bot:"を含んでいるか

 判定後、"self.slack_channel.api_call"でSlackのAPIを呼んでいます。

  • どのようなメソッドか
  • Botの名前
  • 反応するチャネル
  • 返答するワード
  • Botのアイコン画像

 Botの名前、反応するチャネル、返答するワード、Botのアイコン画像はYAML形式で設定した値が反映されます。

 今回使用しているメソッドは"chat.postMessage"です。メッセージを投稿するメソッドです。

SlackBotによる単純な返答システムを動作させる

 実際に作成したシステムを動作させます。なお、前回までの記事で紹介したdockerの設定がしてあるVagrant環境を想定しているため、Vagrant環境の設定方法の説明は省略します。

vagrant up
vagrant ssh

 vagrantを起動してアクセスします。

docker pull masayaresearch/slack:latest 

 今回のシステムの環境が構築されているコンテナを取得します。

docker run -it {取得したdockerコンテナのID} bash

 コンテナにアクセスします。

python app.py 

 これで起動します。

図18 SlackBotの動作イメージ
図18 SlackBotの動作イメージ

 このように、適切に動作すれば"search_bot:"に反応するBotが作成できます。

最後に

 これで単純な返答ができるBotが作成できました。次回はこのBotと、前回まで作成していたElasticseachの検索システムを連携させ、対話Botによる検索システムを完成させます。

参考文献

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Elasticsearchと対話Botによる対話型の検索システム連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 大串 正矢(オオグシ マサヤ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/9923 2017/01/27 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング