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

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

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

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

Q&A

解決済

1回答

1170閲覧

GAS Gmail.search で条件に合わないメールが抽出される。

y6772

総合スコア13

Google Apps Script

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

0グッド

0クリップ

投稿2019/02/01 01:31

前提・実現したいこと

同じ送信先から送られる定型メール
宛先:メールアドレスA
宛先:メールアドレスB
(2つともGmailにエイリアスとしてアカウント登録したもの)
ここからそれぞれの宛先用のスプレッドシート
メールアドレスA用のスプレッドシート
メールアドレスB用のスプレッドシート
を作成し、それぞれのメールのデータを取り込めるようにしたい。

送られてくるメールは
・「メール本文中のABを特定できる文」
・宛先のメールアドレスAまたはB
・Gmail上で付けたラベル「ラベルA」「ラベルB」
で特定できます。
もちろんGmail上でラベルでフィルターすると間違っていないデータを対象にしています。
また、それぞれのメール(スレッド)は1通のみです。

起きている問題

ABそれぞれの内特定の2件程度のデータがAにもBにも重複して取り込まれてしまいます。

該当のソースコード

Google

1//メールアドレスAのデータ抽出用シートのスクリプト 2 3var sheet = SpreadsheetApp.getActive().getSheetByName('指定シート'); 4var data = sheet.getRange(2, 1, sheet.getLastRow()).getValues(); 5 6 function mailListing() { 7 var query = '(to:メールアドレスA)' 8 + '("メール本文中のABを特定できる文")' 9 + '(label:メールアドレスA用のラベル)'; 10 11 var threads = GmailApp.search(query, 0, 50); 12 var messages = GmailApp.getMessagesForThreads(threads); 13 14 for(var i=0; i < messages.length; i++) { 15 for(var j=0; j < messages[i].length; j++) { 16 var id = messages[i][j].getId(); 17 if(!hasId(id)){ 18 var body = messages[i][j].getPlainBody(); 19 /* メール本文全体を取得し正規表現でデータを取得 */ 20 sheet.appendRow([ 21 id, 22 fetchData(body, '利用日', '\r'), 23 fetchData(body, 'お名前:', '様'), 24 ]); //メール本文の正規表現の部分指定 25 } 26 } 27 } 28} 29 30 /* メールIDによる複を回避 */ 31function hasId(id) { 32 var hasId = data.some(function(array, i, data) { 33 return (array[0] === id); 34 }); 35 return hasId; 36} 37 38 39 40//データの正規表現を定義するコード 41 42function fetchData(str, pre, suf) { 43 var reg = new RegExp(pre + '.*?' + suf); 44 var data = ''; 45 46 try{ 47   data = str.match(reg)[0] 48 .replace(pre, '') 49 .replace(suf, ''); 50 51 }catch(e){ 52 data = ''; 53 } 54 return data; 55} 56

試したこと

上記は宛先A用のコードですが、同じもコードでB用のものがあります。
最初の「query」の指定が間違っているかと思い、
to: deliveredto: label: -label:B用 
などクエリの指定を様々な条件を試しましたが、解決されません。
エラーも発生せず動くのですが、どうしても原因が特定できません。
よろしくお願いいたします。

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

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

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

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

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

papinianus

2019/02/01 01:39 編集

特定の2(<10)件ということであって、必ず重複するのではないのですよね?もしそうならそれって、データ依存なので、ブツ見ないと何ともできないと思うのですが。 スレッドが1つというのは理解した上で申し上げてますが、sheet.appendRowのところで、確認用に、iとjの数値を4,5番目に書いてみていただけませんか?
y6772

2019/02/01 02:40

さっそくコメント有難うございます。 対象メールの特定の2件が重複し、他のメールはきちんと振り分けできているため、私もメールデータ自体に問題があるのかと思い、メールのソースなども確認しましたが、重複してしまうデータもA・Bそれぞれの内容になっており、取り違える要素は見当たりませんでした。 プログラミングはかじっていいる程度のため理解不足で、お手数をおかけしますが、「iとjの数値を4,5番目に書く」とは、 i=4; j=5; にするという意味でしょうか?
papinianus

2019/02/01 03:08

sheet.appendRow([ id, fetchData(body, '利用日', '\r'), fetchData(body, 'お名前:', '様'), i, j,]); としてください。
y6772

2019/02/01 03:17

ご丁寧にありがとうございます。 実行結果は同じ結果でした。取り違えたメールも同じです。
papinianus

2019/02/01 07:59

そのときの、i,jの状態をご確認ください。1スレッド1メールが厳格に守られてるとすれば、jは0にしかならないはずですが、1になっていませんか?
guest

回答1

0

ベストアンサー

どうも1スレッドに複数メールがあってそれが重複しているとしか思えないのですが、下記を追加してログを見てもらえますか?

js

1var threads = GmailApp.search(query, 0, 50); 2/* ここから */ 3threads.forEach(function(thread) { 4 Logger.log(thread.getMessageCount()); 5}); 6/* ここまで追加 */ 7var messages = GmailApp.getMessagesForThreads(threads);

投稿2019/02/01 07:49

macaron_xxx

総合スコア3191

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

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

y6772

2019/02/01 08:25

ありがとうございます。 特定のスレッドに一部複数メールがぶら下がっていました。 ログ [19-02-01 00:13:10:722 PST] 3.0 [19-02-01 00:13:10:762 PST] 1.0 [19-02-01 00:13:10:800 PST] 2.0 [19-02-01 00:13:10:834 PST] 1.0 [19-02-01 00:13:10:877 PST] 1.0 確認不足でした。 Gmailではスレッド表示をOFFにしていましたので、それぞれ単一のメールと思い込んでいました。 ただ、確かに送信先は同一のアドレスからですが、なぜ送信先Aに来ているメールと送信先Bに来ているメールが一つのスレッドになってしまうのでしょう? 特にこちらでメールを操作はしていないのですが・・・
macaron_xxx

2019/02/01 08:32 編集

違う宛先ですが、エイリアスとして登録している以上、どちらも”あなた”に送られたメールですので、そこは加味していないのかもしれないですね。 スレッド化される条件については、私は公式文書で見たことがありませんので、回答することを避けます。
y6772

2019/02/01 08:47

ありがとうございます。 仕様でスレッド化は回避できないとして、対象の全てのメールに対して、フィルターを行う必要があるということですね。 同じような事例を見つけたので、コードを修正してみます。
y6772

2019/02/02 01:48

おかげさまで、修正して無事動くようになりました。 クエリでABの全スレッドを全て取り込んでから、スレッド内の全メールに対してA/Bに対するフィルタ―をかけるようにしたらうまくいきました。 思い込みで解決できずにいましたが、助かりました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問