回答編集履歴

4

2021/08/24 07:36

投稿

退会済みユーザー
test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- 日付を質問する時は、この関数に、表示させたいメッセージと一緒に取得したリプライトークンを渡すようにします。
5
+ 日付を質問する時は、この関数に、表示させたいメッセージと一緒にリプライトークンを渡すようにします。
6
6
 
7
7
 
8
8
 

3

修正

2021/08/24 07:36

投稿

退会済みユーザー
test CHANGED
@@ -1,417 +1,405 @@
1
- datetime picker表示させる場合は、リプライではなくプッシュメッセージ送信する必要があります。
1
+ 下記のコード例では、datetime picker表示用に新たにpushDatePickerいう関数を作っます。
2
-
3
- プッシュメッセージ送信時にはユーザーIDが必要となるため
2
+
4
-
3
+
4
+
5
- doPostで受けたイベンオブジェトから、送信先のユーザーID取得ておきます。
5
+ 日付を質問する時は、この関数に、表示させたいメッセージと一緒に得しリプライト渡すようにします。
6
+
7
+
6
8
 
7
9
  ```js
8
10
 
11
+ //開始日時の質問
12
+
9
- var userId = event.source.userId;
13
+ pushDatePicker("開始日を入力してください", replyToken);
10
14
 
11
15
  ```
12
16
 
13
17
 
14
18
 
19
+ ユーザーがdatetime pickerを利用して日付を入力したときにGASに返ってくるデータは、リプライデータと構造が異なるため、冒頭で条件分岐しています。
20
+
15
- 下記のコード例では、datetime picker表示用に新pushDatePickerとい関数を作っています。
21
+ datetime picker経由で入力されデータか否かは、イベントタイプがpostbackかどかで判断できます。
16
-
17
-
18
-
22
+
19
- 日付を質問する時は、この関数に、メッセージと一緒に取得しザーIDを渡すようにします。
23
+ (ここでは、イベントタイプが"postback"であれば datetime picker経由で入力され
24
+
25
+ そうでなければ、通常のリプライデータ)
20
26
 
21
27
 
22
28
 
23
29
  ```js
24
30
 
31
+ var messageText = "";
32
+
33
+ if (eventtype == "postback") {
34
+
35
+ messageText = event.postback.params.datetime;
36
+
37
+ } else {
38
+
39
+ messageText = event.message.text;
40
+
41
+ }
42
+
43
+ ```
44
+
45
+
46
+
47
+ また、datetime pickerを利用して入力された日付時刻データは「2021-08-24T12:34」のような形式になっているため
48
+
49
+ この形式にマッチするように正規表現のパターンも変えておく必要があります。
50
+
51
+
52
+
53
+ ```js
54
+
55
+ var dateExp2 = /(\d+)-(\d+)T\d+:\d+/;
56
+
57
+ ```
58
+
59
+
60
+
61
+ pushDatePicker関数で記事のコードから変えたのは、
62
+
63
+ ・初期値を現在日時とするようにした。 (`"initial": Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy-MM-dd'T'HH:mm"),`)
64
+
65
+ ・メッセージを変数にした
66
+
67
+ ・最大・最小は不要なのでコメントアウト
68
+
69
+ 等です。
70
+
71
+
72
+
73
+ ---
74
+
75
+
76
+
77
+ 全体は下記のようになります。
78
+
79
+ ```js
80
+
81
+ var dateExp2 = /(\d+)-(\d+)T\d+:\d+/;
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+ //受け取ったメッセージの処理
90
+
91
+ function doPost(e) {
92
+
93
+ var event = JSON.parse(e.postData.contents).events[0]
94
+
95
+ var replyToken = event.replyToken;
96
+
97
+ var eventtype = event.type;
98
+
99
+ if (typeof replyToken === 'undefined') {
100
+
101
+ return;
102
+
103
+ }
104
+
105
+ var messageText = "";
106
+
107
+ if (eventtype == "postback") {
108
+
109
+ messageText = event.postback.params.datetime;
110
+
111
+ } else {
112
+
113
+ messageText = event.message.text;
114
+
115
+ }
116
+
117
+ var cache = CacheService.getScriptCache();
118
+
119
+ var type = cache.get("type");
120
+
121
+
122
+
123
+ if (type === null) {
124
+
125
+ //予定の追加
126
+
127
+ if (messageText === "予定の追加") {
128
+
129
+ cache.put("type", 1);
130
+
25
131
  //開始日時の質問
26
132
 
27
- pushDatePicker("開始日を入力してください", userId);
133
+ pushDatePicker("開始日を入力してください", replyToken);
134
+
135
+ //今日、7日間の予定の取得
136
+
137
+ } else if (messageText.match("今日の予定")) {
138
+
139
+ reply(replyToken, getEvents());
140
+
141
+ } else if (messageText.match("今週の予定")) {
142
+
143
+ reply(replyToken, notifyWeekly());
144
+
145
+ } else {
146
+
147
+ //処理方法 の返答
148
+
149
+ replyPlans(replyToken, "「予定の追加」で予定追加します。", "「今日の予定」で今日の予定をお知らせします。", "「今週の予定」で7日間の予定をお知らせします。");
150
+
151
+ }
152
+
153
+ } else {
154
+
155
+ //キャンセル処理
156
+
157
+ if (messageText === "キャンセル") {
158
+
159
+ cache.remove("type");
160
+
161
+ reply(replyToken, "予定追加のキャンセルをしました");
162
+
163
+ return;
164
+
165
+ }
166
+
167
+
168
+
169
+ switch (type) {
170
+
171
+ case "1":
172
+
173
+ //開始日時の追加
174
+
175
+ if (messageText.match(dateExp2)) {
176
+
177
+ var [matched, start_month, start_day] = messageText.match(dateExp2);
178
+
179
+ cache.put("type", 2);
180
+
181
+ cache.put("start_month", start_month);
182
+
183
+ cache.put("start_day", start_day);
184
+
185
+
186
+
187
+ //終了日時の質問
188
+
189
+ var year = new Date().getFullYear();
190
+
191
+ var startDate = new Date(year, cache.get("start_month") - 1, cache.get("start_day"));
192
+
193
+ //pushDatePicker("開始日は\n"+ EventFormat(startDate) + "\nですね。\n\n次に予定の終了日時をお知らせください。", userId);
194
+
195
+ pushDatePicker("次に終了日を入力してください。", replyToken);
196
+
197
+
198
+
199
+ break;
200
+
201
+ } else {
202
+
203
+ reply(replyToken, "予定追加処理中です。\n「キャンセル」\nで追加作業をキャンセルします。");
204
+
205
+ break;
206
+
207
+ }
208
+
209
+ case "2":
210
+
211
+ // 終了日時の追加
212
+
213
+ if (messageText.match(dateExp2)) {
214
+
215
+ var [matched, end_month, end_day] = messageText.match(dateExp2);
216
+
217
+ cache.put("type", 3);
218
+
219
+ cache.put("end_month", end_month);
220
+
221
+ cache.put("end_day", end_day);
222
+
223
+ //予定名の質問
224
+
225
+ var year = new Date().getFullYear();
226
+
227
+ var endDate = new Date(year,cache.get("end_month")-1, cache.get("end_day"));
228
+
229
+
230
+
231
+ reply(replyToken, "終了日時は\n"+EventFormat(endDate)+"\n ですね。\n\n最後に予定名を教えてください。");
232
+
233
+ break;
234
+
235
+ }else{
236
+
237
+ reply(replyToken,"予定追加処理中です。\n「キャンセル」\nで追加作業をキャンセルします。");
238
+
239
+ break;
240
+
241
+ }
242
+
243
+ case "3":
244
+
245
+ //最終確認
246
+
247
+ cache.put("type", 4);
248
+
249
+ cache.put("title", messageText);
250
+
251
+ var [title, startDate, endDate] = createData(cache);
252
+
253
+ //予定追加の確認
254
+
255
+ replyPlans(replyToken, "予定名:"+title,"開始日時:\n"+EventFormat(startDate)+"\n終了日時:\n"+
256
+
257
+ EventFormat(new Date(endDate.setDate(endDate.getDate() - 1))),
258
+
259
+ "予定を追加しますか?\n「はい」か「いいえ」でお知らせください。");
260
+
261
+ break;
262
+
263
+ case "4":
264
+
265
+ if (messageText === "はい") {
266
+
267
+ cache.remove("type");
268
+
269
+ var [title, startDate, endDate]=createData(cache);
270
+
271
+ CalendarApp.getDefaultCalendar().createAllDayEvent(title, startDate, endDate);
272
+
273
+ reply(replyToken,"お疲れ様です\nGoogleカレンダーに予定を追加しました");
274
+
275
+ } else if (messageText === "いいえ") {
276
+
277
+ cache.remove("type");
278
+
279
+ reply(replyToken, "予定の追加をキャンセルしました。");
280
+
281
+ } else {
282
+
283
+ reply(replyToken, "「はい」か「いいえ」でお答えください。");
284
+
285
+ break;
286
+
287
+ }
288
+
289
+ break;
290
+
291
+ }
292
+
293
+ }
294
+
295
+ }
296
+
297
+
298
+
299
+
300
+
301
+ function pushDatePicker(message, replyToken) {
302
+
303
+ var url = "https://api.line.me/v2/bot/message/reply";
304
+
305
+ UrlFetchApp.fetch(url, {
306
+
307
+ "headers": {
308
+
309
+ "Content-Type": "application/json; charset=UTF-8",
310
+
311
+ "Authorization": "Bearer "+ CHANNEL_ACCESS_TOKEN,
312
+
313
+ },
314
+
315
+ "method": "post",
316
+
317
+ "payload": JSON.stringify({
318
+
319
+ "replyToken": replyToken,
320
+
321
+ "messages": [
322
+
323
+ {
324
+
325
+ "type": "template",
326
+
327
+ "altText": "datetime_picker",
328
+
329
+ "template": {
330
+
331
+ "type": "buttons",
332
+
333
+ "thumbnailImageUrl": "https://placehold.jp/640x480.jpg?text=datetime_picker", // 画像のURL
334
+
335
+ "imageAspectRatio": "rectangle", // 画像のアスペクト比、「rectangle: 1.51:1」・「square: 1:1」、デフォルト値はrectangle
336
+
337
+ "imageSize": "cover", // 画像の表示形式
338
+
339
+ "imageBackgroundColor": "#FFFFFF", // 画像の背景色
340
+
341
+ "title": "メニュー",
342
+
343
+ "text": message,
344
+
345
+ "defaultAction": {
346
+
347
+ "type": "uri",
348
+
349
+ "label": "View detail",
350
+
351
+ "uri": "https://www.line.me/"
352
+
353
+ },
354
+
355
+ "actions": [
356
+
357
+ {
358
+
359
+ "type": "datetimepicker",
360
+
361
+ "label": "ここをタップ",
362
+
363
+ "data": "action=settime",
364
+
365
+ "mode": "datetime",
366
+
367
+ "initial": Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy-MM-dd'T'HH:mm"),
368
+
369
+ // "max": "2018-01-24t23:59",
370
+
371
+ // "min": "2017-12-25t00:00"
372
+
373
+ }
374
+
375
+ ]
376
+
377
+ }
378
+
379
+ }
380
+
381
+ ],
382
+
383
+ "notificationDisabled": false // trueだとユーザーに通知されない
384
+
385
+ }),
386
+
387
+ });
388
+
389
+
390
+
391
+ return// ContentService.createTextOutput(JSON.stringify({ "content": "postok"})).setMimeType(ContentService.MimeType.JSON);
392
+
393
+
394
+
395
+ }
396
+
397
+
398
+
399
+ createData(cache)他
400
+
401
+ --->略 (現状から変えなくてよいはず)
402
+
403
+
28
404
 
29
405
  ```
30
-
31
-
32
-
33
- ユーザーがdatetime pickerを利用して日付を入力したときにGASに返ってくるデータは、リプライデータと構造が異なるため、冒頭で条件分岐しています。
34
-
35
- datetime picker経由で入力されたデータか否かは、イベントタイプがpostbackかどうかで判断できます。
36
-
37
- (ここでは、イベントタイプが"postback"であれば datetime picker経由で入力されたデータ
38
-
39
- そうでなければ、通常のリプライデータ)
40
-
41
-
42
-
43
- ```js
44
-
45
- var messageText = "";
46
-
47
- if (eventtype == "postback") {
48
-
49
- messageText = event.postback.params.datetime;
50
-
51
- } else {
52
-
53
- messageText = event.message.text;
54
-
55
- }
56
-
57
- ```
58
-
59
-
60
-
61
- また、datetime pickerを利用して入力された日付時刻データは「2021-08-24T12:34」のような形式になっているため
62
-
63
- この形式にマッチするように正規表現のパターンも変えておく必要があります。
64
-
65
-
66
-
67
- ```js
68
-
69
- var dateExp2 = /(\d+)-(\d+)T\d+:\d+/;
70
-
71
- ```
72
-
73
-
74
-
75
- pushDatePicker関数で記事のコードから変えたのは、
76
-
77
- ・初期値を現在日時とするようにした。 (`"initial": Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy-MM-dd'T'HH:mm"),`)
78
-
79
- ・メッセージを変数にした
80
-
81
- ・最大・最小は不要なのでコメントアウト
82
-
83
- 等です。
84
-
85
-
86
-
87
- ---
88
-
89
-
90
-
91
- 全体は下記のようになります。
92
-
93
- ```js
94
-
95
- var dateExp2 = /(\d+)-(\d+)T\d+:\d+/;
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
- //受け取ったメッセージの処理
104
-
105
- function doPost(e) {
106
-
107
- var event = JSON.parse(e.postData.contents).events[0]
108
-
109
- var replyToken = event.replyToken;
110
-
111
- var userId = event.source.userId;
112
-
113
- var eventtype = event.type;
114
-
115
- if (typeof replyToken === 'undefined') {
116
-
117
- return;
118
-
119
- }
120
-
121
- var messageText = "";
122
-
123
- if (eventtype == "postback") {
124
-
125
- messageText = event.postback.params.datetime;
126
-
127
- } else {
128
-
129
- messageText = event.message.text;
130
-
131
- }
132
-
133
- var cache = CacheService.getScriptCache();
134
-
135
- var type = cache.get("type");
136
-
137
-
138
-
139
- if (type === null) {
140
-
141
- //予定の追加
142
-
143
- if (messageText === "予定の追加") {
144
-
145
- cache.put("type", 1);
146
-
147
- //開始日時の質問
148
-
149
- pushDatePicker("開始日を入力してください", userId);
150
-
151
- //今日、7日間の予定の取得
152
-
153
- } else if (messageText.match("今日の予定")) {
154
-
155
- reply(replyToken, getEvents());
156
-
157
- } else if (messageText.match("今週の予定")) {
158
-
159
- reply(replyToken, notifyWeekly());
160
-
161
- } else {
162
-
163
- //処理方法 の返答
164
-
165
- replyPlans(replyToken, "「予定の追加」で予定追加します。", "「今日の予定」で今日の予定をお知らせします。", "「今週の予定」で7日間の予定をお知らせします。");
166
-
167
- }
168
-
169
- } else {
170
-
171
- //キャンセル処理
172
-
173
- if (messageText === "キャンセル") {
174
-
175
- cache.remove("type");
176
-
177
- reply(replyToken, "予定追加のキャンセルをしました");
178
-
179
- return;
180
-
181
- }
182
-
183
-
184
-
185
- switch (type) {
186
-
187
- case "1":
188
-
189
- //開始日時の追加
190
-
191
- if (messageText.match(dateExp2)) {
192
-
193
- var [matched, start_month, start_day] = messageText.match(dateExp2);
194
-
195
- cache.put("type", 2);
196
-
197
- cache.put("start_month", start_month);
198
-
199
- cache.put("start_day", start_day);
200
-
201
-
202
-
203
- //終了日時の質問
204
-
205
- var year = new Date().getFullYear();
206
-
207
- var startDate = new Date(year, cache.get("start_month") - 1, cache.get("start_day"));
208
-
209
- pushDatePicker("開始日は\n"+ EventFormat(startDate) + "\nですね。\n\n次に予定の終了日時をお知らせください。", userId);
210
-
211
- break;
212
-
213
- } else {
214
-
215
- reply(replyToken, "予定追加処理中です。\n「キャンセル」\nで追加作業をキャンセルします。");
216
-
217
- break;
218
-
219
- }
220
-
221
- case "2":
222
-
223
- // 終了日時の追加
224
-
225
- if (messageText.match(dateExp2)) {
226
-
227
- var [matched, end_month, end_day] = messageText.match(dateExp2);
228
-
229
- cache.put("type", 3);
230
-
231
- cache.put("end_month", end_month);
232
-
233
- cache.put("end_day", end_day);
234
-
235
- //予定名の質問
236
-
237
- var year = new Date().getFullYear();
238
-
239
- var endDate = new Date(year,cache.get("end_month")-1, cache.get("end_day"));
240
-
241
-
242
-
243
- reply(replyToken, "終了日時は\n"+EventFormat(endDate)+"\n ですね。\n\n最後に予定名を教えてください。");
244
-
245
- break;
246
-
247
- }else{
248
-
249
- reply(replyToken,"予定追加処理中です。\n「キャンセル」\nで追加作業をキャンセルします。");
250
-
251
- break;
252
-
253
- }
254
-
255
- case "3":
256
-
257
- //最終確認
258
-
259
- cache.put("type", 4);
260
-
261
- cache.put("title", messageText);
262
-
263
- var [title, startDate, endDate] = createData(cache);
264
-
265
- //予定追加の確認
266
-
267
- replyPlans(replyToken, "予定名:"+title,"開始日時:\n"+EventFormat(startDate)+"\n終了日時:\n"+
268
-
269
- EventFormat(new Date(endDate.setDate(endDate.getDate() - 1))),
270
-
271
- "予定を追加しますか?\n「はい」か「いいえ」でお知らせください。");
272
-
273
- break;
274
-
275
- case "4":
276
-
277
- if (messageText === "はい") {
278
-
279
- cache.remove("type");
280
-
281
- var [title, startDate, endDate]=createData(cache);
282
-
283
- CalendarApp.getDefaultCalendar().createAllDayEvent(title, startDate, endDate);
284
-
285
- reply(replyToken,"お疲れ様です\nGoogleカレンダーに予定を追加しました");
286
-
287
- } else if (messageText === "いいえ") {
288
-
289
- cache.remove("type");
290
-
291
- reply(replyToken, "予定の追加をキャンセルしました。");
292
-
293
- } else {
294
-
295
- reply(replyToken, "「はい」か「いいえ」でお答えください。");
296
-
297
- break;
298
-
299
- }
300
-
301
- break;
302
-
303
- }
304
-
305
- }
306
-
307
- }
308
-
309
-
310
-
311
-
312
-
313
- function pushDatePicker(message, userId) {
314
-
315
-
316
-
317
- UrlFetchApp.fetch(url, {
318
-
319
- "headers": {
320
-
321
- "Content-Type": "application/json; charset=UTF-8",
322
-
323
- "Authorization": "Bearer "+ CHANNEL_ACCESS_TOKEN,
324
-
325
- },
326
-
327
- "method": "post",
328
-
329
- "payload": JSON.stringify({
330
-
331
- "to": userId,
332
-
333
- "messages": [
334
-
335
- {
336
-
337
- "type": "template",
338
-
339
- "altText": "datetime_picker",
340
-
341
- "template": {
342
-
343
- "type": "buttons",
344
-
345
- "thumbnailImageUrl": "https://placehold.jp/640x480.jpg?text=datetime_picker", // 画像のURL
346
-
347
- "imageAspectRatio": "rectangle", // 画像のアスペクト比、「rectangle: 1.51:1」・「square: 1:1」、デフォルト値はrectangle
348
-
349
- "imageSize": "cover", // 画像の表示形式
350
-
351
- "imageBackgroundColor": "#FFFFFF", // 画像の背景色
352
-
353
- "title": "メニュー",
354
-
355
- "text": message,
356
-
357
- "defaultAction": {
358
-
359
- "type": "uri",
360
-
361
- "label": "View detail",
362
-
363
- "uri": "https://www.line.me/"
364
-
365
- },
366
-
367
- "actions": [
368
-
369
- {
370
-
371
- "type": "datetimepicker",
372
-
373
- "label": "日時を選択してください。",
374
-
375
- "data": "action=settime",
376
-
377
- "mode": "datetime",
378
-
379
- "initial": Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy-MM-dd'T'HH:mm"),
380
-
381
- // "max": "2018-01-24t23:59",
382
-
383
- // "min": "2017-12-25t00:00"
384
-
385
- }
386
-
387
- ]
388
-
389
- }
390
-
391
- }
392
-
393
- ],
394
-
395
- "notificationDisabled": false // trueだとユーザーに通知されない
396
-
397
- }),
398
-
399
- });
400
-
401
-
402
-
403
- return// ContentService.createTextOutput(JSON.stringify({ "content": "postok"})).setMimeType(ContentService.MimeType.JSON);
404
-
405
-
406
-
407
- }
408
-
409
-
410
-
411
- createData(cache)他
412
-
413
- --->略 (現状から変えなくてよいはず)
414
-
415
-
416
-
417
- ```

2

2021/08/24 07:33

投稿

退会済みユーザー
test CHANGED
@@ -74,9 +74,9 @@
74
74
 
75
75
  pushDatePicker関数で記事のコードから変えたのは、
76
76
 
77
- ・初期値を現在日時とするようにした。
78
-
79
- メッセージ変数にした (`"initial": Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy-MM-dd'T'HH:mm"),`)
77
+ 初期値現在日時とするようにした (`"initial": Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy-MM-dd'T'HH:mm"),`)
78
+
79
+ ・メッセージを変数にした
80
80
 
81
81
  ・最大・最小は不要なのでコメントアウト
82
82
 

1

2021/08/24 06:48

投稿

退会済みユーザー
test CHANGED
@@ -34,9 +34,7 @@
34
34
 
35
35
  datetime picker経由で入力されたデータか否かは、イベントタイプがpostbackかどうかで判断できます。
36
36
 
37
- (ここでは、
38
-
39
- イベントタイプが"postback"であればdatetime picker経由で入力されたデータ
37
+ (ここでは、イベントタイプが"postback"であれば datetime picker経由で入力されたデータ
40
38
 
41
39
  そうでなければ、通常のリプライデータ)
42
40
 
@@ -78,9 +76,9 @@
78
76
 
79
77
  ・初期値を現在日時とするようにした。
80
78
 
81
- ・メッセージを変数にした
79
+ ・メッセージを変数にした (`"initial": Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy-MM-dd'T'HH:mm"),`)
82
-
80
+
83
- ・最大・最小は不要なのでコメントアウトしている
81
+ ・最大・最小は不要なのでコメントアウト
84
82
 
85
83
  等です。
86
84
 
@@ -104,7 +102,7 @@
104
102
 
105
103
  //受け取ったメッセージの処理
106
104
 
107
- function GetMessage (e) {
105
+ function doPost(e) {
108
106
 
109
107
  var event = JSON.parse(e.postData.contents).events[0]
110
108
 
@@ -410,10 +408,10 @@
410
408
 
411
409
 
412
410
 
413
- function createData(cache) {
411
+ createData(cache)
414
-
412
+
415
- 略 (現状から変えなくてよいはず)
413
+ --->略 (現状から変えなくてよいはず)
416
-
417
- }
414
+
415
+
418
416
 
419
417
  ```