LINE公式アカウントのチャット機能をオンにしたまま、ユーザーから届いたメッセージに Messaging API で既読をつける手順をまとめます。Webhook のメッセージイベントに含まれる既読トークン(markAsReadToken)を取り出し、POST /v2/bot/chat/markAsRead に渡すだけで既読がつきます。前提は、Messaging API チャネルを作成済みで、Webhook を受け取るサーバーとチャネルアクセストークンが用意できていることです。内容は 2026年10月時点の LINE Developers のドキュメントに基づいています。
既読をつけられる条件を確かめる
LINE Official Account Manager の[応答設定]にある[チャット]の状態で、既読のつき方が変わります。
| [チャット] | 既読のつき方 |
|---|---|
| オフ | ユーザーから届いたメッセージに自動で既読がつく |
| オン | 自動では既読がつかない。Messaging API で既読をつけられる |
Messaging API で既読をつけたいときは、[チャット]をオンにしておきます。
今の設定は「ボットの情報を取得する」エンドポイントの markAsReadMode でも確かめられます。
curl -v -X GET https://api.line.me/v2/bot/info \
-H 'Authorization: Bearer {channel access token}'
{
"chatMode": "chat",
"markAsReadMode": "manual"
}
chatMode が chat(チャットがオン)なら markAsReadMode は manual になり、API で既読をつける対象になります。chatMode が bot(チャットがオフ)なら markAsReadMode は auto で、既読は自動でつきます。
手順
1. Webhook から既読トークンを取り出す
ユーザーがメッセージを送ると、LINE Platform から Webhook にメッセージイベントが届きます。既読トークンはイベントの message オブジェクトの中にある markAsReadToken プロパティです。
{
"destination": "xxxxxxxxxx",
"events": [
{
"type": "message",
"message": {
"type": "text",
"id": "468789577898262530",
"quoteToken": "q3Plxr4AgKd...",
"markAsReadToken": "30yhdy232...",
"text": "こんにちは"
},
"replyToken": "38ef843bde154d9b91c21320ffd17a0f",
"source": {
"type": "user",
"userId": "U4af4980629..."
}
}
]
}
ポイントは次の3つです。
- 既読トークンが入るのはメッセージイベントの
messageオブジェクトです。テキスト・画像・動画・音声・ファイル・位置情報・スタンプの各メッセージに含まれます - リファレンス上は「Not always included(常に含まれるとは限らない)」とされているので、値があるかを確かめてから使います
- 既読トークンには有効期限がありません。
replyTokenのように時間がたつと使えなくなるものではないので、保存する場合は扱いに注意します
2. 「メッセージに既読をつける」エンドポイントを呼ぶ
取り出した既読トークンを、POST https://api.line.me/v2/bot/chat/markAsRead のリクエストボディに入れて送ります。
curl -v -X POST https://api.line.me/v2/bot/chat/markAsRead \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {channel access token}' \
-d '{
"markAsReadToken": "{mark as read token}"
}'
| 項目 | 値 |
|---|---|
| メソッド | POST |
| URL | https://api.line.me/v2/bot/chat/markAsRead |
| ヘッダー | Content-Type: application/json と Authorization: Bearer {channel access token} |
| ボディ | markAsReadToken(必須、文字列) |
| レート制限 | 毎秒 2,000 リクエスト |
指定したメッセージと、それより前に届いたすべてのメッセージに既読がつきます。届いたメッセージごとに呼ぶ必要はなく、最後に処理したメッセージのトークンで1回呼べば足ります。
3. Webhook の処理に組み込む
Node.js(18 以降の組み込み fetch)で書くと、Webhook の処理の中で次のように呼べます。署名検証は済んでいる前提です。
const CHANNEL_ACCESS_TOKEN = process.env.LINE_CHANNEL_ACCESS_TOKEN;
async function markAsRead(event) {
const token = event.type === "message" ? event.message?.markAsReadToken : undefined;
if (!token) return; // 既読トークンが無いイベントは何もしない
const res = await fetch("https://api.line.me/v2/bot/chat/markAsRead", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${CHANNEL_ACCESS_TOKEN}`,
},
body: JSON.stringify({ markAsReadToken: token }),
});
if (!res.ok) {
console.error("markAsRead failed", res.status, await res.text());
}
}
既読をつけるのは返信の前でも後でも構いません。既読の呼び出しに失敗しても返信の処理は止めないようにしておくと、既読がつかないだけで済みます。
動作を確認する
- LINE アプリから公式アカウントにメッセージを送る
- サーバーのログで、
markAsReadが200を返したことを確かめる。成功したときのレスポンスは空の JSON です
{}
- LINE アプリのトーク画面で、送ったメッセージに「既読」が表示されることを確かめる
うまくいかないとき
400 で次のエラーが返る
{
"message": "Invalid markAsReadToken. Tokens must be used by the bot that received them via Webhook."
}
既読トークンが正しくありません。そのトークンを Webhook で受け取ったのとは別のチャネル(別のチャネルアクセストークン)で呼んでいないかを確かめます。トークンを加工・切り詰めていないかも見直します。
ポストバックのボタンを押したときに既読をつけようとして失敗する
既読トークンはメッセージイベントの message オブジェクトに含まれるもので、ポストバックイベントには message オブジェクトがありません。リッチメニューやテンプレートメッセージのボタン(postback アクション)を押したときのイベントでは既読トークンが取れないので、既読の処理はメッセージイベントのときだけ走らせます。
メッセージを編集したイベントで既読トークンが無い
ユーザーがメッセージを編集したときのイベントには既読トークンが含まれません。既読は、編集前に届いたメッセージイベントのトークンでつけます。
API を呼ばなくても既読がついている
[応答設定]の[チャット]がオフになっています。チャットがオフのときは自動で既読がつくので、API で既読を制御したい場合は[チャット]をオンにします。



コメント