この記事はSlack その2 Advent Calendar 2016の24日目の記事です。
今年の4月頃から会社でSlackを導入し、案件毎のチャンネルを作ったりしてそれなりに活用しているけれど、#randomチャンネルにほとんど投稿が無くて寂しい!少しでも活性化出来ればと思ってオリジナルのBotを導入してみました。
とりあえずは定期的にオススメのお店情報を投稿するだけのシンプルなBotを作ってみます。hubotは大袈裟だしサーバーを用意して常駐させるのも面倒だったので、AWS Lambdaを使ったサーバレス的な実装をしてみました。
スクレイピング
現時点(2016.12.29)で、食べログやRettyにはAPIが無いようなので、自力でスクレイピングする必要があります。
とりあえずNode.jsプロジェクトを初期化し、必要なモジュールをインストールしておきます。
$ mkdir gourmet_bot; cd $_
$ npm init
$ npm i -S @slack/client cheerio
食べログをスクレイピングしてSlackに投稿する一連のスクリプトを作成します。
const request = require('request')
const cheerio = require('cheerio')
const IncomingWebhook = require('@slack/client').IncomingWebhook
module.exports = () => {
const url = 'https://tabelog.com/tokyo/rstLst/?Srt=D&SrtT=rt&sort_mode=1&ChkNewOpen=1'
const webhook_url = process.env.WEBHOOK_URL
request(url, (err, res, body) => {
const $ = cheerio.load(body)
const topics = $('li.list-rst').map((i, el) => {
const a = $('a.list-rst__comment-text.cpy-comment-text', el).first()
return {
url: a.attr('href'),
restaurant: $('a.list-rst__rst-name-target.cpy-rst-name', el).text().trim(),
title: a.text().trim(),
star: $('span.tb-rating__val.tb-rating__val--strong.list-rst__rating-val', el).first().text().trim(),
meta: $('span.list-rst__area-genre.cpy-area-genre', el).first().text().trim(),
price: $('li.tb-rating.tb-rating--sm.list-rst__budget-item', el).map((i, el) => $(el).text().trim() ).get().join(' ')
}
}).get()
console.log(topics)
const text = "*週間食べログ人気ランキング*\n\n" + topics.map((topic, i) => {
return `[${i+1}] ${topic.restaurant} ${topic.meta} :star: ${topic.star} :moneybag: ${topic.price}\n<${topic.url}|${topic.title}>`
}).join("\n\n")
const webhook = new IncomingWebhook(webhook_url)
webhook.send(text)
})
}
動作確認
SlackのWebhook URLは環境変数で設定しておきます。
$ export WEBHOOK_URL=https://hooks.slack.com/services/***
$ node
> require('./bot')()
Slackに投稿できていることを確認します。
AWS Lambda のデプロイパッケージ作成
まずエンドポイントとなるスクリプトを作成します。
const bot = require('./bot')
exports.handler = (event, context, callback) => {
bot()
}
プロジェクト全体をzipで圧縮します。
$ zip -r gourmet_bot.zip .
Lambda の設定
Functionの新規作成ページでBlank Functionを選びます。
Functionのトリガーを設定するよう促されるけど、とりあえずスルーしてNextボタンで次に進みます。
次のページでFunctionの詳細設定を行います。
Nameを適当に入力し、RuntimeはNode.js
を選択します。
Code entry typeはUpload a .ZIP file
を選ぶとアップロードボタンが表示されるので、先程作成したzipを選択します。
Environment variablesにはローカルで設定したSlackのWebhook URLを入力しておきます。
Timeoutは少し長めに30秒としておきます。
その後は指示に従って保存します。
Testボタンを押すとテスト用に送信されるJSONを設定するダイアログが開きますが、今回は一切不要なのでデフォルトのHello Worldか{}を入力して保存し、テストを実行してみます。これでSlackに投稿されていればLambdaの設定は完了です。
CloudWatch (スケジューリング) の設定
Add triggerのタブからCloudWatch Events - Schedule
を選択し、適当なRule nameを入力してSchedule expressionを設定すると定期的に実行されるようになります。cronっぽいけどLinuxのcrontabとは微妙に異なるので詳しくは公式リファレンスをみてください。
毎週月曜日9:30に実行されるスケジュール設定はcron(30 0 ? * MON *)
のようになります。JSTで設定できれば楽なのですが、おそらくGMT限定っぽいので逆算しています。
以上です。GUIが辛いので今後はCLIでやりたい。
これで#randomチャンネルが盛り上がるかどうかは謎。
使用したソースコード : https://github.com/d-mato/gourmet_bot