はじめに
プライベートでチーム開発をしているのですが、モチベーションを保つことは難しいです。
モチベーションを上げるための施策として前回はGitHubのWebhookでプルリクエストをマージした際にツイートできるようしてみたでGitHubからツイートをする仕組みを作成しました。
そして、今回はSlackのリアクションからツイートできる仕組みを解説となります。
※注意点
現時点のソースコードはかなり雑になっています。
適宜修正する予定のため、最新のコードはGitHubより確認をお願いします。
動作イメージ
SlackでコメントにTwitterのリアクションをすることで、ツイートを行います。
今からQiitaに投稿する記事を書くぞー!!
— a6s-cloud (@CloudA6s) 2019年5月14日
がんばるぞい💪
slackからの投稿です。
構成
構成は前回書いた「GitHubのWebhookでプルリクエストをマージした際にツイートできるようしてみた」と非常に似たような構成となります。GitHubの箇所がそのままSlackに変更になっただけです。
前回はPythonを使用したので今回は何となくNode.jsにしてみました。

環境構築
「Twitter API」と「lambdaとAPI Gatewayの設定」は前回書いてGitHubのWebhookでプルリクエストをマージした際にツイートできるようしてみたを参考にしていただければです。
Slack APIの設定
Slack APIからSlack Appを作成します。
Request URLですが初回認証する際にはchallengeの項目の内容(トークン)をレスポンスで返す必要があります。
イベントはreaction_addedを登録しておきます。(何かしらのリアクションをした際に発火されます)
設定に関してはこちらの記事が分かりやすかったです。
AWS初心者でもわかる! ブラウザ上で完結! AWS+Slack Event APIを使ったSlackボット超入門

lambda実装
slack apiの仕様で3秒以内にレスポンスを返さなければ、再度リクエストが行われてしまいます。
今回は外部APIを呼んでいるためレスポンス時間が5秒ぐらい掛かり、リトライ実行されてしまいました。
レスポンスを返すlambdaと非同期実行するlambdaを用意することで回避可能であるとのことですが、今回は失敗を許容する実装にしています。。
※適宜修正する予定のため、最新のコードはGitHubより確認をお願いします。
exports.handler = (event, context, callback) => {
// slack apiの仕様で3秒以内にレスポンスを返さなければ、再度リクエストを行う
// 2回目のリクエストの場合は終了する
if(event.headers["X-Slack-Retry-Num"]){
console.log("リトライのため終了");
console.log(event);
callback(null, {statusCode: 200,body: JSON.stringify({ok:"ok"})});
return;
}
// レスポンスからデータを取得
const body = JSON.parse(event.body);
console.log(event);
console.log("channel:" + body.event.item.channel);
console.log("latest:" + body.event.item.ts);
console.log("reaction:" + body.event.reaction);
// リアクションが「tweet」リアクション以外なら終了
if(body.event.reaction !== 'tweet'){
console.log("tweetリアクションではないので終了")
callback(null, {statusCode: 200,body: JSON.stringify({ok:"ok"})});
return;
}
const twitter = require('twitter');
const twitter_client = new twitter({
consumer_key: 'xxxxxxxxxxxxx',
consumer_secret: 'xxxxxxxxxxxxx',
access_token_key: 'xxxxxxxxxxxxx',
access_token_secret: 'xxxxxxxxxxxxx'
});
// axios を require してインスタンスを生成する
const axiosBase = require('axios');
const axios = axiosBase.create({
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
responseType: 'json'
});
// Slack APIからコメントを取得するためにパラメータを作成
const queries = {
token: "xxxxxxxxxxxxx",
latest:body.event.item.ts,
limit:1,
inclusive:true,
channel: body.event.item.channel
};
// Slack APIからコメントを取得
axios.get('https://slack.com/api/conversations.history/',{params: queries})
.then(res => {
// 絵文字文字列を絵文字に変換
// 使い方は「Node.jsで絵文字を扱うための、node-emojiライブラリの使い方」に書いています
const emoji = require('node-emoji')
const text = emoji.emojify(res.data.messages[0].text);
console.log("ツイート文章")
console.log(text);
// twitter apiでtweetを行う
twitter_client.post('statuses/update', {status: text + '\nslackからの投稿です。'}, function(error, tweet, response){
if(error) {
console.log('Twitter APIエラー.');
console.log(error);
}
console.log('Twitter完了');
});
}).catch(err =>
console.log(err);
});
callback(null, {statusCode: 200,body: JSON.stringify({ok:"ok"})});
return;
};
参考URL
Node.jsで絵文字を扱うための、node-emojiライブラリの使い方
GitHubのWebhookでプルリクエストをマージした際にツイートできるようしてみた
AWS Lambda + Node.jsでTwitter Botを開発する
AWS初心者でもわかる! ブラウザ上で完結! AWS+Slack Event APIを使ったSlackボット超入門
SlackのReactionのEventに応じて〇〇する
Slack投稿を元にしてTwitter運用するために、GASで一定のリアクション数に達したSlackメッセージを収集した話
Slack Bot をサーバーレスで運用する時の、タイムアウト対策【小技】
[AWS lambda] Slack Botがタイムアウトで何度もレスポンスするのを防ぐ