📧

「こどもちゃれんじタッチ」からのメールをLINEに通知する

2023/06/10に公開

インフラエンジニアが初めての開発にチャレンジ。
Google Apps Script(GAS)を使ってGmailで受信したメールをLINEに通知した。

はじめに

■目的
こどもちゃれんじすてっぷタッチから届く個人宛メールをLINEに転送する。

■背景
パパのメールボックスが慢性的に未読多数の状態となっており、子どもからのメールが埋もれる&気づけない。

■メールのつくり

項目
From こどもちゃれんじタッチ < challenge_touch@mail.benesse.co.jp >
件名 お子さんからのメール
メール本文 返信URLを除き固定
添付ファイル messege.jpeg
※必ずファイルが1つ添付されている(ファイル名固定)
※子どもが自由にお絵描きした画像ファイル

■メールサンプル

■やりかた
Google Apps Scriptを使ってGmailで受信したメールから欲しい情報(件名、メール本文の一部、添付ファイル)のみを抽出し、LINE(LINE Notify)に通知する。
※このために、元々Outlookで受信していたメールをGmailに切り替えた。

前提条件

  • メールの送信上限は3通/日で設定
  • タブレットは約30分で休憩を促される(継続するには掛け算の回答が必要)ため、メールは約30分の間に最大3通届く可能性がある
    ⇒Gmailでは1スレッドに収まる

ざっくり手順

  1. Gmailアドレスを用意する
  2. ラベルを作成する
    「通知対象」…通知対象メールに付与する用
    「通知済み」…通知済みメールに付与する用
  3. フィルタを設定する
    条件: from:(challenge_touch@mail.benesse.co.jp) subject:(お子さんからのメール)
    処理: 受信トレイをスキップ, ラベル「通知対象」を付ける
  4. LINE Notifyのトークンを発行する
    トークン発行は参考サイトが沢山あるのでそちらを参照
  5. GASのコードを書く
  6. トリガーを設定する
  7. 「こどもちゃれんじタッチ」からのメールの宛先を1のアドレスに設定する

GASのコード

// トークン
var lineToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

// LINEに送信(添付ファイル付き)
function sendLineWithFile(lineToken, msg, file){
  let payload = {
    'message' :   msg,
    'imageFile': file
  };
  let options ={
    "method"  : "post",
    "payload" : payload,
    "headers" : {"Authorization" : "Bearer "+ lineToken}
  };
  UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}

function main() {
  // スレッド群を配列で取得
  let query = ('label:通知対象 -label:通知済み');
  let threads = GmailApp.search(query);
  console.log('スレッド数:', threads.length);

  // スレッド群からスレッドを1つずつ取り出して処理
  for( let i in threads ) {
    let thread = threads[i];

    // スレッド内のメール群を配列で取得
    let messages = thread.getMessages();
    console.log('メール数:', messages.length);

    // メール群からメールを1つずつ取り出して処理
    for( let j in messages ) {
      let message = messages[j];
      // 未読メールのみを処理
      if( message.isUnread() ) {
        let msg = "\n■" + message.getSubject()
         + "\n" + message.getPlainBody().slice(0, 250);
        console.log(msg);

        // 添付ファイルを配列で取得
        // contentType == "image/jpeg"
        let atchs = message.getAttachments();
        let contentType = atchs[0].getContentType();
        file = atchs[0].getAs(contentType);
      
       sendLineWithFile(lineToken, msg, file);
      }
    }
    // 既読にする
    thread.markRead();
    // ラベルを追加する
    let ISREAD_LABEL = GmailApp.getUserLabelByName('通知済み');
    thread.addLabel(ISREAD_LABEL);
  }
}

トリガー設定

できたー

やってよかった

  • パパが子どもからのメールに気づけるようになった。
  • 長ったらしい定型文を省いて必要な返信リンクだけを抽出。添付ファイルも一目で確認可能。リンクをタップしてアプリ内ブラウザでサクッと返信。気持ち良い。
  • パパにリリースするために自分のアドレスを使って検証していたものの、思いのほか使い勝手がよかったため自分もそのまま使い続けることになった。
  • JavaScriptの世界観(雰囲気)を感じることができた。
  • 細かいポイントや勉強になった点をNotionに記録として残した。Notionまともに触れたことなかったけどキッカケにできた(さわりだけなんだろうけど)

ひっかかったポイント

  • クラス、メソッド、APIや配列の概念(ふんわりしていた)
  • 通知したいメールのみの抽出(スレッド単位でしかsearchできないことを知らなかった)

注意点

こどもちゃれんじタッチからはこのメールだけでなく、日々のレッスンの取り組み連絡等も届くがそちらは通知されない。

さいごに

もっとシンプルなコードにしたり改善できる点がきっとあると思うけど、ひとまず完成させることができて満足。楽しかった(^^)
開発をメインにお仕事されている皆さんへの尊敬が高まった。

参考にさせていただいたサイト

https://for-dummies.net/gas-noobs/gas-japanese-reference-for-gmail/
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app?hl=ja
https://notify-bot.line.me/doc/ja/
https://qiita.com/kazumax1027/items/6f5c9ef83afb22a3478d
https://velleity-note.blog/web-service/gmail-line/

Discussion