質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Q&A

解決済

1回答

2375閲覧

GASでGoogleスプレッドシートから画像URLを取得してツイートするスクリプトを書いているのですが、URLが空白の時にうまくいきません

ruku_practice

総合スコア1

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

0グッド

0クリップ

投稿2022/12/26 00:15

前提

GASでGoogleスプレッドシートから画像URLを取得してツイートするスクリプトを書いているのですが、URLが空白の時にうまくいきません。

Webで調べていくつか組み合わせて上記のスクリプトをほぼ完成させたのですが、最後の最後でうまくいかない部分があります。それは、URLがない時にうまく行くときと行かない時の差がわからないのです。

実現したいこと

  • GoogleスプレッドシートのB列にツイート本文、C列に画像を添付するときは添付画像のURLがあるデータリスト
  • 上記を読み込み、連続ツイートを発信するスクリプトを作りました
  • 画像URLがない時、ツイート本文のみを呟きたい
  • for文じゃなければ達成できているのですが、for文だと画像URLがない時にエラーが出てしまいます。
  • for文バージョンでも、C列全部に画像URLがある場合は成功します。

発生している問題・エラーメッセージ

エラーメッセージ エラー Exception: Attribute provided with no value: url

該当のソースコード

言語:GoogleAppScript ソースコード①(Web上から拝借したデータを発信するfunction。こちらにソースコード②・③から引数を渡して処理しています) function post_tweet(msg, re_id, img_urls){ var service = twitter.getService(); //TwitterWebServiceのインスタンス var img_ids = []; 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 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 = service.fetch( tw_enpoint_media, { 'method' : "POST", 'payload': { 'media_data': img_64 } } ); // media_idをimg_idsに格納。 img_ids[i] = JSON.parse(img_upload).media_id_string; //Logger.log(img_blob); //Logger.log(img_64); //Logger.log(img_upload); } } // ツイート var response = service.fetch(tw_endpoint_statuses, { method: "post", payload: { 'status' : msg, 'in_reply_to_status_id' : re_id, // 返信するツイートID 'media_ids' : img_ids.join(',') // すでにアップロードした画像のid(カンマ区切りで結合) *3 } }); tw_id = JSON.parse(response).id_str; return tw_id; }
ソースコード② for文でGoogleスプレッドシートから情報をあるだけ取得し、①に投げる処理 function GS2Tweet() { var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("XXX"); // シート名 var tweetMsgs = targetSheet.getRange(1,2,targetSheet.getLastRow()).getValues(); var tweetImgUrls = targetSheet.getRange(1,3,targetSheet.getLastRow()).getValues(); let tweet = new Array(); tweet[-1] = null for(var i =0; i < tweetMsgs.length;i++){ var n = i-1; tweet[i] = post_tweet(tweetMsgs[i],tweet[n],tweetImgUrls[i]); } }

試したこと

同じ画像URLが空白でも、以下だとやりたいことが実現します。

ソースコード③ for文でやりたいことを全部書いてみたら通りました(8行目からURLが空欄のケース) function tweetTest(){ // 連続ツイートの見本 var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("XXX"); // シート名 var tweetMsgs = targetSheet.getRange(1,2,targetSheet.getLastRow()).getValues(); var tweetImgUrls = targetSheet.getRange(1,3,targetSheet.getLastRow()).getValues(); var tw_id1 = post_tweet(tweetMsgs[0],null,tweetImgUrls[0]); var tw_id2 = post_tweet(tweetMsgs[1],tw_id1,tweetImgUrls[1]); var tw_id3 = post_tweet(tweetMsgs[2],tw_id2,tweetImgUrls[2]); var tw_id4 = post_tweet(tweetMsgs[3],tw_id3,tweetImgUrls[3]); var tw_id5 = post_tweet(tweetMsgs[4],tw_id4,tweetImgUrls[4]); var tw_id6 = post_tweet(tweetMsgs[5],tw_id5,tweetImgUrls[5]); var tw_id7 = post_tweet(tweetMsgs[6],tw_id6,tweetImgUrls[6]); var tw_id8 = post_tweet(tweetMsgs[7],tw_id7,[]); var tw_id9 = post_tweet(tweetMsgs[8],tw_id8,[]); var tw_id10 = post_tweet(tweetMsgs[9],tw_id9,[]); var tw_id11 = post_tweet(tweetMsgs[10],tw_id10,[]); var tw_id12 = post_tweet(tweetMsgs[11],tw_id11,[]); var tw_id13 = post_tweet(tweetMsgs[12],tw_id12,[]); }

補足情報(FW/ツールのバージョンなど)

・TwitterWebServiceを使っています。
・Twitterのエンドポイントは、
var tw_endpoint_statuses = "https://api.twitter.com/1.1/statuses/update.json";
var tw_enpoint_media = "https://upload.twitter.com/1.1/media/upload.json";
の2つを使っています。

どなたか、教えていただけると幸いです。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2022/12/26 03:28

空白か判断すればいいのでは?
ruku_practice

2022/12/26 08:52 編集

ありがとうございます! 空白判定として以下のように記載してみたのですが、やはり同じエラーがでてしまいます。。。 判定の仕方が誤ってるでしょうか。。。''以外にnullも試したのですが、変わらずです。。。 ==== function GS2Tweet(){ var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("xxx"); // シート名 var tweetMsgs = targetSheet.getRange(1,2,targetSheet.getLastRow()).getValues(); var tweetImgUrls = targetSheet.getRange(1,3,targetSheet.getLastRow()).getValues(); let tweet = new Array(); tweet[-1] = null for(var i =0; i < tweetMsgs.length;i++){ var n = i-1; if(tweetImgUrls[i] === ''){ tweet[i] = post_tweet(tweetMsgs[i],tweet[n],[]); }else{ tweet[i] = post_tweet(tweetMsgs[i],tweet[n],tweetImgUrls[i]); } } }
YAmaGNZ

2022/12/26 09:48

post_tweetのほうで画像URLが空なら画像をアップロードせずに文章だけでツイートすればいいのでは?
ruku_practice

2022/12/26 11:09

ありがとうございます! post_tweetの方で判定するようにしてみたのですが、やはり、if文判定がうまくいかない状況です。 img_urls === '' img_urls.length === 0 なども試したのですがダメです。 なお、このログ(Logger.log('img_urls="%s"',img_urls);)の結果は、 img_urls="[]" と出ます。 ==== function post_tweet(msg, re_id, img_urls){ var service = twitter.getService(); //TwitterWebServiceのインスタンス if (img_urls.length === 0) { console.log("img_urls is empty!") } var img_ids = []; Logger.log('img_urls="%s"',img_urls); if(img_urls.length === 0){ Logger.log('img_urls=null'); var response = service.fetch(tw_endpoint_statuses, { method: "post", payload: { 'status' : msg, 'in_reply_to_status_id' : re_id, // 返信するツイートID //'media_ids' : img_ids.join(',') // すでにアップロードした画像のid(カンマ区切りで結合) *3 } }) tw_id = JSON.parse(response).id_str; return tw_id; Logger.log('空白ケース'); }else{ Logger.log('img_urls=true'); 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 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 = service.fetch( tw_enpoint_media, { 'method' : "POST", 'payload': { 'media_data': img_64 } } ); // media_idをimg_idsに格納。 img_ids[i] = JSON.parse(img_upload).media_id_string; } } // ツイート var response = service.fetch(tw_endpoint_statuses, { method: "post", payload: { 'status' : msg, 'in_reply_to_status_id' : re_id, // 返信するツイートID 'media_ids' : img_ids.join(',') // すでにアップロードした画像のid(カンマ区切りで結合) *3 } }); tw_id = JSON.parse(response).id_str; return tw_id; Logger.log('空白ではないケース'); } }
YAmaGNZ

2022/12/26 12:43

呼び出し側で引数に[]を渡しているのであれば length=1 img_urls[0]='' という状態になります。 エディタでブレイクポイントを設定してデバッグしてみるといいでしょう。
ruku_practice

2022/12/26 13:49

できました!丁寧なアドバイスありがとうございました!!
guest

回答1

0

自己解決

YAmaGNZさんの丁寧なアドバイスのおかげで解決しました!

function post_tweetのif文を以下のように書くことで解決しました。ありがとうございました!!
====

function post_tweet(msg, re_id, img_urls){ var service = twitter.getService(); //TwitterWebServiceのインスタンス if (img_urls[0] === '') { console.log("img_urls is empty!") } var img_ids = []; Logger.log('img_urls="%s"',img_urls); if(img_urls[0] === ''){ Logger.log('img_urls=null'); var response = service.fetch(tw_endpoint_statuses, { method: "post", payload: { 'status' : msg, 'in_reply_to_status_id' : re_id, // 返信するツイートID //'media_ids' : img_ids.join(',') // すでにアップロードした画像のid(カンマ区切りで結合) *3 } }) tw_id = JSON.parse(response).id_str; return tw_id; Logger.log('空白ケース'); }else{ Logger.log('img_urls=true'); 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 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 = service.fetch( tw_enpoint_media, { 'method' : "POST", 'payload': { 'media_data': img_64 } } ); // media_idをimg_idsに格納。 img_ids[i] = JSON.parse(img_upload).media_id_string; } } // ツイート var response = service.fetch(tw_endpoint_statuses, { method: "post", payload: { 'status' : msg, 'in_reply_to_status_id' : re_id, // 返信するツイートID 'media_ids' : img_ids.join(',') // すでにアップロードした画像のid(カンマ区切りで結合) *3 } }); tw_id = JSON.parse(response).id_str; return tw_id; Logger.log('空白ではないケース'); } }

投稿2022/12/26 13:49

ruku_practice

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問