回答編集履歴
9
あ
test
CHANGED
@@ -487,11 +487,3 @@
|
|
487
487
|
```
|
488
488
|
|
489
489
|
3 つにわけようかと思ってたんですが相互に依存する関数があるので 1 回答にしました。219724 のときにおもったんですがよくこれだけ以前の回答がまるでなかったかのような処理を再発明できますよね。感服します。手直ししてて 219724 のコードが動きそうだなーと思いました。
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
個人的には 219287 が好みのコードなんですがやりたいことが複雑すぎて逆に可読性が落ちています。設計からやりなおしが必要と反省。
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
もうお金払って人に頼むレベルです。それがいやならカレンダーの通知のようなありものの機能を使うべき。これまでもそうですが根本的に、オレオレ仕様の実装が面倒である、以上の困難はないです。その面倒な仕様について試行錯誤した形跡はいつも提示されるコードには存在しません。「やりたいこと」にあたるの部分は常に丸投げです。
|
8
a
test
CHANGED
@@ -25,3 +25,473 @@
|
|
25
25
|
|
26
26
|
|
27
27
|
開始時間と終了時間が同じ日でないとき、日数差✕24を足す。便利機能はないので自力で頑張るしかないです。
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
```javascript
|
32
|
+
|
33
|
+
// 219287 style
|
34
|
+
|
35
|
+
const lineToken = "LINE コード";
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
function q219287() {
|
40
|
+
|
41
|
+
const today = new Date();
|
42
|
+
|
43
|
+
const days = [0,1,2,3,4,5,6].map(function (d) { return (new Date()).setDate(today.getDate() + d);});
|
44
|
+
|
45
|
+
const events = days.reduce(function (a, c) {
|
46
|
+
|
47
|
+
const eves = getEvents(c);
|
48
|
+
|
49
|
+
return eves.length === 0 ? a : a.concat([c, eves]);
|
50
|
+
|
51
|
+
},[]);
|
52
|
+
|
53
|
+
if(events.length === 0) { return; }
|
54
|
+
|
55
|
+
const message = events.map(function (e) { return [toDate(e[0])].concat(e[1].map(eventAsText));}).join("\n");
|
56
|
+
|
57
|
+
sendToLine(message);
|
58
|
+
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
function getEvents(thedate) {
|
64
|
+
|
65
|
+
const calendars = {
|
66
|
+
|
67
|
+
"①@group.calendar.google.com" : "①",
|
68
|
+
|
69
|
+
"②@group.calendar.google.com" : "②",
|
70
|
+
|
71
|
+
"③@group.calendar.google.com" : "③",
|
72
|
+
|
73
|
+
"④@group.calendar.google.com" : "④",
|
74
|
+
|
75
|
+
"⑤@group.calendar.google.com" : "⑤",
|
76
|
+
|
77
|
+
"⑥@gmail.com" : "⑥",
|
78
|
+
|
79
|
+
};
|
80
|
+
|
81
|
+
return Object.keys(calendars).map(function (e) { return CalendarApp.getCalendarById(e);}).map(function (cal) {
|
82
|
+
|
83
|
+
return [calendars[e], getEventsStartsInTheDay(cal, thedate)];
|
84
|
+
|
85
|
+
}).filter(function (e) {
|
86
|
+
|
87
|
+
return e[1].length > 0;
|
88
|
+
|
89
|
+
});
|
90
|
+
|
91
|
+
}
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
function eventAsText(events) {
|
96
|
+
|
97
|
+
return events.map(function (e) {
|
98
|
+
|
99
|
+
return '◆ ' + e[0] + '\n' + e[1].map(eventToString).join('\n\n');
|
100
|
+
|
101
|
+
}).join('\n');
|
102
|
+
|
103
|
+
}
|
104
|
+
|
105
|
+
function sendToLine(text) {
|
106
|
+
|
107
|
+
const token = lineToken;
|
108
|
+
|
109
|
+
const options = {
|
110
|
+
|
111
|
+
"method": "post",
|
112
|
+
|
113
|
+
"payload": "message=" + text,
|
114
|
+
|
115
|
+
"headers": {"Authorization": "Bearer " + token}
|
116
|
+
|
117
|
+
};
|
118
|
+
|
119
|
+
UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
|
120
|
+
|
121
|
+
}
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
function toTime(targetdate, basedate) {
|
126
|
+
|
127
|
+
const min = Utilities.formatDate(str, 'JST', "mm");
|
128
|
+
|
129
|
+
const hour = Utilities.formatDate(str, 'JST', "HH");
|
130
|
+
|
131
|
+
if(targetdate.getDate() === basedate.getDate()) {
|
132
|
+
|
133
|
+
return hour + ":" + min;
|
134
|
+
|
135
|
+
}
|
136
|
+
|
137
|
+
const target = new Date(targetdate.getFullYear(), targetdate.getMonth(), targetdate.getDate());
|
138
|
+
|
139
|
+
const base = new Date(basedate.getFullYear(), basedate.getMonth(), basedate.getDate());
|
140
|
+
|
141
|
+
const datediff = Math.floor(target - base / 86400000);
|
142
|
+
|
143
|
+
return ("0" + ((hour - 0) + 24 * datediff)).slice(-2) + ":" + min;
|
144
|
+
|
145
|
+
}
|
146
|
+
|
147
|
+
function toDate(date) {
|
148
|
+
|
149
|
+
return Utilities.formatDate(dt, 'JST', '★ MM/dd(' + ["日", "月", "火", "水", "木", "金", "土"][date.getDay()] + ')');
|
150
|
+
|
151
|
+
}
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
function getEventsStartsInTheDay(calendar, thedate) {
|
156
|
+
|
157
|
+
const dateNum = thedate.getDate();// 219287 のエラーからすると (new Date(thedate)).getDate(); か。
|
158
|
+
|
159
|
+
return calendar.getEventsForDay(thedate).filter(function (e) {
|
160
|
+
|
161
|
+
return e.getStartTime().getDate() === dateNum;
|
162
|
+
|
163
|
+
});
|
164
|
+
|
165
|
+
}
|
166
|
+
|
167
|
+
function eventToString(event) {
|
168
|
+
|
169
|
+
const start = event.getStartTime();
|
170
|
+
|
171
|
+
return toTime(start, start) + ' - ' + toTime(event.getEndTime(), start) + '\n ' + event.getTitle() + '\n\n';
|
172
|
+
|
173
|
+
}
|
174
|
+
|
175
|
+
// 219287
|
176
|
+
|
177
|
+
// 219724 style
|
178
|
+
|
179
|
+
function sendTodaySchedule() {
|
180
|
+
|
181
|
+
var accessToken = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN');
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
const message = [0,1,2,3,4,5,6].map(function (d) { return getMessage(d);}).filter(function (e) { return e !== "";}).join("\n");
|
186
|
+
|
187
|
+
if (!_isNull(message)) {
|
188
|
+
|
189
|
+
const options =
|
190
|
+
|
191
|
+
{
|
192
|
+
|
193
|
+
'method': 'post'
|
194
|
+
|
195
|
+
, 'payload': 'message=' + message
|
196
|
+
|
197
|
+
, 'headers': {'Authorization': 'Bearer ' + accessToken}
|
198
|
+
|
199
|
+
, muteHttpExceptions: true
|
200
|
+
|
201
|
+
};
|
202
|
+
|
203
|
+
UrlFetchApp.fetch('https://notify-api.line.me/api/notify', options);
|
204
|
+
|
205
|
+
}
|
206
|
+
|
207
|
+
}
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
function getMessage(prm) {
|
212
|
+
|
213
|
+
const week = ['日', '月', '火', '水', '木', '金', '土'];
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
var arrCals = [];
|
218
|
+
|
219
|
+
arrCals.push(CalendarApp.getCalendarById('Googleカレンダー@gmail.com'));
|
220
|
+
|
221
|
+
arrCals.push(CalendarApp.getCalendarById('Googleカレンダー@group.calendar.google.com'));//①
|
222
|
+
|
223
|
+
arrCals.push(CalendarApp.getCalendarById('Googleカレンダー@group.calendar.google.com'));//②
|
224
|
+
|
225
|
+
arrCals.push(CalendarApp.getCalendarById('Googleカレンダー@group.calendar.google.com'));//③
|
226
|
+
|
227
|
+
arrCals.push(CalendarApp.getCalendarById('Googleカレンダー@group.calendar.google.com'));//④
|
228
|
+
|
229
|
+
arrCals.push(CalendarApp.getCalendarById('Googleカレンダー@group.calendar.google.com'));//⑤
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
var date = new Date();
|
234
|
+
|
235
|
+
var strHeader = '';
|
236
|
+
|
237
|
+
date = new Date(date.getYear(), date.getMonth(), date.getDate() + prm);
|
238
|
+
|
239
|
+
strHeader += Utilities.formatDate(date, 'JST', 'yyyy/M/d')
|
240
|
+
|
241
|
+
+ '(' + week[date.getDay()] + ') の予定\n';
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
var strBody = getEvents(arrCals, date);
|
246
|
+
|
247
|
+
//if ( _isNull(strBody) ) strBody = '予定はありません。';
|
248
|
+
|
249
|
+
return _isNull(strBody) ? '' : strHeader + strBody;
|
250
|
+
|
251
|
+
}
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
function getEvents(prmarrCals, prmDate) {
|
256
|
+
|
257
|
+
var strEvents = '';
|
258
|
+
|
259
|
+
var strStart = '';
|
260
|
+
|
261
|
+
var strEnd = '';
|
262
|
+
|
263
|
+
var strTime = '';
|
264
|
+
|
265
|
+
var strLocation = '';
|
266
|
+
|
267
|
+
var strDescription = '';
|
268
|
+
|
269
|
+
if (!_isNull(prmarrCals)) {
|
270
|
+
|
271
|
+
for (var j = 0; j < prmarrCals.length; j++) {
|
272
|
+
|
273
|
+
var currentEvents = '';
|
274
|
+
|
275
|
+
var arrEvents = prmarrCals[j].getEventsForDay(new Date(prmDate));
|
276
|
+
|
277
|
+
for (var i = 0; i < arrEvents.length; i++) {
|
278
|
+
|
279
|
+
// if (!_isNull(strEvents)) strEvents += '\n';
|
280
|
+
|
281
|
+
var starts = arrEvents[i].getStartTime();
|
282
|
+
|
283
|
+
if (starts.getDate() !== prmDate.getDate()) continue;
|
284
|
+
|
285
|
+
strStart = _HHmm(starts);
|
286
|
+
|
287
|
+
strEnd = toTime(arrEvents[i].getEndTime(), starts);
|
288
|
+
|
289
|
+
if (strStart === strEnd) {
|
290
|
+
|
291
|
+
strTime = '終日';
|
292
|
+
|
293
|
+
} else {
|
294
|
+
|
295
|
+
strTime = strStart + '~' + strEnd;
|
296
|
+
|
297
|
+
}
|
298
|
+
|
299
|
+
currentEvents += '・' + strTime + '【' + arrEvents[i].getTitle() + '】';
|
300
|
+
|
301
|
+
strLocation = arrEvents[i].getLocation();
|
302
|
+
|
303
|
+
strDescription = arrEvents[i].getDescription();
|
304
|
+
|
305
|
+
if (!_isNull(strLocation)) currentEvents += '\n 場所:' + strLocation;
|
306
|
+
|
307
|
+
if (!_isNull(strDescription)) currentEvents += '\n 説明:' + strDescription;
|
308
|
+
|
309
|
+
}
|
310
|
+
|
311
|
+
if (_isNull(currentEvents)) continue;
|
312
|
+
|
313
|
+
if (!_isNull(strEvents)) strEvents += '\n';
|
314
|
+
|
315
|
+
strEvents += prmarrCals[j].getName() + '\n' + currentEvents;
|
316
|
+
|
317
|
+
}
|
318
|
+
|
319
|
+
}
|
320
|
+
|
321
|
+
return strEvents;
|
322
|
+
|
323
|
+
}
|
324
|
+
|
325
|
+
|
326
|
+
|
327
|
+
function _HHmm(str) {
|
328
|
+
|
329
|
+
return Utilities.formatDate(str, 'JST', 'HH:mm');
|
330
|
+
|
331
|
+
}
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
function _isNull(prm) {
|
336
|
+
|
337
|
+
if (prm == '' || prm === null || prm === undefined) {
|
338
|
+
|
339
|
+
return true;
|
340
|
+
|
341
|
+
} else {
|
342
|
+
|
343
|
+
return false;
|
344
|
+
|
345
|
+
}
|
346
|
+
|
347
|
+
}
|
348
|
+
|
349
|
+
//219724
|
350
|
+
|
351
|
+
//236158 style
|
352
|
+
|
353
|
+
const token = "LINE_TOKEN";
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
const calendarTitleMap = {
|
358
|
+
|
359
|
+
"①@group.calendar.google.com" : "①",
|
360
|
+
|
361
|
+
"②@group.calendar.google.com" : "②",
|
362
|
+
|
363
|
+
"③@group.calendar.google.com" : "③",
|
364
|
+
|
365
|
+
"④@group.calendar.google.com" : "④",
|
366
|
+
|
367
|
+
"⑤@group.calendar.google.com" : "⑤",
|
368
|
+
|
369
|
+
"⑥@gmail.com" : "⑥",
|
370
|
+
|
371
|
+
|
372
|
+
|
373
|
+
};
|
374
|
+
|
375
|
+
|
376
|
+
|
377
|
+
const weekday = ["日", "月", "火", "水", "木", "金", "土"];
|
378
|
+
|
379
|
+
|
380
|
+
|
381
|
+
function notifyWeekly() {
|
382
|
+
|
383
|
+
var _counter = 0;
|
384
|
+
|
385
|
+
const calendars = CalendarApp.getAllCalendars();
|
386
|
+
|
387
|
+
var dt = new Date()
|
388
|
+
|
389
|
+
var message = "週間予定\n\n";
|
390
|
+
|
391
|
+
|
392
|
+
|
393
|
+
for ( var i = 3; i < 8; i++ ) {
|
394
|
+
|
395
|
+
|
396
|
+
|
397
|
+
dt.setDate(dt.getDate() + 2);
|
398
|
+
|
399
|
+
message += Utilities.formatDate(dt, 'JST', '★ MM/dd(' + weekday[dt.getDay()] + ')') + "\n";
|
400
|
+
|
401
|
+
|
402
|
+
|
403
|
+
var dayText = "";
|
404
|
+
|
405
|
+
for(j in calendars) {
|
406
|
+
|
407
|
+
var calendar = calendars[j];
|
408
|
+
|
409
|
+
|
410
|
+
|
411
|
+
var calendarName = calendarTitleMap[calendar.getId()]
|
412
|
+
|
413
|
+
if ( calendarName == undefined ) {
|
414
|
+
|
415
|
+
continue;
|
416
|
+
|
417
|
+
}
|
418
|
+
|
419
|
+
|
420
|
+
|
421
|
+
var events = calendar.getEventsForDay(dt);
|
422
|
+
|
423
|
+
if( events.length == 0 ) {
|
424
|
+
|
425
|
+
continue;
|
426
|
+
|
427
|
+
}
|
428
|
+
|
429
|
+
|
430
|
+
|
431
|
+
dayText += "< " + calendarName + " >\n";
|
432
|
+
|
433
|
+
for(j in events) {
|
434
|
+
|
435
|
+
var tmp = toDayText(events[j], dt);
|
436
|
+
|
437
|
+
dayText += tmp === "" ? "" : tmp + "\n";
|
438
|
+
|
439
|
+
}
|
440
|
+
|
441
|
+
//dayText += "\n"
|
442
|
+
|
443
|
+
}
|
444
|
+
|
445
|
+
|
446
|
+
|
447
|
+
if ( dayText == "") {
|
448
|
+
|
449
|
+
dayText += "予定はありません\n\n";
|
450
|
+
|
451
|
+
counter++;
|
452
|
+
|
453
|
+
}
|
454
|
+
|
455
|
+
message += dayText;
|
456
|
+
|
457
|
+
}
|
458
|
+
|
459
|
+
if(_counter === 5) { return; }
|
460
|
+
|
461
|
+
sendToLine(message);
|
462
|
+
|
463
|
+
}
|
464
|
+
|
465
|
+
|
466
|
+
|
467
|
+
function toDayText(event, date) {
|
468
|
+
|
469
|
+
const st = event.getStartTime();
|
470
|
+
|
471
|
+
if(st.getDate() !== date.getDate()) { return ""; }
|
472
|
+
|
473
|
+
return toTimeText(st) + ' - ' + toTime(event.getEndTime(), st) + " " + event.getTitle() + '\n';
|
474
|
+
|
475
|
+
}
|
476
|
+
|
477
|
+
|
478
|
+
|
479
|
+
function toTimeText(str){
|
480
|
+
|
481
|
+
return Utilities.formatDate(str, 'JST', 'HH:mm');
|
482
|
+
|
483
|
+
}
|
484
|
+
|
485
|
+
//236158
|
486
|
+
|
487
|
+
```
|
488
|
+
|
489
|
+
3 つにわけようかと思ってたんですが相互に依存する関数があるので 1 回答にしました。219724 のときにおもったんですがよくこれだけ以前の回答がまるでなかったかのような処理を再発明できますよね。感服します。手直ししてて 219724 のコードが動きそうだなーと思いました。
|
490
|
+
|
491
|
+
|
492
|
+
|
493
|
+
個人的には 219287 が好みのコードなんですがやりたいことが複雑すぎて逆に可読性が落ちています。設計からやりなおしが必要と反省。
|
494
|
+
|
495
|
+
|
496
|
+
|
497
|
+
もうお金払って人に頼むレベルです。それがいやならカレンダーの通知のようなありものの機能を使うべき。これまでもそうですが根本的に、オレオレ仕様の実装が面倒である、以上の困難はないです。その面倒な仕様について試行錯誤した形跡はいつも提示されるコードには存在しません。「やりたいこと」にあたるの部分は常に丸投げです。
|
7
a
test
CHANGED
File without changes
|
6
a
test
CHANGED
File without changes
|
5
a
test
CHANGED
File without changes
|
4
a
test
CHANGED
File without changes
|
3
a
test
CHANGED
File without changes
|
2
a
test
CHANGED
File without changes
|
1
a
test
CHANGED
File without changes
|