撮影スクリプト ViewRingoに ポーズURLをXにポストする機能がありましたが, ポーズだけで画像は付かなかったという。。。 普通,画像の方がポストされると思いますよね。 で,これは,ViewRingoからXに画像つきポストが できるようにした際のメモをまとめたものです。
やったこと (このページの内容)| API | OAuth1.0a | OAuth2.0 | POST, USER | Media Upload |
|---|---|---|---|---|
| API v1.1 | X | X | ||
| API v2 | X | X | X |
C:\xampp\htdocsがドキュメントルートになっているはずです。
公開サーバのフォルダ配置などを考慮して,ローカルのPHPを配置するフォルダを決めてください。
ここでは,C:\xampp\htdocs\twitter\に作ったことにします。
composer require abraham/twitteroauth
C:\xampp\htdocs\twitter\のフォルダでテストする場合
http://localost/twitter/callback.phpとかにします。
Consumer keyとConsumer secretは,ユーザIDとパスワードのようなもの,
Access tokenとAccess token secretはOAuth1.0a認証のIDとパスワードのようなもの,
OAuth2.0では,Client IDとClient Secretも必要になります。
開発時にはこれらを頻繁に使うので,config.phpとかにまとめて記入していました。
config.php $consumerKey = "........."; $consumerSecret = "........"; $accessToken = ".............."; $accessTokenSecret = ".........."; $clientID = "..........."; $clientSecret = "........."; $redirectUri = 'http://localhost/twitter/callback.php';これをPHPで,
require './config.php'とかすればすぐに使えます。
本番では,.ENVとか読み取れないファイルに記載するのが良いようです。
testOAuth1.0a.php
require "./config.php";
require "vendor/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
$connection = new TwitterOAuth($consumerKey,
$consumerSecret, $accessToken, $accessTokenSecret);
$connection->setApiVersion(2);
$response = $connection->get('users/me', []);
print_r($response);
ブラウザでhttp://localhost/twitter/testOAuth1.0a.phpにアクセスすると
Response
stdClass Object (
[data] => stdClass Object (
[id] => *****************
[name] => Ringo🍎🍎🍎
[username] => ringo3apples
)
)
のように,ユーザIDや名前,ユーザー名の応答が返ってきます。
testOAuth2.0.phpで認証プロセスを開始して,
callback.phpにコールバックする場合,
testOAuth2.0.php
require "./config.php";
$scope = rawurlencode('tweet.read tweet.write users.read offline.access');
$url = "https://twitter.com/i/oauth2/authorize?response_type=code
&client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}
&state=state&code_challenge=challenge&code_challenge_method=plain";
header(“Location: ${url}”);
$scopeの詳細は,/2/users/meここにあります。
今回の$scopeには,ツイートの読み書きとユーザ情報の読み込み,
offline.accessを設定しています。
offline.accessは後述のリフレッシュトークンを受け取るためのオプションです。http://localhost/twitter/testOAuth2.0.phpにアクセスすると,
上記のURLが設定されて,Twitterの認証サーバにリダイレクトされます。
ブラウザはTwitterの認証サーバのアクセス承認画面になります。
ここで,アクセスを承認すると,callback.phpへリダイレクトされます。callback.phpにリダイレクトされます。
このとき,URLに認証コードがついているので,callback.phpで受け取ります。
callback.php
require "./config.php";
$url = 'https://api.twitter.com/2/oauth2/token';
$headerStrings = [
'Content-Type: application/x-www-form-urlencoded',
'Authorization: Basic ' . base64_encode("${clientId}:${clientSecret}"),
];
$postField = [
"code" => $_GET['code'],
"grant_type" => "authorization_code",
"redirect_uri" => $redirectUri,
"code_verifier" => "challenge",
"client_id" => $clientId,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerStrings);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postField));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if(curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
exit(0);
}
curl_close($ch);
if($httpCode < 300){
$data = json_decode($response);
$accessToken = $data -> access_token;
$refreshToken = $data -> refresh_token;
echo "Access token: ${accessToken}<br>Refresh token: ${refreshToken}";
}else{
echo "${httpCode}<br>";
print_r($data);
}
callback.phpでは,URLから認証コードを$_GET['code']で受取り,
ポストフィールド$postFieldに追加します。
ポストフィールドには,認証方式がauthorization_codeであるとか,
リダイレクトURI,チャレンジの確認,client_idなどが入っています。
また,ヘッダーには,client_idとclient_secretを:で繋いで,
base64変換したものでBasic認証します。curl関数で/2/oauth2/tokenのエンドポイントにPOSTで送ります。
問題なければ,アクセストークンeaccessTokenと
リフレッシュトークンrefreshTokenがjsonにまとめられて返ってきます。
usersMe.php
require "./config.php";
$accessToken = ".....................................";
$url = 'https://api.twitter.com/2/users/me?user.fields=profile_image_url';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken,
'Content-Type: application/json',
'Accept: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if(curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
exit(0);
}
curl_close($ch);
if($httpCode < 300){
$data = json_decode($response);
$id = $data->data->id;
$name = $data->data->name;
$username = $data->data->username;
$icon = $data->data->profile_image_url;
}else{
echo "${httpCode}<br>";
print_r($data);
}
ヘッダにアクセストークンを使ってBearer認証を行っています。セッテだけなので比較的簡単です。
URLにはuser.fieldsを追加していて,ユーザのアイコン絵のURLも要求しています。
他の情報が欲しい場合はURLに追加します。このあたりの詳細は
/2/users/meにあります。
Response
stdClass Object (
[data] => stdClass Object (
[id] => *****************
[name] => Ringo3web
[username] => ringo3web
[profile_image_url] => ******************
)
)
今度は,X Developerに登録したユーザではなく,アクセス承認したアカウントの情報が表示されているはずです。
つまり,このトークンを使うと,アクセス承認したアカウントの代理でアクセスすることになります。
refresh.php
require "./config.php";
$refreshToken = ".....................................";
$url = 'https://api.twitter.com/2/oauth2/token';
$headerStrings = [
'Content-Type: application/x-www-form-urlencoded',
'Authorization: Basic ' . base64_encode("${clientId}:${clientSecret}"),
];
$postField = [
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => $clientId,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerStrings);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postField));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if(curl_errno($ch)) {
echo 'Curl error: ' . curl_error($ch);
exit(0);
}
curl_close($ch);
if($httpCode < 300){
$data = json_decode($response);
$accessToken = $data -> access_token;
$refreshToken = $data -> refresh_token;
}else{
echo "Refresh fail: ${httpCode} ${response}";
exit(0);
}
リフレッシュの方法は,Authenticationに書かれていますが,
X Developerの例ではリフレシュトークンだけで認証していますが,
私のところでは上手くいかなかったので,
ヘッダにBasic認証も付けています。もしかしたら不要なのかもしれません。
これで新しいアクセストークンが入手できます。
この時,リフレシュトークンも新しくなります。
additional_ownersにツイートするユーザのID$userIdを登録して,
アップロードした画像をツイートするユーザも使えるようにしています。
tweet.php
require "vendor/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
require "./config.php";
$accessToken = ".....................................";
$userId = "...........";
$image = "image.png";
$tweet = "This is the main text for tweet.";
$connection = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);
$connection->setApiVersion(1.1);
$media = $connection->upload('media/upload', [
'media' => $image,
'additional_owners' => [$userId]
]);
$mediaId = $media->media_id_string;
if ($mediaId && isset($_COOKIE['twitterOauth'][$id]['AccessToken'])){
$accessToken = $_COOKIE['twitterOauth'][$id]['AccessToken'];
$url = 'https://api.twitter.com/2/tweets';
$headers = [
'Authorization: Bearer ' . $accessToken,
'Content-Type: application/json'
];
$postData = [
'text' => $tweet,
'media' => [
'media_ids' => [$mediaId],
],
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $response;