SlackでTwitterがやりたい!
はじめに
Slackアドベントカレンダー17日目です!
今回は,業務中にもTwitterをするために,Slack上でTwitterを行うためのSlack Appを実装してみます.
できたもの
今の所Slack上から以下の機能が使用可能です.
前日に咳き込みながら急ピッチで作ったので,これだけで勘弁してください(^_^;)
Slack上のフォームにメッセージを入力し送信すると,Tweetが投稿されます.
入力して,送信ボタンを押す.
実際に,Twitter上にも投稿されます!(SlackでのURLの表示など課題は残っています.)
同様に,ファボ,リツイートも可能です.
作り方
コードはGitHub上で公開しています.
使用技術
Slack
Home Tab
タイムラインの表示箇所Block Kit
UIの作成Web API
メッセージの投稿
最新の投稿の情報を取得Event API
Home Tabへのアクセス
Tweetの検出Interactive component
ボタンのクリック
プログラミング
- Ruby
- Sinatra
- twitter api / slack api
1. 準備
Slack Appを作成してください.
Scope
使用するスコープです.
サイドバー > Features > OAuth & Permisson > Scopeから設定を済ませておきます.
Event
使用するイベントのタイプです.
サイドバー > Event Subscriptionsから設定を済ませておきます.
同時に,Request URLを登録しておきます.
残念ながらEvent apiのコールバックで指定することができるURLはhttpsに限られています.
ngrokといったポートフォワーディングサービスを使用することで,ローカルで開発を完結することができます!登録は必要ですが,無料で使用可能です.
authtoken: [取得したauth tokenを記載する]
tunnels:
sinatra:
proto: http
addr: 4567
登録が完了したら,取得したauth tokenをngrok.ymlに記載して,$ngrok start -config ngrok.yml --all --region=jp
で起動します.
サーバとngrokを立ち上げ,ngrokのコンソール画面に表示されているhttpsのURLを入力すれば,Verifiedが表示され,登録が完了するはずです!
Interactive Component
ボタンが押されたときのEventを受け取ります.
ボタンやピッカーといったコンポーネントに対するイベントはEvent APIとま分離されているようなので,
別途URLを設定しておきます.
Home Tab
今回は,タイムラインを投稿する場としてHomeTabを使用しました.
普通のチャンネルでも良かったのですが,HomeTabは個別に割り当てられており,Tabを開くイベントも提供されていることから,Tabを開くタイミングでロードを行えば,タイムラインの表示にぴったりだなと感じました.
サイドバー Features > App HOME からHome Tabを有効にしておきます.
Twitter API
Twitter APIを使用するのでそちらの登録も済ませておきます.
環境変数
少し多いですが,以下6つの環境変数を設定しておきます.
slack
- SLACK_VERIFICATION_TOKNE
- SLACK_ACCESS_TOKEN
- TWITTER_CONSUMER_KEY
- TWITTER_CONSUMER_SECRET
- TWITTER_ACCESS_TOKEN
- TWITTER_ACCESS_TOKEN_SECRET
2. タイムライン
ここからは実際にサーバを立てて処理を書いていきます.
Slackにタイムラインを表示する流れはとてもシンプルです.まずはHomeTabを開くイベントを待ち受ける処理を書きます.イベントが発生すると先程指定したURLにリクエストが飛んできます.飛んできたリクエストに対してイベントごとに振り分ける処理を書いてあげます.
post '/event' do
params = JSON.parse(request.body.read)
return {challenge: params["challenge"]}.to_json if params["type"] == 'url_verification'
# accept event only from slack
return if params["token"] != ENV["SLACK_VERIFICATION_TOKEN"]
if params["event"]["type"] == "app_home_opened" && params["event"]["tab"] == "messages"
handle_messages_opened(params)
elsif params["event"]["type"] == "app_home_opened" && params["event"]["tab"] == "home"
handle_tab_opened(params)
elsif params["event"]["type"] == "message" && params["event"]["subtype"] != "bot_message"
handle_message(params)
end
status :ok
end
イベントタイプがapp_home_opendでメッセージタブに対するイベントを受け付けると,次に
handle_messages_opend関数が呼び出されます.
ここでは次のような処理が行われています.
1. Slack上にある最新のメッセージのtimestampを取得
2. Twitter APIを用いて取得したtimestampよりも新しいTweetの情報を取得
3. 取得したTweetをもとにブロックを組み立ててUIを構築
4. Slack Web APIを使用してTweetをSlackにpost
...
def handle_messages_opened(params)
twitter_client = TwitterClient.new
slack_client = SlackClient.new
channel = params["event"]["channel"]
latest_timestamp = slack_client.latest_timestamp(channel)
tweets = twitter_client.home_timeline(latest_timestamp)
tweets.each do |tweet|
block = [
{
type: "section",
text: {
type: "mrkdwn",
text: tweet.full_text
}
},
{
type: "context",
elements: [
{
type: "mrkdwn",
text: Time.at(tweet.created_at).getlocal.strftime("%-H時%-M分・%Y年%-m月%-d日")
}
]
},
{
type: "actions",
elements: [
{
type: "button",
text: {
type: "plain_text",
emoji: true,
text: "♡ #{tweet.favorite_count}"
},
value: tweet.id.to_s,
action_id: "favo"
},
{
type: "button",
text: {
type: "plain_text",
emoji: true,
text: "RT #{tweet.retweet_count}"
},
value: tweet.id.to_s,
action_id: "retweet"
}
]
}
]
slack_client.post_message(
channel,
block,
"#{tweet.user.name} tweet",
"#{tweet.user.name} / @#{tweet.user.screen_name}",
tweet.user.profile_image_uri.to_s
)
end
end
...
外部APIとのやり取りには,クライアントライブラリを使用しています.このライブラリをラップする形で,slack_client.rbとtwitter_client.rbの2つのファイルがapp.rbの他に存在します.
3. Tweet
タイムラインを眺めるだけは退屈なので,tweet機能を導入します.
普段Slack上でチャットをするように,メッセージを投稿すると,その内容がTwitterにも投稿されるようにします.message.im
イベントを有効にしているため,チャンネル上にメッセージを投稿すると先ほどと同様に指定したURLへリクエストが送られます.params["event"]["subtype"] != "bot_message"を指定しておかないと,タイムラインを更新する際の,botによる投稿にも反応してしまいます.
post '/event' do
params = JSON.parse(request.body.read)
...省略...
elsif params["event"]["type"] == "message" && params["event"]["subtype"] != "bot_message"
handle_message(params)
end
status :ok
end
入力したメッセージが取得できれば,あとはTwitter Apiを用いてPostするだけです.
4. ファボ・リツイート
ボタンがクリックされたら,以下の処理が実行されます.
handle_messages_opened関数の中で,ブロックを用いてUIを組み立てたと思いますが,その時に付与したaction_idをもとに,2つのボタンのどちらが押されたかを識別することができます.
post '/interaction' do
params = JSON.parse(request.params["payload"])
return if params["token"] != ENV["SLACK_VERIFICATION_TOKEN"]
if params["actions"][0]["action_id"] == "favo"
handle_favo_button(params)
elsif params["actions"][0]["action_id"] == "retweet"
handle_retweet_button(params)
end
end
action_idに応じて,favoとretweetの処理に振り分けます.valueでfavoやリツイートの対象となる
ツイートのIDを持たせてあるので,呼び出された関数でtwitter apiを使用して実行します.
まとめ・展望
カレンダー担当日をすっかり忘れていて,急ピッチで実装を行いました.
解説も実装も適当で申し訳なかったです.時間をみて修正を進めて参ります.
加えて,使用できるTwitterの機能もいまだ限定的なので,追加で実装を進めていこうと思います!また,今後OAuthを導入することで,Slack Appを導入したワークスペースに所属する他のユーザについてもTwitterができるような仕組みを実装できればなと考えています.
参考文献
Mercari:GolangでSlack Interactive Messageを使ったBotを書く
Qiita:Slack API 新機能を使ってアプリのホーム・ヴューを活用しよう
Author And Source
この問題について(SlackでTwitterがやりたい!), 我々は、より多くの情報をここで見つけました https://qiita.com/takeru56/items/a1dff47be63adc8439d7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .