LINE Messaging API
LINE Messaging API enables bot development for LINE, the dominant messaging platform in Japan, Thailand, and Taiwan with 196M+ monthly users. Official SDKs exist for Python and Node.js. Primary documentation is in Japanese — English docs are complete but may lag Japanese versions.
Warnings
- breaking Signature verification is mandatory. Never process webhook events without verifying X-Line-Signature header using HMAC-SHA256 with your channel secret.
- breaking Do not use body parsers (bodyParser.json, express.json) before LINE webhook middleware in Node.js. Pre-parsing the body breaks signature verification.
- breaking Reply tokens are single-use and expire in 30 seconds. Storing and reusing a reply token will fail silently.
- gotcha Webhook endpoint must return HTTP 200 within 30 seconds. LINE Platform retries failed webhooks if webhook redelivery is enabled.
- gotcha Channel access token and channel secret are different credentials. Confusing them is the most common setup error.
- gotcha No error is returned when pushing messages to users who have blocked the bot. Delivery silently fails.
- gotcha Content from user messages (images, video, audio) must be fetched separately via GET /v2/bot/message/{messageId}/content using api-data.line.me domain, not api.line.me.
Install
-
pip install line-bot-sdk -
npm install @line/bot-sdk
Imports
- WebhookHandler (Python v3)
from linebot.v3 import WebhookHandler
- MessagingApi (Python v3)
from linebot.v3.messaging import Configuration, ApiClient, MessagingApi
Quickstart
from flask import Flask, request, abort
from linebot.v3 import WebhookHandler
from linebot.v3.exceptions import InvalidSignatureError
from linebot.v3.messaging import (
Configuration, ApiClient, MessagingApi,
ReplyMessageRequest, TextMessage
)
from linebot.v3.webhooks import MessageEvent, TextMessageContent
app = Flask(__name__)
configuration = Configuration(access_token='YOUR_CHANNEL_ACCESS_TOKEN')
handler = WebhookHandler('YOUR_CHANNEL_SECRET')
@app.route('/callback', methods=['POST'])
def callback():
signature = request.headers['X-Line-Signature']
body = request.get_data(as_text=True)
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
@handler.add(MessageEvent, message=TextMessageContent)
def handle_message(event):
with ApiClient(configuration) as api_client:
line_bot_api = MessagingApi(api_client)
line_bot_api.reply_message(
ReplyMessageRequest(
reply_token=event.reply_token,
messages=[TextMessage(text=event.message.text)]
)
)
if __name__ == '__main__':
app.run()