会員サイトで管理している「会員番号123の山田さん」と、LINE公式アカウントの友だちの1人を同じ人だと分かるようにするのが、この記事でいうID連携です。結びつけておくと、レッスンの前日に予約した本人だけへLINEで案内を送れます。公式アカウントの標準機能だけではできず、LINE Developersで作るチャネルと、受け口になる小さなサーバーが要ります。この記事では、結びつける方法を4つ比べたうえで、LINEログインのボタンを会員サイトに付ける流れと、トークから連携するアカウント連携の流れを、どちらも公式の手順どおりに書きます。例は全記事で共通の、予約制の小さな料理教室「サンプル料理教室」です。前提として、公式アカウントでMessaging APIを使える状態にしてある(「Messaging APIの始め方:チャネル・アクセストークン・Webhook」の内容)ものとします。
この記事の内容
先に決めること
ここを飛ばすと、作ったあとに作り直しになります。
1つ目は、プロバイダーを1つに揃えることです。LINE Developersでは、チャネルをプロバイダーと呼ぶ入れ物の下に作ります。ユーザーIDはプロバイダーごとに別の値が発行され、同じプロバイダーの下ならLINEログインのチャネルとMessaging APIのチャネルで同じIDになります。プロバイダーが違うと、同じ人でもIDが変わり、ログインで取ったIDに公式アカウントからメッセージを送れません。しかも、公式アカウントでMessaging APIを有効にするときに選んだプロバイダーは、あとから変えられません。チャネルを別のプロバイダーへ移すこともできません。運用代行や拡張ツールの会社が持っているプロバイダーの下に作ると、契約を切ったときに困ります。自社名のプロバイダーを1つ作り、そこに全部置きます。
2つ目は、どこから連携を始めるかです。会員サイトのマイページから「LINEで連携」を押してもらうならLINEログイン、LINEのトーク画面のリッチメニューから始めるならMessaging APIのアカウント連携が素直です。サンプル料理教室は、会員サイトに毎回ログインする人が少なく、LINEのほうがよく開かれるので、リッチメニューからの連携を主にし、会員サイトにもLINEログインのボタンを付けます。
3つ目は、何を取るかです。結びつけに要るのはユーザーIDだけです。表示名やプロフィール画像は変わるので、会員の名前は会員台帳のものを使います。メールアドレスは、取るなら事前に申請が要ります。サンプル料理教室は会員台帳にメールアドレスがあるので取りません。
4つ目は、作る人と置き場所です。どの方法でも、LINEからの戻り先を受けるサーバーが要ります。会員サイトがWordPressなら同じサーバーに置けますし、別の小さなサーバーやn8nで受けることもできます。チャネルシークレットやチャネルアクセストークンを置く場所なので、ブラウザ側のJavaScriptだけでは作れません。
結びつける4つの方法
検索すると「LINE ID連携」「アカウント連携」「LINEログイン」が同じ意味で出てきますが、仕組みは別物です。
| 方法 | どこから始まるか | 必要なもの | 結びつくもの | 向く場面 |
|---|---|---|---|---|
| LINEログイン | 会員サイト・アプリのログインボタン | LINEログインのチャネル、コールバックを受けるサーバー | 会員とユーザーID。友だちかどうかは別 | Webの会員サイトがあり、会員登録やログインをLINEで済ませたい |
| 友だち追加オプション | LINEログインの同意画面 | LINEログインのチャネルと、同じプロバイダーのMessaging APIチャネル | ログインと同時に公式アカウントの友だちになる | ログインした会員に、そのままLINEで送りたい |
| Messaging APIのアカウント連携 | 公式アカウントのトーク画面 | Messaging APIのチャネル、Webhookを受けるサーバー、会員サイトのログイン画面 | 友だちと会員番号 | すでに友だちの人を、あとから会員と結びたい |
| LIFF | LINEの中で開くWebページ | LINEログインのチャネルに追加したLIFFアプリ | 開いた人のユーザーID。友だち追加オプションも付けられる | LINEの中で予約や会員登録のフォームを開きたい |
迷ったら、すでに友だちが多い公式アカウントはアカウント連携から、Webの会員サイトが中心ならLINEログインと友だち追加オプションから始めます。両方を同じプロバイダーで作っておけば、どちらで結んでも同じユーザーIDになります。
もう1つ、言葉の取り違えを先に片づけておきます。
| 呼び方 | 中身 | 連携に使うか |
|---|---|---|
| ユーザーID | U で始まり16進数32桁が続く文字列。LINEプラットフォームが発行し、プロバイダーごとに違う | 使う。会員番号と結びつけるのはこれ |
| LINE ID | 友だち検索に使う、利用者が自分で決めるID | 使わない。連携トークンの発行にも使えない |
| 表示名 | 利用者がいつでも変えられる名前 | 使わない。名寄せの手がかりにもしない |
| 公式アカウントのベーシックID・プレミアムID | 公式アカウント側のID。トークメニューのアカウント名の下とビジネスプロフィールに出る | 使わない。人を見分ける値ではない |
LINEログインのチャネルを作る
LINEログインそのものは無料で使えます(2026年10月時点)。手順はPCのブラウザで行います。
- LINE Developersコンソールに、公式アカウントの管理者と同じアカウントでログインする。
- 公式アカウントでMessaging APIを有効にしたときに選んだプロバイダーをクリックする。
- 「チャネル設定」タブで「LINEログイン」を選ぶ。
- 「サービスを提供する地域」で日本を選ぶ。
- 「会社・事業者の所在国・地域」で日本を選ぶ。
- 「チャネル名」に
サンプル料理教室 会員サイトと入れる。「LINE」やそれに似た文字は入れられません。 - 「チャネル説明」と「メールアドレス」を入れる。
- 「アプリタイプ」で「ウェブアプリ」を選ぶ(もう1つは「ネイティブアプリ」)。「2要素認証の必須化」は初期値のオンのままにします。
- 「プライバシーポリシーURL」に会員サイトのプライバシーポリシーのURLを入れる。認証プロバイダーでなければ任意ですが、入れておきます。
- LINE開発者契約を確認して「LINE開発者契約に同意します。」にチェックを入れ、「作成」を押す。

作ったチャネルは「開発中」の状態です。この状態ではチャネルのAdminかTesterの権限を持つ人しかログインできません。スタッフで動きを確かめたら、ステータスを「公開済み」に変えます。「公開済み」から「開発中」には戻せません。
続けて、戻り先のURLを登録します。
- 作ったチャネルの「LINEログイン設定」タブを開く。
- 「コールバックURL」の「編集」を押し、
https://member.example.com/line/callbackを入れて「更新」を押す。テスト用のURLもあるなら、改行して並べる。 - 同じタブの「ウェブアプリでLINEログインを利用する」がオンになっているか確かめる。

メールアドレスも取るなら、「チャネル基本設定」タブの「OpenID Connect」で「申請」を押し、申請条件に同意して、メールアドレスの取得と使い方を利用者に示す文面のスクリーンショットを上げます。受理されると「メールアドレス取得権限」に「申請済み」と出ます。会員登録画面の「LINEで登録すると、LINEに登録したメールアドレスを会員サイトの連絡先として使います」のような文を先に作っておく必要があります。
会員サイトにログインボタンを付ける
LINEログインの中身は、OAuth 2.0の認可コードの流れとOpenID Connectです。会員サイトから見ると、次の4往復になります。
| 順番 | 会員サイトがすること | LINE側から返るもの |
|---|---|---|
| 1 | ボタンを押した人を認可URLへ送る。state と nonce を作ってセッションに残す | LINEのログイン・同意画面 |
| 2 | コールバックURLで受ける。state が送ったものと同じか確かめる | code(認可コード)と state |
| 3 | 認可コードをトークンのエンドポイントへ送る | access_token、id_token、refresh_token |
| 4 | IDトークンを検証し、中の sub(ユーザーID)を会員番号と結ぶ | 表示名・画像・ユーザーIDの入ったペイロード |
認可URLは次の形です。redirect_uri はURLエンコードし、state はログインのたびにランダムに作ります。state 自体はURLエンコードが要らない英数字にします。
https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id=YOUR_LOGIN_CHANNEL_ID&redirect_uri=https%3A%2F%2Fmember.example.com%2Fline%2Fcallback&state=8f3a1c0d9e7b42a6&scope=profile%20openid&nonce=5b2e9d71c4a8f036&bot_prompt=normal
scope は profile と openid を付けます。openid を付けないとIDトークンが返りません。email を付けるのは申請が通ってからです。
認可コードは有効期間10分で、1回しか使えません。受け取ったらすぐにトークンと交換します。
curl -X POST https://api.line.me/oauth2/v2.1/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code' \
-d 'code=RECEIVED_CODE' \
--data-urlencode 'redirect_uri=https://member.example.com/line/callback' \
-d 'client_id=YOUR_LOGIN_CHANNEL_ID' \
-d 'client_secret=YOUR_LOGIN_CHANNEL_SECRET'
返ってくるアクセストークンの有効期間は30日、リフレッシュトークンは発行から最長90日です。結びつけが目的なら、アクセストークンを長く持ち続ける必要はありません。IDトークンは、署名を自分で検証するか、検証のエンドポイントに投げます。小さな会員サイトなら後者が楽です。
curl -X POST https://api.line.me/oauth2/v2.1/verify \
-d 'id_token=RECEIVED_ID_TOKEN' \
-d 'client_id=YOUR_LOGIN_CHANNEL_ID' \
-d 'nonce=NONCE_SAVED_IN_SESSION'
成功すると、sub にユーザーID、name に表示名、picture に画像のURL、amr にログインの方法(pwd、lineautologin、lineqr、linesso、mfa のどれか)が入って返ります。amr は条件によっては入らないことがあるので、これに頼った処理は作りません。IDトークンを使わずに GET https://api.line.me/v2/profile にアクセストークンを付けて、userId と displayName を取ることもできます。
ここまでをNode.js(18以上)で書くと次のとおりです。会員サイトへのログインは既存の仕組みのままとし、ログイン済みの会員が /line/login を開く前提です。npm install express express-session で動きます。
// server.mjs
import express from 'express';
import session from 'express-session';
import crypto from 'node:crypto';
import { appendFile } from 'node:fs/promises';
const CHANNEL_ID = process.env.LINE_LOGIN_CHANNEL_ID;
const CHANNEL_SECRET = process.env.LINE_LOGIN_CHANNEL_SECRET;
const CALLBACK_URL = 'https://member.example.com/line/callback';
const app = express();
app.use(session({ secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false }));
app.get('/line/login', (req, res) => {
if (!req.session.memberNo) return res.redirect('/login');
const state = crypto.randomBytes(16).toString('hex');
const nonce = crypto.randomBytes(16).toString('hex');
req.session.lineState = state;
req.session.lineNonce = nonce;
const q = [
'response_type=code',
'client_id=' + CHANNEL_ID,
'redirect_uri=' + encodeURIComponent(CALLBACK_URL),
'state=' + state,
'scope=' + encodeURIComponent('profile openid'),
'nonce=' + nonce,
'bot_prompt=normal',
].join('&');
res.redirect('https://access.line.me/oauth2/v2.1/authorize?' + q);
});
app.get('/line/callback', async (req, res) => {
const { code, state, error } = req.query;
if (error) return res.redirect('/mypage?line=canceled');
if (!state || state !== req.session.lineState) return res.status(400).send('state mismatch');
delete req.session.lineState;
const tokenRes = await fetch('https://api.line.me/oauth2/v2.1/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code', code, redirect_uri: CALLBACK_URL,
client_id: CHANNEL_ID, client_secret: CHANNEL_SECRET,
}),
});
if (!tokenRes.ok) return res.status(502).send('token error');
const token = await tokenRes.json();
const verifyRes = await fetch('https://api.line.me/oauth2/v2.1/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ id_token: token.id_token, client_id: CHANNEL_ID, nonce: req.session.lineNonce }),
});
if (!verifyRes.ok) return res.status(401).send('id_token invalid');
const payload = await verifyRes.json();
// 会員番号, ユーザーID, 連携した日時, 経路 を1行で残す(本番は会員台帳のDBへ)
await appendFile('links.csv', [req.session.memberNo, payload.sub, new Date().toISOString(), 'line_login'].join(',') + '\n');
res.redirect('/mypage?line=linked');
});
app.listen(3000);
ログインボタンは、LINEの「LINEログインボタン デザインガイドライン」に従います。テンプレートをダウンロードした時点でガイドラインに同意した扱いになり、基本色は #06C755 から変えられません。自分で緑のボタンを描かず、配布されている画像を使います。

ログインの方法は環境で変わります。スマートフォン版LINEにログインしている状態で、LINE内ブラウザかスマートフォンの外部ブラウザから認可URLを開くと、自動ログインになり画面は出ません。PC版LINEでは自動ログインは動きません。ブラウザに前回のログインが残っていれば、先に「次のアカウントでログイン」の確認画面が出て、「ログイン」か「別のアカウントでログイン」を選びます。別のアカウントを選ぶと、メールアドレスとパスワードの入力欄と「ログイン」、それに「QRコードログイン」が出ます。プライベートブラウズや、OSの仕様で自動ログインが失敗することもあります。

ログインと同時に友だち追加してもらう
友だち追加オプションは、LINEログインの同意画面に「公式アカウントを友だち追加する」の選択を出す仕組みです。条件は2つあります。公式アカウントのMessaging APIチャネルが、LINEログインのチャネルと同じプロバイダーにあること。操作する人が、LINEログインのチャネルのAdmin権限と、公式アカウントの管理者権限の両方を持っていることです。
- LINE Developersコンソールで、LINEログインのチャネルがあるプロバイダーを開く。
- LINEログインのチャネルをクリックする。
- 「チャネル基本設定」タブの「リンクされたLINE公式アカウント」で「編集」を押す。
- サンプル料理教室の公式アカウントを選び、「更新」を押す。
- 認可URLに
bot_prompt=normalかbot_prompt=aggressiveを付ける。
1つのLINEログインのチャネルにリンクできる公式アカウントは1つです。normal は同意画面の中に選択を出し、aggressive は同意画面のあとに友だち追加するかを聞く画面を別に出します。サンプル料理教室は normal にしています。体験レッスンの予約をLINEログイン経由にしたとき、aggressive だと画面が1枚増えて、ログインそのものをやめる人が出たからです。
同意画面の出方は、その人と公式アカウントの関係で変わります。
| 同意画面を開いたときの関係 | 出るもの |
|---|---|
| まだ友だちではない | 友だち追加のオプション。有効にして進むと友だちになる |
| ブロックしている | ブロック解除のオプション |
| すでに友だち | 友だち追加済みであることの表示。オプションは出ない |
認証プロバイダー配下のチャネルで bot_prompt=normal | オプションが最初から有効になっている |

ログインのあと、コールバックURLに friendship_status_changed が付きます。true ならこのログインで友だち追加かブロック解除が起き、false なら変化なしです。オプションが出なかったときはこのパラメータ自体が付きません。今この瞬間に友だちかどうかは、アクセストークンで GET https://api.line.me/friendship/v1/status を呼ぶと friendFlag で返ります。true は友だちでブロックしていない状態、false はそれ以外です。前日の案内を送る対象を決めるときは、連携の有無だけでなくここも見ておくと、届かない相手に送ろうとしなくて済みます。
トークから会員番号と結ぶ(アカウント連携)
Messaging APIのアカウント連携は、LINEログインのチャネルがなくても使えます。そのかわり、相手が公式アカウントの友だちであることが前提です。公式の流れは5段階です。
- 友だちのユーザーIDで、連携トークンを発行する。
- 連携トークンを付けた連携URLを、その人に送る。
- その人が連携URLを開き、会員サイトにログインする。会員サイトは会員番号を得る。
- 会員サイトが
nonceを作って会員番号と一緒に保存し、その人をLINEの連携エンドポイントへ送る。 - LINEからアカウント連携イベントが届いたら、
nonceで会員番号を引き、ユーザーIDと結ぶ。
連携トークンは、Messaging APIのチャネルアクセストークンで発行します。有効期間は10分で、1回しか使えません。
curl -X POST https://api.line.me/v2/bot/user/U0123456789abcdef0123456789abcdef/linkToken \
-H 'Authorization: Bearer YOUR_CHANNEL_ACCESS_TOKEN'
{ "linkToken": "NMZTNuVrPTqlr2IF8Bnymkb7rXfYv5EY" }
サンプル料理教室では、リッチメニューの「会員連携」をタップするとトークに 会員連携 と送られるようにし、Webhookでそれを受けたら連携トークンを発行して、ボタン付きのテンプレートメッセージで返しています。公式の例はプッシュメッセージですが、ユーザーの発言への応答メッセージで返せばメッセージ通数に数えられません。
{
"replyToken": "RECEIVED_REPLY_TOKEN",
"messages": [{
"type": "template",
"altText": "会員サイトとLINEを連携します",
"template": {
"type": "buttons",
"text": "会員サイトにログインすると、レッスン前日のご案内がLINEに届きます。",
"actions": [{
"type": "uri",
"label": "連携する",
"uri": "https://member.example.com/line/link?linkToken=NMZTNuVrPTqlr2IF8Bnymkb7rXfYv5EY"
}]
}
}]
}
これを POST https://api.line.me/v2/bot/message/reply に送ります。

/line/link では、まだ会員サイトにログインしていなければログイン画面を出し、ログイン後に linkToken を持ったまま戻します。ログインできたら nonce を作ります。nonce は推測できず1回だけ使う値で、長さは10文字以上255文字以下です。会員番号のような予測できる値は使いません。公式の推奨は、安全な乱数で16バイト以上を作り、Base64にすることです。
// server.mjs に追記。/line/link で会員ログインを確かめたあとの処理
const nonceStore = new Map();
const nonce = crypto.randomBytes(16).toString('base64');
// nonce と会員番号を結んで保存(10分ほどで捨てる)
nonceStore.set(nonce, { memberNo: req.session.memberNo, createdAt: Date.now() });
res.redirect('https://access.line.me/dialog/bot/accountLink?linkToken='
+ encodeURIComponent(req.query.linkToken) + '&nonce=' + encodeURIComponent(nonce));
Base64には + や / や = が入るので、URLに載せるときにエンコードを忘れないようにします。
LINEは、連携トークンを発行された本人が開いたかを確かめ、Webhookにアカウント連携イベントを送ってきます。
| 状況 | Webhookに届くもの | すること |
|---|---|---|
| 本人と確認できた | type が accountLink、link.result が ok、link.nonce、source.userId | nonce で会員番号を引き、ユーザーIDと保存する。応答で「連携しました」と返す |
| 本人と確認できなかった | link.result が failed。source と replyToken は入らない | 何も結ばない。保存した nonce は捨てる |
| 連携トークンが期限切れ・使用済み | 何も届かない。その人の画面にエラーが出る | トークからもう一度「会員連携」を押してもらう |
Webhookは、署名を確かめてから処理します。チャネルシークレットを鍵にリクエストボディをHMAC-SHA256で計算し、Base64にしたものが x-line-signature ヘッダーと一致するかを見ます。ボディをパースしてから計算すると一致しません。
// server.mjs に追記。Webhook URL は https://member.example.com/webhook
app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
const sig = crypto.createHmac('sha256', process.env.MESSAGING_CHANNEL_SECRET).update(req.body).digest('base64');
if (sig !== req.get('x-line-signature')) return res.sendStatus(401);
res.sendStatus(200);
const { events } = JSON.parse(req.body.toString('utf8'));
for (const ev of events) {
if (ev.type !== 'accountLink') continue;
const saved = nonceStore.get(ev.link.nonce);
nonceStore.delete(ev.link.nonce);
if (ev.link.result !== 'ok' || !saved) continue;
await appendFile('links.csv', [saved.memberNo, ev.source.userId, new Date().toISOString(), 'account_link'].join(',') + '\n');
}
});
自前で「会員番号を入力してください」とトークで聞いてIDを結ぶ作り方は避けます。他人の会員番号を入れれば、その人の会員情報に自分のLINEが結ばれてしまうからです。公式の手順は、連携URLを発行された本人が開いたかをLINE側で確かめるので、このすり替えを防げます。
サンプル料理教室の例:前日に本人へ送る
サンプル料理教室では、会員台帳(Googleスプレッドシートか、顧客管理のkintone)に次の列を足しています。
| 列 | 例 | 使い道 |
|---|---|---|
| 会員番号 | M-0123 | 会員サイトのID。結びつけの片側 |
| LINEユーザーID | U0123456789abcdef0123456789abcdef | 送り先。結びつけのもう片側 |
| 連携の経路 | line_login / account_link | どちらで結んだか |
| 連携した日時 | 2026-10-20 19:42 | 同意した時点の記録 |
| 同意した文面の版 | 2026-10版 | どの説明を読んで同意したか |
| 連携の状態 | 連携中 / 解除 | 解除したら送らない |
予約は会員番号で入っているので、毎晩18時に翌日のレッスンを予約している会員を引き、連携中でLINEユーザーIDがある人にだけプッシュメッセージを送ります。
curl -X POST https://api.line.me/v2/bot/message/push \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_CHANNEL_ACCESS_TOKEN' \
-d '{
"to": "U0123456789abcdef0123456789abcdef",
"messages": [{
"type": "text",
"text": "山田さま、明日10月28日(水)19:00から「秋の和定食」のレッスンです。エプロンをお持ちください。変更はこのトークでご連絡ください。"
}]
}'
名前は会員台帳の名前を入れます。LINEの表示名はニックネームのことが多く、宛名に使うと違和感が出ます。プッシュメッセージはメッセージ通数に数えられます。2026年10月時点で、コミュニケーションプランは月200通、ライトプランは月5,000円で5,000通、スタンダードプランは月15,000円で30,000通まで無料で送れます。スタンダードプランだけは、30,000通を超えた分も追加メッセージ(1通あたり約3円まで、送る数で単価が変わる。税別)として送れます。コミュニケーションプランとライトプランは追加メッセージを送れません。ブロックしている人のユーザーIDに送った分は数えられません。前日・当日の送り分けや、無断キャンセルへの効き方は「予約のリマインドをLINEで自動送信する:前日・当日の通知と無断キャンセル対策」に書いています。

連携していない会員には、これまでどおりメールで送ります。全員をLINEに寄せようとせず、連携した人だけLINEに切り替える形にすると、連携率が低いうちから運用を始められます。
個人情報と同意の取り方
ユーザーIDは、会員台帳と結んだ時点でその人を特定できる情報になります。LINE開発者契約でも、ログイン情報がアプリで使えるようになることを利用者に知らせること、同意を得た時期以降に同意を得た用途でだけ使うこと、取った情報で第三者のサービスに広告を出さないことが決められています。
サンプル料理教室では、連携ボタンのすぐ上に次の文を置いています。
LINEと連携すると、会員番号とLINEのユーザーIDを結びつけて保存します。
使い道は、レッスン前日のご案内、予約の変更・キャンセルのご連絡、教室からのお知らせです。
広告の配信や、教室以外への提供には使いません。
連携はマイページの「LINE連携を解除」から、いつでも解除できます。
会員を退会すると、LINEとの連携も解除され、退会したことがLINEヤフー株式会社に通知されます。
最後の2行は、LINEログイン開発ガイドラインの必須事項に合わせたものです。LINEログインを組み込んだサイトから会員が退会するときや、連携を解除するときは、権限を取り消すエンドポイントでその人の代わりに権限を取り消し、何が起きるかを機能のそばか規約に書くことになっています。
curl -X POST https://api.line.me/user/v1/deauthorize \
-H 'Authorization: Bearer YOUR_CHANNEL_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ "userAccessToken": "USER_ACCESS_TOKEN" }'
Authorization に入れるのは、有効期間を指定できるチャネルアクセストークン(v2.1)か、ステートレスチャネルアクセストークンです。成功すると 204 が返り、利用者がすでに自分で連動を解除していた場合などは 400 が返ります。ここで要るのは利用者のアクセストークンなので、LINEログインで結んだ会員の分は、退会のときに取り消せるように保存しておくか、退会の操作の中でもう一度LINEログインしてもらいます。ログアウトのときにアクセストークンを取り消すなら POST https://api.line.me/oauth2/v2.1/revoke です。利用者自身は、LINEの「ホーム」→「設定」→「アカウント」→「連動アプリ」から連動を解除できます。
アカウント連携でも、いつでも解除できるようにしておくことと、連携するときに解除できると伝えることが公式に求められています。会員台帳の状態を 解除 にして送り先から外し、リッチメニューを連携前のものに戻します。
ほかに決めておくのは2つです。1つは保存期間で、退会した会員のユーザーIDは消す日を決めておきます。もう1つは見られる人で、会員台帳のLINEユーザーIDの列を、送信の仕組みと担当者だけが見られるようにします。
応用
連携の状態でリッチメニューを切り替えると、連携の案内を出し続けずに済みます。Messaging APIでは人ごとにリッチメニューを付け替えられるので、連携前の人には「会員連携」のボタン、連携済みの人には「予約の確認」「LINE連携を解除」のボタンを出します。公式もこの使い方を例に挙げています。
LIFFを使うと、LINEの中で開く予約フォームが開いた人のユーザーIDを持てるので、フォームに入れた会員番号とその場で結べます。LIFFアプリはLINEログインのチャネルの「LIFF」タブで追加し、1つのチャネルに30件まで置けます。LIFFアプリの設定にも友だち追加オプション(On (normal)、On (aggressive)、Off)があります。ただ、公式はLIFFをLINEミニアプリに統合する予定を出していて、新しく作るならLINEミニアプリとして作るよう勧めています。どちらを選ぶかは「LINEミニアプリとLIFF:何が違い、自社に要るか」で比べています。

自分でサーバーを書かずにLIFFのフォームを使いたいなら、拡張ツールに任せる手もあります。オープンソースのL Harnessは本体の利用料が0円で(公式アカウントの配信料やCloudflareなどの費用は別)、LINEの中で完結するフォームをLIFFで持ち、回答を友だちの情報に保存できます。会員台帳がkintoneにあるなら、結んだユーザーIDとやりとりを顧客管理に入れる流れを「LINEとkintoneをつなぐ:友だちとやりとりを顧客管理に入れる」に書いています。
できないことと、その代わり
| できないこと | 理由 | 代わりの手 |
|---|---|---|
| LINE Official Account Managerの設定だけで会員と結ぶ | 標準機能に連携の仕組みがない | アカウント連携か、LINEログインを小さなサーバーで受ける |
| 別のプロバイダーのチャネルで取ったユーザーIDに送る | ユーザーIDがプロバイダーごとに違う | 同じプロバイダーにチャネルを作り直し、連携をやり直してもらう |
| 公式アカウントのプロバイダーをあとから変える | Messaging APIを有効にしたときに選んだものは変えられない | 最初に自社名のプロバイダーを選ぶ |
| 友だちでない人にアカウント連携の案内を送る | アカウント連携は友だちが前提 | 会員サイトにLINEログインと友だち追加オプションを付ける |
| 申請なしでメールアドレスを取る | email スコープは事前の申請が要る | 会員台帳のメールアドレスを使う。要るなら申請する |
| PC版LINEで自動ログインさせる | 自動ログインはスマートフォン版LINEだけ | PCではQRコードかメールアドレスでのログインを案内する |
| 連携トークンを使い回す | 10分で切れ、1回しか使えない | 連携のたびに発行し直す |
よく詰まるところ
| 症状 | 原因 | 直し方 |
|---|---|---|
| ログインで取ったユーザーIDに送ると届かない | LINEログインとMessaging APIのチャネルが別のプロバイダーにある | 同じプロバイダーにLINEログインのチャネルを作り直す |
| 「リンクされたLINE公式アカウント」に公式アカウントが出ない | プロバイダーが違うか、操作している人が公式アカウントの管理者でない | Messaging APIチャネルのプロバイダーを確かめ、管理者権限のある人が操作する |
| スタッフ以外がログインできない | チャネルが「開発中」のまま | 動きを確かめてから「公開済み」に変える |
| ログインボタンを押してもコールバックURLに戻らない | client_id か redirect_uri が間違っているとリダイレクトされない | 「LINEログイン設定」に登録したURLと一字一句同じにする |
| トークンの交換で失敗する | 認可コードの10分が過ぎたか、同じコードを2回使った | コールバックを受けたらすぐ交換する。再読み込みで二度送らない |
IDトークンの検証で IdToken expired. | 期限切れのIDトークンを後から検証している | ログイン直後に検証し、結果のユーザーIDだけ保存する |
IDトークンの検証で Invalid IdToken Audience. | client_id に別のチャネルのIDを入れた | LINEログインのチャネルIDを入れる。Messaging APIのチャネルIDではない |
id_token が返ってこない | scope に openid がない | scope=profile%20openid にする |
| アカウント連携イベントが届かない | 連携トークンが期限切れか使用済み | トークから「会員連携」を押し直してもらい、新しいトークンで送る |
link.result が failed になる | 連携URLを、トークンを発行された本人以外が開いた | 連携URLを転送しないよう案内する。本人の端末でやり直す |
nonce から会員番号が引けない | Base64の + や / をエンコードせずURLに載せた | encodeURIComponent してからリダイレクトする |
| Webhookの署名が一致しない | パース後のJSONで計算した。チャネルシークレットを再発行した | 生のボディで計算する。新しいシークレットに差し替える |
| ログインのたびに「ログインしました」というトークが届くと問い合わせが来る | LINEログインをすると、LINEからログイン通知が届く | 案内文に「ログインするとLINEから通知が届きます」と書いておく |
負荷テストのあとに 429 が返る | LINEプラットフォームへの大量リクエストは禁止されている | 負荷テストはLINEに投げない環境で行う |
ログインと連携の記録は、自分で残します。LINE側に問い合わせても、認可リクエストやAPIのログは出してもらえません。認可リクエストの時刻とパラメータ、受け取った認可コードかエラー、APIのレスポンスヘッダーの x-line-request-id とステータスコードを、一定期間残しておくと原因を追えます。
次にやること
- Messaging APIの始め方:チャネル・アクセストークン・Webhook
- 予約のリマインドをLINEで自動送信する:前日・当日の通知と無断キャンセル対策
- LINEミニアプリとLIFF:何が違い、自社に要るか
- LINEとkintoneをつなぐ:友だちとやりとりを顧客管理に入れる