SlackのBoltフレームワークを使ってWordPressをSlackから検索するBotを作ってみた

はじめに

DevIOを検索するために毎回Chromeへと切り替えるのも少々面倒だなと感じていたものの、かといって楽する方法については見当すらついていませんでした。

SlackのBoltフレームワークに触れる機会があり、チュートリアルをたどってみた結果「Slackから気軽に記事検索ができそうだな」という結論に至り、試しに作ってみました。

Boltチュートリアルを読みすすめつつBot雛形を作る

以下のQiita記事を参考にすすめます。画面毎の操作をまとまっているため、途中でブラウザのタブをうっかり閉じたりでもしないかぎりは迷いません。 Hello World, Bolt! ⚡️ Bolt フレームワークを使って Slack Bot を作ろう - Qiita

なお、途中でglitchを使う場面があります。コードのExportを考慮してGitHubアカウントにてglitchアカウントを作成しておきましょう。 Glitch

BotでJSONのレスポンスを取得してSlackに流す

index.jsonにてWordPressの検索APIを行い、レスポンスを加工して投稿します。

const { App } = require('@slack/bolt');
const store = require('./store');
const URL = 'https://domain.jp/wp-json/wp/v2/posts?search=';
const app = new App({
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  token: process.env.SLACK_BOT_TOKEN
});

var util = require('util');
app.event('app_home_opened', ({ event, say }) => {
  // Look up the user from DB
  let user = store.getUser(event.user);
  if(!user) {
    user = {
      user: event.user,
      channel: event.channel
    };
    store.addUser(user);
    say(`Hello world, and welcome <@${event.user}>!`);
  } else {
    say('Hi again!');
  }
});


// Listens to incoming messages that contain "hello"
app.message('記事検索', ({ message, say }) => {
  // say() sends a message to the channel where the event was triggered
  var keyword = message.text;
  keyword = keyword.replace(/記事検索 /g,'');
  require('https').get(URL+keyword, function (res) {
    res.setEncoding('utf8');
    var body = ''
    res.on('data', function (chunk) {
        body += chunk;
    });
    res.on('end', function (chunk) {
        // body の値を json としてパースしている
        res = JSON.parse(body);
        var result = `「${keyword}」の検索結果\n`;
        res.forEach(function(item, index) {
          result += item.title.rendered;
          result += '\n';
          result += item.link;
          result += '\n';
        });
        say(result);
    })
  }).on('error', function (e) {
    console.log(e.message);
  });
});


// Start your app
(async () => {
  await app.start(process.env.PORT || 3000);
  console.log(' Bolt app is running!');
})();

以下のようにレスポンスが帰ってきました。

ハマりがちだと思われる箇所

以下、実際にやってみてハマった箇所です。

Botがメッセージに応答してくれない

チュートリアルだけを読んだ状態だと恐らく対処できません。

Slack APIのBot編集画面にて、左メニューEvent Subscriptions > Subscribe to Bot Eventsで「Add Bot User Event」からmessage.imを追加して、画面右下の「Save Change」を実行する必要があります。

app.messageのmessageオブジェクトの詳細がわからない

dumpしてBotに喋らせるのが手軽です。以下のような関数をindex.jsに追加して、BotにhelloとIMしてみましょう。

var util = require('util');
app.message('hello', ({ message, say }) =>; {
  // say() sends a message to the channel where the event was triggered
  say(util.inspect(message));
});

アクセサが判ったら、${message.user}のように置き換えます。

var util = require('util');
app.message('hello', ({ message, say }) =>; {
  // say() sends a message to the channel where the event was triggered
  say(`${message.user}`);
});

なお、dump結果がランダム文字列になっていても、Botにアクセサ指定で喋らせた時には本来の文字列へと変換されます。

あとがき

Boltそのものにはそれほど時間もかかりませんでしたが、JSONのリクエスト及び加工については結構時間が掛かっています。とりあえずで始めたため、エラーログの取得などを準備しておけば全体として手早く完了できた気がします。

Slack BoltとGlitchの組み合わせでのBot作成は本当にお手軽だったため、二の足を踏んでいた人にはお薦めです。