3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Google Apps Script (GAS) で Gmail のメールが重複する

Posted at

Gmail の罠

Gmailのメールをスケジュール実行で取得し、自動処理させているときにソレは起こりました。
一度読んだメールを、また読み込んでしまうのです。
はじめにコードを書いたときはスレッドをまたがって重複が起こってしまうとは思いもよりませんでした。

スレッドについて

メールへの返信が繰り返されるときに、Gmailがいい感じにひとまとめにして表示してくれる機能です。ただスレッドにされる条件は明示されておらず、返信でなくともスレッドでまとめられることがあります。
Google Apps Script で Gmail を扱うときはこのスレッド単位で処理することになります。
スレッドの中にはメッセージ(メール)が複数存在します。※単一の場合もありますが
またスレッドも複数存在する場合があります。
よって以下のようなコードを記述し、各スレッド各メッセージでループ処理することになります。

sample_1.js
// 検索条件
const query = '"tunneltype="ssl-web" reason="login successfully" newer_than:2d -label:logged';

// スレッド取得
const myThreads = GmailApp.search(query);

  // スレッド単位でループ
  myThreads.forEach((myThread, indexThr) => {
    // スレッドからメッセージ取得
    const myMessages = myThread.getMessages();
    // スレッド内の各メッセージでループ
    myMessages.forEach((myMessage, indexMsg) => {
      // メール本文を取得
      const mailBody = myMessage.getPlainBody();

重複問題

前述のように各スレッド内のメッセージを読み出すことで、GAS からメールを見ることができます。
ここで複数スレッドが存在した場合、何故か異なるスレッドに同一のメッセージが含まれる事があります。普通にWebブラウザでメールを見たときはそんなことはないはずなのですが、何故か GAS からだとそのような動きになります。

以下はデバッグ用にログを採ったものですが、同じメッセージIDが異なるスレッドに存在していることが分かります。
image.png

実は「処理済みフラグを」付けるラベルを設定して重複対策しているのですが、ラベルではこの重複を回避できません。

回避策

処理済みのメッセージIDをどこかに記録しておき、重複チェックすることにしました。
今回はGoogleスプレッドシートにメッセージIDを記録します。

sample_2.js
// メッセージIDを取得
const msgId = myMessage.getId();

// 重複メッセージ判定
const textFinder = mySheet.createTextFinder(msgId);
const ranges = textFinder.findAll();
// 重複メッセージが存在しないことを確認(件数ゼロ)
if (ranges.length == 0) {
  // メールに対する処理

  // 1行目の前に空行を追加
  mySheet.insertRowBefore(1);
  //メッセージIDをG1セルに記録
  mySheet.getRange("G1").setValue(msgId);
}

このコードをつっこむことで無事重複を回避することができました。

考察

メール件数が増えてきたり、処理が重くなったりしたら Google スプレッドシートではなくデータベースなどを利用したほうがいいかもしれませんが、しばらくこれで様子を見てみます。

メッセージIDは世界で一つだけということになっているので、メッセージIDの重複は考えてません。

今回対象にしていたメールがネットワーク機器からのログで、syslog 経由で通知メールとして Gmail で受け取っていたものでした。このような宛先、送信元、件名などが毎回同じになるメールが重複の原因になりやすいのかもしれません。通常のメールであればここまでの重複チェックは不要かも?

以上

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?