TwitterのAPIを利用して、任意のユーザーへダイレクトメッセージを送信するPHPのコードです。ライブラリは使わずに直接実装するケースを想定しています。
#前提条件
・送信元のアカウントでAPIを利用出来る。(Twitter Developersに登録済み)
・送信相手のユーザーIDが判明している。
・送信相手がこちら(送信元)のアカウントをフォローしている。
#処理の流れ
- 署名キーを作る
- HTTPヘッダ用のパラメータを作る
- パラメータ(2.)をソートする
- 署名キー(1.)とパラメータ(3.)から署名を作る
- パラメータ(3.)に署名(4.)を追加する
- パラメータ(3.)からHTTPヘッダ用の配列を作る
- POSTデータ用の配列を作る
- cURLでエンドポイントにデータを投げる
- エンドポイントの応答を受け取る
##接続先(エンドポイント)
https://api.twitter.com/1.1/direct_messages/events/new.json
##処理に必要な値
Twitter Developersで下記の値を予め取得しておく必要があります。
$api_key = 'APIキー';
$api_secret = 'APIシークレット';
$access_token = 'アクセストークン';
$access_token_secret = 'アクセストークンシークレット';
#1. 署名キーを作る
APIシークレットとアクセストークンシークレットを用いて署名キーを作成します。
$signature_key = rawurlencode( $api_secret )."&".rawurlencode( $access_token_secret );
#2. HTTPヘッダ用のパラメータを作る
エンドポイントへ渡すための認証データを連想配列で作成します。
$paramData = array(
"oauth_token" => rawurlencode( $access_token ),
"oauth_consumer_key" => rawurlencode( $api_key ),
"oauth_signature_method" => rawurlencode( "HMAC-SHA1" ),
"oauth_timestamp" => time(),
"oauth_nonce" => microtime(),
"oauth_version" => rawurlencode( "1.0" )
);
#3. パラメータをソートする
ksortで連想配列をソートします。これを忘れると認証エラーが起き得ます。
ksort( $paramData );
#4. 署名キーとパラメータから署名を作る
1で作成した署名キーと、2で作成したパラメータの配列を利用して、署名を作ります。
$sig_param = rawurlencode('POST')."&".
rawurlencode('https://api.twitter.com/1.1/direct_messages/events/new.json')."&".
rawurlencode( http_build_query( $paramData , "", "&" ) );
$signature = hash_hmac( "sha1", $sig_param, $signature_key, TRUE );
$signature = base64_encode( $signature );
#5. パラメータに署名を追加する
連想配列に署名を追加します。
$paramData['oauth_signature'] = $signature;
#6. パラメータからHTTPヘッダ用の配列を作る
cURLで使うための配列を新たに作成しておきます。
$httpHeader = array(
'Authorization: OAuth '.http_build_query( $paramData, "", "," ),
'content-type: application/json'
);
#7. POSTデータ用の配列を作る
cURLで送信するボディにあたるデータを作成します。これは後にjsonエンコードします。
ここで送信先のユーザーIDと、送信したいメッセージもセットします。
$postData = array(
"event" => array(
"type" => "message_create",
"message_create" => array(
"target" => array(
"recipient_id" => '送信先のユーザID' //送信先ID
),
"message_data" => array(
"text" => '送信メッセージ' //送信したいメッセージ
)
)
)
);
Eventオブジェクトの中に入れ子で情報を詰め込んでいます。
上記のサンプルコードは必須項目のみを記述していますが、message_dataオブジェクト(メッセージが入っているところ)にはオプションも追記可能です。
詳しくはTwitter公式のAPIリファレンスを確認してください。1
#8. cURLでエンドポイントにデータを投げる
これまでに作成した各種配列をセットして、cURLでエンドポイントへデータを渡します。
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
curl_setopt($ch, CURLOPT_URL, 'https://api.twitter.com/1.1/direct_messages/events/new.json');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, rawurlencode('POST'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $postData ));
$json = curl_exec($ch);
curl_close($ch);
#9. エンドポイントの応答を受け取る
ダイレクトメッセージの送信に成功すると、message_createイベントのIDやタイムスタンプを含んだjsonデータが返されます。ここでjsonデータを連想配列へ変換しておきます。
$response = json_decode( $json, true );
echo var_dump( $response );
var_dumpした結果が下記です。
array(1) {
["event"]=> array(4) {
["type"]=> string(14) "message_create"
["id"]=> string(19) "イベントID"
["created_timestamp"]=> string(13) "1561275503817" //ミリ秒
["message_create"]=> array(3) {
["target"]=> array(1) {
["recipient_id"]=> string(10) "送信先のID"
}
["sender_id"]=> string(19) "送信元のID"
["message_data"]=> array(2) {
["text"]=> string(24) "送信メッセージ"
["entities"]=> array(4) {
["hashtags"]=> array(0) { }
["symbols"]=> array(0) { }
["user_mentions"]=> array(0) { }
["urls"]=> array(0) { }
}
}
}
}
}
これ以降の処理は、idが含まれているか、などの条件で処理判定すればよいかと思います。
if( empty( $response['event']['id'] ) ){
//失敗時の処理
} else {
//成功時の処理
}
尚、レスポンスデータに含まれるタイムスタンプはミリ秒で返ってきます。2
そのままでは日付表示が出来ないので、秒に変換する必要があります。
$timestamp = $response['event']['created_timestamp'];
echo date('Y-m-d H:i:s', ( $timestamp / 1000 )); //1000で割って秒にする
結果
2019-06-24 06:42:31
#最後に
Qiitaに登録して初めて書く記事となります。コードや文章に稚拙な部分があるかもしれませんが、ご容赦ください。可読性を優先してわざと定数化していない箇所はあります。
誤りのご指摘やご意見などがありましたら、是非お願いいたします。
####注釈(参考サイト)