割と誰でも当たり前にやっている、Google Apps Script(GAS)で作るLINE Bot。 かつては「GASではLINEbotは作れない」と言われていた時期もありましたが、コロナ前、必死に試行錯誤していたら実はできることが分かり、今やそれは一般常識になりました。
そして今回、長年「GASではまともに動かせない」と言われてきたのが LIFF(LINE Front-end Framework) です。 私も一度は挫折しましたが、「やっぱりできるはずだ」と挑み続けた結果、ついに「接続拒否」も「無限ループ」も「真っ白な画面」も出さない実装に辿り着きました。
起きていたエラー
接続拒否
無限ループ
真っ白な画面
2026年1月初旬に、この感動の全容とハンズオン解説をYouTubeにアップする予定ですが、まずは核心となるプログラムをここに記しておきます。
解決のために頑張ったこと2つ
- SDKをあえて使わない
LIFF SDKの標準認証がGASのサンドボックス環境と相性が悪いため、バックエンド側で認証を通す構成にしています。これにより、GASでも100%確実にユーザー情報を取得できるLIFFアプリを実現しました。
-
target="_top"の活用
フロントエンド側で、Googleのiframeガードを無効化するため、JavaScriptではなくHTMLリンクで最上層からリダイレクトしています。
実装手順
まず、Apps Scriptの画面を開き、右上の「デプロイ」から、「新バージョン」でウェブアプリを選択し、URLを発行してください。その時、アクセスできるユーザーは「全員」にしておいてください。
次に、LINE Developers のページでプロバイダーを作成してください。
チャネルは「LINE login」を選択してください。
登録していく際、Endpoint URLのところに、先ほどApps Scriptの画面で発行したウェブアプリのURLを貼ってください。
あとは、とりあえず適当に入力して、LIFFのIDを発行してください。入力が終わると、コピーできるようになっているはずです。
ここまでできたら、Apps Scriptの中で、プログラムを変えていきます。
下記のプログラムをコピペします。
あなたのチャネルID と あなたのチャネルシークレット と {{***WebアプリのID***}} の部分だけ、書き換えてください。
バックエンド側のプログラム
/**
* ログイン前はボタンを表示し、LINEからの戻り(code付き)時は名前を表示する
*/
function doGet(e) {
var code = e.parameter.code;
var userName = "";
if (code) {
// 認証コードがあるなら、サーバーサイドからLINE APIを叩いて名前を取得
userName = getUserNameFromCode(code);
}
var template = HtmlService.createTemplateFromFile('index');
template.userName = userName;
return template.evaluate()
.setTitle('GAS×LIFF 連携アプリ')
.addMetaTag('viewport', 'width=device-width, initial-scale=1')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
/**
* 認証コードをアクセストークンに交換し、プロフィールを取得する
*/
function getUserNameFromCode(code) {
const CHANNEL_ID = 'あなたのチャネルID';
const CHANNEL_SECRET = 'あなたのチャネルシークレット';
const REDIRECT_URI = 'https://script.google.com/macros/s/{{***WebアプリのID***}}/exec';
try {
// 1. codeをアクセストークンに交換
var tokenRes = UrlFetchApp.fetch('https://api.line.me/oauth2/v2.1/token', {
method: 'post',
payload: {
grant_type: 'authorization_code',
code: code,
redirect_uri: REDIRECT_URI,
client_id: CHANNEL_ID,
client_secret: CHANNEL_SECRET
},
muteHttpExceptions: true
});
var tokenData = JSON.parse(tokenRes.getContentText());
if (!tokenData.access_token) return "トークン取得エラー";
// 2. アクセストークンを使ってユーザープロフィールを取得
var profileRes = UrlFetchApp.fetch('https://api.line.me/v2/profile', {
headers: { Authorization: 'Bearer ' + tokenData.access_token }
});
return JSON.parse(profileRes.getContentText()).displayName;
} catch (e) {
return "取得失敗: " + e.toString();
}
}
フロント側のプログラム
新規ファイルを作るのですが、HTMLの方を選択してください。
下記のプログラムをコピペします。
{{***あなたのチャネルID***}} と {{***WebアプリのID***}} の部分だけ、書き換えてください。
<!DOCTYPE html>
<html>
<head>
<base target="_top"> </head>
<body style="font-family: sans-serif; text-align: center; padding-top: 50px; line-height: 1.6;">
<h2>GAS × LINE 連携テスト</h2>
<? if (userName) { ?>
<div style="background: #e1f5fe; padding: 20px; border-radius: 10px; display: inline-block; border: 1px solid #0288d1;">
<p style="margin: 0; color: #555;">ログインに成功しました!</p>
<h1 style="color: #0288d1; margin: 10px 0;">こんにちは、<?= userName ?> さん</h1>
</div>
<? } else { ?>
<div id="login-area">
<p>LINEでログインして開始してください</p>
<a href="https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id={{***あなたのチャネルID***}}&redirect_uri=https%3A%2F%2Fscript.google.com%2Fmacros%2Fs%2F{{***WebアプリのID***}}%2Fexec&scope=profile%20openid&state=gas-login"
style="display: inline-block; padding: 15px 40px; background: #06C755; color: white; text-decoration: none; border-radius: 8px; font-weight: bold; font-size: 18px; box-shadow: 0 4px 0 #05a346;">
LINEでログイン
</a>
</div>
<? } ?>
</body>
</html>
以上のプログラムでデプロイしてください。2回目以降は、Apps Script画面の「デプロイの管理」から、右上の鉛筆マークの「編集」を押し、「新バージョン」でデプロイすれば、URLを変えずにデプロイできます。
これで、発行しているLIFFのURLを開き、LINEでログインしてください。
下のような成功画面が出ていれば、成功です!
成功画面
宣伝
Udemyでは、Google Apps Script(GAS)やWebの講座、それからChatGPT×LINEの講座も出しています。今回の内容がより分かるようもなると思いますので、もし興味があればご受講ください。










