公式LINEでユーザー登録したときに、どこからユーザー登録したかをURLのパラメータと紐づけることで把握したい場合があります。
例えば、申込フォームで申込を完了したときに、LINEのユーザー登録をした人の情報を、フォームの情報と紐づけたい場合などです。
ここでは、URLパラメータを取得して、公式LINEで友だち追加(LINE登録)した時にユーザー情報を取得してスプレッドシートに自動入力する方法(リンク追跡方法)を解説しています。
Webhookでパラメータを取得できない
友だち追加のURLにパラメータを付与して、LINE Messaging APIのWebhookを使って、そのパラメータを取得できると、紐づけがとても簡単です。
ですが、残念ながら今のところWebhookで友だち追加のURLのパラメータをイベントとして取得することはできません。
例えば、「https://line.me/R/ti/p/@lineID?ref=1234」のような友だち追加URLを作成し、Webhookで登録したURLにPOSTで送信されたデータを、{ref, 1234}のような形で取得することはできません。
解決策:LIFFアプリを使う
解決策として、LIFFアプリを使ってログイン情報を取得してすぐに、トーク画面にリダイレクトさせる方法があります。
LIFFアプリではURLのパラメータを取得できるので、取得したデータとユーザー情報を、友だち登録が完了したときにWebhookで送信されるユーザー情報と紐づけることで対応できます。
処理の流れは以下のようになります。
LIFFアプリのリンクにパラメータを付与する
↓
LIFFアプリを開いたら、パラメータやユーザーIDを取得する
↓
取得したデータをGASにGETで送信する
↓
取得したデータをスプレッドシートに書き込む
↓
指定したユーザーIDの友だち追加画面を開く
↓
友だち登録のイベントをMessaging APIのWebhookで取得する
↓
パラメータとWebhookのイベントをマッチさせる(友だち登録の確認)
以上の流れで、こちらが設定した固有のパラメータとユーザーIDを紐づけることができます。
LIFFアプリとは何かや使い方については下記をご参考ください。
作成の大まかな流れ
URLに付与したパラメータとユーザーIDなどの情報を取得するための、一連の仕組みを作成する大まかな流れは以下のようになります。
- LINE Messaging APIでイベントを取得する(POST: doPost)
- GASのアプリケーションをデプロイ(GET: doGet)
- WEBアプリケーションの作成(LIFFアプリ登録用)
- LINEログインチャネルの作成
- LIFFアプリの作成
LINE Messaging APIでイベントを取得する
LINE Messaging APIでイベントを取得する方法については下記をご参考ください。
上記の記事のコードの場合、メッセージのイベントも取得するようになっています。このため、友達の人数やメッセージのやり取りが多い場合にデータ量が膨大になります。
今回は、ユーザー情報と友だち追加あるいはブロック(解除)の情報が取得できればいいので、GASのコードは以下のようにします。
// スプレッドシートのIDとシート名を設定
const ACCESS_TOKEN = "チャネルアクセストークン";
const SPREADSHEET_ID = 'スプシID';
const SHEET_NAME = 'シート名';
// LINEのWebhookからイベントデータを受信する
function doPost(e) {
const eventData = JSON.parse(e.postData.contents);
// スプレッドシートのシートを取得
const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
// イベントごとに処理を行う
eventData.events.forEach(event => {
const eventType = event.type; // イベントタイプ(例: message, follow, unfollowなど)
const userId = event.source.userId || '不明なユーザー';
let eventContent = '';
// 指定のイベントタイプのみ処理
if (eventType === 'follow') {
eventContent = '友だち追加';
} else if (eventType === 'unfollow') {
eventContent = '友だち削除';
} else if (eventType === 'join') {
eventContent = 'グループ参加';
} else if (eventType === 'leave') {
eventContent = 'グループ退出';
} else {
// その他のイベントは処理しない
return;
}
// ユーザープロファイルを取得
let userProfile = getUserProfile(userId);
// スプレッドシートに書き出す
sheet.appendRow([new Date(), userId, userProfile.displayName, userProfile.pictureUrl, eventType, eventContent]);
});
}
// LINE APIからユーザー情報を取得
function getUserProfile(userId) {
const url = `https://api.line.me/v2/bot/profile/${userId}`;
const options = {
"headers": {
"Authorization": "Bearer " + ACCESS_TOKEN
},
"method": "GET",
};
const response = UrlFetchApp.fetch(url, options);
return JSON.parse(response.getContentText());
}
Apps Scriptでコードを修正した場合は、再度デプロイして、発行されたURLをWebhookに登録する必要があります。
以上で、友だち登録のイベントが発生したときに、指定したシートにユーザー情報やイベント情報を自動で追加していきます。
GASのアプリケーションをデプロイ(GETで取得した情報を入力する)
続いて、LIFF用のWEBアプリで取得したデータを、スプレッドシートにGETで送信するためのApps Scriptを作成します。
const spreadsheetId = "スプシID";
const sheetName = "シート名";
// doGet関数でGASへのGETリクエストを処理する
function doGet(e) {
try {
const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
const parameter = e.parameter.id || 'idなし';
const userId = e.parameter.userId || 'userIdなし';
const displayName = e.parameter.displayName || '表示名なし';
const pictureUrl = e.parameter.pictureUrl || '画像URLなし';
const timestamp = new Date();
// スプレッドシートにパラメータとユーザー情報を追記
sheet.appendRow([timestamp, parameter, userId, displayName, pictureUrl]);
return ContentService.createTextOutput('OK');
} catch (error) {
return ContentService.createTextOutput('Error: ' + error.message);
}
}
GETメソッドでデータが送信されてきたときに、パラメータに含まれている「id」「userId」「dispalyName」「pictureUrl」を取得して、スプレッドシートに追記します。
作成が完了したらデプロイしておきます。デプロイしたURLはLIFFアプリの中で使用します。
WEBアプリケーションの作成(LIFFアプリ登録用)
続いて、LIFFアプリに登録するためのWEBアプリケーションを作成します。
コードは以下のようにします。次の3つのデータは個別に入力する必要があります。
- liffId
変数のliffIdにLIFFアプリのIDを入力する必要があります。LIFFアプリ作成後にIDを入力してください。 - deployedUrl
デプロイしたURLを入力します。(doPostの最新版) - window.location.href
公式LINEのユーザーIDを入力します。(LIFFアプリでデータ送信した後に、公式LINEの友だち追加画面にリダイレクトします)
<head>
<title>LINE Login via LIFF</title>
<script src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>
</head>
<body>
<div id="line-modal" class="line-modal">
<div class="line-modal-content">
<div style="margin: 32px 0px auto; text-align: center;">
<img src="https://example.com/ロゴ.png" width="300">
</div>
<div style="margin: 16px auto;">
<div style="text-align: center; color: #bbb;">
ページ読み込み中…
</div>
</div>
</div>
</div>
<script>
// LIFFの初期化とユーザー情報の取得
async function main() {
const liffId = 'LIFFアプリのIDを入力';
await liff.init({ liffId });
// URLのパラメータから「id」を取得
const urlParams = new URLSearchParams(window.location.search);
const parameterId = urlParams.get('id');
// ログイン状態を確認し、未ログインの場合はログイン
if (!liff.isLoggedIn()) {
// ログインしていない場合、パラメータを保持してログイン
liff.login({ redirectUri: `${window.location.href}` });
return;
}
// LIFF SDKでユーザー情報を取得
const profile = await liff.getProfile();
const userId = profile.userId;
const displayName = encodeURIComponent(profile.displayName); // エンコード
const pictureUrl = encodeURIComponent(profile.pictureUrl); // エンコード
// GASのエンドポイントURLにパラメータとユーザー情報を送信
const deployedUrl = "デプロイしたURL";
const gasUrl = `${deployedUrl}?id=${parameterId}&userId=${userId}&displayName=${displayName}&pictureUrl=${pictureUrl}`;
fetch(gasUrl)
.then(response => response.text())
.then(data => {
console.log(data); // 成功メッセージの表示
// データ送信が完了したら友だち登録画面にリダイレクト
window.location.href = 'https://line.me/R/ti/p/公式LINEのユーザーID';
})
.catch(error => console.error('Error:', error));
}
main();
</script>
全画面を覆うモーダルが表示され、ロゴのイメージと「ページ読込中・・・」というテキストを表示します。(ロゴのURLは適宜変更してください)

GASへのデータ送信が完了すると、通常のLINEのログインページ(友だち済みの場合はトーク画面)にリダイレクトします。
なお、liff.login({ redirectUri: ${window.location.href} });
が重要です。これがないと、LINEにログインしたときにパラメータが削除されて取得した値が「null」になってしまいます。
上記内容でWEBページを公開します。
LINEログインチャネルの作成
LIFFアプリを作成するには、LINEログインチャネルを作成する必要があります。(LIFFアプリはLINEログインチャネルの中の機能の一つです)
LINE Developersにログインして、Messaging APIで作成したプロバイダーを選択し「新規チャネル作成」をクリックします。

「LINEログイン」をクリックします。

入力項目があるので、必須情報などを入力していきます。
アプリタイプは「ウェブアプリ」を選択します。

- ウェブアプリ:ウェブページにLINEログインを組み込む場合。
- ネイティブアプリ:iOS/AndroidのアプリにLINEログインを組み込む場合。
2要素認証はOFFでも問題ありません。(ONの場合、認証番号を入力します。)

開発者契約に同意し「作成」をクリックします。

LIFFアプリの作成
先ほど作成したWEBアプリのURLを取得しておきます。
メニューの「LIFF」をクリックします。

「追加」をクリックします。

LIFFアプリの情報を入力していきます。
サイズ(Full, Tall, Compact)
サイズには「Full」「Tall」「Compact」mの3つがあります。選択内容によって、LINEの画面上での表示サイズが変化します。

(参考)LINE Front-end Framework (LIFF)
ここではFullを選択します。

エンドポイントURL
エンドポイントURLに先ほど公開したアプリのURLを入力します。

エンドポイントURLに登録したURLが、LIFFアプリの認証後に表示されます。
Scope
Scopeは次の3つが用意されています。使いたいメソッドに合わせて選択します。

openid
:liff.getIDToken()
およびliff.getDecodedIDToken()
を使用するためのスコープ。profile
:liff.getProfile()
およびliff.getFriendship()
を使用するためのスコープ。chat_message.write
:liff.sendMessages()
を使用するためのスコープ。アカウントの種類によっては、このオプションが[すべて表示]の下に表示されることがあります。
- openid
liff.getIDToken() や liff.getDecodedIDToken() を使用して、IDトークンを取得するためのスコープです。
IDトークンは、ユーザーを認証するための情報を含んでおり、サーバー側で検証することで、ユーザーの情報を安全に取得することができます。 - profile
liff.getProfile() や liff.getFriendship() を使用して、ユーザーのプロフィール情報(名前、画像など)や友だち関係を取得するためのスコープです。 - chat_message.write
liff.sendMessages() を使用して、LINEのトークルームにメッセージを送信するためのスコープです。
このスコープを有効にすることで、LIFFアプリからユーザーとのコミュニケーションをよりインタラクティブにすることができます。
友だち追加オプション
公式アカウントの友だち追加を表示させるかどうか、いつ表示させるかを指定します。
友だち追加したときにログイン情報を取得したい場合は「On(aggressive)」にします。

- On (normal):LIFFアプリの権限の同意画面に、LINE公式アカウントを友だち追加するオプションを追加します。
- On (aggressive):LIFFアプリの権限の同意画面の後に、LINE公式アカウントを友だち追加するかどうか確認する画面を表示します。
- Off:LINE公式アカウントを友だち追加するオプションを表示しません。
Scan QR
LIFFアプリでLIFFアプリ内でQRコードを読み取るための機能、liff.scanCodeV2()を利用する場合は、オンにします。

モジュールモード
モジュールモードをONにすると、LIFFアプリのヘッダー部分に表示される「シェア」や「友だちに送る」などのアクションボタンを非表示にすることができます。
なお、モジュールモードのオプションはLIFFアプリの画面サイズが「Full」に設定されている場合にのみ表示されます。

設定が完了したら「追加」をクリックします。

LIFFアプリが登録されます。

シェアターゲットピッカーとは、LIFFアプリからLINEの友だちに対して、メッセージやコンテンツを直接送信できる機能です。
例えば、LIFFアプリで獲得したクーポンやキャンペーン情報を、友だちに簡単にシェアできます。
LIFF IDが発行されるので、コピーしてWEBアプリの「liffId」の値に貼り付けます。
以上でシステムの作成は完了です。
試してみる
LIFF URLを叩くとアプリが起動します。
LIFF URLにつけるパラメータは「?id=」の形にする必要があります。例えば、以下のURLでLIFFアプリにログインすると「12345」というパラメータを取得することができます。
例:https://liff.line.me/LiFFのID?id=12345
▼LIFF URL

LIFFの認証が完了して、LIFFアプリとLINEが連動した時点でスプレッドシートに以下のようなデータが入ります。

LIFFアプリのあとに表示されるLINEログインで友だち登録が完了すると、スプレッドシートに次のようなデータが送信されます。

あとは、対象のユーザーIDの直近のイベントタイプが「follow」か「unfollow」かを判定すれば、ユーザー情報とLINE友だち登録のステータスを紐づけることができます。