前々回, 前回と同じくTwitterの返信も以前(2020年)のスクリプトではできませんので修正します。
画像アップロードはAPI1.1, 文字部分の投稿はAPI2.0です(小難しい)。
画像を投稿します。複数画像も。5枚以上はスレッドにして対応します。
目次
Step一覧
Google Apps ScriptでTwitterに投稿する方法を4回に分けて掲載しています。
- Twitter API登録方法 (備忘録) ← これはそのまま。
- Twitter APIとGoogle Apps Script 連携でツイート Ver.2024 (備忘録)
- Google Apps ScriptでTwitterにスレッド(返信)投稿 Ver.2024 (備忘録)
- Google Apps ScriptでTwitterに画像投稿 複数画像も!Ver.2024 (備忘録) ← 今ココ
POINT
今回のポイントです。
- 画像アップロードはAPI1.1を使用, 文字の投稿はAPI2.0を使用 ← 前回と違う
- 認証に使用するライブラリをTwitterWebService.gs → OAuth1, OAuth2に変更
- API1.1ではClient IDは使わない、使うのはAPI Key
- 画像は事前にmedia-updateでアップロード
- media_id取得時はmedia_id_stringを使用
- 返信は投稿時payloadにmedia_idで画像(メディア)を指定
- 複数画像はmedia_idをカンマでつなげて文字列にしてから投稿
手順
[手順1] ライブラリOAuth1の導入
ライブラリOAuth1の導入
Google Apps Scriptの画面 →「リソース」→「ライブラリ」
ライブラリのプロジェクトキー↓を入力し「追加」
1CXDCY5sqT9ph64fFwSzVtXnbjpSfWdRymafDrtIZ7Z_hwysTY7IIhi7s
バージョンは最新、Dev.Modeは無効でOK
googleworkspace / apps-script-oauth1 at GitHub
[手順2] 連携認証のスクリプトを入力
連携認証のスクリプトを入力
とりあえず何も考えずに入力(笑)。
Client IDとClient Secretは次項以降で確認する。
// 設定
const twi_api_key = ‘XXXXX’;
const twi_api_secret_key = ‘XXXXX’;
// Twitter(X) OAuth1認証
function getTwitterService1_() {
return OAuth1.createService(‘twitter’)
.setAccessTokenUrl(‘https://api.twitter.com/oauth/access_token’)
.setRequestTokenUrl(‘https://api.twitter.com/oauth/request_token’)
.setAuthorizationUrl(‘https://api.twitter.com/oauth/authorize’)
.setConsumerKey(twi_api_key)
.setConsumerSecret(twi_api_secret_key)
.setCallbackFunction(‘twiAuth1Callback_’) // コールバック関数名
.setPropertyStore(PropertiesService.getUserProperties());
}
// OAuth1コールバック
function twiAuth1Callback_(request) {
var twitterService = getTwitterService1_();
var isAuthorized = twitterService.handleCallback(request);
if (isAuthorized) {
return HtmlService.createHtmlOutput(‘Success! You can close this tab.’);
} else {
return HtmlService.createHtmlOutput(‘Denied. You can close this tab.’);
}
}
// OAuth1リセット
function resetTwiOAuth1() {
getTwitterService1_().reset();
}
// OAuth1認証用URL取得
function getTwiOAuth1URL() {
Logger.log(getTwitterService1_().authorize());
}
ちなみにOAuth2を使用することになるのでOAuth1と明示した。
ここで使用するのはClienet IDでなくAPI Key。
(コード見本はClient IDって書いてあるものあり。)
[手順3] Twitter API Key and Secretを入手
Twitter API keyとAPI secret keyを確認し上のコードのxxxxxxxx部分に入力する。
Twitter Developer Portal → Projects & Apps から該当Appを開く
「API Key and Secret」にある。
必要に応じて再作成する。
ついでに他のところも問題なさそうか確認する。
[手順4] Google Apps ScriptでTwitterアプリの認証作業
- getTwiOAuth1URL関数実行
Google Apps Scriptの画面 →「関数の選択」で「getTwiOAuth1URL」を選択し実行▶︎ - ログから認証用URLを取得
Google Apps Scriptの画面 →「表示」→「ログ」
https://api.twitter.comから始まるURL - 認証用URL(上で取得)をブラウザで開く
認証画面が出るので内容を確認(できること/できないこと)し認証
成功するとSuccessと表示される。
閉じてOK。
[手順5] Twitterに投稿
前回作成した返信機能付きpost_tweet関数を使用します。
ライブラリOAuth2も引き続き使います。
引数をmsg(投稿する文章), re_id(返信元のツイートID), img_urls(画像のURL配列)、
戻り値を今回投稿したツイートIDとします。
エンドポイントは今回から事前に変数に設定しています。
// twitterエンドポイントURL
const twi_endpoint1 = “https://upload.twitter.com/1.1/media/upload.json”;
const twi_endpoint2 = “https://api.twitter.com/2/tweets”;
// twitterへ投稿
// 返り値はツイートした投稿のID
function post_tweet(msg, re_id, img_urls){
var service1 = getTwitterService1_();
var service2 = getTwitterService2_();
if (service1.hasAccess() && service2.hasAccess()) {
var img_ids = [];
if(!img_urls){
// 画像がない時はスキップ
}else if(img_urls.length > 4){
// 5枚以上ある時は分割して投稿。最初の投稿の返信(スレッド)になる。文章は同じ。*1
var img_urls_now = img_urls.splice(0,4);
var tw_id = post_tweet(msg, re_id, img_urls_now);
tw_id = post_tweet(msg, tw_id, img_urls);
return tw_id;
}else if(img_urls){
// 画像が4枚以下の場合は順番にエンコード→アップロードする。*2
// idを取得して配列imgidsに返す。
for(var i = 0; i < img_urls.length; i++){
var img_blob = UrlFetchApp.fetch(img_urls[i]).getBlob();
var img_64 = Utilities.base64Encode(img_blob.getBytes());
var img_upload = service1.fetch(
twi_endpoint1, {
'method' : "POST",
'payload': { 'media_data': img_64 }
}
);
var result1 = JSON.parse(img_upload.getContentText());
// media_idをimg_idsに格納。
img_ids[i] = result1.media_id_string;
}
}
// 条件に合わせてpayload作成 *3
var payload = "";
if (re_id && img_ids.length > 0){
// 返信, 画像あり
payload = {
text: msg,
reply: {in_reply_to_tweet_id: re_id},
media: {media_ids: img_ids}
};
} else if (re_id) {
// 返信, 画像なし
payload = {
text: msg,
reply: {in_reply_to_tweet_id: re_id}
};
} else if (img_ids.length > 0){
// 画像あり, 返信でない
payload = {
text: msg,
media: {media_ids: img_ids}
};
} else {
// 返信でない, 画像なし
payload = {text: msg};
}
// 投稿
var response = UrlFetchApp.fetch(twi_endpoint2, {
method: ‘POST’,
‘contentType’: ‘application/json’,
headers: { Authorization: ‘Bearer ‘ + service2.getAccessToken() },
muteHttpExceptions: true,
payload: JSON.stringify(payload)
});
var result = JSON.parse(response.getContentText());
var twi_id = result.data.id;
return twi_id;
} else {
Logger.log(“Not Authorized”);
return null;
}
}
function test_tweet(){
// 連続ツイートの見本
var twi_id1 = post_tweet(“GASツイートテスト”, “”, [“url1”, “url2”]);
var twi_id2 = post_tweet(“GASツイート返信テスト”, twi_id1);
}
*1 (2020Ver.と同じ)
5枚以上画像がある場合の対応
同じ関数(post_twitter)を呼び出すのは良くない気もするけど、
スクリプトが単純になるので。
5枚以上の場合はスレッド(返信)になります。
最後の投稿のIDが最終的に返り値になります。
*2 (2020Ver.と同じ)
画像を投稿する場合は、文章を投稿する前に、画像をアップロードします。
画像をBlobを経由してBase64に変換させ(中身については私はよくわかっていないw)
media/upload.jsonにPOST。
media_id_stringを取得。
media_idは数値として取得してしまい丸められてしまうのでダメ(数値の大きさの問題)。
*3
文章を投稿する時に、media-idsで画像IDを投稿。
画像IDは配列で渡す(API1.1と違う)。
payloadは条件分岐して作成。
長かったですが、これでtwitter投稿の関数作成はこれで終わりです。
これを使って、Blog投稿お知らせやInstagramを自動投稿していきたいと思います。
Reference
- apps-script-oauth1 /samples /Twitter.gs at GitHub
- 【X(Twitter) bot】GASでスプレッドシートから自動投稿するX Botの作り方:③テキスト+画像投稿 at かずログ
余談
とりあえず、1年くらい動かなかったTwitter自動投稿が直りました(笑)。
重い腰を持ち上げるのに時間はかかるし、
やり始めると一日作業だし。
(私、ノンプログラマーです。)
それにしても2つのAPIを使うのは煩雑で面倒ですね。
Leave a Reply