この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
ベルリンの半瀬です。 こんにちは。
はじめに
ベルリンチームは主にSlackでやり取りをしていますが、国内ではChatWorkが主なので、そちらの動きも追う必要があります。 行ったり来たりするのは不便なので、一部の部屋の投稿だけSlackに流す方法を探していました。 下記のZapierを使った方法などはすぐに設定ができて楽そうでした。
ChatWork→Slack連携: ChatWorkの新着通知をSlackに投稿する | atskimura-memo
ZapierのFreeプランではZap回数に制限があったりするので、流量の多い部屋だとすぐに上限に到達してしまうことや、 もう少しリアルタイム性が欲しいなーということで、試しにlambdaとcloudwatch eventで自動転記をしてみました。 (スクリプトは↑の参考URLを見本とさせていただきました(__m謝
pythonスクリプト
2.7で書きます。こんな感じ
#-*- coding: utf-8 -*-
from __future__ import print_function
import requests
from datetime import datetime
cwtoken = '787dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
sltoken = 'xoxp-4xxxxxxxxxxx-50xxxxxxxxxxxx-2xxxxxxxxxxxxxx-d65dxxxxxxxxxxxxxxxxxxxxxxxx'
cwapiurl = 'https://api.chatwork.com/v2'
slapiurl = 'https://slack.com/api'
def lambda_handler(event, context):
fromto = event['fromto']
for list in fromto:
roomid = list['cwroomid']
channel = list['slchannel']
url1 = cwapiurl + '/rooms/' + roomid + '/messages'
headers1 = {'X-ChatWorkToken': cwtoken }
try :
req1 = requests.get(url1, headers=headers1)
if req1.status_code == 204 :
print('204' )
else :
res_json=req1.json()
i = 0
l = len(res_json) - 1
while i <= l :
body = res_json[i]['body']
name = res_json[i]['account']['name']
msid = res_json[i]['message_id']
time = res_json[i]['send_time']
try :
text = '*' + str(datetime.fromtimestamp(time)) + ' message from: ' + name + '*\n```' + body + '```'
url2 = slapiurl + '/chat.postMessage'
params2 = {
'token' : sltoken,
'channel' : channel,
'text' : text,
'as_user': 'false',
'username': 'ChatWork(auto)'
}
req2 = requests.put(url2, params=params2)
except Exception as e :
print('[error][put]' + str(e))
i += 1
except Exception as e :
print('[error][get]' + str(e))
if __name__ == "__main__":
lambda_handler({}, {})
このスクリプトはchatwork api のトークンとslack apiのトークンが前提になっています。 chatworkはここを参考に、slackはここからそれぞれ取得しておきましょう。slack のpermission scopeは「chat:write:bot」が必要です。
注意: できないこと - slackからChatworkへの転記はできません。
スクリプトの使い方
トークンと部屋情報の記載
cwtoken
にChatworkのトークンを、sltoken
にSLackのトークンを入れます。
次に、転機元のChatwork部屋と転記先のslackチャンネルの情報が必要となりますが、fromto = event['fromto']
の様な形としておき、これはcloudwatchからJSONリスト形式で渡す様にします(後述)。
Lambda
AWS Lambdaに載せます。requestsモジュールを使っていますので、パッケージ化をしてからアップロードしましょう。
CloudWatch Eventsの設定(転送元と先の指定)
Cloudwatch 「ルール」からアップロードしたlambda関数を指定して、1分間隔での実行を指定します。 その際、「入力の設定」から「定数(JSONテキスト)」を選択し、以下を参考にJSONテキストを渡す様に指定します。
AWS CloudWach Events実行時に便利なConfigure input | Developers.IO
{
"fromto": [{
"cwroomid": "<ChatWorkルームのID>",
"slchannel": "<SlackチャンネルのID>"
}, {
"cwroomid": "< 〃 >",
"slchannel": "< 〃 >"
}, {
"cwroomid": "< 〃 >",
"slchannel": "< 〃 >"
}]
}
cwroomid
に、ルームID( 例:「https://kcw.kddi.ne.jp/#!rid{{ここの数字}}」)
slchannel
にチャンネル名(例: #test1だと、「test1」)
複数ある場合は、リスト形式で追記します。「,」を忘れずに。
以下の様な形で設定します。
テスト
Chatworkに投稿
1分以内にSlackで表示。もちろん絵文字は反映されません。
終わりに
以上です。
APIの制限周りを考慮しきれていません。Chatwork APIは「5分に100回まで」という制限があるので、APIを実行するユーザーで他にAPI実行していないかどうか、気をつけてください。分間実行でもChatwork側で20部屋くらいを指定すると上限に当たる気がします。 多分そこまで使わないはず。。はず。。
参考にしたもの
Methid chat.postMessage | Slack API Rate Limits | Slack API エンドポイント: /rooms | ChatWork API ドキュメント エンドポイント: APIの利用回数制限について | ChatWork API ドキュメント
それではー