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

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

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

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

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google Apps Script

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

OAuth

OAuth(Open Authorization)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Twitter

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

Q&A

解決済

1回答

1978閲覧

Google Apps Scriptで動作するTwitter Botを作成中、twitterとの連携認証のスクリプトどうしても動作しません。

cusmix

総合スコア2

Google スプレッドシート

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

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google Apps Script

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

OAuth

OAuth(Open Authorization)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Twitter

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

0グッド

2クリップ

投稿2021/11/13 15:23

編集2021/11/13 15:37

前提・実現したいこと

Google Apps Scriptで動作するTwitter Botを作成中、twitterとの連携認証のスクリプトどうしても動作しません。

最終的には、エラーを解消させて、スプレッドシートの検索ワードをtwitterで検索し、botがそのツイートに対して、RTないし、いいねをする、という動作を実行するようにしたいです。

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

下記の記事を参考にさせていただき、動作させようとしています。

https://moripro.net/gas-twitter-bot/
https://teratail.com/questions/240990

『authorize』は、下記のメッセージで実行完了

23:59:55 お知らせ 実行開始
23:59:56 情報 Already authorized
23:59:57 お知らせ 実行完了

『reset』は、下記のメッセージで実行完了

0:00:55 お知らせ 実行開始
0:00:55 お知らせ 実行完了

『authCallback』で、下記のメッセージが出てしまいます。

0:01:41 お知らせ 実行開始
0:01:42 エラー
TypeError: undefined からプロパティ「parameter」を読み取れません。
(匿名) @ Service.gs:265
(匿名) @ TwitterWebService.gs:38
authCallback @ コード.gs:19

この状態で、『authorize』を再度実行すると、下記のメッセージが表示されます。

0:02:38 お知らせ 実行開始
0:02:38 情報 Open the following URL and re-run the script: https://api.twitter.com/oauth/authorize?oauth_token=xxxxxxxxxxxxxxxxxx
0:02:39 お知らせ 実行完了

URLから、認証後、再度『authorize』を実行すると実行完了しますが、『authCallback』で、また、同様のエラーが発生します。

このあと、下記の方のコードを参考にさせていただき、

https://gist.github.com/belltreeSzk/8c122a5ffb2fa3753275ddfc8eef895d
https://gist.github.com/cucmberium/e687e88565b6a9ca7039

//認証用インスタンスの生成 var twitter = TwitterWebService.getInstance( ' ',//API Key ' '//API secret key ); //アプリを連携認証する function authorize() { twitter.authorize(); } //認証を解除する function reset() { twitter.reset(); } //認証後のコールバック function authCallback(request) { return twitter.authCallback(request); } // セルを取得 var sheetData = SpreadsheetApp.getActi veSpreadsheet().getSheetByName("シート1"); // 「シート1」はシート名 /** いいね or RT 機能 ① 検索ワードをスプレッドシートから取得する ② 検索ワードをTwitterで検索する(たくさん取れてしまうので「直近10分間」の検索を10分毎に行う) ③ ツイートに いいね or RT をする ④ 他に検索ワードがあれば②に戻る */ function main () { // ① 検索ワードをスプレッドシートから取得する var searchWords = pickUpSearchWords(); // searchWordsの中身は // [ [ '投稿内容', 'いいね or RT', '最終TweetId'] , [ '投稿内容', 'いいね or RT', '最終TweetId'] , [ '投稿内容', 'いいね or RT', '最終TweetId'] ,....,] // という形式になっているので1つずつ見ていく for (var i = 0, il = searchWords.length; i < il; i++ ) { var searchWord = searchWords[i][0]; var type = searchWords[i][1]; var lastTweetId = searchWords[i][2]; // ツイートを検索する // 【参考】 https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets function findTweets (searchWord, lastTweetId) { var service = twitter.getService(); var query = { q: searchWord, // 検索ワード lang: 'ja', // 日本語検索 locale: 'ja', // 日本限定で検索 result_type: 'recent', // 直近のツイートを検索 since_id: lastTweetId // これ以前のツイートは見ない } // 検索の内容を queryStr にまとめていく var queryStr = ''; for (var key in query) { // URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする queryStr += key + '=' + encodeURIComponent(query[key]) + '&' } // &が余計に付いているので削除しておく var queryStr = queryStr.slice(0, -1); var response = service.fetch('https://api.twitter.com/1.1/search/tweets.json?' + queryStr); var result = JSON.parse(response) return result.statuses } // ② Twitterで検索する var tweetList = findTweets(searchWord, lastTweetId); // ③ 複数件ツイートを取得されるので for を使って1つずつツイートを取り出し いいね or RT をする for (var j = 0, jl = tweetList.length; j < jl; j++ ) { var tweet = tweetList[j]; // 重複処理をしないように最新のツイートIDを保存する var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var lastTweetIdCol = 3; // 『最終TweetId』の列までなので3列目まで var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); // i = 0 の時1行目なので+1してる updateCell.setValue(lastTweetId); } } // 検索ワードをスプレッドシートから取得する function pickUpSearchWords () { var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var startRow = 1 + titleRow; // 1行目は『検索ワード』とか書いているので2行目から var startCol = 1; var endRow = sheetData.getLastRow() - titleRow; // 最後の行まで(2行目から始まっているので-1している) // !!!!!! 変更 !!!!!!! var endCol = 4; // 『実行回数』の列までなので4列目まで // 一括で取得する var cells = sheetData.getRange(startRow, startCol, endRow, endCol).getValues(); // cellsの中身は // [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] ,....,] // という形式になる return cells; } }

『authCallback』の実行を飛ばして、『main』について、実行すると下記のように実行完了しますが、動作はしません。

0:17:13 お知らせ 実行開始
0:17:15 お知らせ 実行完了

function main () { // ① 検索ワードをスプレッドシートから取得する var searchWords = pickUpSearchWords(); // searchWordsの中身は // [ [ '投稿内容', 'いいね or RT', '最終TweetId'] , [ '投稿内容', 'いいね or RT', '最終TweetId'] , [ '投稿内容', 'いいね or RT', '最終TweetId'] ,....,] // という形式になっているので1つずつ見ていく for (var i = 0, il = searchWords.length; i < il; i++ ) { var searchWord = searchWords[i][0]; var type = searchWords[i][1]; var lastTweetId = searchWords[i][2]; // ツイートを検索する // 【参考】 https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets function findTweets (searchWord, lastTweetId) { var service = twitter.getService(); var query = { q: searchWord, // 検索ワード lang: 'ja', // 日本語検索 locale: 'ja', // 日本限定で検索 result_type: 'recent', // 直近のツイートを検索 since_id: lastTweetId // これ以前のツイートは見ない } // 検索の内容を queryStr にまとめていく var queryStr = ''; for (var key in query) { // URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする queryStr += key + '=' + encodeURIComponent(query[key]) + '&' } // &が余計に付いているので削除しておく var queryStr = queryStr.slice(0, -1); var response = service.fetch('https://api.twitter.com/1.1/search/tweets.json?' + queryStr); var result = JSON.parse(response) return result.statuses } // ② Twitterで検索する var tweetList = findTweets(searchWord, lastTweetId); // ③ 複数件ツイートを取得されるので for を使って1つずつツイートを取り出し いいね or RT をする for (var j = 0, jl = tweetList.length; j < jl; j++ ) { var tweet = tweetList[j]; // 重複処理をしないように最新のツイートIDを保存する var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var lastTweetIdCol = 3; // 『最終TweetId』の列までなので3列目まで var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); // i = 0 の時1行目なので+1してる updateCell.setValue(lastTweetId); } } // 検索ワードをスプレッドシートから取得する function pickUpSearchWords () { var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var startRow = 1 + titleRow; // 1行目は『検索ワード』とか書いているので2行目から var startCol = 1; var endRow = sheetData.getLastRow() - titleRow; // 最後の行まで(2行目から始まっているので-1している) // !!!!!! 変更 !!!!!!! var endCol = 4; // 『実行回数』の列までなので4列目まで // 一括で取得する var cells = sheetData.getRange(startRow, startCol, endRow, endCol).getValues(); // cellsの中身は // [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] ,....,] // という形式になる return cells; } }

該当のソースコード

//認証後のコールバック function authCallback(request) { return twitter.authCallback(request); }

こちらのコードを変更する必要があるのか、別に問題があるのかも検討が付かない状態です。

こちらについて、ご回答いただくために、不足情報が何かもわからない状況です。そのあたりから、ご教示いただきたいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

認証が完了しているのであれば、
authorize()やauthCallback()には何の問題もありません。

text

1ここでの「認証が完了している」とは 2  スクリプトエディタ上で authorize() 関数を手動実行 3=> 表示されたリンクをブラウザのURL入力欄に貼り付けて移動。 4=> Twitterの連携画面が表示されるので連携承認ボタンを押す。 5=> ページが切り変わって左上に「SUCCESS!!」と表示される。 6 7までが完了している、という意味です)

   

authCallback()関数は、認証手続中に内部的に呼ばれるものであり、直接実行するものではありません
(authCallback()を直接実行するとエラーが出るのは仕様です)

また、reset()を実行すると、authorize()で設定したデータが消えてしまいます

したがって、上記の手順でauthorize()を実行~「SUCCESS!!」表示までが正常に表示された後は、
reset()やauthCallback()を実行する必要はありません。

・認証が完了している状態で「『authCallback』の実行を飛ばして、『main』について、実行すると下記のように実行完了しますが、動作はしません。」とのことですが、
動作していないように見えるだけで、質問文記載のコード自体は動いていると思われます。


質問文記載のコードのmain()関数以下で行おうとしていることは単に、
「シート1の特定セルから値(ツイートID)を取得して、同じ値を同じ場所に書き込む」(検索結果がなければ何もしない)という処理なので
実行しても何も動いていないように見えるだけであると考えられます。
(for文の中に関数が定義されている点が不可解ですが・・・)


・下記に例として、シート1に指定した検索ワードの検索結果をログ表示するコードを記載します。
authorize()、authCallback()は変更していません。
main()以下を変更しています。
for文の中に関数が定義されている部分等も修正しています。

最初に実行するときは、シート1の3列目のIDを空欄にして実行してください。(空欄にしていないと検索結果が表示されない可能性があるため)

//認証用インスタンスの生成 var twitter = TwitterWebService.getInstance( ' ',//API Key ' '//API secret key ); //アプリを連携認証する function authorize() { twitter.authorize(); } //認証を解除する function reset() { twitter.reset(); } //認証後のコールバック function authCallback(request) { return twitter.authCallback(request); } // セルを取得 var sheetData = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1"); // 「シート1」はシート名 function main() { // ① 検索ワードをスプレッドシートから取得する var searchWords = pickUpSearchWords(); for (var i = 0; i < searchWords.length; i++) { var searchWord = searchWords[i][0]; var type = searchWords[i][1]; var lastTweetId = searchWords[i][2]; // ② Twitterで検索する var tweetList = findTweets(searchWord, lastTweetId); // ③ 複数件ツイートを取得されるので for を使って1つずつツイートを取り出す for (var j = 0; j < tweetList.length; j++) { var tweet = tweetList[j]; // ユーザー名、ツイート、ツイートIDをログ表示 console.log([tweet.user.name, tweet.text, tweet.id].join('\n')) lastTweetId = tweet.id } // 重複処理をしないように最新のツイートIDを保存する var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var lastTweetIdCol = 3; // 『最終TweetId』の列までなので3列目まで var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); // i = 0 の時1行目なので+1してる updateCell.setValue(lastTweetId); } } // 検索ワードをスプレッドシートから取得する function pickUpSearchWords() { var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var startRow = 1 + titleRow; // 1行目は『検索ワード』とか書いているので2行目から var startCol = 1; var endRow = sheetData.getLastRow() - titleRow; // 最後の行まで(2行目から始まっているので-1している) // !!!!!! 変更 !!!!!!! var endCol = 4; // 『実行回数』の列までなので4列目まで // 一括で取得する var cells = sheetData.getRange(startRow, startCol, endRow, endCol).getValues(); // cellsの中身は // [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] ,....,] // という形式になる return cells; } // ツイートを検索する // 【参考】 https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets function findTweets(searchWord, lastTweetId) { var service = twitter.getService(); var query = { q: searchWord, // 検索ワード lang: 'ja', // 日本語検索 locale: 'ja', // 日本限定で検索 result_type: 'recent', // 直近のツイートを検索 since_id: lastTweetId // これ以前のツイートは見ない } // 検索の内容を queryStr にまとめていく var queryStr = ''; for (var key in query) { // URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする queryStr += key + '=' + encodeURIComponent(query[key]) + '&' } // &が余計に付いているので削除しておく var queryStr = queryStr.slice(0, -1); var response = service.fetch('https://api.twitter.com/1.1/search/tweets.json?' + queryStr); var result = JSON.parse(response) return result.statuses }

追記(コメントより)

元の質問文では、下記色付き行で強調している部分のうち、findTweets()関数が、forループの中に定義されている状態になっています。
(単純なコピペミスでしょうか?)
上記の回答コードではこの部分を修正し、関数をforループの外(厳密には、さらにその外であるmain()の外)に出しています。
また、pickUpSearchWords()関数もmain()の外に出しています。

diff

1※質問文の一番最初のバージョンに記載されているコード 2function main () { 3 // ① 検索ワードをスプレッドシートから取得する 4 var searchWords = pickUpSearchWords(); 5 6 // searchWordsの中身は 7 // [ [ '投稿内容', 'いいね or RT', '最終TweetId'] , [ '投稿内容', 'いいね or RT', '最終TweetId'] , [ '投稿内容', 'いいね or RT', '最終TweetId'] ,....,] 8 // という形式になっているので1つずつ見ていく 9 for (var i = 0, il = searchWords.length; i < il; i++ ) { 10 var searchWord = searchWords[i][0]; 11 var type = searchWords[i][1]; 12 var lastTweetId = searchWords[i][2]; 13 14 15// findTweets()は、forループの中に定義されてしまっているため、外に出した方がよい。 16+// ツイートを検索する 17+// 【参考】 https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-+tweets 18+function findTweets (searchWord, lastTweetId) { 19+ var service = twitter.getService(); 20+ var query = { 21+ q: searchWord, // 検索ワード 22+ lang: 'ja', // 日本語検索 23+ locale: 'ja', // 日本限定で検索 24+ result_type: 'recent', // 直近のツイートを検索 25+ since_id: lastTweetId // これ以前のツイートは見ない 26+ } 27+ // 検索の内容を queryStr にまとめていく 28+ var queryStr = ''; 29+ for (var key in query) { 30+ // URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする 31+ queryStr += key + '=' + encodeURIComponent(query[key]) + '&' 32+ } 33+ // &が余計に付いているので削除しておく 34+ var queryStr = queryStr.slice(0, -1); 35 36+ var response = service.fetch('https://api.twitter.com/1.1/search/tweets.json?' + +queryStr); 37+ var result = JSON.parse(response) 38+ return result.statuses 39+} 40 41 // ② Twitterで検索する 42 var tweetList = findTweets(searchWord, lastTweetId); 43 44 // ③ 複数件ツイートを取得されるので for を使って1つずつツイートを取り出し いいね or RT をする 45 for (var j = 0, jl = tweetList.length; j < jl; j++ ) { 46 var tweet = tweetList[j]; 47 48 // 重複処理をしないように最新のツイートIDを保存する 49 var titleRow = 1; // 『検索ワード』とか書いている部分の行数 50 var lastTweetIdCol = 3; // 『最終TweetId』の列までなので3列目まで 51 var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); // i = 0 の時1行目なので+1してる 52 updateCell.setValue(lastTweetId); 53 } 54} 55 56// pickUpSearchWords()は、main()内にあっても問題なく動くが、他の関数から利用することを考えると外に出した方がよい。 57+// 検索ワードをスプレッドシートから取得する 58+function pickUpSearchWords () { 59+ var titleRow = 1; // 『検索ワード』とか書いている部分の行数 60+ var startRow = 1 + titleRow; // 1行目は『検索ワード』とか書いているので2行目から 61+ var startCol = 1; 62+ var endRow = sheetData.getLastRow() - titleRow; // 最後の行まで(2行目から始まっているので-1している) 63 64+ // !!!!!! 変更 !!!!!!! 65+ var endCol = 4; // 『実行回数』の列までなので4列目まで 66 67+ // 一括で取得する 68+ var cells = sheetData.getRange(startRow, startCol, endRow, endCol).getValues(); 69+ 70+ // cellsの中身は 71+ // [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] ,....,] 72+ // という形式になる 73+ 74+ return cells; 75+} 76}

投稿2021/11/13 23:55

編集2021/11/15 00:33
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

cusmix

2021/11/14 02:28

qnoirさん ご回答ありがとうございました。 丁寧なご説明に大変感謝しております。 "(for文の中に関数が定義されている点が不可解ですが・・・)" というご指摘は、具体的にどのあたりのことを指すのかをご教示いただけますとうれしいです。 また、本文、最下部に掲載しますコードを追加する予定であったことを失念しておりました。 更に、下記のコードを追加すると、 『pickUpSearchWords』 『findTweets』 『getTweetStatus』 『putFavorite』 『putRetweet』 の全てにおいて、 "構文エラー: Missing } in compound statement. 行: xx ファイル: コード" という、エラーが発生し、保存することができなかったので、『main』で終了してしまっていました。 もし、 "(for文の中に関数が定義されている点が不可解ですが・・・)" というところが、こちらの手掛かりになれば、と思いお伺いしてしまいました。 掲載漏れのコードのエラーについては、本件と切り離した方がよいと思うので、改めて、質問させていただこうと思っております。 初心者にも、ご丁寧にご対応いただいたこと、重ねてお礼申し上げます。 -------------------------- // 検索ワードをスプレッドシートから取得する function pickUpSearchWords () { var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var startRow = 1 + titleRow; // 1行目は『検索ワード』とか書いているので2行目から var startCol = 1; var endRow = sheetData.getLastRow() - titleRow; // 最後の行まで(2行目から始まっているので-1している) var endCol = 3; // 『最終TweetId』の列までなので3列目まで // 一括で取得する var cells = sheetData.getRange(startRow, startCol, endRow, endCol).getValues(); // ちなみにcellsの中身は // [ [ '投稿内容', 'いいね or RT', '最終TweetId'] , [ '投稿内容', 'いいね or RT', '最終TweetId'] , [ '投稿内容', 'いいね or RT', '最終TweetId'] ,....,] // という形式になっている return cells; } // ツイートを検索する // 【参考】 https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets function findTweets (searchWord, lastTweetId) { var service = twitter.getService(); var query = { q: searchWord, // 検索ワード lang: 'ja', // 日本語検索 locale: 'ja', // 日本限定で検索 result_type: 'recent', // 直近のツイートを検索 since_id: lastTweetId // これ以前のツイートは見ない } // 検索の内容を queryStr にまとめていく var queryStr = ''; for (var key in query) { // URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする queryStr += key + '=' + encodeURIComponent(query[key]) + '&' } // &が余計に付いているので削除しておく var queryStr = queryStr.slice(0, -1); var response = service.fetch('https://api.twitter.com/1.1/search/tweets.json?' + queryStr); var result = JSON.parse(response) return result.statuses } // いいね/RTの状態を確認 // 【参考】 https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-lookup function getTweetStatus (tweet) { var service = twitter.getService(); var response = service.fetch('https://api.twitter.com/1.1/statuses/lookup.json?id=' + tweet.id_str); var result = JSON.parse(response) return result[0]; } // いいね を付ける // 【参考】 https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-favorites-create function putFavorite (tweet) { var service = twitter.getService(); var response = service.fetch('https://api.twitter.com/1.1/favorites/create.json', { method: 'post', payload: { id: tweet.id_str } }); } // RT を付ける // 【参考】 https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-retweet-id function putRetweet (tweet) { var service = twitter.getService(); var response = service.fetch('https://api.twitter.com/1.1/statuses/retweet/' + tweet.id_str +'.json', { method: 'post' }); }
退会済みユーザー

退会済みユーザー

2021/11/14 02:35

「for文の中に関数が定義されている点」について、追記しました。
cusmix

2021/11/20 10:10

qnoirさん、 せっかくご回答いただいたのに、返信が遅くなり申し訳ありませんでした。 ”関数をforループの外(厳密には、さらにその外であるmain()の外)に出”さないと、永遠にループするということまでは理解ができたのですが、 また、コピペ間違いなのだとは思うのですが、syntax errorが出てしまい、回避できなくなっておりました。 とても丁寧にご説明いただいたのに、活用することができず、大変悔しく、また、申し訳ない気持ちです。 結局、下記のコードで、動作させることができたので、ここで、決着とさせました。 ------------------------------ //認証用インスタンスの生成 var twitter = TwitterWebService.getInstance( '         ',//API Key '         '//API secret key ); // 認証 function authorize() { twitter.authorize(); } // 認証解除 function reset() { twitter.reset(); } // 認証後のコールバック function authCallback(request) { return twitter.authCallback(request); } // セルを取得 var sheetData = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1"); // 「シート1」はシート名 /** いいね or RT 機能 ① 検索ワードをスプレッドシートから取得する ② 検索ワードをTwitterで検索する(たくさん取れてしまうので「直近10分間」の検索を10分毎に行う) ③ ツイートに いいね or RT をする ④ 他に検索ワードがあれば②に戻る */ // ツイートを検索する // 【参考】 https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets function findTweets (searchWord, lastTweetId) { var service = twitter.getService(); var query = { q: searchWord, // 検索ワード lang: 'ja', // 日本語検索 locale: 'ja', // 日本限定で検索 result_type: 'recent', // 直近のツイートを検索 since_id: lastTweetId // これ以前のツイートは見ない } // 検索の内容を queryStr にまとめていく var queryStr = ''; for (var key in query) { // URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする queryStr += key + '=' + encodeURIComponent(query[key]) + '&' } // &が余計に付いているので削除しておく var queryStr = queryStr.slice(0, -1); var response = service.fetch('https://api.twitter.com/1.1/search/tweets.json?' + queryStr); var result = JSON.parse(response) return result.statuses } function main () { // ① 検索ワードをスプレッドシートから取得する var searchWords = pickUpSearchWords(); // searchWordsの中身は // [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'],....,] // という形式になっているので1つずつ見ていく for (var i = 0, il = searchWords.length; i < il; i++ ) { var searchWord = searchWords[i][0]; var type = searchWords[i][1]; var lastTweetId = searchWords[i][2]; // !!!!!! 追加 !!!!!!! var limit = searchWords[i][3]; // ② Twitterで検索する var tweetList = findTweets(searchWord, lastTweetId); var count = 0 // ③ 複数件ツイートを取得されるので for を使って1つずつツイートを取り出し いいね or RT をする for (var j = 0, jl = tweetList.length; j < jl; j++ ) { var tweet = tweetList[j]; if (tweet.id_str > lastTweetId) { lastTweetId = tweet.id_str; } // !!!!!! 追加 !!!!!!! if (count == limit) { // lastTweetIdを出来るだけ新しくしたい場合は continue; // 次回以降の実行で続きのツイートを使いたい場合は break; continue; } count++; if (type == 'いいね') { putFavorite (tweet); } else if (type == 'RT') { putRetweet (tweet); } } // 最新のツイートIDを保存して重複処理をしないようにする var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var lastTweetIdCol = 3; // 『最終TweetId』の列までなので3列目まで var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); // i = 0 の時1行目なので+1してる updateCell.setValue(lastTweetId); } } // 検索ワードをスプレッドシートから取得する function pickUpSearchWords () { var titleRow = 1; // 『検索ワード』とか書いている部分の行数 var startRow = 1 + titleRow; // 1行目は『検索ワード』とか書いているので2行目から var startCol = 1; var endRow = sheetData.getLastRow() - titleRow; // 最後の行まで(2行目から始まっているので-1している) // !!!!!! 変更 !!!!!!! var endCol = 4; // 『実行回数』の列までなので4列目まで // 一括で取得する var cells = sheetData.getRange(startRow, startCol, endRow, endCol).getValues(); // cellsの中身は // [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] ,....,] // という形式になる return cells; } ------------------------------
退会済みユーザー

退会済みユーザー

2021/11/20 10:15 編集

ご丁寧にコメントありがとうございます。 解決されたのであればよかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問