1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

f20: twist api で 外部へメッセージ送信

Posted at

.

以前の記事
f17: twist api で 新規スレッド投稿
https://qiita.com/cxfgp/items/85fe57686e5e360fa255
(外部から twist のチャンネル/スレッドへ投稿)

の逆 ( incoming -> outgoing ) になります
その設定メモです

上記記事でも触れてますが、

こちらの方が、
twist api を用いた記事を書いております
(golang + outgoing ですね)
TwistのchatbotをGoで作ってみた
https://qiita.com/usk81/items/bfd15ec3c5ecc23d0b8f

こちらでも
・twist について
・twist webhook について
の解説がありますのでご参考ください

今回は 「outgoing -> 外部 php へPOST」 になります

[ 実現すること ]
twist のチャンネルのスレッドに、手動で投稿したら、
bot が検知して、外部サーバーに設置した php に POST される
(今回は、そのデータをメールに送信)


[ 00. メニュー ]

01. キッチン

02. ポイント (outgoing + test token)

03. 仕込み1 (token の発行/url の設定)
04. 仕込み2 (POSTされる側のスクリプト作成)
05. 仕込み3 (bot のスレッド参加)

06. 味見 (スレッド投稿 -> メール受信)
07. デザート


[ 01. キッチン ]

 ・ さくらのレンタルサーバー
 ・ php

 ・ twist の ID 登録
  https://twist.com/login?lang=ja


[ 02. ポイント (outgoing + test token) ]

twist api で outgoing webhook (外部へポスト) を行う場合、
本来は、購読(subscribe) api を使って、
どのイベントをどのURLに送るかを明示的に登録する必要があります

「登録と外部ポストの流れ」
1. oauth認証でアクセストークンを取得
2. 購読(subscribe)api で webhook イベントを登録
3. 指定イベントを実行
4. ポストされるスクリプト(例: webhook.php)で json データを受信

参考:twist 公式ドキュメント(英語)
twist Developer 「Outgoing webhook」
https://developer.twist.com/v3/#outgoing-webhook

ですが、

TwistのchatbotをGoで作ってみた
-> Botの場合、General Integrationを設定すれば
  subscribeの登録も不要なのでかなり楽です。

この方もおっしゃられているとおり、

購読(subscribe)等の設定を行わずに
手っ取り早く、POST する方法 (OAuth 2 test token の利用)
が用意されているのでそちらを使ってみます

その名の通り、test (テスト) token ですので、制約もあります

・特定のチャンネルのみを検知する、といったスコープの制限ができません
・token の有効期限は不明だが突然無効になる可能性あり
・検知対象が意図しない範囲に広がるリスクがある

明示的にチャンネル制限をかけたいなら、
通常の access token + 購読(subscribe)設定
で制御する必要があります
(長期運用には refresh token の仕組みが必要です)

実際、test token にて、webhook テストをしてみた結果、
bot が参加した チャンネルA 内が範囲のようでした
(outgoing の場合は、なのかもしれません)
-> チャンネルA のすべてのスレッド内投稿を検知
-> チャンネルB のスレッド内投稿は検知されなかった

このあたりについては不透明な部分が多く、
例えば、チャンネルB に、incoming webhook を設定して
投稿の無限ループに陥る、というようなことにならないようご注意ください
(自己責任でお願いします)

参考:twist 公式ドキュメント(英語)
twist Developer 「OAuth 2」
https://developer.twist.com/v3/#oauth-2


[ 03. 仕込み1 (token の発行/url の設定) ]

まずは、outgoing 用に、test token の発行と、
webhook URL の設定を行います

twist に web でログイン後、
Integration Management
https://twist.com/app_console
へ遷移します

01. 「token」 の発行

「create a new app」 ボタン押下し、
「Create Integration」 ページにて
・Integration type: General integration
・Integration name: (例: test-hook2)
を設定し 「Create integration」 ボタン押下にて、
api token が発行されます

q201.jpg

q202.jpg

q203-02.jpg

02. 「OAuth 2 test token」 の取得

使用する token は oauth2: から始まる
「OAuth 2 test token」 です

(トークンのコピーボタンはないので、
最後の桁までコピーできてることを確認して、
どこかに控えておきます)

q204-02.jpg

03. 「Bot」 の設定と、webhook URL の設定

「Name」 (例: abc)
「Outgoing webhook URL」 ご自身のサーバーの スクリプト設定

を設定し 「Add bot」 ボタン押下にて、
bot を作成します

q206-02.jpg


[ 04. 仕込み2 (POSTされる側のスクリプト作成) ]

04. webhook URL を設定した外部サーバーに
設置したスクリプトの作成

outgoing.php

<?php

	// レスポンス 200 を応答しておく
	http_response_code(200);
	header('Content-Type: text/plain; charset=utf-8');

	// メール用設定
	mb_language("Japanese");
	mb_internal_encoding("UTF-8");

	// 時刻設定
	date_default_timezone_set('Asia/Tokyo');
	$ndate = date("Y/m/d H:i:s");

	// json 取得
	$raw_post = file_get_contents('php://input');

	// 重複投稿防止用キー取得
	$key = sha1($raw_post);

	// 重複投稿チェック(おまけ的ハッシュ値チェック)
	// php スクリプトの同階層に /processed/ ディレクトリを作成し、
	// 完全同一の投稿が存在しない場合のみ処理を進める
	if (!file_exists("processed/$key")) {

		// 重複投稿防止用ファイル作成
		file_put_contents("processed/$key", $raw_post);

		// json デコード
		$data1 = json_decode($raw_post, true);

		// empty case
		if (empty($data1)) {

			$subject1 = "twist-posted: ng: 400-1: ".$ndate;
			$text1 = "\n"."400: no data received"."\n";

		// json が不正な場合
		} elseif (json_last_error() !== JSON_ERROR_NONE) {

			$subject1 = "twist-posted: ng: 400-2: ".$ndate;
			$text1 = "\n"."400: invalid json data"."\n";

		} else {

			$subject1 = "twist-posted: ok: ".$ndate;

			// 重複投稿チェック用のキーファイル(/processed/$key)に、
			// 全項目が出力されているので、
			// その中からお好きな項目を抜き出して、本文としてセットする

			// ちなみに、
			// $ndate は、日本時間('Asia/Tokyo')
			// $data1["posted"] は、twist 現地サーバー時間 (US?) です

			$col1 = trim($data1["posted"]);
			$col2 = trim($data1["url"]);
			$col3 = trim($data1["channel_id"]);
			$col4 = trim($data1["thread_id"]);
			$col5 = trim($data1["id"]);
			$col6 = trim($data1["content"]);
			$text1 = "\n".$col1."\n".$col2."\n".$col3."\n".$col4."\n".$col5."\n".$col6."\n";

		 }

		$ipes1 = $_SERVER['REMOTE_ADDR'];
		$page1 = $_SERVER['REQUEST_URI'];

		// ログ出力
		$logs1 = "[$ndate] $ipes1 $page1 $text1\n";
		file_put_contents('post1.log', $logs1, FILE_APPEND);

		$text2 = htmlspecialchars_decode($text1, ENT_NOQUOTES);
		$message1 = "\n".$ndate."\n".$ipes1."\n".$page1."\n".$text2."\n";

		$headers1 = 'From: from@mailaddress.com';
		// return address
		$param1 = 'from@mailaddress.com';

		$too1 = 'to@mailaddress.com';
		$ccc1 = 'cc@mailaddress.com';
		$bcc1 = '';

		// cc
		if (!empty($ccc1)) {
			$headers1 = '\n';
			$headers1 = 'Cc:'.$ccc1;
		}

		// bcc
		if (!empty($bcc1)) {
			$headers1 = '\n';
			$headers1 = 'Bcc:'.$bcc1;
		}

		// メール送信
		if (mb_send_mail($too1, $subject1, $message1, $headers1, $param1)) {
			// echo "send mail ok";
			// などの処理を書く
		 } else {
			// echo "send mail ng";
			// などの処理を書く
		 } 

	}

?>

[ 05. 仕込み3 (bot のスレッド参加) ]

05. スレッド投稿に反応(検知)して、外部にPOSTされるように、
スレッドに bot を参加させます

05-1) チャンネル (例: チャンネルA) 作成

・「Channels」 -> + Create new channel

q200.jpg

q200b.jpg

・「Privacy」 -> Public - Anyone on your team can join
・「Set default participants」 -> Everyone in channel

05-2) ひとまず手動で新規スレッドにてテスト投稿

q200e-02.jpg

URLより、以下確認
https://twist.com/a/1111/ch/2222/t/3333/

a -> ワークスペース ID
ch -> チャンネル ID
t -> スレッド ID

05-3) 上記 チャンネルA のスレッド指定で curl (bot のスレッド参加)

(test token は、oauth2:部分も含めて記載する)

curl -X POST https://api.twist.com/api/v3/comments/add \
  -H "Authorization: Bearer oauth2:xxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "thread_id": "3333",
    "content": "監視中"
  }'

この curl による post が、無事、
指定スレッドに書き込みされましたら、
以降のスレッド投稿で、指定した webhook URL へポストされます


[ 06. 味見 (スレッド投稿 -> メール受信) ]

チャンネルのスレッド内で手動投稿を行い、
指定の外部 webhook URL に post され、
メール受信されれば完了です

(メールが届かない場合は、ログ確認で
・サーバーに到達しているか
・到達しているけどスクリプトエラーか
・スクリプト処理は正常でメールフィルターにひっかかってないか
などの切り分け)


[ 07. デザート ]

多くの サービスは、
ポーリング監視または常駐監視による
outgoing の実現が多い中、
twist は知名度は低いですが、
slack と同様、イベント駆動型で
outgoing が利用できる素敵なサービスです


.

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?