0
# Webhook Event Handling
1
2
Comprehensive webhook processing for receiving and handling LINE platform events. Includes signature validation, event parsing, and handlers for all event types including messages, user interactions, and bot lifecycle events.
3
4
## Capabilities
5
6
### Webhook Handler
7
8
Primary interface for processing LINE webhook callbacks with automatic signature validation and event dispatching.
9
10
```python { .api }
11
class WebhookHandler:
12
def __init__(self, channel_secret: str):
13
"""
14
Initialize webhook handler with channel secret for signature validation.
15
16
Args:
17
channel_secret: LINE channel secret for webhook signature validation
18
"""
19
20
def handle(self, body: str, signature: str) -> None:
21
"""
22
Process webhook callback by validating signature and dispatching events.
23
24
Args:
25
body: Raw webhook request body as string
26
signature: X-Line-Signature header value
27
28
Raises:
29
LineBotApiError: If signature validation fails
30
"""
31
32
def add(self, event_type, message=None):
33
"""
34
Decorator for registering event handlers.
35
36
Args:
37
event_type: Event class to handle (MessageEvent, FollowEvent, etc.)
38
message: Optional message type filter for MessageEvent
39
40
Returns:
41
Decorator function for handler registration
42
"""
43
```
44
45
### Signature Validation
46
47
Cryptographic validation of webhook signatures to ensure message authenticity and security.
48
49
```python { .api }
50
class SignatureValidator:
51
def __init__(self, channel_secret: str):
52
"""Initialize validator with channel secret."""
53
54
def validate(self, body: bytes, signature: str) -> bool:
55
"""
56
Validate webhook signature against request body.
57
58
Args:
59
body: Raw request body as bytes
60
signature: X-Line-Signature header value without 'base64=' prefix
61
62
Returns:
63
bool: True if signature is valid, False otherwise
64
"""
65
```
66
67
### Webhook Parser
68
69
Direct webhook payload parsing for custom event processing workflows.
70
71
```python { .api }
72
class WebhookParser:
73
def __init__(self, channel_secret: str):
74
"""Initialize parser with channel secret for validation."""
75
76
def parse(self, body: str, signature: str) -> List[Event]:
77
"""
78
Parse webhook payload into event objects after signature validation.
79
80
Args:
81
body: Raw webhook request body as string
82
signature: X-Line-Signature header value
83
84
Returns:
85
List[Event]: Parsed event objects
86
87
Raises:
88
LineBotApiError: If signature validation fails
89
"""
90
```
91
92
### Webhook Payload
93
94
Container for raw webhook data and metadata.
95
96
```python { .api }
97
class WebhookPayload:
98
def __init__(self, events: List[Event]):
99
"""
100
Initialize payload with parsed events.
101
102
Args:
103
events: List of parsed event objects
104
"""
105
106
@property
107
def events(self) -> List[Event]:
108
"""Get list of events in the payload."""
109
```
110
111
## Event Types
112
113
### Base Event Classes
114
115
```python { .api }
116
class Event:
117
"""Base event class for all LINE webhook events"""
118
type: str
119
timestamp: int
120
source: Source
121
mode: str
122
webhook_event_id: str
123
delivery_context: DeliveryContext
124
125
class CallbackRequest:
126
"""Root webhook callback request"""
127
destination: str
128
events: List[Event]
129
```
130
131
### Message Events
132
133
Events triggered when users send messages to the bot.
134
135
```python { .api }
136
class MessageEvent(Event):
137
"""User sent a message to the bot"""
138
reply_token: str
139
message: MessageContent
140
141
class MessageContent:
142
"""Base message content"""
143
id: str
144
type: str
145
146
class TextMessageContent(MessageContent):
147
"""Text message content"""
148
text: str
149
emojis: Optional[List[Emoji]] = None
150
mention: Optional[Mention] = None
151
152
class ImageMessageContent(MessageContent):
153
"""Image message content"""
154
content_provider: ContentProvider
155
image_set: Optional[ImageSet] = None
156
157
class VideoMessageContent(MessageContent):
158
"""Video message content"""
159
duration: int
160
content_provider: ContentProvider
161
162
class AudioMessageContent(MessageContent):
163
"""Audio message content"""
164
duration: int
165
content_provider: ContentProvider
166
167
class LocationMessageContent(MessageContent):
168
"""Location message content"""
169
title: str
170
address: str
171
latitude: float
172
longitude: float
173
174
class StickerMessageContent(MessageContent):
175
"""Sticker message content"""
176
package_id: str
177
sticker_id: str
178
sticker_resource_type: str
179
keywords: Optional[List[str]] = None
180
text: Optional[str] = None
181
182
class FileMessageContent(MessageContent):
183
"""File message content"""
184
file_name: str
185
file_size: int
186
```
187
188
### User Interaction Events
189
190
Events triggered by user interactions with the bot and platform features.
191
192
```python { .api }
193
class FollowEvent(Event):
194
"""User followed the bot"""
195
reply_token: str
196
follow_detail: FollowDetail
197
198
class UnfollowEvent(Event):
199
"""User unfollowed the bot"""
200
pass
201
202
class JoinEvent(Event):
203
"""Bot was added to a group or room"""
204
reply_token: str
205
joined_members: JoinedMembers
206
207
class LeaveEvent(Event):
208
"""Bot was removed from a group or room"""
209
pass
210
211
class PostbackEvent(Event):
212
"""User triggered a postback action"""
213
reply_token: str
214
postback: PostbackContent
215
216
class BeaconEvent(Event):
217
"""User interacted with a LINE Beacon"""
218
reply_token: str
219
beacon: BeaconContent
220
221
class AccountLinkEvent(Event):
222
"""Account linking event occurred"""
223
reply_token: str
224
link: LinkContent
225
226
class UnsendEvent(Event):
227
"""User unsent a message"""
228
unsend: UnsendDetail
229
230
class VideoPlayCompleteEvent(Event):
231
"""User finished watching a video message"""
232
reply_token: str
233
video_play_complete: VideoPlayComplete
234
```
235
236
### Group Events
237
238
Events related to group and room member management.
239
240
```python { .api }
241
class MemberJoinedEvent(Event):
242
"""Members joined a group or room"""
243
reply_token: str
244
joined_members: JoinedMembers
245
246
class MemberLeftEvent(Event):
247
"""Members left a group or room"""
248
left_members: LeftMembers
249
```
250
251
### Bot Lifecycle Events
252
253
Events related to bot activation, suspension, and lifecycle management.
254
255
```python { .api }
256
class ActivatedEvent(Event):
257
"""Bot was activated"""
258
pass
259
260
class DeactivatedEvent(Event):
261
"""Bot was deactivated"""
262
pass
263
264
class BotSuspendedEvent(Event):
265
"""Bot account was suspended"""
266
pass
267
268
class BotResumedEvent(Event):
269
"""Bot account suspension was lifted"""
270
pass
271
```
272
273
### Membership Events
274
275
Events related to LINE membership features and subscriptions.
276
277
```python { .api }
278
class MembershipEvent(Event):
279
"""Membership-related event occurred"""
280
reply_token: str
281
membership: MembershipContent
282
283
class JoinedMembershipContent(MembershipContent):
284
"""User joined a membership"""
285
pass
286
287
class LeftMembershipContent(MembershipContent):
288
"""User left a membership"""
289
pass
290
291
class RenewedMembershipContent(MembershipContent):
292
"""User renewed a membership"""
293
pass
294
```
295
296
### Module Events
297
298
Events related to LINE module functionality and attachments.
299
300
```python { .api }
301
class ModuleEvent(Event):
302
"""Module-related event occurred"""
303
reply_token: str
304
module: ModuleContent
305
306
class AttachedModuleContent(ModuleContent):
307
"""Module was attached"""
308
pass
309
310
class DetachedModuleContent(ModuleContent):
311
"""Module was detached"""
312
pass
313
```
314
315
### Delivery Events
316
317
Events related to message delivery and push notification completion.
318
319
```python { .api }
320
class PnpDeliveryCompletionEvent(Event):
321
"""Push notification delivery completed"""
322
delivery: PnpDelivery
323
```
324
325
## Event Sources
326
327
Source information identifying where events originated.
328
329
```python { .api }
330
class Source:
331
"""Base event source"""
332
type: str
333
334
class UserSource(Source):
335
"""Event from individual user"""
336
user_id: str
337
338
class GroupSource(Source):
339
"""Event from group chat"""
340
group_id: str
341
user_id: Optional[str] = None
342
343
class RoomSource(Source):
344
"""Event from room chat"""
345
room_id: str
346
user_id: Optional[str] = None
347
```
348
349
## Content Models
350
351
### Postback Content
352
353
```python { .api }
354
class PostbackContent:
355
data: str
356
params: Optional[dict] = None
357
```
358
359
### Beacon Content
360
361
```python { .api }
362
class BeaconContent:
363
hwid: str
364
type: str
365
device_message: Optional[bytes] = None
366
```
367
368
### Mention Features
369
370
```python { .api }
371
class Mention:
372
mentionees: List[Mentionee]
373
374
class Mentionee:
375
"""Base mentionee class"""
376
type: str
377
378
class UserMentionee(Mentionee):
379
"""Specific user mentioned"""
380
user_id: str
381
382
class AllMentionee(Mentionee):
383
"""All users mentioned"""
384
pass
385
```
386
387
### Content Provider
388
389
```python { .api }
390
class ContentProvider:
391
type: str # "line" or "external"
392
original_content_url: Optional[str] = None
393
preview_image_url: Optional[str] = None
394
```
395
396
## Usage Examples
397
398
### Basic Webhook Handler Setup
399
400
```python
401
from flask import Flask, request, abort
402
from linebot.v3 import WebhookHandler
403
from linebot.v3.webhooks.models import MessageEvent, TextMessageContent
404
405
app = Flask(__name__)
406
handler = WebhookHandler('YOUR_CHANNEL_SECRET')
407
408
@app.route("/callback", methods=['POST'])
409
def callback():
410
signature = request.headers['X-Line-Signature']
411
body = request.get_data(as_text=True)
412
413
try:
414
handler.handle(body, signature)
415
except Exception as e:
416
abort(400)
417
418
return 'OK'
419
420
@handler.add(MessageEvent, message=TextMessageContent)
421
def handle_text_message(event):
422
print(f"Received text: {event.message.text}")
423
print(f"From user: {event.source.user_id}")
424
```
425
426
### Advanced Event Handling
427
428
```python
429
from linebot.v3.webhooks.models import (
430
FollowEvent, PostbackEvent, BeaconEvent,
431
ImageMessageContent, LocationMessageContent
432
)
433
434
@handler.add(FollowEvent)
435
def handle_follow(event):
436
print(f"New follower: {event.source.user_id}")
437
# Send welcome message using messaging API
438
439
@handler.add(PostbackEvent)
440
def handle_postback(event):
441
postback_data = event.postback.data
442
print(f"Postback received: {postback_data}")
443
# Process postback action
444
445
@handler.add(MessageEvent, message=ImageMessageContent)
446
def handle_image(event):
447
message_id = event.message.id
448
print(f"Image received: {message_id}")
449
# Download and process image using MessagingApiBlob
450
451
@handler.add(MessageEvent, message=LocationMessageContent)
452
def handle_location(event):
453
location = event.message
454
print(f"Location: {location.title} at {location.latitude}, {location.longitude}")
455
456
@handler.add(BeaconEvent)
457
def handle_beacon(event):
458
beacon = event.beacon
459
print(f"Beacon interaction: {beacon.hwid} - {beacon.type}")
460
```
461
462
### Direct Webhook Processing
463
464
```python
465
from linebot.v3 import WebhookParser, SignatureValidator
466
467
# Initialize components
468
validator = SignatureValidator('YOUR_CHANNEL_SECRET')
469
parser = WebhookParser('YOUR_CHANNEL_SECRET')
470
471
def process_webhook(body_bytes, signature):
472
# Manual signature validation
473
if not validator.validate(body_bytes, signature):
474
raise ValueError("Invalid signature")
475
476
# Parse events directly
477
body_str = body_bytes.decode('utf-8')
478
events = parser.parse(body_str, signature)
479
480
for event in events:
481
if isinstance(event, MessageEvent):
482
print(f"Message from {event.source.user_id}: {event.message.text}")
483
elif isinstance(event, FollowEvent):
484
print(f"New follower: {event.source.user_id}")
485
```
486
487
### Group and Room Event Handling
488
489
```python
490
from linebot.v3.webhooks.models import (
491
JoinEvent, LeaveEvent, MemberJoinedEvent, MemberLeftEvent,
492
GroupSource, RoomSource
493
)
494
495
@handler.add(JoinEvent)
496
def handle_join(event):
497
if isinstance(event.source, GroupSource):
498
print(f"Bot joined group: {event.source.group_id}")
499
elif isinstance(event.source, RoomSource):
500
print(f"Bot joined room: {event.source.room_id}")
501
502
@handler.add(MemberJoinedEvent)
503
def handle_member_joined(event):
504
joined_users = event.joined_members.members
505
for member in joined_users:
506
print(f"New member: {member.user_id}")
507
508
@handler.add(LeaveEvent)
509
def handle_leave(event):
510
print("Bot was removed from chat")
511
```