概要
- 定刻になったら、いらすとやの画像付きのメッセージをSlackのチャンネルに投稿する。
- トリガーワードがSlackに投稿されたら、いらすとやの画像付きのメッセージで返信する。
なお、画像はランダムで指定されるため、何が出てくるかはお楽しみです
※本記事は、すでにSlack Botを運用されている前提で書いていますので、Node環境の準備やSlackのAPI Tokenの払い出しなどの情報は割愛していますので、ご了承ください
Slackへの投稿イメージ
必要なノードモジュールは3つ
npm install -S botkit
npm install -S puppeteer
npm install -S node-cron
メインのスクリプト
index.js
const botkit = require('botkit');
const puppeteer = require('puppeteer');
const cron = require('node-cron');
if (!process.env.SLACK_TOKEN) {
console.log('Error: Specify token in environment');
process.exit(1);
}
const controller = botkit.slackbot({
debug: true,
});
const bot = controller.spawn({
token: process.env.SLACK_TOKEN,
}).startRTM();
// Bot起動時のSlack疎通確認用
controller.hears(['ping'], 'direct_message,direct_mention,mention,ambient', function (bot, message) {
bot.reply(message, 'PONG');
});
// --------------------------------------------------
// いらすとや画像をSlackに投稿する
// --------------------------------------------------
function postIrasutoya(channel){
(async () => {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://www.irasutoya.com/2016/04/blog-post_890.html');
await page.click('a[href="#random"]');
await page.waitForNavigation({ waitUntil: 'domcontentloaded' });
const image = await page.$('#post .entry img');
const src = await image.getProperty('src');
const url = await src.jsonValue();
const title = await page.$eval('#post h2', item => {
return item.innerText;
});
bot.say({
channel: channel,
text: '休憩しようぜ!<' + url + '|' + title + '>',
as_user: false,
username : 'いらすとや',
icon_emoji: ':+1:',
}, function(err, res) {
if (err) {
bot.botkit.log('Failed to postMessage', err);
}
});
await browser.close();
})();
}
// トリガーワードで実行する
controller.hears(['いらすとや'], 'direct_message,direct_mention,mention,ambient', function(bot, message) {
postIrasutoya(message.channel);
});
// cronでスケジュール実行する(月曜〜金曜の12時と15時)
cron.schedule('0 0 12,15 * * 1-5', () => {
postIrasutoya('#general'); // #generalチャンネルに投稿
});
解説1: いらすとやの画像をランダムに取得する
- いらすとやの画像ページを開き、下部にあるランダムボタンをクリックする。
- クリック後に表示されたページの画像のURLとタイトルを取得する。
- Slackに画像のタイトルとURLを投稿する。
解説2: トリガーワードで実行する
controller.hearsの第一引数が、トリガーワードになります。
複数指定や正規表現指定も可能です。
controller.hearsの第二引数は、反応するメッセージイベントの種類を指定します。
イベントの種類 | 説明 |
---|---|
direct_message | ユーザーからのダイレクトメッセージに反応します。 |
direct_mention | チャンネル内でのダイレクトメンションのメッセージに反応します。 |
mention | チャンネル内でのメンション付きのメッセージに反応します。 |
ambient | チャンネル内でのメンションがないメッセージに反応します。 |
※@メンションがメッセージの先頭についているのがダイレクトメンションです。(direct_mention)
解説3: cronでスケジュール実行する
cron.scheduleの引数で、スケジュールを指定します。
引数の中の左から「秒、分、時、日、月、曜日」で指定することができます。
'0 0 12,15 * * 1-5'
の場合は、1-5が月曜〜金曜を意味しており、月曜〜金曜の間の12時0分0秒と15時0分0秒を意味しています。
詳細は、merencia/node-cronのREADME.mdのCron Syntaxをご参照ください。
どうしてこれを作ったか
- 作業に集中していると、休憩も忘れて没頭しがちなので、休憩を喚起(歓喜)したかった。
- 最初はSlackの/remindで休憩メッセージを出していたが、テキストだけだと無機質で事務的に感じるようになってしまった。
- 休憩する、という空気感(和む、安らぐ)を出したかったので画像付きを試みました。
- 最初はlgtm.inの画像を出そうと思ったが、ランダムに出てくる画像のほとんどに、LGTMさを感じられず、当初の目的の休憩する空気感に沿わないと判断して、いらすとやの画像を採用しました。
※この記事を書いている時に知ったのですが、lgtm.inのサイトは閉じるようですね。(2018年9月23日に確認した時点)