はじめに
LINEは、国内で最も利用されているメッセージングアプリの1つであり、スマートフォン・携帯電話所有者のうち83.7%がLINEを利用していると報告されています。
特に10代から60代の全世代で8〜9割以上が利用しており、他のSNSを大きく上回る利用率です。
出典:モバイル社会研究所(https://www.moba-ken.jp/project/service/20230417.html)
こうした背景から、ユーザーへの通知手段として「LINEでメッセージを送りたい」という要望が非常に多くなっています。
本記事では、LINE Messaging API を使ってユーザーにメッセージを送信する方法と、そのためのユーザーIDの取得手法について、社内の開発実装の観点から記載します。
LINEの基本用語
プロバイダー
LINE Developersを使用してサービスを提供し、利用者の情報を取得する個人の開発者・企業・組織を指します。
ユーザーIDはプロバイダー単位で発行されるため、開発環境と本番環境でプロバイダーを分けて運用するのが望ましいかと思います。
チャネル
LINEプラットフォームが提供する機能を利用するためのルート・経路。プロバイダーに紐づきます。
2025年4月現在、
- LINEログインチャネル
- Messaging API チャネル
- ブロックチェーンサービスチャネル
- LINEミニアプリチャネル
の4つが作成可能となっています。
今回は、弊社の開発で使用する【LINEログインチャネル】【Messaging API チャネル】に焦点を当てて記載します。
※【ブロックチェーンサービスチャネル】【LINEミニアプリチャネル】は利用していないため、調査を割愛
LINE公式アカウント
LINEユーザーが実際に友だち追加するアカウント。Messaging API チャネルと1対1で紐づいています。
LINE公式アカウント専用の管理画面があるため、Messaging APIを利用しなくてもLINEで友だちとなったユーザーとのやり取りは可能です。

なおLINE公式アカウントからのメッセージの送信通数によって利用料金が請求されます。

関係の整理
プロバイダー(開発者/企業の管理単位)
└── チャネル(LINEのサービスと接続する単位)
└── Messaging API(チャット連携用API)─ LINE公式アカウント1
└── Messaging API(チャット連携用API)─ LINE公式アカウント2
└── LINEログインチャネル
LINEログインチャネルにはLINE公式アカウントは紐づきません。
LINEログインチャネルを登録する際にサムネイル画像などを設定しますが、それは公式アカウントとは別の物となります。

LINEユーザーへメッセージを送信する準備
ユーザーにメッセージを送るには、対象ユーザーの ユーザーIDを取得する必要があります。
ユーザーIDはプロバイダーごとに発行される一意の識別子であり、LINEで登録されているユーザーの表示名や、LINEでの友だち検索に利用するLINE IDとは異なります。

ユーザーIDを取得する
方法1:Webhookで取得(followやmessageイベント)
ユーザーが、LINE公式アカウントを友だち追加したり、LINE公式アカウントにメッセージを送ったりすると、LINE Developersコンソールの[Webhook URL]で指定したURL(ボットサーバー)に対して、LINEプラットフォームからWebhookが送られます。ユーザーIDは、このWebhookに含まれています。
出典:LINE Developersサイト(https://developers.line.biz/ja/docs/messaging-api/getting-user-ids/#get-user-ids-in-webhook)
{
出典:LINE Developersサイト(https://developers.line.biz/ja/docs/messaging-api/getting-user-ids/#get-user-ids-in-webhook)
“destination”: “xxxxxxxxxx”,
“events”: [
{
“type”: “follow”,
“timestamp”: 1462629479859,
“source”: {
// ユーザーIDはsourceオブジェクトのuserIdプロパティから取得できる
“type”: “user”,
“userId”: “U8189cf6745fc0d808977bdb0b9f22995”
},
“replyToken”: “nHuyWiB7yP5Zw52FIkcQobQuGDXCTA”,
“mode”: “active”,
“webhookEventId”: “01FZ74A0TDDPYRVKNK77XKC3ZR”,
“deliveryContext”: {
“isRedelivery”: false
}
}
]
}
LINEの友だち追加、メッセージ送信などのユーザー発信のアクションが必要です。
マーケティング用途には適していますが、今回のようにDB上の会員情報とLINEユーザーIDを紐づけたい場合には向いていません。
方法2:友だち全員のユーザーIDを取得する
LINE公式アカウントと友だちになっているユーザー全員のユーザーIDは、LINE公式アカウントを友だち追加したユーザーのリストを取得するエンドポイントで取得できます。
出典:LINE Developersサイト(https://developers.line.biz/ja/docs/messaging-api/getting-user-ids/#get-all-friends-user-ids)
curl -v -X GET https://api.line.me/v2/bot/followers/ids -H ‘Authorization: Bearer {channel access token}’ -d ‘limit=1000’ -d ‘start=yANU9IA…’ -G
出典:LINE Developersサイト(https://developers.line.biz/ja/docs/messaging-api/getting-user-ids/#get-all-friends-user-ids)
{ “userIds”: [“U4af4980629…”, “U0c229f96c4…”, “U95afb1d4df…”], “next”: “yANU9IA…” }
出典:LINE Developersサイト(https://developers.line.biz/ja/docs/messaging-api/getting-user-ids/#get-all-friends-user-ids)
今回のようにDB上の会員情報とLINEユーザーIDを紐づけたい場合には向いていません。
方法3:LINE認証後、自身のユーザーIDを取得する
LINEログインチャネルを利用してLINEログインを実装し、LINE認証済みの状態でGET profileエンドポイントをコールするとユーザーIDを取得できます。
curl -v -X GET https://api.line.me/v2/profile
出典:LINE Developers サイト(https://developers.line.biz/ja/reference/line-login/#get-user-profile)
-H ‘Authorization: Bearer {access token}’
※access token: LINE認証時に取得できるscopeに紐づくtoken
{
出典:LINE Developers サイト(https://developers.line.biz/ja/reference/line-login/#get-user-profile)
“userId”: “U4af4980629…”,
“displayName”: “Brown”,
“pictureUrl”: “https://profile.line-scdn.net/abcdefghijklmn”,
“statusMessage”: “Hello, LINE!”
}
LINEログイン・認証を実装するシステムであれば相性がよく、DB上の会員情報との紐付けも可能となっています。
方法4:ユーザーアカウントの連携でユーザーIDを取得する
LINEアプリからユーザー起点でアカウント紐付けをしてもらう方法です。
出典:LINE Developers サイト(https://developers.line.biz/ja/docs/messaging-api/linking-accounts/#account-link-sequence )
- ボットサーバーが、LINEのユーザーIDから連携トークンを発行するAPIを呼び出す。
- LINEプラットフォームが連携トークンを発行し、ボットサーバーに返す。
- ボットサーバーがユーザーに連携URLを送信するために、Messaging APIを呼び出す。
- LINEプラットフォームが、ユーザーに連携URLを送信する。
- ユーザーが連携URLにアクセスする。
- ウェブサーバーがログイン画面を表示する。
- ユーザーが、自社サービスの認証情報を入力する。
- ウェブサーバーが自社サービスのユーザーIDを取得し、それを使ってnonce(number used once)を生成する。
- ウェブサーバーが、ユーザーをアカウント連携するエンドポイントにリダイレクトする。
- ユーザーが、アカウントを連携するエンドポイントにアクセスする。
- LINEプラットフォームがボットサーバーに、LINEのユーザーIDとnonceを含むイベントをWebhookで送信する。

実際の処理例
0.ユーザーが特定の文字列を送信し(リッチメニューからボタンを押下し)、サーバーがwebhookを受け取る
ユーザーがリッチメニューの「アカウント連携」をクリックすると、「●●●とアカウント連携したい」のメッセージが送信される
サーバー側はメッセージイベントのwebhookを受信する

// グループトークでユーザーからメンションと絵文字を含むテキストメッセージが送られた場合
出典:LINE Developers サイト(https://developers.line.biz/ja/reference/messaging-api/#message-event)
{
“destination”: “xxxxxxxxxx”,
“events”: [
{
“replyToken”: “nHuyWiB7yP5Zw52FIkcQobQuGDXCTA”,
“type”: “message”,
“mode”: “active”,
“timestamp”: 1462629479859,
“source”: {
“type”: “group”,
“groupId”: “Ca56f94637c…”,
“userId”: “U4af4980629…”
},
“webhookEventId”: “01FZ74A0TDDPYRVKNK77XKC3ZR”,
“deliveryContext”: {
“isRedelivery”: false
},
“message”: {
“id”: “444573844083572737”,
“type”: “text”,
“quoteToken”: “q3Plxr4AgKd…”,
“text”: “@All @example Good Morning!! (love)”,
“emojis”: [
{
“index”: 29,
“length”: 6,
“productId”: “5ac1bfd5040ab15980c9b435”,
“emojiId”: “001”
}
],
“mention”: {
“mentionees”: [
{
“index”: 0,
“length”: 4,
“type”: “all”
},
{
“index”: 5,
“length”: 8,
“userId”: “U49585cd0d5…”,
“type”: “user”,
“isSelf”: false
}
]
}
}
}
]
}
1.ボットサーバーが、LINEのユーザーIDから連携トークンを発行するAPIを呼び出す。
2. LINEプラットフォームが連携トークンを発行し、ボットサーバーに返す。
3.ボットサーバーがユーザーに連携URLを送信するために、Messaging APIを呼び出す。
4.LINEプラットフォームが、ユーザーに連携URLを送信する。
from linebot.v3.messaging import Configuration, MessagingApi, ApiClient, PushMessageRequest, ApiException, ReplyMessageRequest
configuration = Configuration(
access_token = LINE_CHANNEL_ACCESS_TOKEN
)
line_bot_api = MessagingApi(ApiClient(configuration))
# LINE Messaging APIからのメッセージイベントを処理
@handler.add(MessageEvent)
def handle_message(event):
text = event.message.text
user_id = event.source.user_id
if text == “●●●とアカウント連携したい”:
“””アカウント連携メッセージを送信”””
try:
#1.ボットサーバーが、LINEのユーザーIDから連携トークンを発行するAPIを呼び出す。
#2. LINEプラットフォームが連携トークンを発行し、ボットサーバーに返す。
ret = line_bot_api.issue_link_token(user_id)
login_url = f”{LOGIN_PAGE_URL}?link_token={ret.link_token}”
print(login_url)
message_dict = {
‘replyToken’: event.reply_token,
‘messages’: [{
‘type’: ‘template’,
‘altText’: ‘アカウント連携’,
‘template’: {
‘type’: ‘buttons’,
‘text’: ‘●●●へログインしてLINEアカウントと●●●を連携しましょう’,
‘actions’: [{
‘type’: ‘uri’,
‘label’: ‘ログインして連携する’,
‘uri’: login_url
}]
}
}]
}
reply_message_request = ReplyMessageRequest.from_dict(message_dict)
#3.ボットサーバーがユーザーに連携URLを送信するために、Messaging APIを呼び出す。
#4.LINEプラットフォームが、ユーザーに連携URLを送信する。
push_message_result = line_bot_api.reply_message_with_http_info(reply_message_request)
except ApiException as e:
logging.info(‘Exception when calling MessagingApi->push_message: %sn’ % e)
print(‘Exception when calling MessagingApi->push_message: %sn’ % e)
raise HTTPException(
status_code=500,
detail=’Exception when calling MessagingApi->push_message: %sn’ % e
)
5.ユーザーが連携URLにアクセスする。

6.ウェブサーバーがログイン画面を表示する。
7.ユーザーが、自社サービスの認証情報を入力する。
8.ウェブサーバーが自社サービスのユーザーIDを取得し、それを使ってnonce(number used once)を生成する。
フロント側でユーザーログイン後に
API: POST /xxxx/try_link_account パラメーター: link_token
を実施
@router.post(“/try_link_account”) @require_user() def try_link_account( body: TryLinkAccountRequest, db: Session = Depends(get_db), authenticated_user: User = Depends(get_active_authenticated_user), summary=”アカウント連携のためにnonceを作成しユーザーをLINEプラットフォームへリダイレクト” ): #8.ウェブサーバーが自社サービスのユーザーIDを取得し、それを使ってnonce(number used once)を生成する。 nonce = LineService.create_nonce(db, authenticated_user) url = f”https://access.line.me/dialog/bot/accountLink?linkToken={body.link_token}&nonce={nonce}” return {“url”: url} class LineService: @staticmethod def create_nonce(db: Session, user: User): nonce = secrets.token_urlsafe(32) db_update_user = user_crud.update_user_line_info(db, user_id=user.id, user=schemas[“UserLineInfoUpdate”](line_nonce=nonce)) if db_update_user is not None: return nonce else: return None
9.ウェブサーバーが、ユーザーをアカウント連携するエンドポイントにリダイレクトする。
10.ユーザーが、アカウントを連携するエンドポイントにアクセスする。
API: POST /xxxx/try_link_accountの戻り値のURLへリダイレクト
11.LINEプラットフォームがボットサーバーに、LINEのユーザーIDとnonceを含むイベントをWebhookで送信する。
ユーザー側には連携成功画面が表示される

サーバー側はアカウント連携イベントのwebhookを受け取り、DBのユーザーとLINE user idを紐付け、リッチメニューをログイン後リッチメニューへ変更
# LINE Messaging APIからのアカウント連携イベントを処理 @handler.add(AccountLinkEvent) def handle_account_link(event): if event.link.result != “ok”: logging.info(f”Line handle_account_link fail: {event}”) return nonce = event.link.nonce line_user_id = event.source.user_id if LineService.link_account(get_db_session(), line_user_id, nonce): # アカウント連携成功 message_dict = { ‘to’: line_user_id, ‘messages’: [ { ‘type’: ‘text’, ‘text’: ‘アカウント連携が完了いたしました。メニューからアカウント連携を解除することも可能です。’ }, ] } push_message_request = PushMessageRequest.from_dict(message_dict) try: line_bot_api.link_rich_menu_id_to_user( user_id=line_user_id, rich_menu_id=LINE_AFTER_LOGIN_RICHMENU_ID ) push_message_result = line_bot_api.push_message_with_http_info(push_message_request, _return_http_data_only=False) except ApiException as e: logging.info(‘Exception when calling MessagingApi->push_message: %sn’ % e) print(‘Exception when calling MessagingApi->push_message: %sn’ % e) else: print(“handle_account_link LineService.link_account falase”) db_user = user_crud.get_user_by_line_user_id(db=get_db_session(), line_user_id=line_user_id) if db_user is not None: message_dict = { ‘to’: line_user_id, ‘messages’: [ { ‘type’: ‘text’, ‘text’: ‘対象のユーザーはすでにアカウント連携済みです。メニューからアカウント連携を解除することも可能です。’ }, ] } push_message_request = PushMessageRequest.from_dict(message_dict) try: line_bot_api.link_rich_menu_id_to_user( user_id=line_user_id, rich_menu_id=LINE_AFTER_LOGIN_RICHMENU_ID ) push_message_result = line_bot_api.push_message_with_http_info(push_message_request, _return_http_data_only=False) except ApiException as e: logging.info(‘Exception when calling MessagingApi->push_message: %sn’ % e) print(‘Exception when calling MessagingApi->push_message: %sn’ % e)
ユーザーへメッセージを送信する
Messaging APIでは、大きく分けて2種類の送信方法を利用できます。
応答メッセージ
ユーザーがLINE公式アカウントを友だち追加したり、LINE公式アカウントにメッセージを送ったりしたときに、Messaging APIで応答できる。
webhookに含まれるreplyTokenを宛先としてメッセージを送付する
curl -v -X POST https://api.line.me/v2/bot/message/reply -H ‘Content-Type: application/json’ -H ‘Authorization: Bearer {channel access token}’ -d ‘{ “replyToken”:”nHuyWiB7yP5Zw52FIkcQobQuGDXCTA”, “messages”:[ { “type”:”text”, “text”:”Hello, user” }, { “type”:”text”, “text”:”May I help you?” } ] }’
出典:LINE Developers サイト(https://developers.line.biz/ja/docs/messaging-api/sending-messages/#reply-messages)
- 最大5つまでメッセージオブジェクトを送信可能
- 応答メッセージは従量課金の対象外のため、応答メッセージで送れる場合は、応答メッセージで送ったほうがお得
任意のタイミングで送付するメッセージ
user_idを指定してメッセージを送付。一度に複数のユーザーへメッセージを送ることも可能
curl -v -X POST https://api.line.me/v2/bot/message/push -H ‘Content-Type: application/json’ -H ‘Authorization: Bearer {channel access token}’ -d ‘{ “to”: “U4af4980629…”, “messages”:[ { “type”:”text”, “text”:”Hello, world1″ }, { “type”:”text”, “text”:”Hello, world2″ } ] }’
出典:LINE Developers サイト(https://developers.line.biz/ja/docs/messaging-api/sending-messages/#send-messages-at-any-time)
- 最大5つまでメッセージオブジェクトを送信可能
- 従量課金の対象となる
- メッセージ通数は、メッセージの送信対象となった人数でカウントされる
例:1回のリクエストで4つのメッセージオブジェクトを含むプッシュメッセージを5人へ送った場合、
メッセージ通数は5通となる
送信するメッセージの種類
メッセージオブジェクト(送信するメッセージの内容を表すJSONオブジェクト)は複数の種類がある
- テキストメッセージ
- スタンプメッセージ
- 画像メッセージ
- 動画メッセージ
- 音声メッセージ
- クイックリプライ
※クイックリプライは、ユーザーが返信するためのボタンを、メッセージと一緒に表示する機能

テンプレートメッセージ
テンプレートメッセージは、あらかじめレイアウトが定義されたテンプレートをカスタマイズして構築するメッセージ。
ボタンテンプレート
画像、タイトル、テキストに加えて、複数のアクションボタンが含まれたテンプレート

カルーセルテンプレート
複数のカラムを表示するテンプレート。カラムは横にスクロールして順番に表示できる。
まとめ
LINEで通知を行うためにユーザーIDを取得する方法もいろいろあります。
システム要件に応じて適した手段を採用しましょう。
コメント