回答編集履歴
7
answer
CHANGED
@@ -82,7 +82,7 @@
|
|
82
82
|
|
83
83
|
下記のコードでは、putRetweet関数や、putFavorite関数を直接実行してしまった場合、引数tweetが空かどうかを判定し、空の場合はreturnすることでエラー停止を回避するように修正しました。
|
84
84
|
|
85
|
-
このプログラムは
|
85
|
+
このプログラムは(一度authorize()関数を実行してTwitter認証が完了していれば)基本的に、**main()を実行する**だけでよいです。(main()以外を実行しても正常に動作しません)
|
86
86
|
|
87
87
|
【回答コード(全体)】
|
88
88
|
```js
|
6
answer
CHANGED
@@ -58,6 +58,7 @@
|
|
58
58
|
|
59
59
|
下記コードについて、エラーが発生しても停止せずエラー内容を表示するように修正しました。
|
60
60
|
(try ~ catch文で囲む)
|
61
|
+
|
61
62
|
---
|
62
63
|
|
63
64
|
|
@@ -79,8 +80,9 @@
|
|
79
80
|
元のコードで、putRetweet関数や、putFavorite関数を直接実行すると、引数tweetが空っぽ(undefined)のため、
|
80
81
|
「undefined からプロパティ「id_str」を読み取れません。」というエラーが発生します。
|
81
82
|
|
82
|
-
下記のコードでは、putRetweet関数や、putFavorite関数を実行した
|
83
|
+
下記のコードでは、putRetweet関数や、putFavorite関数を直接実行してしまった場合、引数tweetが空かどうかを判定し、空の場合はreturnすることでエラー停止を回避するように修正しました。
|
83
84
|
|
85
|
+
このプログラムは、基本的に、**main()だけを実行する**ようにしてください。(main()以外を実行しても正常に動作しません)
|
84
86
|
|
85
87
|
【回答コード(全体)】
|
86
88
|
```js
|
5
追加
answer
CHANGED
@@ -49,6 +49,40 @@
|
|
49
49
|
|
50
50
|
なお、**一定時間内に大量にキーワード検索や、RT・Fav(「いいね」)を実行した場合、API制限がかかってしばらく検索・RT・Favができなく場合があるので、実行する際は注意してください。**
|
51
51
|
|
52
|
+
# 追記2
|
53
|
+
|
54
|
+
> 該当部分に、コードを追加したところ、新たにエラーが出てしまったので、
|
55
|
+
|
56
|
+
すでにリツイート済みのツイートに重ねてリツイートしようとしたり、
|
57
|
+
すでにいいねが済んでいるツイートに、重ねて「いいね」をしようとしたため、エラーで停止しています。
|
58
|
+
|
59
|
+
下記コードについて、エラーが発生しても停止せずエラー内容を表示するように修正しました。
|
60
|
+
(try ~ catch文で囲む)
|
61
|
+
---
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
> ① 検索ワードをスプレッドシートから取得する
|
66
|
+
> ② 検索ワードをTwitterで検索する(たくさん取れてしまうので「直近10分間」の検索を10分毎に行う)
|
67
|
+
> ③ ツイートに いいね or RT をする
|
68
|
+
> ④ 他に検索ワードがあれば②に戻る
|
69
|
+
> の順番通りにコードを並べる必要があるのかと思い
|
70
|
+
|
71
|
+
実際のところ、順番通りに並べる必要はありません。
|
72
|
+
呼び出し元より後ろにある関数であっても、**自動的に探して認識してくれます。**
|
73
|
+
今回のエラーの原因は、上述のようにリツイート済みのツイートに重ねてリツイートしようとしたためです。
|
74
|
+
|
75
|
+
さらに、putRetweet関数や、putFavorite関数を直接実行されようとしたのではないでしょうか。
|
76
|
+
|
77
|
+
putRetweet関数や、putFavorite関数は、main()関数から呼び出される専用の関数です。
|
78
|
+
|
79
|
+
元のコードで、putRetweet関数や、putFavorite関数を直接実行すると、引数tweetが空っぽ(undefined)のため、
|
80
|
+
「undefined からプロパティ「id_str」を読み取れません。」というエラーが発生します。
|
81
|
+
|
82
|
+
下記のコードでは、putRetweet関数や、putFavorite関数を実行したときに、引数tweetが空かどうかを判定し、空の場合はreturnすることでエラー停止を回避するように修正しました。
|
83
|
+
|
84
|
+
|
85
|
+
【回答コード(全体)】
|
52
86
|
```js
|
53
87
|
//認証用インスタンスの生成
|
54
88
|
var twitter = TwitterWebService.getInstance(
|
@@ -180,16 +214,40 @@
|
|
180
214
|
// いいね を付ける
|
181
215
|
// 【参考】 https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-favorites-create
|
182
216
|
function putFavorite(tweet) {
|
217
|
+
// tweetが空っぽ(undefined)の場合はreturn
|
218
|
+
if (typeof tweet === "undefined") return;
|
183
219
|
var service = twitter.getService();
|
184
220
|
var options = { method: 'post' };
|
221
|
+
// エラーが発生したら、catchのブロックにジャンプ。
|
222
|
+
try {
|
185
|
-
|
223
|
+
service.fetch('https://api.twitter.com/1.1/favorites/create.json?id=' + tweet.id_str, options);
|
224
|
+
} catch(e) {
|
225
|
+
// メッセージに「"code":139」という文字列が含まれている場合は、内容を表示
|
226
|
+
if (e && e.message.indexOf('{"code":139') > -1) {
|
227
|
+
Logger.log("このツイートにはすでに「いいね」を押しています。\n[id] "+tweet.id_str +" [username]" + tweet.user.name + "\n[tweet]「"+ tweet.text.slice(0, 40) + "...」");
|
228
|
+
} else {
|
229
|
+
Logger.log("エラー:" + e.message)
|
230
|
+
}
|
231
|
+
}
|
186
232
|
}
|
187
233
|
|
188
234
|
// RT を付ける
|
189
235
|
// 【参考】 https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-retweet-id
|
190
236
|
function putRetweet(tweet) {
|
237
|
+
// tweetが空っぽ(undefined)の場合はreturn
|
238
|
+
if (typeof tweet === "undefined") return;
|
191
239
|
var service = twitter.getService();
|
192
240
|
var options = { method: 'post' };
|
241
|
+
// エラーが発生したら、catchのブロックにジャンプ。
|
242
|
+
try {
|
193
|
-
|
243
|
+
service.fetch('https://api.twitter.com/1.1/statuses/retweet/' + tweet.id_str +'.json', options);
|
244
|
+
} catch(e) {
|
245
|
+
// メッセージに「"code":327」という文字列が含まれている場合は、内容を表示
|
246
|
+
if (e && e.message.indexOf('{"code":327') > -1) {
|
247
|
+
Logger.log("このツイートはすでにリツイート済みです。\n[id] "+tweet.id_str +" [username]" + tweet.user.name + "\n[tweet]「"+ tweet.text.slice(0, 40) + "...」");
|
248
|
+
} else {
|
249
|
+
Logger.log("エラー:" + e.message)
|
250
|
+
}
|
251
|
+
}
|
194
252
|
}
|
195
253
|
```
|
4
answer
CHANGED
@@ -45,7 +45,7 @@
|
|
45
45
|
|
46
46
|
下記を保存の上、シート1のB列を「RT」、C列を空欄、D列を10等にして実行すると、
|
47
47
|
検索ワードを含むツイートが自動でRTされ、C列は最新のlastTweetIdに更新されると思います。
|
48
|
-
(D列が空欄だと
|
48
|
+
(※実行時にシート1のD列にも数字を入れる必要があります。D列が空欄だとRTやいいねが実行されません)
|
49
49
|
|
50
50
|
なお、**一定時間内に大量にキーワード検索や、RT・Fav(「いいね」)を実行した場合、API制限がかかってしばらく検索・RT・Favができなく場合があるので、実行する際は注意してください。**
|
51
51
|
|
3
answer
CHANGED
@@ -40,7 +40,7 @@
|
|
40
40
|
とのことですが、これはメッセージの通り、putRetweetという関数がどこにも定義されていないのにputRetweetを呼び出そうとしたからです。
|
41
41
|
|
42
42
|
下記のように、putRetweetやputFavoritesを実装する必要があります。
|
43
|
-
(下記
|
43
|
+
(下記ソースコードの「以下追加」以降の部分)
|
44
44
|
(前の御質問のコメント記載のソースを参考にして修正)
|
45
45
|
|
46
46
|
下記を保存の上、シート1のB列を「RT」、C列を空欄、D列を10等にして実行すると、
|
2
追記
answer
CHANGED
@@ -25,4 +25,171 @@
|
|
25
25
|
一定時間経過しないと、APIでは当該ツイート(直近で取得したtweetIdより後のツイート)が取得できないことがあります。
|
26
26
|
|
27
27
|
(なお、上記の画像の場合「Twitter」という単語を含むツイートは世界中で常時つぶやかれているため、
|
28
|
-
10秒間隔で実行しても、シート1上のlastTweetIdは実行する度更新されます)
|
28
|
+
10秒間隔で実行しても、シート1上のlastTweetIdは実行する度更新されます)
|
29
|
+
|
30
|
+
----
|
31
|
+
# 追記(コメントより)
|
32
|
+
|
33
|
+
> 20:39:36 お知らせ 実行開始
|
34
|
+
> 20:39:37 エラー
|
35
|
+
> ReferenceError: 「putRetweet」が定義されていません。
|
36
|
+
> main @ コード.gs:94
|
37
|
+
>
|
38
|
+
> というエラーが出てしまいました。
|
39
|
+
|
40
|
+
とのことですが、これはメッセージの通り、putRetweetという関数がどこにも定義されていないのにputRetweetを呼び出そうとしたからです。
|
41
|
+
|
42
|
+
下記のように、putRetweetやputFavoritesを実装する必要があります。
|
43
|
+
(下記シースコードの「以下追加」以降の部分)
|
44
|
+
(前の御質問のコメント記載のソースを参考にして修正)
|
45
|
+
|
46
|
+
下記を保存の上、シート1のB列を「RT」、C列を空欄、D列を10等にして実行すると、
|
47
|
+
検索ワードを含むツイートが自動でRTされ、C列は最新のlastTweetIdに更新されると思います。
|
48
|
+
(D列が空欄だとなにも実行されません)
|
49
|
+
|
50
|
+
なお、**一定時間内に大量にキーワード検索や、RT・Fav(「いいね」)を実行した場合、API制限がかかってしばらく検索・RT・Favができなく場合があるので、実行する際は注意してください。**
|
51
|
+
|
52
|
+
```js
|
53
|
+
//認証用インスタンスの生成
|
54
|
+
var twitter = TwitterWebService.getInstance(
|
55
|
+
' ',//API Key
|
56
|
+
' '//API secret key
|
57
|
+
);
|
58
|
+
|
59
|
+
// 認証
|
60
|
+
function authorize() {
|
61
|
+
twitter.authorize();
|
62
|
+
}
|
63
|
+
|
64
|
+
// 認証解除
|
65
|
+
function reset() {
|
66
|
+
twitter.reset();
|
67
|
+
}
|
68
|
+
|
69
|
+
// 認証後のコールバック
|
70
|
+
function authCallback(request) {
|
71
|
+
return twitter.authCallback(request);
|
72
|
+
}
|
73
|
+
|
74
|
+
// セルを取得
|
75
|
+
var sheetData = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1"); // 「シート1」はシート名
|
76
|
+
|
77
|
+
/**
|
78
|
+
いいね or RT 機能
|
79
|
+
① 検索ワードをスプレッドシートから取得する
|
80
|
+
② 検索ワードをTwitterで検索する(たくさん取れてしまうので「直近10分間」の検索を10分毎に行う)
|
81
|
+
③ ツイートに いいね or RT をする
|
82
|
+
④ 他に検索ワードがあれば②に戻る
|
83
|
+
*/
|
84
|
+
// ツイートを検索する
|
85
|
+
// 【参考】 https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets
|
86
|
+
function findTweets (searchWord, lastTweetId) {
|
87
|
+
var service = twitter.getService();
|
88
|
+
var query = {
|
89
|
+
q: searchWord, // 検索ワード
|
90
|
+
lang: 'ja', // 日本語検索
|
91
|
+
locale: 'ja', // 日本限定で検索
|
92
|
+
result_type: 'recent', // 直近のツイートを検索
|
93
|
+
since_id: lastTweetId // これ以前のツイートは見ない
|
94
|
+
}
|
95
|
+
// 検索の内容を queryStr にまとめていく
|
96
|
+
var queryStr = '';
|
97
|
+
for (var key in query) {
|
98
|
+
// URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする
|
99
|
+
queryStr += key + '=' + encodeURIComponent(query[key]) + '&'
|
100
|
+
}
|
101
|
+
// &が余計に付いているので削除しておく
|
102
|
+
var queryStr = queryStr.slice(0, -1);
|
103
|
+
|
104
|
+
var response = service.fetch('https://api.twitter.com/1.1/search/tweets.json?' + queryStr);
|
105
|
+
var result = JSON.parse(response)
|
106
|
+
return result.statuses
|
107
|
+
}
|
108
|
+
|
109
|
+
function main () {
|
110
|
+
// ① 検索ワードをスプレッドシートから取得する
|
111
|
+
var searchWords = pickUpSearchWords();
|
112
|
+
|
113
|
+
// searchWordsの中身は
|
114
|
+
// [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'],....,]
|
115
|
+
// という形式になっているので1つずつ見ていく
|
116
|
+
for (var i = 0, il = searchWords.length; i < il; i++ ) {
|
117
|
+
var searchWord = searchWords[i][0];
|
118
|
+
var type = searchWords[i][1];
|
119
|
+
var lastTweetId = searchWords[i][2];
|
120
|
+
|
121
|
+
// !!!!!! 追加 !!!!!!!
|
122
|
+
var limit = searchWords[i][3];
|
123
|
+
|
124
|
+
// ② Twitterで検索する
|
125
|
+
var tweetList = findTweets(searchWord, lastTweetId);
|
126
|
+
|
127
|
+
var count = 0
|
128
|
+
// ③ 複数件ツイートを取得されるので for を使って1つずつツイートを取り出し いいね or RT をする
|
129
|
+
for (var j = 0, jl = tweetList.length; j < jl; j++ ) {
|
130
|
+
var tweet = tweetList[j];
|
131
|
+
if (tweet.id_str > lastTweetId) {
|
132
|
+
lastTweetId = tweet.id_str;
|
133
|
+
}
|
134
|
+
|
135
|
+
// !!!!!! 追加 !!!!!!!
|
136
|
+
if (count == limit) {
|
137
|
+
// lastTweetIdを出来るだけ新しくしたい場合は continue;
|
138
|
+
// 次回以降の実行で続きのツイートを使いたい場合は break;
|
139
|
+
break;
|
140
|
+
}
|
141
|
+
count++;
|
142
|
+
|
143
|
+
if (type == 'いいね') {
|
144
|
+
putFavorite (tweet);
|
145
|
+
} else if (type == 'RT') {
|
146
|
+
putRetweet (tweet);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
// 最新のツイートIDを保存して重複処理をしないようにする
|
151
|
+
var titleRow = 1; // 『検索ワード』とか書いている部分の行数
|
152
|
+
var lastTweetIdCol = 3; // 『最終TweetId』の列までなので3列目まで
|
153
|
+
var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); // i = 0 の時1行目なので+1してる
|
154
|
+
updateCell.setValue(lastTweetId);
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
// 検索ワードをスプレッドシートから取得する
|
159
|
+
function pickUpSearchWords () {
|
160
|
+
var titleRow = 1; // 『検索ワード』とか書いている部分の行数
|
161
|
+
var startRow = 1 + titleRow; // 1行目は『検索ワード』とか書いているので2行目から
|
162
|
+
var startCol = 1;
|
163
|
+
var endRow = sheetData.getLastRow() - titleRow; // 最後の行まで(2行目から始まっているので-1している)
|
164
|
+
|
165
|
+
// !!!!!! 変更 !!!!!!!
|
166
|
+
var endCol = 4; // 『実行回数』の列までなので4列目まで
|
167
|
+
|
168
|
+
// 一括で取得する
|
169
|
+
var cells = sheetData.getRange(startRow, startCol, endRow, endCol).getValues();
|
170
|
+
|
171
|
+
// cellsの中身は
|
172
|
+
// [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] ,....,]
|
173
|
+
// という形式になる
|
174
|
+
|
175
|
+
return cells;
|
176
|
+
}
|
177
|
+
|
178
|
+
// ------------------------------以下追加------------------------------
|
179
|
+
|
180
|
+
// いいね を付ける
|
181
|
+
// 【参考】 https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-favorites-create
|
182
|
+
function putFavorite(tweet) {
|
183
|
+
var service = twitter.getService();
|
184
|
+
var options = { method: 'post' };
|
185
|
+
service.fetch('https://api.twitter.com/1.1/favorites/create.json?id=' + tweet.id_str, options);
|
186
|
+
}
|
187
|
+
|
188
|
+
// RT を付ける
|
189
|
+
// 【参考】 https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-retweet-id
|
190
|
+
function putRetweet(tweet) {
|
191
|
+
var service = twitter.getService();
|
192
|
+
var options = { method: 'post' };
|
193
|
+
service.fetch('https://api.twitter.com/1.1/statuses/retweet/' + tweet.id_str +'.json', options);
|
194
|
+
}
|
195
|
+
```
|
1
answer
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
|
17
17
|
(その背景として、シート1上の検索ワードが、それほど頻繁につぶやかれている単語ではない、ということが考えられます)
|
18
18
|
|
19
|
-
初回、lastTweetID(C列)を空欄にしてスクリプトを実行すると、
|
19
|
+
初回、lastTweetID(C列)を空欄または0にしてスクリプトを実行すると、
|
20
20
|
lastTweetIdは取得したツイートの最大IDに更新されます。
|
21
21
|
|
22
22
|
ただし、Twitter APIのデータ反映にはタイムラグがあります。
|