回答編集履歴

7

2021/11/23 07:51

投稿

退会済みユーザー
test CHANGED
@@ -166,7 +166,7 @@
166
166
 
167
167
   
168
168
 
169
- このプログラムは基本的に、**main()だけを実行する**ようにしてください。(main()以外を実行しても正常に動作しません)
169
+ このプログラムは(一度authorize()関数を実行してTwitter認証が完了していれば)基本的に、**main()を実行する**だけでよいです。(main()以外を実行しても正常に動作しません)
170
170
 
171
171
   
172
172
 

6

2021/11/23 07:51

投稿

退会済みユーザー
test CHANGED
@@ -118,6 +118,8 @@
118
118
 
119
119
  (try ~ catch文で囲む)
120
120
 
121
+  
122
+
121
123
  ---
122
124
 
123
125
   
@@ -160,9 +162,11 @@
160
162
 
161
163
 
162
164
 
163
- 下記のコードでは、putRetweet関数や、putFavorite関数を実行したときに、引数tweetが空かどうかを判定し、空の場合はreturnすることでエラー停止を回避するように修正しました。
165
+ 下記のコードでは、putRetweet関数や、putFavorite関数を直接実行してしまっ場合、引数tweetが空かどうかを判定し、空の場合はreturnすることでエラー停止を回避するように修正しました。
166
+
167
+  
168
+
164
-
169
+ このプログラムは、基本的に、**main()だけを実行する**ようにしてください。(main()以外を実行しても正常に動作しません)
165
-  
166
170
 
167
171
   
168
172
 

5

追加

2021/11/22 14:37

投稿

退会済みユーザー
test CHANGED
@@ -100,6 +100,74 @@
100
100
 
101
101
 
102
102
 
103
+ # 追記2
104
+
105
+
106
+
107
+ > 該当部分に、コードを追加したところ、新たにエラーが出てしまったので、
108
+
109
+
110
+
111
+ すでにリツイート済みのツイートに重ねてリツイートしようとしたり、
112
+
113
+ すでにいいねが済んでいるツイートに、重ねて「いいね」をしようとしたため、エラーで停止しています。
114
+
115
+
116
+
117
+ 下記コードについて、エラーが発生しても停止せずエラー内容を表示するように修正しました。
118
+
119
+ (try ~ catch文で囲む)
120
+
121
+ ---
122
+
123
+  
124
+
125
+  
126
+
127
+
128
+
129
+ > ① 検索ワードをスプレッドシートから取得する
130
+
131
+ > ② 検索ワードをTwitterで検索する(たくさん取れてしまうので「直近10分間」の検索を10分毎に行う)
132
+
133
+ > ③ ツイートに いいね or RT をする
134
+
135
+ > ④ 他に検索ワードがあれば②に戻る
136
+
137
+ > の順番通りにコードを並べる必要があるのかと思い
138
+
139
+
140
+
141
+ 実際のところ、順番通りに並べる必要はありません。
142
+
143
+ 呼び出し元より後ろにある関数であっても、**自動的に探して認識してくれます。**
144
+
145
+ 今回のエラーの原因は、上述のようにリツイート済みのツイートに重ねてリツイートしようとしたためです。
146
+
147
+
148
+
149
+ さらに、putRetweet関数や、putFavorite関数を直接実行されようとしたのではないでしょうか。
150
+
151
+
152
+
153
+ putRetweet関数や、putFavorite関数は、main()関数から呼び出される専用の関数です。
154
+
155
+
156
+
157
+ 元のコードで、putRetweet関数や、putFavorite関数を直接実行すると、引数tweetが空っぽ(undefined)のため、
158
+
159
+ 「undefined からプロパティ「id_str」を読み取れません。」というエラーが発生します。
160
+
161
+
162
+
163
+ 下記のコードでは、putRetweet関数や、putFavorite関数を実行したときに、引数tweetが空かどうかを判定し、空の場合はreturnすることでエラー停止を回避するように修正しました。
164
+
165
+  
166
+
167
+  
168
+
169
+ 【回答コード(全体)】
170
+
103
171
  ```js
104
172
 
105
173
  //認証用インスタンスの生成
@@ -362,11 +430,35 @@
362
430
 
363
431
  function putFavorite(tweet) {
364
432
 
433
+ // tweetが空っぽ(undefined)の場合はreturn
434
+
435
+ if (typeof tweet === "undefined") return;
436
+
365
437
  var service = twitter.getService();
366
438
 
367
439
  var options = { method: 'post' };
368
440
 
441
+ // エラーが発生したら、catchのブロックにジャンプ。
442
+
443
+ try {
444
+
369
- service.fetch('https://api.twitter.com/1.1/favorites/create.json?id=' + tweet.id_str, options);
445
+ service.fetch('https://api.twitter.com/1.1/favorites/create.json?id=' + tweet.id_str, options);
446
+
447
+ } catch(e) {
448
+
449
+ // メッセージに「"code":139」という文字列が含まれている場合は、内容を表示
450
+
451
+ if (e && e.message.indexOf('{"code":139') > -1) {
452
+
453
+ Logger.log("このツイートにはすでに「いいね」を押しています。\n[id] "+tweet.id_str +" [username]" + tweet.user.name + "\n[tweet]「"+ tweet.text.slice(0, 40) + "...」");
454
+
455
+ } else {
456
+
457
+ Logger.log("エラー:" + e.message)
458
+
459
+ }
460
+
461
+ }
370
462
 
371
463
  }
372
464
 
@@ -378,11 +470,35 @@
378
470
 
379
471
  function putRetweet(tweet) {
380
472
 
473
+ // tweetが空っぽ(undefined)の場合はreturn
474
+
475
+ if (typeof tweet === "undefined") return;
476
+
381
477
  var service = twitter.getService();
382
478
 
383
479
  var options = { method: 'post' };
384
480
 
481
+ // エラーが発生したら、catchのブロックにジャンプ。
482
+
483
+ try {
484
+
385
- service.fetch('https://api.twitter.com/1.1/statuses/retweet/' + tweet.id_str +'.json', options);
485
+ service.fetch('https://api.twitter.com/1.1/statuses/retweet/' + tweet.id_str +'.json', options);
486
+
487
+ } catch(e) {
488
+
489
+ // メッセージに「"code":327」という文字列が含まれている場合は、内容を表示
490
+
491
+ if (e && e.message.indexOf('{"code":327') > -1) {
492
+
493
+ Logger.log("このツイートはすでにリツイート済みです。\n[id] "+tweet.id_str +" [username]" + tweet.user.name + "\n[tweet]「"+ tweet.text.slice(0, 40) + "...」");
494
+
495
+ } else {
496
+
497
+ Logger.log("エラー:" + e.message)
498
+
499
+ }
500
+
501
+ }
386
502
 
387
503
  }
388
504
 

4

2021/11/22 14:34

投稿

退会済みユーザー
test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
  検索ワードを含むツイートが自動でRTされ、C列は最新のlastTweetIdに更新されると思います。
94
94
 
95
- (D列が空欄だとなにも実行されません)
95
+ ※実行時にシート1のD列にも数字を入れる必要あります。D列が空欄だとRTやいいねが実行されません)
96
96
 
97
97
 
98
98
 

3

2021/11/21 17:38

投稿

退会済みユーザー
test CHANGED
@@ -82,7 +82,7 @@
82
82
 
83
83
  下記のように、putRetweetやputFavoritesを実装する必要があります。
84
84
 
85
- (下記ースコードの「以下追加」以降の部分)
85
+ (下記ースコードの「以下追加」以降の部分)
86
86
 
87
87
  (前の御質問のコメント記載のソースを参考にして修正)
88
88
 

2

追記

2021/11/21 17:34

投稿

退会済みユーザー
test CHANGED
@@ -53,3 +53,337 @@
53
53
  (なお、上記の画像の場合「Twitter」という単語を含むツイートは世界中で常時つぶやかれているため、
54
54
 
55
55
  10秒間隔で実行しても、シート1上のlastTweetIdは実行する度更新されます)
56
+
57
+
58
+
59
+ ----
60
+
61
+ # 追記(コメントより)
62
+
63
+
64
+
65
+ > 20:39:36 お知らせ 実行開始
66
+
67
+ > 20:39:37 エラー
68
+
69
+ > ReferenceError: 「putRetweet」が定義されていません。
70
+
71
+ > main @ コード.gs:94
72
+
73
+ >
74
+
75
+ > というエラーが出てしまいました。
76
+
77
+
78
+
79
+ とのことですが、これはメッセージの通り、putRetweetという関数がどこにも定義されていないのにputRetweetを呼び出そうとしたからです。
80
+
81
+
82
+
83
+ 下記のように、putRetweetやputFavoritesを実装する必要があります。
84
+
85
+ (下記シースコードの「以下追加」以降の部分)
86
+
87
+ (前の御質問のコメント記載のソースを参考にして修正)
88
+
89
+
90
+
91
+ 下記を保存の上、シート1のB列を「RT」、C列を空欄、D列を10等にして実行すると、
92
+
93
+ 検索ワードを含むツイートが自動でRTされ、C列は最新のlastTweetIdに更新されると思います。
94
+
95
+ (D列が空欄だとなにも実行されません)
96
+
97
+
98
+
99
+ なお、**一定時間内に大量にキーワード検索や、RT・Fav(「いいね」)を実行した場合、API制限がかかってしばらく検索・RT・Favができなく場合があるので、実行する際は注意してください。**
100
+
101
+
102
+
103
+ ```js
104
+
105
+ //認証用インスタンスの生成
106
+
107
+ var twitter = TwitterWebService.getInstance(
108
+
109
+ '         ',//API Key
110
+
111
+ '         '//API secret key
112
+
113
+ );
114
+
115
+
116
+
117
+ // 認証
118
+
119
+ function authorize() {
120
+
121
+ twitter.authorize();
122
+
123
+ }
124
+
125
+
126
+
127
+ // 認証解除
128
+
129
+ function reset() {
130
+
131
+ twitter.reset();
132
+
133
+ }
134
+
135
+
136
+
137
+ // 認証後のコールバック
138
+
139
+ function authCallback(request) {
140
+
141
+ return twitter.authCallback(request);
142
+
143
+ }
144
+
145
+
146
+
147
+ // セルを取得
148
+
149
+ var sheetData = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1"); // 「シート1」はシート名
150
+
151
+
152
+
153
+ /**
154
+
155
+ いいね or RT 機能
156
+
157
+ ① 検索ワードをスプレッドシートから取得する
158
+
159
+ ② 検索ワードをTwitterで検索する(たくさん取れてしまうので「直近10分間」の検索を10分毎に行う)
160
+
161
+ ③ ツイートに いいね or RT をする
162
+
163
+ ④ 他に検索ワードがあれば②に戻る
164
+
165
+ */
166
+
167
+ // ツイートを検索する
168
+
169
+ // 【参考】 https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets
170
+
171
+ function findTweets (searchWord, lastTweetId) {
172
+
173
+ var service = twitter.getService();
174
+
175
+ var query = {
176
+
177
+ q: searchWord, // 検索ワード
178
+
179
+ lang: 'ja', // 日本語検索
180
+
181
+ locale: 'ja', // 日本限定で検索
182
+
183
+ result_type: 'recent', // 直近のツイートを検索
184
+
185
+ since_id: lastTweetId // これ以前のツイートは見ない
186
+
187
+ }
188
+
189
+ // 検索の内容を queryStr にまとめていく
190
+
191
+ var queryStr = '';
192
+
193
+ for (var key in query) {
194
+
195
+ // URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする
196
+
197
+ queryStr += key + '=' + encodeURIComponent(query[key]) + '&'
198
+
199
+ }
200
+
201
+ // &が余計に付いているので削除しておく
202
+
203
+ var queryStr = queryStr.slice(0, -1);
204
+
205
+
206
+
207
+ var response = service.fetch('https://api.twitter.com/1.1/search/tweets.json?' + queryStr);
208
+
209
+ var result = JSON.parse(response)
210
+
211
+ return result.statuses
212
+
213
+ }
214
+
215
+
216
+
217
+ function main () {
218
+
219
+ // ① 検索ワードをスプレッドシートから取得する
220
+
221
+ var searchWords = pickUpSearchWords();
222
+
223
+
224
+
225
+ // searchWordsの中身は
226
+
227
+ // [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'],....,]
228
+
229
+ // という形式になっているので1つずつ見ていく
230
+
231
+ for (var i = 0, il = searchWords.length; i < il; i++ ) {
232
+
233
+ var searchWord = searchWords[i][0];
234
+
235
+ var type = searchWords[i][1];
236
+
237
+ var lastTweetId = searchWords[i][2];
238
+
239
+
240
+
241
+ // !!!!!! 追加 !!!!!!!
242
+
243
+ var limit = searchWords[i][3];
244
+
245
+
246
+
247
+ // ② Twitterで検索する
248
+
249
+ var tweetList = findTweets(searchWord, lastTweetId);
250
+
251
+
252
+
253
+ var count = 0
254
+
255
+ // ③ 複数件ツイートを取得されるので for を使って1つずつツイートを取り出し いいね or RT をする
256
+
257
+ for (var j = 0, jl = tweetList.length; j < jl; j++ ) {
258
+
259
+ var tweet = tweetList[j];
260
+
261
+ if (tweet.id_str > lastTweetId) {
262
+
263
+ lastTweetId = tweet.id_str;
264
+
265
+ }
266
+
267
+
268
+
269
+ // !!!!!! 追加 !!!!!!!
270
+
271
+ if (count == limit) {
272
+
273
+ // lastTweetIdを出来るだけ新しくしたい場合は continue;
274
+
275
+ // 次回以降の実行で続きのツイートを使いたい場合は break;
276
+
277
+ break;
278
+
279
+ }
280
+
281
+ count++;
282
+
283
+
284
+
285
+ if (type == 'いいね') {
286
+
287
+ putFavorite (tweet);
288
+
289
+ } else if (type == 'RT') {
290
+
291
+ putRetweet (tweet);
292
+
293
+ }
294
+
295
+ }
296
+
297
+
298
+
299
+ // 最新のツイートIDを保存して重複処理をしないようにする
300
+
301
+ var titleRow = 1; // 『検索ワード』とか書いている部分の行数
302
+
303
+ var lastTweetIdCol = 3; // 『最終TweetId』の列までなので3列目まで
304
+
305
+ var updateCell = sheetData.getRange(i + 1 + titleRow, lastTweetIdCol, 1, 1); // i = 0 の時1行目なので+1してる
306
+
307
+ updateCell.setValue(lastTweetId);
308
+
309
+ }
310
+
311
+ }
312
+
313
+
314
+
315
+ // 検索ワードをスプレッドシートから取得する
316
+
317
+ function pickUpSearchWords () {
318
+
319
+ var titleRow = 1; // 『検索ワード』とか書いている部分の行数
320
+
321
+ var startRow = 1 + titleRow; // 1行目は『検索ワード』とか書いているので2行目から
322
+
323
+ var startCol = 1;
324
+
325
+ var endRow = sheetData.getLastRow() - titleRow; // 最後の行まで(2行目から始まっているので-1している)
326
+
327
+
328
+
329
+ // !!!!!! 変更 !!!!!!!
330
+
331
+ var endCol = 4; // 『実行回数』の列までなので4列目まで
332
+
333
+
334
+
335
+ // 一括で取得する
336
+
337
+ var cells = sheetData.getRange(startRow, startCol, endRow, endCol).getValues();
338
+
339
+
340
+
341
+ // cellsの中身は
342
+
343
+ // [ [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] , [ '投稿内容', 'いいね or RT', '最終TweetId', '実行回数'] ,....,]
344
+
345
+ // という形式になる
346
+
347
+
348
+
349
+ return cells;
350
+
351
+ }
352
+
353
+
354
+
355
+ // ------------------------------以下追加------------------------------
356
+
357
+
358
+
359
+ // いいね を付ける
360
+
361
+ // 【参考】 https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-favorites-create
362
+
363
+ function putFavorite(tweet) {
364
+
365
+ var service = twitter.getService();
366
+
367
+ var options = { method: 'post' };
368
+
369
+ service.fetch('https://api.twitter.com/1.1/favorites/create.json?id=' + tweet.id_str, options);
370
+
371
+ }
372
+
373
+
374
+
375
+ // RT を付ける
376
+
377
+ // 【参考】 https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-retweet-id
378
+
379
+ function putRetweet(tweet) {
380
+
381
+ var service = twitter.getService();
382
+
383
+ var options = { method: 'post' };
384
+
385
+ service.fetch('https://api.twitter.com/1.1/statuses/retweet/' + tweet.id_str +'.json', options);
386
+
387
+ }
388
+
389
+ ```

1

2021/11/21 17:33

投稿

退会済みユーザー
test CHANGED
@@ -34,7 +34,7 @@
34
34
 
35
35
 
36
36
 
37
- 初回、lastTweetID(C列)を空欄にしてスクリプトを実行すると、
37
+ 初回、lastTweetID(C列)を空欄または0にしてスクリプトを実行すると、
38
38
 
39
39
  lastTweetIdは取得したツイートの最大IDに更新されます。
40
40