質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

2回答

580閲覧

Gmailでの指定日時送信(同時刻に複数送信したい場合)について

mozuq

総合スコア15

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

1クリップ

投稿2019/02/22 04:43

Googleフォームで受けつけた内容をもとに、GoogleAppsScirptを使ってGmailで指定日時にメールを送信したいのですが、
同じ日時に複数の人への送信ができません。
コードのどこが間違っているか、またどのようにすればいいか教えていただけないでしょうか。
よろしくお願いいたします。

送信についての条件

  • 送信する日時:9時、10時、11時など、毎時0分。下書きメールの件名に記載
  • 送信する数:日時によって違う
  • 送信先:毎回異なる
  • 送信メール:Googleフォームの回答受けつけ時に、その内容をもとに下書きメールを別のscriptであらかじめ作成

スクリプトが行っていること

下書きのメールを取得し……

  • 下書きメールの件名に {西暦年/月/日 時:分}(例:{2019/01/31 13:00}) があれば、その日時を抽出して、指定日時送信のscriptが実行された時間よりも件名の日時が過去の日時であれば送信する。
  • 件名に {西暦年/月/日 時:分} がない、もしくは件名の日時がscript実行時の日時よりも未来であれば送信しない。

スクリプトのトリガー

最初はトリガーを1分に1回で設定していたが、GASのGmail読み取り制限に引っかかってしまったため、
現在は特定の日時にトリガーを作成するscriptを使用して、指定日時送信メールのscriptを実行させている。

問題点

関数のデバッグは、件名の日時を過ぎてから行っているが、
下書きメールの件名 {西暦年/月/日 時:分} の日時が同じものが複数あっても、画像の赤枠部分の1件しか送信されていない。
なお、下書き16件分の中にはGmailに設定してある返信定型文や、件名に**{西暦年/月/日 時:分}**がないものも含まれる。
イメージ説明イメージ説明

ちなみに、件名に**{西暦年/月/日 時:分}**がある下書きメールを全て削除すると、ログでは全ての下書きメールが出てきます。
イメージ説明
イメージ説明

GoogleAppsScript

1function delaySendDraftMail() { 2 var drafts = GmailApp.getDraftMessages(); 3 var len = drafts.length; 4 Logger.log('下書きの数(len):' + len); 5 //下書きがなければ終了 6 if (!len) { 7 return false; 8 } 9 //現在時刻を取得 10 var now = (new Date()).getTime(); 11 //下書きの数だけ繰り返す 12 for (var i = 0, l = len; i < l; i++) { 13 var mes = drafts[i]; 14 Logger.log('型(mes):' + typeof mes); 15 16 if ('object' !== typeof mes) { 17 continue; 18 } 19 //件名を取得 20 var str = mes.getSubject(); 21 Logger.log('件名(str):' + str); 22 //件名から日時を抽出 23 var match = str.match(/^(\{(\d{4}[/\-]\d{1,2}[/\-]\d{1,2} \d{1,2}:\d{1,2})\}) ?(.*)?/); 24 Logger.log('件名から抽出した日時(match):' + match); 25 //日時が抽出できないならスキップ 26 if (!match || !match[1]) { 27 continue; 28 } 29 //時間を取得 30 var time = (new Date(match[2].replace(/\-/g,'/')+' +09:00')).getTime(); 31 Logger.log('時間(time):' + time); 32 //時間を取得できない、または未来の時間なら無視 33 if(!time || (time && time>now)){ 34 continue; 35 } 36 //各情報をセット 37 var to = mes.getTo(); 38 var subject = match[3] || ''; 39 var body = mes.getPlainBody(); 40 var options = {}, val; 41 //必要な情報がなければスキップ 42 if (!to || !body) { 43 continue; 44 } 45 // From を変更した場合でも対応 46 var from = mes.getFrom(); 47 var aliases = GmailApp.getAliases(); 48 Logger.log('別名アドレス(aliases):' + aliases); 49 50 for (var i = 0, l = aliases.length; i < l; i++) { 51 var val = aliases[i]; 52 // From エイリアス一覧にマッチすれば From として使用 53 if (-1 !== from.indexOf(val)) { 54 options['from'] = val; 55 break; 56 } 57 } 58 if (val = mes.getCc()) {//Cc 59 options['cc'] = val; 60 } 61 if (val = mes.getBcc()) {//Bcc 62 options['bcc'] = val; 63 } 64 if (val = mes.getBody()) {//HTML本文 65 //bodyにdivタグがあればHTMLとみなす 66 if ( val.indexOf('<div')!==-1 ) { 67 options['htmlBody'] = val; 68 } 69 } 70 //添付ファイル 71 if (val = mes.getAttachments()) { 72 options['attachments'] = val; 73 } 74 // 送信! 75 var status = GmailApp.sendEmail(to, subject, body, options); 76 Logger.log('送信(status):' + status); 77 78 //送信したら下書きをゴミ箱へ 79 if (status) { 80 mes.moveToTrash(); 81 } 82 } 83}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t_obara

2019/02/22 05:51

問題点を見つけるために、コードを最小限にしてどのように振る舞うかを確認するのが効果的なことがあります。今回もたとえば、何もしないようにして問題なくメールリストアップできるか、ゴミ箱にだけ移動させたら実施できるかなどちょっとずつ処理を追加して何をしたことで想定外の動作をするか確認してみてはいかがでしょうか。 また、sendEmailの戻りはGmailAppオブジェクトなので、それを参照して送信できたかを確認するのは間違った使い方だと思います。
guest

回答2

0

GoogleAppsScript

1// From を変更した場合でも対応 2 var from = mes.getFrom(); 3 4(省略) 5 6//添付ファイル 7 if (val = mes.getAttachments()) { 8 options['attachments'] = val; 9 } 10

この部分が不要だったので削除し、送信元メールアドレスと名前は毎回同じでいいので、その部分を以下のように書きかえました。

GoogleAppsScript

1// var options = {}, val; ←これはやめた 2 var options = { 3  from: '●●●●●●@●●●.●●●.jp', 4 name: 'あああああああああ' 5 };

これで同じ日時に複数送信できました。
なんだか恥ずかしい結果ですが、解決して良かったです。

投稿2019/02/25 08:20

mozuq

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

※全面書きかえしました。t_obara様のご指摘に感謝します

原因は、draftsをループしているカウンタ変数iおよび上限変数l
別名(alias)をループしているカウンタ変数iおよび上限変数lが同じであることではないでしょうか。

下記概念コードで示しますが、hereのところにあるlは最初のループから「1」が出力され、ループは1回で終端します。

javascript

1function q175842() { 2 var limit = 5; 3 for(var i = 0, l = limit; i < l; i++) { 4 var alius = 1; 5 for(var i = 0, l = alius; i < l; i++) { 6 Logger.log("inner"); 7 } 8 Logger.log(l); //here 9 Logger.log("outer"); 10 } 11}

従って提示コードが上手く動くのは、下書きとaliasが上手く強調している場合のみで
例えば下書きが3通あるときは、上から順にaliasの指定が3件、2件、1件となっている特殊状況です。

投稿2019/02/22 04:57

編集2019/02/22 07:28
papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papinianus

2019/02/22 07:30

ご指摘ありがとうございます。getDraftsとgetDraftMessagesを混同いたしておりました。 ご指摘および当初より回答で懸念を表明しておりました停止するならエラーが発生するはず、の2点を考慮し、全コードを読み直して、回答を書き換えました。
papinianus

2019/02/22 07:36

質問者様へ 質疑で指摘されているstatusの件ですが、私の技量ではtry/catchくらいしか思いつきませんでした。 ``` var sentSuccess = false; try { GmailApp.sendEmail(); sentSuccess = true; } catch (e) { // sentSuccess = false; } finally { if(sentSuccess) { mes.moveToTrash(); }  } ``` みたいな
mozuq

2019/02/25 08:07

お二方ともに、ご回答ありがとうございます。 ■t_obata様 ちょっとずつ処理をしていく、確かにそのとおりですね。 ログを確認することに夢中で、思いつきませんでした。 sendEmailの件につきまして、ご指摘いただきありがとうございます。 ■papinianus様 原因を教えていただきありがとうございます。 今回、私が質問として書いたコードですが、ネットにあるものを参考にしました。 原因とコードを照らし合わせ、コードの中に自分には不要な箇所があることがわかり、書きかえると同じ日時に複数のメールを送信することができました。 なお、try~文の提示につきましてもありがとうございます。 こちらにつきましては、もう少し自分で勉強してコードを変えていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問