LINE Webhook Processing
Overview
When a user sends a chat message, follows or unfollows the account, or taps a postback button on LINE, the resulting webhook arrives at line-management-webhook-go, which performs a light check and immediately pushes it onto the line_webhook queue. All real processing happens in this worker, making it the main entry point for every user interaction.
Its responsibilities fall into five parts: verify the signature, resolve the OA, warm the edge cache, upsert the line_user row, and dispatch each event to its destination queue or feature.
Business Flow
-
Receive a payload made up of
webhookId,headers, andbody, where the body is the raw LINE webhook request. -
Read the
x-line-signatureheader. If it is absent the handler returns an error, so the message is nacked and lands in the DLQ. -
getLineOAByWebhookId(webhookId)resolves the owning OA, backed by a Redis cache to spare the database. -
Verify the signature by computing
HMAC-SHA256over the body usingoa.channelSecretId, base64-encoding it, and comparing against the header. A mismatch returns an error and the message goes to the DLQ. -
Warm the cache on a best-effort basis — a failure here does not affect the main flow. The worker writes a Redis hash at
webhook_config:<webhookId>holdinglineOaId,forwardWebhookUrl, and the full mbox configuration (enabled flag, keywords, and the greeting / warning / end / timeout messages) with a one-hour TTL, plus ambox_inbox:<inboxId>mapping. This lets webhook-go read its configuration quickly without touching the database. -
Find or create the
line_userrow from theuserIdon the first event. For an unknown user the worker verifies the access token, fetches the profile from LINE, and callscreateLineUser. -
Dispatch every event according to its type.
Text messages — routed by
line_oa.message_handling_config.priority:auto_response_only(the default) publishes toline_auto_response.ai_classifier_onlypublishes tomessage_received_trigger.auto_response_firstpublishes toline_auto_responsewithfallbackToAiset to true.
Special messages
- The text
memberpublishes aline_change_richmenumessage of typemember, switching the user to the member rich menu. - The text
guestsetsuser_typeto guest.
Every message event also updates
last_activity_typetomessageandlast_activity_statustoactive.Other event types
postbacksetslogEventTypetowebhookand publishes the whole payload onto thetracking_logqueue.followrefreshes the profile, updates the user record, assigns the member rich menu, and runs friend-track attribution.unfollowmarksfollowasnoand records the unfollow event.
-
Publishes on the message path are fire-and-forget: a failed publish is logged and processing continues with the next event, matching the legacy NestJS behaviour of not awaiting the result.
-
Event-level errors are handled by
handleWebhookError, which logs them, whileProcessLineWebhookalways returns nil so the message is acked.
Key Files & Functions
internal/lineoa/webhook.goService.ProcessLineWebhook(ctx, payload)— entry pointwarmWebhookConfigCache(),processEvents(),handleMessageEvent(),handleFollowEvent(),handleUnfollowEvent(),runFriendTrackAttribution(),handleWebhookError()
internal/lineoa/consumer.go—Consumer.HandleLineWebhook, bound to theline_webhookqueueinternal/lineoa/service.go—getLineOAByWebhookId(),findById(),issueAccessToken(), andverifyAccessToken(), with tokens cached for one hour under Redis keys prefixedLINE_OA:internal/lineoa/lineuser.go—findByLineUserId(),createLineUser(),updateLineUser()internal/lineoa/types.go—LineForwardWebhookPayload,WebhookEvent, and the event-type and priority enums- Queues: consumes
line_webhook; publishes toline_auto_response,message_received_trigger,line_change_richmenu, andtracking_log(runtime profilemain)
Connections to Other Services
- Job source —
line-management-webhook-go, the endpoint that receives webhooks from LINE. - Database —
line_oa(channel secret, access token,message_handling_config),line_user(find-or-create plus last-activity fields), andfriend_track_event/friend_track_campaign. - Redis — the
LINE_OA:key family for token caching, pluswebhook_config:<webhookId>andmbox_inbox:<inboxId>. - LINE API —
GET /v2/bot/profile/{userId}and the OAuth endpoints for issuing and verifying channel access tokens. - Downstream features triggered — auto response, AI message triggers, rich menu management, tracking log recording, and friend track.