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

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

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

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

Google Apps Script

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

Twitter

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

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Q&A

解決済

1回答

1763閲覧

GAS Twitter API v2でリツイートBOTを作成しようと試みた所、ログが実行開始。そして、実行完了となるのですが、スプレットシートもTwitterアカウントも同じく反応が見られません。

pons15564

総合スコア2

Google スプレッドシート

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

Google Apps Script

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

Twitter

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

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

0グッド

0クリップ

投稿2022/06/27 16:48

前提・実現したいこと
Google Apps Scriptで動作するTwitter Botを作成中です。スプレッドシートにある検索ワードをtwitterで検索し、ツイートにいいね or RTをする。

発生している問題・エラーメッセージ
下記の記事を参考にさせていただき、動作させようとしています。
https://kabatin.hateblo.jp/entry/2022/02/27/205845

上記のサイトで【今回はこんな感じで「検索ワード(ハッシュタグ)」、「いいね or RT」の種別と、
重複して投稿をしてしまわないように「最新TweetID」を保持するようにしてあります。】とあるのですが、
**スプレッドシートの設定で私が初心者すぎて分からなかったので設定できていません。【シート1】は作れました

スプレッドシートの検索キーワードで検索した、最終TweetIDがスプレッドシートに上書きされて、その後、それをもとに、

"Twitteを検索"→"スプレッドシートの最終TweetIDが更新"→いいね or RTをする→"最終TwitterID以降で検索"

としたいのですが、残念ながら何もおこらず、、
ご回答いただくために、不足情報が何かもわからない状況です。そのあたりから、ご教示いただきたいです。

現在のソースコード

// ベアラートークンと認証用インスタンス

var bearerToken = '      '
var twitter = TwitterWebService.getInstance(
'      ', // 作成したアプリケーションのConsumer Key
'            ' // 作成したアプリケーションのConsumer Secret
);
var userID = '         ' // Twitter ユーザID

// 認証周り
function authorize() { twitter.authorize(); } // 認証
function reset() { twitter.reset(); } // 認証解除
function authCallback(request) { return twitter.authCallback(request); } // 認証後のコールバック

// シートを取得
var sheetData = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1"); // 「シート1」はシート名

// APIコール時のオプション(GET)
const getOption = {
method: 'get',
contentType: 'application/json',
muteHttpExceptions: true,
headers: { Authorization: 'Bearer ' + bearerToken }
}
// APIコール時のオプション(POST)
const postOption = {
method: 'post',
contentType: 'application/json',
muteHttpExceptions: true,
headers: { Authorization: 'Bearer ' + bearerToken },
}

function main()
{
var service = twitter.getService();

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];

var tweetList = findTweets(service, searchWord, lastTweetId); if (tweetList == null) { continue } for (var j = 0; j < tweetList.length; j++) { var tweet = tweetList[j]; if (tweet.id > lastTweetId) { lastTweetId = tweet.id; } if (type == 'いいね') { putFavorite (service, tweet); } else if (type == 'RT') { putRetweet (service, tweet); } } var titleRow = 1; var lastTweetIdCol = 3; var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); updateCell.setValue(lastTweetId);

}
}

// 検索ワードをスプレッドシートから取得する
function pickUpSearchWords()
{
var titleRow = 1;
var startRow = 1 + titleRow;
var startCol = 1;
var endRow = sheetData.getLastRow() - titleRow;
var endCol = 3;

return sheetData.getRange(startRow, startCol, endRow, endCol).getValues();
}

// ツイートを検索する
function findTweets(service, searchWord, lastTweetId)
{
// API URL
var getPoint = 'https://api.twitter.com/2/tweets/search/recent?query='

// 検索キーワードとパラメータ
var keyWord = encodeURIComponent(searchWord)
var params = '&tweet.fields=author_id,id,text,created_at&max_results=20'
params += '&since_id=' + lastTweetId

// アクセスURL組み立て
var url = getPoint + keyWord + params

var response = service.fetch(url, getOption);
var result = JSON.parse(response)
return result.data
}

// いいね
function putFavorite(service, tweet)
{
targetTweet = { 'tweet_id': tweet.id }
postOption.payload = JSON.stringify(targetTweet)
service.fetch('https://api.twitter.com/2/users/' + userID + '/likes', postOption);
}

// リツイート
function putRetweet(service, tweet)
{
targetTweet = { 'tweet_id': tweet.id }
postOption.payload = JSON.stringify(targetTweet)
var result = service.fetch('https://api.twitter.com/2/users/' + userID + '/retweets', postOption);
}

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/06/27 22:31

認証や検索自体はうまくいっているが、検索結果が返ってきていないだけの可能性も考えられます。 各関数の要所でconsole.log〜を書いてみて、期待する動作になっているか、また変数に値が入っているか、確認されてはいかがでしょうか?
pons15564

2022/06/28 02:45 編集

回答ありがとうございます。console.logを初めて調べてやってみようと試みたのですが、私がconsole.logを上手く理解していないようで、期待した確認作業ができませんでした。 console.logを使い、動作確認の仕方をご教授して頂ければ幸いです。 上記のコードを使用した時の(console.log)を教えて頂けると嬉しいです。
pons15564

2022/06/28 12:38

2通目のメールに返信できなかったので、こちらにコメントさせていただきました。 ご丁寧にありがとうございます。早速やってみました。 結果がこちらです。 21:23:00 情報 pickUpSearchWords@sheetData.~.getValues():   ,RT, 21:23:00 情報 findTweets@result.data:[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object] 21:23:00 情報 main@tweetList:[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object] 21:23:00 情報 putRetweet@targetTweet:[object Object]) 21:23:00 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:00 情報 putRetweet@targetTweet:[object Object]) 21:23:01 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:01 情報 putRetweet@targetTweet:[object Object]) 21:23:01 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:01 情報 putRetweet@targetTweet:[object Object]) 21:23:01 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:01 情報 putRetweet@targetTweet:[object Object]) 21:23:01 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:01 情報 putRetweet@targetTweet:[object Object]) 21:23:02 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:02 情報 putRetweet@targetTweet:[object Object]) 21:23:02 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:02 情報 putRetweet@targetTweet:[object Object]) 21:23:02 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:02 情報 putRetweet@targetTweet:[object Object]) 21:23:02 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:02 情報 putRetweet@targetTweet:[object Object]) 21:23:03 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:03 情報 putRetweet@targetTweet:[object Object]) 21:23:03 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:03 情報 putRetweet@targetTweet:[object Object]) 21:23:03 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:03 情報 putRetweet@targetTweet:[object Object]) 21:23:03 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:03 情報 putRetweet@targetTweet:[object Object]) 21:23:04 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:04 情報 putRetweet@targetTweet:[object Object]) 21:23:04 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:04 情報 putRetweet@targetTweet:[object Object]) 21:23:04 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:04 情報 putRetweet@targetTweet:[object Object]) 21:23:04 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:04 情報 putRetweet@targetTweet:[object Object]) 21:23:05 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:05 情報 putRetweet@targetTweet:[object Object]) 21:23:05 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:05 情報 putRetweet@targetTweet:[object Object]) 21:23:05 情報 putRetweet@result:{"data":{"retweeted":true}} 21:23:05 情報 main@updateCell.setValue(lastTweetId:     ) 全てERROR?って事でよろしいんでしょうか?チョットパニックです(汗) 回答をご教授いただけると嬉しいですm(__)m
退会済みユーザー

退会済みユーザー

2022/06/28 14:08 編集

そのログを見る限りでは、きちんとデータは取得できていて、エラーも起きておらずうまく行っているはず(プログラムによって自動リツイートされているはず)と思うのですが、何も起きていない(自動リツイートが全くなされていない)のでしょうか?
pons15564

2022/06/28 13:15 編集

なるほど!!エラーではなかったのですね。少し安心致しました。 ご指摘の様に、いいねを押していなかったので、押して試した所、同じ結果になりました。 が、しかし、スプレットシートの所を更に(RT)から(いいね)に変更してみた所、このようになりました。 21:56:09 情報 pickUpSearchWords@sheetData.~.getValues():    ,いいね, 21:56:09 情報 findTweets@result.data:undefined 21:56:09 情報 main@tweetList:undefined 2件の未定義?と表示されています。スプレットシートに何か問題でもあるのでしょうか? 参考URLで確かめてみました。 実際にツイートを「検索」「いいね」「リツイート」しているのは以下の部分になります。 「検索」 Twitter API v2 のツイート検索エンドポイントは https://api.twitter.com/2/tweets/search/recent です。 GET でのアクセスになるため、query にそれぞれパラメータを付与してアクセスします。 パラメータには、検索ワード、取得フィールド(ユーザID、ツイートID、内容、日時)、最大取得件数の指定と、 重複防止のためにスプレッドシートに記録していた最新ツイートIDを使用して、 どのツイートIDのツイート以降を検索対象とするかを since_id で指定しています。 レスポンス形式は JSON です。。と書いてありました。 ほんと情けない気持ちなのですが、やり方がわからなくてスプレットシートに何も出来ていません。TwitterAPI2からの情報もスプレットシートに読み込んでも、もらえていません。 本当に申し訳ありませんが、今一度ご教授お願い出来ると嬉しいです。
退会済みユーザー

退会済みユーザー

2022/06/28 14:14

繰り返しになりますが、ログを見る限り、プログラム自体は正常に動いています。 ただしこのプログラムは、1度動かすと、その時点で検索して出てきた全部の対象ツイートにいいねまたはリツイートを行ってしまうため 新たな対象ツイートがなされるまでは、それ以上いいね又はリツイートができなくなります。 そのような状態の場合は、しばらくの間「undefined」という表示になります。 「undefined」が出ているということは、まだ新しい検索結果がないという意味です。 これはプログラム自体の仕様です。 (すでにいいねやリツイートが済んでいる同じツイートに対して重複して「いいね」や「リツイート」を行おうとしても、APIリソースを消費するだけで意味ないですよね?それを回避するための仕組みです
pons15564

2022/06/28 15:11 編集

正常に動いているんですか!!! 早速、検索ワードを変更してみました。 何と!!!!!出来きておりました。 本当に嬉しい気持ちでいっぱいです。(今日は眠れません!!) 実は、1か月以上前から自分で何とかしようとこのように悩んでいました。意味もわからないまま月日は流れ、思い切ってteratail様のサイトに登録、投稿し、不安な気持ちでいた所、【qnoir】様に救われました。 本当に、本当に、ありがとうございました。色々とアドバイス回答等して頂き、感謝でしかありません。 本当ならば、何かお礼をしたいのですが、何もできないのが、とても、もどかしいです( ;∀;) このプログラムを理解できた事が本当に嬉しいです。ありがとうございました。 ごめんなさい。【qnoir】様の評価を最大評価にしたいと思い探しているのですが、、このサイトのどこかで評価等行えないでしょうか?ご教授お願い頂けると幸いです。
退会済みユーザー

退会済みユーザー

2022/06/29 02:02

確認及びフィードバックありがとうございます。 評価については回答1件につき一つしかできませんので、特に気にしていただかなくてよいです。
pons15564

2022/06/29 11:03

そうなんですね。1つしかできないのが、本当に残念です。( ;∀;) 困っている所を助けて頂き、本当にありがとうございました。
guest

回答1

0

ベストアンサー

※コメント欄より
下記を実行したときにどのように出力されるでしょうか。
これによってツイートの検索結果がゼロのためうまく行っていないように見えるだけなのか、はたまたなにかエラーが発生しているのかがわかる可能性があります。

js

1// ベアラートークンと認証用インスタンス 2 3var bearerToken = '      ' 4var twitter = TwitterWebService.getInstance( 5 '      ', // 作成したアプリケーションのConsumer Key 6 '            ' // 作成したアプリケーションのConsumer Secret 7); 8var userID = '         ' // Twitter ユーザID 9 10// 認証周り 11function authorize() { twitter.authorize(); } // 認証 12function reset() { twitter.reset(); } // 認証解除 13function authCallback(request) { return twitter.authCallback(request); } // 認証後のコールバック 14 15// シートを取得 16var sheetData = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1"); // 「シート1」はシート名 17 18// APIコール時のオプション(GET) 19const getOption = { 20 method: 'get', 21 contentType: 'application/json', 22 muteHttpExceptions: true, 23 headers: { Authorization: 'Bearer ' + bearerToken } 24} 25// APIコール時のオプション(POST) 26const postOption = { 27 method: 'post', 28 contentType: 'application/json', 29 muteHttpExceptions: true, 30 headers: { Authorization: 'Bearer ' + bearerToken }, 31} 32 33function main() { 34 var service = twitter.getService(); 35 36 var searchWords = pickUpSearchWords(); 37 for (var i = 0; i < searchWords.length; i++) { 38 var searchWord = searchWords[i][0]; 39 var type = searchWords[i][1]; 40 var lastTweetId = searchWords[i][2]; 41 42 var tweetList = findTweets(service, searchWord, lastTweetId); 43 // 追加 44 console.log(`main@tweetList:` + tweetList); 45 if (tweetList == null) { 46 continue 47 } 48 49 for (var j = 0; j < tweetList.length; j++) { 50 var tweet = tweetList[j]; 51 if (tweet.id > lastTweetId) { 52 lastTweetId = tweet.id; 53 } 54 if (type == 'いいね') { 55 putFavorite(service, tweet); 56 } else if (type == 'RT') { 57 putRetweet(service, tweet); 58 } 59 } 60 61 var titleRow = 1; 62 var lastTweetIdCol = 3; 63 var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); 64 // 追加 65 console.log(`main@updateCell.setValue(lastTweetId:` + lastTweetId + ')'); 66 updateCell.setValue(lastTweetId); 67 } 68} 69 70// 検索ワードをスプレッドシートから取得する 71function pickUpSearchWords() { 72 var titleRow = 1; 73 var startRow = 1 + titleRow; 74 var startCol = 1; 75 var endRow = sheetData.getLastRow() - titleRow; 76 var endCol = 3; 77 // 追加 78 console.log(`pickUpSearchWords@sheetData.~.getValues():` 79 + sheetData.getRange(startRow, startCol, endRow, endCol).getValues()); 80 return sheetData.getRange(startRow, startCol, endRow, endCol).getValues(); 81} 82 83// ツイートを検索する 84function findTweets(service, searchWord, lastTweetId) { 85 // API URL 86 var getPoint = 'https://api.twitter.com/2/tweets/search/recent?query=' 87 88 // 検索キーワードとパラメータ 89 var keyWord = encodeURIComponent(searchWord) 90 var params = '&tweet.fields=author_id,id,text,created_at&max_results=20' 91 params += '&since_id=' + lastTweetId 92 93 // アクセスURL組み立て 94 var url = getPoint + keyWord + params 95 96 var response = service.fetch(url, getOption); 97 var result = JSON.parse(response) 98 // 追加 99 console.log(`findTweets@result.data:` + result.data); 100 return result.data 101} 102 103// いいね 104function putFavorite(service, tweet) { 105 var targetTweet = { 'tweet_id': tweet.id } 106 // 追加 107 console.log('putFavorite@targetTweet:' + targetTweet + ')'); 108 109 postOption.payload = JSON.stringify(targetTweet) 110 var result = service.fetch('https://api.twitter.com/2/users/' + userID + '/likes', postOption); 111 console.log('putFavorite@result:' + result.getContentText()); 112} 113 114// リツイート 115function putRetweet(service, tweet) { 116 var targetTweet = { 'tweet_id': tweet.id } 117 // 追加 118 console.log('putRetweet@targetTweet:' + targetTweet + ')'); 119 120 postOption.payload = JSON.stringify(targetTweet) 121 var result = service.fetch('https://api.twitter.com/2/users/' + userID + '/retweets', postOption); 122 console.log('putRetweet@result:' + result.getContentText()); 123}

投稿2022/06/28 12:06

編集2022/06/30 15:05
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問