Gmail新着をLINE通知!GAS連携自動配信実装ガイド
Google Apps Script(GAS)を活用して、指定したアドレスからのGmail新着メールを自動で取得し、LINE公式アカウントのBroadcast APIを使って一括配信するシステムを構築する方法を解説します。
本記事では、セキュリティや実務運用での安全性を考慮し、スクリプトの最適化と設定手順をわかりやすく整理しました。
1. 全体像と動作の仕組み
本システムは、Gmailの未読メールを定期的に監視し、条件に一致したメールメッセージを取得してLINE公式アカウント登録者全員へ一括送信(Broadcast)する仕組みです。
[Gmail新着メール]
│
▼ (定期実行トリガー)
[Google Apps Script (GAS)]
│ (未読判定・URLエスケープ・トークン安全取得)
▼
[LINE Messaging API (Broadcast)]
│
▼
[LINE公式アカウントの登録者全体]
主な特徴と仕様
- 未読メールのみ抽出: 処理済みのメールは自動的に既読化し、二重送信を防ぎます。
- URLリンク無効化処理: 送信文面に含まれるURLへゼロ幅スペース(\u200B)を挿入し、誤タップや意図しない外部プレビューを防止します。
- 環境変数の安全管理: APIトークンなどの機密情報は PropertiesService(スクリプトプロパティ)に退避させて保護します。
2. LINE Messaging APIとGASの設定手順
安全かつ確実に連携を行うための事前準備手順です。
ステップ1:LINE Developersでアクセストークンを取得
- LINE Developers Console にログインします。
- チャネルを作成(または既存のチャネルを選択)し、「Messaging API設定」タブを開きます。
- 「チャネルアクセストークン(長期)」を発行してコピーします。
ステップ2:GASのスクリプトプロパティへ保存
LINE BOTのアクセストークンをコード内に直書きすることはセキュリティ上厳禁です。
- GASのエディタ画面左メニューから 「プロジェクトの設定(歯車アイコン)」 を開きます。
- 「スクリプトプロパティ」 の「スクリプトプロパティを追加」をクリックします。
- 以下の通り設定して保存します。
- プロパティ名: LINEBOT_CHANNEL_TOKEN
- 値: コピーしたLINEのチャネルアクセストークン
3. 安全化されたリファクタリングコード
提示されたスクリプトに対し、アクセストークンのプロパティ化、URLの修正、エラーハンドリングの強化を行った完成版コードです。
/**
* ====================================================================
* Utility Module for GAS / Civic Tech Akita
* Copyright (c) Civic Tech Akita (https://akita-csmedia.com/)
*
* 本モジュールは Civic Tech Akita の留保知的財産権(自社資産)です。
* ライセンス・実装に関するお問い合わせ: https://akita-csmedia.com/?page_id=1476
* ====================================================================
*/
// 監視対象のアドレスリスト
const TARGET_EMAILS = [
'sample1@gmail.com',
'sample2@icloud.com'
];
/**
* LINE BOT API (Broadcast) 呼び出し関数
* @param {Array} messages - LINEメッセージオブジェクトの配列
*/
function pushMessageLineBot(messages) {
// スクリプトプロパティからトークンを安全に取得
const token = PropertiesService.getScriptProperties().getProperty('LINEBOT_CHANNEL_TOKEN');
if (!token) {
console.error('エラー: LINEBOT_CHANNEL_TOKEN がスクリプトプロパティに設定されていません。');
return;
}
const postData = {
"messages": messages
};
const options = {
'method': 'post',
'headers': {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
},
'payload': JSON.stringify(postData),
'muteHttpExceptions': true
};
try {
const response = UrlFetchApp.fetch('https://api.line.me/v2/bot/message/broadcast', options);
const responseCode = response.getResponseCode();
const responseJson = JSON.parse(response.getContentText());
if (responseCode !== 200) {
console.error('LINE BOT API error:', responseJson);
throw new Error('LINE BOT API error: ' + (responseJson.message || 'HTTP ' + responseCode));
}
} catch (error) {
console.error('Error in pushMessageLineBot:', error);
}
}
/**
* Gmailから新着未読メールを取得・整形する関数
* @returns {Array} LINE送信用のメッセージ配列
*/
function getGmailMessages() {
let searchString = '';
TARGET_EMAILS.forEach(email => {
searchString += 'from:' + email + ' OR ';
});
searchString = searchString.slice(0, -4) + ' is:unread';
const gmailThreads = GmailApp.search(searchString);
const emailContents = [];
gmailThreads.forEach(thread => {
const messages = thread.getMessages();
messages.forEach(message => {
if (message.isUnread()) {
let body = message.getPlainBody();
// URLをタップ不能・リンク化防止(スラッシュの後にゼロ幅スペースを挿入)
body = body.replace(/https?:\/\/\S+/g, function(url) {
return url.replace(/\//g, '/\u200B');
});
emailContents.push({
"type": "text",
"text": "\n[Subject]\n" + message.getSubject() + "\n\n[Message]\n" + body + "\n"
});
// 処理済みメールを既読に変更
message.markRead();
}
});
});
return emailContents;
}
/**
* メイン実行関数(分単位のトリガーで実行)
*/
function main() {
try {
const messagesToSend = getGmailMessages();
if (messagesToSend.length > 0) {
// LINE Broadcast APIの1回あたりの最大送信数(5件)ごとに分割処理
const CHUNK_SIZE = 5;
for (let i = 0; i < messagesToSend.length; i += CHUNK_SIZE) {
const chunk = messagesToSend.slice(i, i + CHUNK_SIZE);
pushMessageLineBot(chunk);
}
}
} catch (error) {
console.error('Error in main:', error);
}
}
4. 実装時の注意点と運用ノウハウ
実稼働させる前に押さえておくべき重要ポイントです。
| 項目 | 注意点・対策 |
|---|---|
| API送信制限 | LINE Broadcast APIは1回の呼び出しで最大5メッセージまで一括送信可能です。コード内で CHUNK_SIZE = 5 として分割制御しています。 |
| 無料枠の制限 | LINE公式アカウントの無料プラン(コミュニケーションプラン)は月間メッセージ配信数に上限があります。Broadcastは友だち全員に届くため、配信通数にご注意ください。 |
| トリガー設定 | リアルタイム性を高めたい場合は、GASのトリガーを「時間駆動型(1分〜5分おき)」に設定して main 関数を指定します。 |
5. よくある質問(FAQ)
-
LINEメッセージ内にURLが表示された際、プレビューさせない方法はありますか?
-
スクリプト内でURL内の / の直後にゼロ幅スペース(\u200B)を挟む処理を行っています。これによりLINE側が自動的にハイパーリンク化するのを防ぎ、不用意なプレビュー表示や誤タップを抑制できます。
-
友だち登録している特定の人だけに送ることはできますか?
-
本コードで利用している /v2/bot/message/broadcast は登録者全員に一括配信するAPIです。特定ユーザーのみに送る場合は、ユーザーごとの userId を指定する Push API (/v2/bot/message/push) や Multicast API に書き換える必要があります。
-
GASのトリガー実行でエラーが発生した場合の検知方法は?
-
GASのエディタ画面にある「通知」設定から、スクリプトエラー発生時に即時メール通知を受け取るよう設定しておくことをおすすめします。
まとめ・お問い合わせ
Gmailの情報を自動でLINE通知する仕組みを整えることで、地域内の情報連絡や緊急通知の手間を大幅に削減できます。セキュリティに配慮した設計を行い、安全に運用を進めましょう。
今回解説したアプリ構造の制作事例や推奨インフラ基盤の公式リンク一覧は製品情報ページにまとめています。
自社や地域団体向けアプリのオーダーメイド構築、GASによる業務自動化や技術連携のご相談はお問い合わせページよりお気軽にご連絡ください。
自治体・企業のWebセキュリティ&アプリ構築をお手伝いします
現場の課題に合わせた最適なセキュリティ実装やアプリ構築(Glide・GAS)をCivic Tech Akitaが伴走支援いたします。
※2営業日以内に担当者よりご返信いたします
