SlackBOTを作って、Slackを盛り上げよう

こんにちは、にゅ〜ぶるです。

少し前(いや、かなり前か…笑)に、こんなツイートをしました。

そうです!「にゅ〜ぶる会」に秘書が出来ました!!!

秘書と言っても、人ではなくて、SlackBOTなんですけどね…(人だと思った方すみません…💦)
今回は、SlackBOTの作り方を簡単にまとめて、皆さんのSlackにも適用されたら、いろんなところのSlackが盛り上がると嬉しいな!と思って記事にしています。

SlackBOTとは…?

一言で言うと、Slackで誰かが投稿した内容に自動で応答するアプリです。

作るのは難しいと思うかも知れませんが、実は簡単です。
必要なスキルは、

  • スプレッドシート
  • GAS(JavaScript)
  • Slack
  • ググる力

です!

では、順を追って説明していきますね。

Slackのアプリ設定にある「カスタムインテグレーション」に「Incoming Webhook」を追加します。

「インテグレーションの設定」は自由で良いです。
GAS側から、自由に変更出来るためです。ただし、実際に投稿されたアイコンをクリックした際などの情報は、ここで設定した情報が表示されるので、必要あれば変更ください。

ここで必要なのは、「WebhookURL」です。
このURLに情報をセットして呼び出すと、Slackに投稿されます。

GASでBOTの処理を作成します。

まずは、Slackへ投稿する処理を作りましょう。
簡単に言うと、投稿したい内容を用意して、UrlFetchApp.fetchを呼ぶだけです。

var INCOMING_URL = 'ここに、IncomingのWebhookURLを貼り付けてください';
function postSlackMsg(botName, botIcon, channel, message) {
   var payload  = { 'text'      : message,  // 投稿内容
                    'username'  : botName,  //botの名前
                    'icon_url'  : botIcon,  //botのアイコン
                    'channel'   : channel,  //投稿するチャンネル
  };
  var options = { 'method'      : 'post',
                  'contentType' : 'application/json',
                  'payload'     : JSON.stringify(payload),
  };

  UrlFetchApp.fetch(INCOMING_URL, options);
}

次は、Slackから受け取る側ですね。

受け取る関数は、doPost(e)です。Slackからこれが呼ばれるので、ここは固定にしてください。

function doPost(e) {
    var verifyToken = 'ここに、Outgoingのトークンを貼り付けてください(後述)';
    // 投稿の認証
    if(verifyToken != e.parameter.token){
      throw new Error('トークン違う!');
    }
    // 自分の投稿には反応しない(無限ループ対策)
    if(e.parameter.user_id == 'USLACKBOT'){
      throw new Error('無限ループダメ!絶対!');
    }
    var botName = 'ぶるこ';
    var botIcon = 'https://i.imgur.com/4gSmS8r.jpg';
    // Trigger Words部分の削除(とりあえず4文字)
    var triggerMsg = e.parameter.text.substr(4);
    var replyMsg = searchMsg(triggerMsg);
    postSlackMsg(botName, botIcon, e.parameter.channel_id, replyMsg);
  }

途中に出て来ました「searchMsg」BOTの反応を決める関数です。
仕組みは、スプレッドシートの情報を抽出するようにしました。

// スプレッドからリプライを検索する
function searchMsg(triggerMsg) {
  var replyMsg = '';
  if(triggerMsg != ''){
    var sheet    = SpreadsheetApp.openById('ここに、スプレッドシートのIDを貼り付けてください').getSheetByName('ここに、シート名を貼り付けてください');
    var lastRow = sheet.getLastRow();
    for(var row = 2; row <= lastRow; row++) {
      // トリガー文字を含む場合はその行のリプライを選択
      if(sheet.getRange(row,1).getValue().indexOf(triggerMsg) != -1){
        var lastCol = findLastCol(sheet, row);
        replyMsg = sheet.getRange(row,getRandomInt(2, lastCol)).getValue();
        break;
      }
    }
  }
  return replyMsg;
}

途中に出てくる共通関数を、置いておきますね。

/*
 * 指定行の「最終列の列番号」を返す
 * @param {number} 行番号
 * @return {number} 最終列の列番号
 */
function findLastCol(sheet, row) {
  // 指定の行を二次元配列に格納する ※シート全体の最終行までとする
  var rowValues = sheet.getRange(row, 1, 1, sheet.getLastColumn()).getValues();
  //二次元配列を一次元配列に変換する
  RowValues = Array.prototype.concat.apply([], RowValues);
  var lastCol = RowValues.filter(String).length;
  return lastCol;
}
/*
 * 乱数を返す
 *
 * @param {min} 最小値
 * @param {max} 最大値
 */
 function getRandomInt(min, max) {
   var ran = Math.floor(Math.random() * Math.floor(max - min + 1));
   return min + ran;
 }

Slackのアプリ設定にある「カスタムインテグレーション」に「Outgoing Webhook」を追加します。

今度は、Slackの投稿情報をGASに連携するための設定です。
「インテグレーションの設定」は以下の通りです。

引き金となる言葉

このワードで始まる投稿に反応するようになります。BOTの名称にしておくと良いでしょう。

URL

GASの公開URLをここに設定してください。

トークン

どのSlackから呼ばれたかのキー情報になりますので、
このキーからのみ処理を動かすように、処理の先頭に追加しましょう。
※前術しましたdoPost(e)の先頭でチェックします。

完成!?

実際に動かすと、こんな感じになります。

あとは、スプレッドシートの内容を充実化させていけば、いろいろなメッセージに自動応答していく事が可能になります。

まだまだ改善の余地があるプロジェクトになっていますが、最初のスタートとしてはこれぐらいで十分かなと思います。ソースコードや動きに疑問・質問等ありましたら、コメント等でご連絡頂けると助かります🙇‍♂️

SlackSlackBOT

Posted by にゅ~ぶる