見出し画像

Gmailをスプレッドシートに自動転記

はじめに

今回は受信したGmailの中から特定の件名のみ抽出し、スプレッドシートに必要な内容を転記していきたいと思います。

GmailにWEBサイトのフォームを飛ばし申し込みを受け付ける、あるいはECの購入時にGmailに転送させるなど、何らかの方法でGmailに届いたメールの中から、必要な情報(商品情報や顧客情報など)ログとしてスプレッドシートに蓄積する場合などが該当します。
もし自動化しない場合、毎日○時にチェックして、そこまでで溜まっていた分だけ手動で入れるという方法をとることになります。
しかしこれは自動で行うことができるんです。
そこで今回もGASを使ってこれらの処理を自動化していきます。

※GASとは・・・
Google Apps Scriptという、Googleのサービスをカスタムできるプログラミングのサービスです。(Microsoft officeでいうVBAみたいな)

プログラミングが初めての方でもできるように手順を説明していますので、ぜひ参考にしてみてください。

仕組み

まずどのようにして自動化されているのかざっくりイメージをご説明します。

プロセスとしては大きく3つで、

①メールがたまる
②定時でメールを取得
③スプレッドシートに転記

と意外と単純です。

それでは実際に作っていきます。

手順①スプレッドシートを用意する

適当なスプレッドシートの拡張機能を開いて拡張機能からGoogle Apps Scriptを開きます。

後はここにコード(プログラム)を書けば自動になります。

手順②コードを書く

別にコードを書かなくても、↓をコピペしていただければ大丈夫です。

ただ、抜き出したい情報や処理対象のメールの本文などによってもコードが変わってきますので、カスタマイズできるように説明していきます。

function mail(){
  const query = 'is:unread subject:"購入手続き完了のお知らせ"'
  const threads = GmailApp.search(query)
  const datas = threads.map((thread)=>{
    const messages = thread.getMessages()
    const body = messages[0].getPlainBody()
    const trackingNumber = body.indexOf("【購入番号】")
    const name = body.indexOf("【氏名】")
    const mail = body.indexOf("【メールアドレス】")
    const day = body.indexOf("【購入日】")
    const trackingNumberData = body.substring(trackingNumber + 8, name - 4)
    const nameData = body.substring(name + 6, mail - 4)
    const mailData = body.substring(mail + 11, day - 4)
    const dayData = body.substring(day + 7, body.length - 4)
    const today = new Date()
    const data = [today , trackingNumberData , nameData , mailData , dayData]
    thread.markRead()
    return data
  })
  const ss = SpreadsheetApp.openById("1F6b4zQxltFSkShFvxXTwnlQwi1McpVT_jHPWjSjzXQw")
  const sh = ss.getSheetByName("購入履歴")
  const lastRow = sh.getLastRow()
  sh.getRange(lastRow + 1,1,datas.length,datas[0].length).setValues(datas)
  SpreadsheetApp.flush()
}

手順③トリガーの設定

さっき書いたプログラムをいつ実行するかの設定です。残念ながらメールを受けた時に都度実行するというトリガーは存在しないので、ここでは時間主導型のトリガーを利用します。

※時間主導型のトリガーとは、毎日何時とか何曜日の何時など、時間をベースにしてプログラムを自動的に実行します。

①トリガーを開く

②右下のトリガーを追加押して、トリガーを設定

  • 実行する関数:mail(手順2の関数名)

  • イベントのソースを選択:時間主導型

  • 時間ベースのトリガーのタイプを選択:時間ベースのタイマー

  • 時間の間隔を選択:1時間おき

手順④プログラム認証

コードを実行する前に初回実行時限定で認証作業をクリアしておく必要があります。
(こちらは最初だけなので、2回目以降は普通に実行できます。)

詳しくは↓の記事を参考にしてみてください。

要点解説

メール本文の取得

メールの本文を取得するには直接はできません。階層構造を順に下る必要があります。
Gmailはこのような構造になっています。

スレッド > メッセージ > 本文

なかなか聞きなれない言葉かもしれませんが、Gmailではスレッドという単位でメールが管理されます。
このスレッドというのは送信元と件名が同一のメールの集合です。

この赤1個1個がスレッドです。2とか4など数字が表示されていると思いますが、それがパックされているメッセージの件数を指します。

展開するとこんな感じ

一つのスレッドの中に4つのメッセージが含まれていることがわかります。

そしてこれらスレッドやメッセージを一度に複数個処理することができます。

↑で行くと5つのスレッドを配列にまとめて処理ができます。

※配列とは
複数データの処理を円滑にするために[ ]で括られたデータを指します。これはGASのベースであるJavaScriptやその他の言語でも使用されるデータ型の一種です。詳しくは↓

今回は複数にまとめられたスレッドをthreads、複数にまとめられたメッセージをmessagesとして定数に格納しそれぞれに同じ処理をしています。

イメージで言うとこんな感じ

threads = [スレッド1,スレッド2,スレッド3,スレッド4,スレッド5]

スレッド1 = [メッセージ1,メッセージ2,メッセージ3,メッセージ4]

従ってより階層構造を整理すると、

threads > スレッド > messages > メッセージ > 本文

となります。複数のスレッド→そのうち1スレッド→全メッセージ→1件のメッセージ→本文といった具合です。

構造がある程度理解できたと思うので、具体的な方法を説明します。

GmailApp.search()

特定条件に合致するスレッドを抽出できるのが、このsearchメソッドです。
イメージは↓のような状態です。

条件を満たすスレッドを全て取得します。

検索条件などの詳細はこのサイトが参考になります。

thread.getMessages()

このメソッドを使うことで、threadとしてパックされている複数のメッセージを配列として取得できます。
イメージ的には↓の状態です。
あるスレッド内のメールを全て取得します。

thread.markRead()

スレッドを既読としてマークするメソッドです。今回の例では未読のスレッドを条件としているので、処理が終わったスレッドは既読にする必要があります。.searchメソッドの条件に「未読」を指定する場合は忘れずに設定してください。

メール本文から特定文字列を抽出

これは文字列を抽出できる.substring()メソッドを使います。
このメソッドの引数は二つでどちらも数字です。

  • 抽出開始位置

  • 抽出する文字数

そのため本文全体の中から目印となる文字列の位置を.indexOf()メソッドで抽出しています。indexOf()メソッドは引数に指定した文字列の頭の位置を数字で返します。それにその目印の文字数を足してあげれば、目的の文字列を抽出できます。

今回の例では↓のようなメール本文を想定しています。

スプレッドシート転記のポイント

スプレッドシートに転記する時は必ずAPIの呼びだじが入るため、1つずつ挿入していたらそれだけで時間がかかります。

そこでデータを一個にまとめて一括で転記します。そこでも役に立つのが配列です。

const datas = [
 [1行目の1列目,1行目の2列目,1行目の3列目],
 [2行目の1列目,2行目の2列目,2行目の3列目],
 [1行目の1列目,1行目の2列目,1行目の3列目]
]

sh.getRange(1,1,datas.length,datas[0].length).setValues(datas)

まとめ

以上でGmailから情報を抜き出してスプレッドシートに転記できます。
ポイントはメールの階層構造の部分です。そこが理解できれば多様な条件で取得〜処理までできると思います。

この記事が気に入ったらサポートをしてみませんか?