Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8913

どこ住み?てかSlackやってる?生後10ヶ月のエンジニアが爆速10時間でChatbot制作!‬

$
0
0

[前置き]
閲覧ありがとうございます!エンジニア歴10ヶ月のひよっこwebでべろぱーです。
本投稿はエンジニア歴3年未満程度の初学者向け投稿になります。
個人で何か作りたいけど、丁度いい規模感のアイデアが思い付かない...
そんなあなたに!お手軽なChatbotの制作をオススメします!
というわけで作ってみましたー!↓↓

作ったもの -What I made-

🎉🎉地域の飲食店検索Slackチャットボット「GourmetNav」 🎉🎉

Slack上で動作するチャットボット。
「駅名」+ 「空白」 + 「店名に関わるキーワード」を入力すると、その地域の飲食店名とお店のURLを飛ばしてくれる(σ・ω・)σ
gourmetnav.gif

おもしろいところ

  • 地図を見ずに、駅名なんとなくの店名だけで検索できる。Slackで!!
  • チェーン店も、もちろん対象。目指せ、地域のスタバマスター!٩(。˃ ᵕ ˂ )وイェーィ♪

なにができるの

  • 「GourmetNav」の検索結果から、ワンクリックで各飲食店のサイトに飛べる。
  • わざわざブラウザで色んなページを見に行ったりしなくていい。
  • 検索結果にたまーに混じっている別の地域のお店、とかがない(←ここ重要!)

技術的な話

TL;DR (大まかなデータの流れ)

Slack× GAS× 駅情報取得API× ぐるなびAPIを使用しています。

  1. Slackのチャンネル「GourmetNav」から、「駅名」+ 「半角(または全角)空白」 + 「店名に関わるキーワード」を入力、送信。
  2. Slackから受け取った入力情報をGAS上で参照。
  3. 駅情報取得APIを用いて、入力情報内の「駅名」から緯度・経度を取得。
  4. ぐるなびAPIを用いて、上記の緯度・経度からその地域の飲食店を検索、一覧にしてGoogle Spreadsheetに出力(2度目以降はシートを初期化して更新するのでデータは保持しない)
  5. 生成されたSpreadsheet内の飲食店一覧から、「店名に関わるキーワード」と部分一致する「飲食店名」とその「サイトURL」を取得。
  6. 取得した「飲食店名」とその「サイトURL」をSlack側に出力。
  7. Slackのデータ容量圧迫しないように投稿を毎日自動削除するようにトリガーを設定(任意)

具体的な面倒くさいところ

1. まず、ローカルでの開発環境構築(任意)

ある程度のコード量/ロジックを書くならば、GASをブラウザ上のスクリプトエディタでベタ書きするのは、間違いなくNonsenseなんじゃないかと思います。(知らんけど)
(参考): Google Apps Script をローカル環境で快適に開発するためのテンプレートを作りました
(著者): @howdy39

※型定義ないとデバックしづらいのでTypeScriptも入れました(任意)

今回デバッグしていて初めて気付いたんですけど、Javascriptって配列にtypeofかけても「object」って返されるんですね。なんて暗黒言語!!
競技プログラミング(Atcoder)でC#愛好家の私には拒絶反応が出たので、typescript導入しました。
(参考): clasp + TypeScriptで課題改善botを作った
(著者): @mochisuna
(参考): JavaScriptの型などの判定いろいろ
(著者): @amamamaou

2. GASでSlackからの入力情報を受け取り、参照し、出力する(必須)

開発環境を整備したら、まずはSlackとBotによる簡単な入出力を実装する。
下記の記事を参考にすると、以下のようなことができる。
✔️GASでPOSTリクエストを受け取る
✔️SlackでOutgoing WebHookの設定を行う
✔️GASでSlackから渡された値を参照する
(参考): Slack上のメッセージをGoogleAppsScriptで受け取ってよしなに使う
(著者): @kyo_nanba

※このとき、SlackAppというライブラリを使用することで設定が少し楽になる

世の中のSlack愛好家の皆さんに圧倒的感謝!
SlackApp作成者@soundTrickerさんに三跪九叩頭しましょう。
(参考): Slack BotをGASでいい感じで書くためのライブラリを作った

3. 駅情報取得API, ぐるなびAPIを上記の中に組み込んで出力内容を工夫する

この部分に関しては、記事読んで実践するだけですんなり実装できました。
(参考): GoogleAppsScriptでぐるなびAPIから取得した駅周辺のお店をスプレッドシートに書き出す
(著者): @kouheidev

4. 上記参考記事を悪魔合体させながら論理構造を調整

今回は社内Slack上で作成したこともあり、一旦ソースコードは開示しません。
(まだまだ生後10ヶ月のエンジニア、トークンの扱いとかGASの仕様とか、セキュリティ面に関しては完璧に理解してるわけじゃないので!)
ただまあ、ベテランの皆さんなら多分苦もなく実装できると思います。(・ω・。)


苦労したところ

無限ループ🌀🌀

GAS上でのテストでは問題ないのに、
Slackで実際に入出力をテストすると無限ループが頻繁に発生しました。(恐ろしい...)
暫くして気付いたのですが、下記のロジックによるものでした。
ユーザの「A」という検索ワードに対して、「GourmetNav」は該当する検索結果を見つけてきます。
そして、「Aが見つかりました!」とSlackに出力してくれるわけです。
この出力を、GAS側は「ユーザによる新しい入力」として検知し、再び検索/出力処理を繰り返すわけです。
なるほど〜〜それはそうだわ! ということで、
doPost内の記述に下記を加えることで無限ループは解消します!

  if (e.parameter.user_name == "slackbot"){
    throw new Error("this is bot."); //入力者がbotだった場合、エラーを返します
  }

まとめ

Slackからのデータ入力をSpreadsheetに出力だとか、
Spreadsheet側の入力をSlackに出力するだとか、
こうした一方通行なBotならQiita上にも数多くあります

ただ、今回作成したのはInteractiveなChatBot。
ユーザ入力に対して、GAS側で入力を検知、
各API内を検索、Spleadsheetに検索結果を出力、
そして、ユーザの求めている情報にマッチする情報のみをユーザに提供する。

こうしたInteractiveなSlackチャットボット制作記事は、決して多くはないかと思います。
GASでSlack向けに開発している方にとって、何かの一助となれば幸いです。

ついったフォローしてね。(・ω・。)
@NadjaHarold


Viewing all articles
Browse latest Browse all 8913

Trending Articles