回答編集履歴

9

修正

2021/11/18 23:01

投稿

退会済みユーザー
test CHANGED
@@ -20,7 +20,9 @@
20
20
 
21
21
  フロント(html)から、バック(GAS)内の関数を呼び出す、という流れです。
22
22
 
23
- (つまりGAS側からフロントエンド(ブラウザ)へのプッシュ通知ではなく、フロントエンド側からGASのデータをプルしてくる形です
23
+ (つまりGAS側からフロントエンド(ブラウザ)へのプッシュ通知ではなく、フロントエンド側からGASのデータをプルしてくる形です)
24
+
25
+
24
26
 
25
27
  ---
26
28
 

8

修正

2021/11/18 23:01

投稿

退会済みユーザー
test CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  フロント(html)から、バック(GAS)内の関数を呼び出す、という流れです。
22
22
 
23
-
23
+ (つまりGAS側からフロントエンド(ブラウザ)へのプッシュ通知ではなく、フロントエンド側からGASのデータをプルしてくる形です。)
24
24
 
25
25
  ---
26
26
 
@@ -306,17 +306,17 @@
306
306
 
307
307
  `t.new_Me[i] = maildata;`
308
308
 
309
- の部分ですが、meildataはどこにも定義されていないのでエラーになると思います。
309
+ の部分ですが、maildataはどこにも定義されていないのでエラーになると思います。
310
310
 
311
311
  (フロント側で定義されているように見えてもバック側では共有されません)
312
312
 
313
313
 
314
314
 
315
- 回答のコードでは、プリンティングスクリプトレットを使用して、GAS側のグローバル変数 errormailを、
315
+ 回答のコードでは、プリンティングスクリプトレットを使用して、GAS側のグローバル変数 errormailの内容(文字列)を、
316
316
 
317
317
  Vueのmessageの初期値に設定しています。(下記)
318
318
 
319
- (このように、ページの読み込み時にGAS側の変数をフロントに渡すことは可能です)
319
+ (このように、ページの読み込み時にGAS側の変数の内容をフロントに渡すことは可能です)
320
320
 
321
321
 
322
322
 

7

2021/11/18 23:00

投稿

退会済みユーザー
test CHANGED
@@ -50,7 +50,11 @@
50
50
 
51
51
  * 最新のメールを取得し、日時・本文を加工して返す関数
52
52
 
53
+ *  戻り値:
54
+
53
- *  戻り値string:最新のメールの内容
55
+ *  条件に合致するメールがある場合:最新のメールの内容(string)
56
+
57
+ *  条件に合致するメールがない場合:null
54
58
 
55
59
  */
56
60
 

6

2021/11/18 16:52

投稿

退会済みユーザー
test CHANGED
@@ -32,6 +32,8 @@
32
32
 
33
33
  【コード.gs】
34
34
 
35
+ ※GAS側のトリガー設定は、スプレッドシートに常時一定間隔でエラー内容を記載する必要がなければ不要です。
36
+
35
37
  ```js
36
38
 
37
39
  // エラーメールの内容を記録するシート

5

2021/11/18 16:50

投稿

退会済みユーザー
test CHANGED
File without changes

4

2021/11/18 16:48

投稿

退会済みユーザー
test CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  (2)フロント側(index.html)で、setIntervalを利用して一定間隔で(1)の関数を呼び出し、
12
12
 
13
- Vueのwatchで返ってくる文字列を監視。変化がある場合はalertで表示する。
13
+ 返ってくる文字列をVueのwatchで監視。変化がある場合はalertで表示する。
14
14
 
15
15
 
16
16
 

3

修正

2021/11/18 16:48

投稿

退会済みユーザー
test CHANGED
@@ -248,9 +248,9 @@
248
248
 
249
249
  ```
250
250
 
251
- おそらく、「一定期間内のすべてのメールから特定の単語を抜き出す」スクリプトをコピペされたのだと思いますが、
251
+ おそらく、「一定期間内のすべてのメールから、本文に特定の単語が含まれているものを抜き出す」スクリプトのようなものをコピペされたのだと思いますが、
252
-
252
+
253
- 今回は最新のメールだけ受信できれば良いので、for文でループさせる必要はありません。
253
+ 今回は最新のメールだけ取得できれば良いので、for文でループさせる必要はありません。
254
254
 
255
255
 
256
256
 
@@ -266,7 +266,9 @@
266
266
 
267
267
  ```
268
268
 
269
- でstrTerms条件に合致した最新のメールを取得できます。
269
+ のようにすることstrTermsに指定した条件に合致する最新のメールを取得できます。
270
+
271
+
270
272
 
271
273
 
272
274
 
@@ -306,11 +308,9 @@
306
308
 
307
309
  回答のコードでは、プリンティングスクリプトレットを使用して、GAS側のグローバル変数 errormailを、
308
310
 
309
- Vueのmessageの初期値に設定しています。
311
+ Vueのmessageの初期値に設定しています。(下記)
310
-
311
-
312
-
312
+
313
- このように、ページの読み込み時にGAS側の変数をフロントに渡すことは可能です
313
+ このように、ページの読み込み時にGAS側の変数をフロントに渡すことは可能です
314
314
 
315
315
 
316
316
 

2

修正

2021/11/18 16:47

投稿

退会済みユーザー
test CHANGED
@@ -1,19 +1,335 @@
1
- GAS内でのmaildataの変化を、フロント(js.html?)内のVueのwatchプロパティで直接監視することはできません。
1
+ バックエンド(GAS内での変数maildataの変化を、フロント(js.html?)内のVueのwatchプロパティで
2
+
2
-
3
+ 直接監視することはできません。
3
-
4
4
 
5
5
 
6
6
 
7
7
  アプローチとしては、
8
8
 
9
- (1)GAS、「最新のメールを取得し、直近のメール内容が異なっいればtrueを返す」APIまウェブアプリとして公開する
9
+ (1)GAS側は、「最新のメールを取得し、直近のメール内容を文字列にして返す」関数を実装したウェブアプリとして作成
10
-
10
+
11
- (2)フロント(index.html)で、setIntervalを利用して一定間隔で(1)のAPI叩きtrueが返ってきたらalertする
11
+ (2)フロント(index.html)で、setIntervalを利用して一定間隔で(1)の関数呼び出し
12
-
13
-
14
-
12
+
15
- (あえてvueのwatchを使いたいならば、(1)のAPIの方は最新のメールの内容を文字列として返ようにす
13
+ Vueのwatchで返ってくる文字列を監視。変化がある場合はalertで表示する
16
14
 
17
15
 
18
16
 
19
17
  という方向になろうかと思います。
18
+
19
+
20
+
21
+ フロント(html)から、バック(GAS)内の関数を呼び出す、という流れです。
22
+
23
+
24
+
25
+ ---
26
+
27
+
28
+
29
+ 下記は参考のコードです。
30
+
31
+
32
+
33
+ 【コード.gs】
34
+
35
+ ```js
36
+
37
+ // エラーメールの内容を記録するシート
38
+
39
+ var sheet = SpreadsheetApp.openById("スプレッドシートID").getSheetByName("シート2");
40
+
41
+ // 直近のエラーメールの内容
42
+
43
+ var errormail = sheet.getRange("A1").getValue()
44
+
45
+
46
+
47
+ /*
48
+
49
+ * 最新のメールを取得し、日時・本文を加工して返す関数
50
+
51
+ *  戻り値:string:最新のメールの内容
52
+
53
+ */
54
+
55
+ function fetchContactMail() {
56
+
57
+ // 現在時刻
58
+
59
+ var now_time = Math.floor(new Date().getTime() / 1000);
60
+
61
+
62
+
63
+ // 検索条件:現在時刻から63秒以内に受信した未読メール
64
+
65
+ // (ただしエラーメールの内容が空白の場合、一週間以内まで範囲を広げる)
66
+
67
+ var pasttime = errormail !== '' ? 60 + 3 : 60*60*24*7;
68
+
69
+ var time_term = now_time - pasttime;
70
+
71
+ var strTerms = '(is:unread after:' + time_term + ')';
72
+
73
+
74
+
75
+ //最新のメールを取得
76
+
77
+ var myThreads = GmailApp.search(strTerms, 0, 1);
78
+
79
+ var myMsgs = GmailApp.getMessagesForThreads(myThreads);
80
+
81
+ if (myMsgs.length == 0) return null;
82
+
83
+ var msg = myMsgs[0].slice(-1)[0];
84
+
85
+ // メール日時・本文の取得・加工
86
+
87
+ var valMsg = " " + (msg.getDate().getMonth() + 1) + "/" + msg.getDate().getDate()
88
+
89
+ + " " + msg.getDate().getHours() + ":" + msg.getDate().getMinutes()
90
+
91
+ + "\n[from]" + msg.getFrom()
92
+
93
+ + "\n" + msg.getSubject()
94
+
95
+ + "\n\n[Message]\n" + msg.getPlainBody();
96
+
97
+
98
+
99
+ sheet.getRange("A1").setValue(valMsg);
100
+
101
+ return valMsg;
102
+
103
+ }
104
+
105
+
106
+
107
+ function doGet(e) {
108
+
109
+ var html = HtmlService.createTemplateFromFile("index").evaluate();
110
+
111
+ var content = html.getContent();
112
+
113
+ return HtmlService.createTemplate(content).evaluate();
114
+
115
+ }
116
+
117
+
118
+
119
+ ```
120
+
121
+ 【index.html】
122
+
123
+ ```HTML
124
+
125
+ <!DOCTYPE html>
126
+
127
+ <html>
128
+
129
+ <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
130
+
131
+
132
+
133
+ <head>
134
+
135
+ <base target="_top">
136
+
137
+ <meta charset="UTF-8">
138
+
139
+ </head>
140
+
141
+
142
+
143
+ <body>
144
+
145
+
146
+
147
+ <div id="app">
148
+
149
+ <p>{{ message }}</p>
150
+
151
+ </div>
152
+
153
+
154
+
155
+ <script>
156
+
157
+ new Vue({
158
+
159
+ el: "#app",
160
+
161
+ data: function() {
162
+
163
+ return{
164
+
165
+ // 初期値を設定
166
+
167
+ message: <?= errormail ?>
168
+
169
+ }
170
+
171
+ },
172
+
173
+ created () {
174
+
175
+ setInterval(() => {
176
+
177
+ // 1分ごとに最新のメールの内容を取得(GAS側の関数を呼び出し、
178
+
179
+ // 戻り値を引数にしてchangeValメソッドを呼び出す。)
180
+
181
+ google.script.run.withSuccessHandler(this.changeVal).fetchContactMail();
182
+
183
+ }, 60000)
184
+
185
+ },
186
+
187
+ watch: {
188
+
189
+ message: function(newMsg) {
190
+
191
+ alert("新しいエラーメールを受信しました。\n" + newMsg);
192
+
193
+ },
194
+
195
+ },
196
+
197
+ methods: {
198
+
199
+ changeVal :function(val) {
200
+
201
+ var vm = this;
202
+
203
+ vm.message = val;
204
+
205
+ }
206
+
207
+ }
208
+
209
+ });
210
+
211
+ </script>
212
+
213
+ </body>
214
+
215
+ </html>
216
+
217
+ ```
218
+
219
+  
220
+
221
+  
222
+
223
+ ---
224
+
225
+ ・補足
226
+
227
+ **元の質問文のコードのfetchContactMail()について:**
228
+
229
+ ```
230
+
231
+ function fetchContactMail() {
232
+
233
+ for(var i = 0; i < myMsgs.length;i++){
234
+
235
+ valMsgs[i] = " " + myMsgs[i].slice(-1)[0].getDate().getMonth() + "/"+ myMsgs[i].slice(-1)[0].getDate().getDate()
236
+
237
+ + " " + myMsgs[i].slice(-1)[0].getDate().getHours() + ":" + myMsgs[i].slice(-1)[0].getDate().getMinutes()
238
+
239
+ + "\n[from]" + myMsgs[i].slice(-1)[0].getFrom()
240
+
241
+ + "\n" + myMsgs[i].slice(-1)[0].getSubject()
242
+
243
+ valMsgs[i] = valMsgs[i] + "\n\n[Message]\n"+ myMsgs[i].slice(-1)[0].getPlainBody();
244
+
245
+
246
+
247
+ }
248
+
249
+ ```
250
+
251
+ おそらく、「一定期間内のすべてのメールから特定の単語を抜き出す」スクリプトをコピペされたのだと思いますが、
252
+
253
+ 今回は最新のメールだけ受信できれば良いので、for文でループさせる必要はありません。
254
+
255
+
256
+
257
+ ```
258
+
259
+ var myThreads = GmailApp.search(strTerms, 0, 1);
260
+
261
+ var myMsgs = GmailApp.getMessagesForThreads(myThreads);
262
+
263
+ if (myMsgs.length == 0) return null;
264
+
265
+ var msg = myMsgs[0].slice(-1)[0];
266
+
267
+ ```
268
+
269
+ でstrTermsの条件に合致した最新のメールを取得できます。
270
+
271
+
272
+
273
+
274
+
275
+ **元の質問文のコードのmain()について:**
276
+
277
+ ```
278
+
279
+ function main() {
280
+
281
+
282
+
283
+ new_Me = fetchContactMail()
284
+
285
+ if(new_Me.length > 0){
286
+
287
+ for(var i = new_Me.length-1; i >= 0; i--){
288
+
289
+ sheet.getRange("A1").setValue(new_Me[i]);
290
+
291
+ t.new_Me[i] = maildata;
292
+
293
+ }
294
+
295
+ }
296
+
297
+ ```
298
+
299
+ `t.new_Me[i] = maildata;`
300
+
301
+ の部分ですが、meildataはどこにも定義されていないのでエラーになると思います。
302
+
303
+ (フロント側で定義されているように見えてもバック側では共有されません)
304
+
305
+
306
+
307
+ 回答のコードでは、プリンティングスクリプトレットを使用して、GAS側のグローバル変数 errormailを、
308
+
309
+ Vueのmessageの初期値に設定しています。
310
+
311
+
312
+
313
+ このように、ページの読み込み時にGAS側の変数をフロントに渡すことは可能です。
314
+
315
+
316
+
317
+ ```diff
318
+
319
+ new Vue({
320
+
321
+ el: "#app",
322
+
323
+ data: function() {
324
+
325
+ return{
326
+
327
+ // 初期値を設定
328
+
329
+ + message: <?= errormail ?>
330
+
331
+ }
332
+
333
+ },
334
+
335
+ ```

1

修正

2021/11/18 16:44

投稿

退会済みユーザー
test CHANGED
@@ -1,4 +1,6 @@
1
- フロント(js.html?)内で定義されているmaildataを、常時バックエンドGASのmain()内で共有し、vueのwatchプロパティで監視することはできません。
1
+ GAS内でのmaildataの変化を、フロント(js.html?)内のVueのwatchプロパティで直接監視することはできません。
2
+
3
+
2
4
 
3
5
 
4
6