Power AutomateでLINEに通知するフローを作成した話。
Googleスプレッドシートのデータを元に、GASで未送信データを検知してLINE通知する仕組みを実装。自動通知の流れを1つの構成として完成させます。
未送信データの管理、送り先の切り替え、トリガー設定までをまとめます。
GoogleスプレッドシートでLINE通知データを管理する
部品としてあとから使いやすいように、今回は「Googleスプレッドシートにデータが書き込まれたら、その値をもとにLINE通知をする」という仕組みを完成させる。
Power Automateからは、Googleスプレッドシートにデータを書き込むだけで好きなタイミングでLINE通知ができるようになるという想定。
Googleスプレッドシートのデータ構成
Googleスプレッドシートのデータ構成は以下のように設定した。
| 列 | 項目 | 説明 |
|---|---|---|
| A列 | ID | Power Automateからのランダム識別子 |
| B列 | 種別 | LINEかその他か、後の拡張を考えて設置 |
| C列 | 送り先 | グループIDの指定 自分 / 共有 |
| D列 | 件名 | LINE通知には未使用 |
| E列 | 本文 | LINEで実際通知される本文 |
| F列 | 状態 | 未:送信対象 / 済:送信済み(再送防止) |
| G列 | 送信日時 | 送信した日時を残す |
今後の拡張を考えてLINE通知するだけなら不要な項目のD列の「件名」列も作成し、B列の「種別」がLINEになっているものだけ送信するという仕組みにしてみた。
※使い道は今のところ決めていませんが、後から通知方法を増やす可能性を考えて残しています。
前回の記事で、スクリプトプロパティに下記3つを設定した。
- LINE_API_KEY:チャネルアクセストークン(長期)
- LINE_GROUP_ID_GP:前回の記事で取得したLINE公式アカウント・私・夫のグループID
- LINE_GROUP_ID_USER:前回の記事で取得したLINE公式アカウント・私のグループID
Google Apps ScriptでC列の「送り先」が
「自分」となっているときは「LINE_GROUP_ID_USER」のグループIDを使用し、
「共有」となっているときは「LINE_GROUP_ID_GP」のグループIDを使用して送信する。
個人的に自分にだけ通知したい内容は「自分」、夫と共有したい内容については「共有」を指定してGoogleスプレッドシートに書き込めば振り分けができる。
Google Apps Scriptのコードを記述する
実際にコードを記述していく(※記述場所やデプロイについては前回の記事もご参考ください。)
以下のコードは、LINE公式アカウントを個人用途で検証するためのサンプルです。
公開Botなど、不特定多数の人が使う用途は想定していません。
チャネルアクセストークンやグループIDなどの値は、外部に公開しないよう注意してください。
コードは生成AIを用いて作成しており、利用は自己責任でお願いします。
function sendLineFromSheet_UnsentOnly() {
const lock = LockService.getScriptLock();
if (!lock.tryLock(5000)) return;
try {
const props = PropertiesService.getScriptProperties();
// スクリプトプロパティでチャネルアクセストークン(長期)をLINE_API_KEYに設定しておく
const token = props.getProperty('LINE_API_KEY');
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('Data');
if (!sheet) return;
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
// まず F列(送信状態)だけ取得
const statusRange = sheet.getRange(2, 6, lastRow - 1, 1); // F2:F
const statusValues = statusRange.getValues();
// 未処理行の行番号を集める
const targetRows = [];
for (let i = 0; i < statusValues.length; i++) {
if (statusValues[i][0] === '未') {
targetRows.push(i + 2); // 実際の行番号
}
}
// 未処理がなければ即終了(ここが省エネ)
if (targetRows.length === 0) return;
const now = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss');
// 未処理行だけ処理
for (const rowNum of targetRows) {
const row = sheet.getRange(rowNum, 1, 1, 7).getValues()[0];
// B列=送信手段がLINEのみ
if (row[1] !== 'LINE') continue;
let targetId = '';
// スクリプトプロパティで、LINE_GROUP_ID_GP と LINE_GROUP_ID_USER にグループIDを設定しておく
switch (row[2]) {
case '共有':
targetId = props.getProperty('LINE_GROUP_ID_GP');
break;
case '自分':
targetId = props.getProperty('LINE_GROUP_ID_USER');
break;
default:
targetId = props.getProperty('LINE_GROUP_ID_USER');
}
if (!targetId) continue;
const message = row[4];
const options = {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
},
payload: JSON.stringify({
to: targetId,
messages: [{ type: 'text', text: message }]
}),
muteHttpExceptions: true
};
const res = UrlFetchApp.fetch(
'https://api.line.me/v2/bot/message/push',
options
);
if (res.getResponseCode() === 200) {
// 成功した行だけ更新
sheet.getRange(rowNum, 6).setValue('済'); // F列
sheet.getRange(rowNum, 7).setValue(now); // G列
}
}
} finally {
lock.releaseLock();
}
}
Google Apps Scriptのトリガーを設定する
実行トリガーを設定する。
今回は、いつGoogleスプレッドシートに書き込まれるかわからないため、スプレッドシートに書き込まれたあとどのくらいの時間で実行したいかを考えて頻度を設定する必要がある。
1分で設定すると、ちょくちょくエラーが発生するようだったので、10分間隔くらい(短くても5分)で設定することを推奨する。


- Google Apps Scriptの左メニューの「トリガー」を選択
- 右下の「トリガーを追加」をクリック
- 実行する関数は記述したコードの関数名を選択
- 実行するデプロイは「Head」
- イベントのソースは「時間主導型」
- 時間ベースのトリガーのタイプは「分ベースのタイマー」
- 時間の間隔は「10分おき」
- 保存ボタンを押す
これでGoogle Apps Script側の準備は完了。
実際にGoogleスプレッドシートに書き込んでみる
テストとして、Googleスプレッドシートに1行手動でデータを追加する。
以下の4か所だけ値を入れればOK。
| 列 | 項目 | 値 |
|---|---|---|
| B列 | 種別 | LINE |
| C列 | 送り先 | 自分 |
| E列 | 本文 | テスト |
| F列 | 状態 | 未 |
しばし待ってLINEに通知が入り、F列の状態が「済」G列の送信日時に送信された時刻が入れば成功。
C列を「共有」にした場合なども試してみて、グループの鳴り分けも問題なく実施されるため、これで、Googleスプレッドシートに書き込まれた内容をもとにLINE通知する部品は完成とする。
※10分待つのは結構長いので、テストの間だけトリガーの時間の間隔を1分にしても良いと思います。
部品としてのGoogle Apps Scriptの用意は終わったため、次回はPower Automateから狙った時間に通知を送る設定をする。
※次回記事は現在執筆中です。


