LoginSignup
12
3

More than 3 years have passed since last update.

Slackでリアクションをした際にツイートできるようにしてみた

Posted at

はじめに

プライベートでチーム開発をしているのですが、モチベーションを保つことは難しいです。

モチベーションを上げるための施策として前回はGitHubのWebhookでプルリクエストをマージした際にツイートできるようしてみたでGitHubからツイートをする仕組みを作成しました。
そして、今回はSlackのリアクションからツイートできる仕組みを解説となります。

※注意点
現時点のソースコードはかなり雑になっています。
適宜修正する予定のため、最新のコードはGitHubより確認をお願いします。

動作イメージ

SlackでコメントにTwitterのリアクションをすることで、ツイートを行います。
スクリーンショット 2019-05-14 21.55.15.png

構成

構成は前回書いた「GitHubのWebhookでプルリクエストをマージした際にツイートできるようしてみた」と非常に似たような構成となります。GitHubの箇所がそのままSlackに変更になっただけです。

前回はPythonを使用したので今回は何となくNode.jsにしてみました。

スクリーンショット 2019-05-20 0.29.26.png

環境構築

「Twitter API」と「lambdaとAPI Gatewayの設定」は前回書いてGitHubのWebhookでプルリクエストをマージした際にツイートできるようしてみたを参考にしていただければです。

Slack APIの設定

Slack APIからSlack Appを作成します。
Request URLですが初回認証する際にはchallengeの項目の内容(トークン)をレスポンスで返す必要があります。

イベントはreaction_addedを登録しておきます。(何かしらのリアクションをした際に発火されます)

設定に関してはこちらの記事が分かりやすかったです。
AWS初心者でもわかる! ブラウザ上で完結! AWS+Slack Event APIを使ったSlackボット超入門

スクリーンショット 2019-05-14 22.43.31.png

lambda実装

slack apiの仕様で3秒以内にレスポンスを返さなければ、再度リクエストが行われてしまいます。

今回は外部APIを呼んでいるためレスポンス時間が5秒ぐらい掛かり、リトライ実行されてしまいました。
レスポンスを返すlambdaと非同期実行するlambdaを用意することで回避可能であるとのことですが、今回は失敗を許容する実装にしています。。
※適宜修正する予定のため、最新のコードはGitHubより確認をお願いします。

slackのtokenは設定画面から確認できます。
スクリーンショット 2019-05-20 1.08.57.png


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がタイムアウトで何度もレスポンスするのを防ぐ

12
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
3