การรับฟังเหตุการณ์และคำสั่งแบบเฉือน
app_mention คำสั่งแบบเฉือน และตัวจัดการการดำเนินการใน Slack Bolt
การรับฟังเหตุการณ์และคำสั่งแบบเฉือน เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Agents และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
ภาพรวมการสมัครรับเหตุการณ์ของ Slack
Slack ส่งเหตุการณ์ให้แอปของคุณเมื่อมีสิ่งต่าง ๆ เกิดขึ้น เช่น มีการโพสต์ข้อความ มีคนกล่าวถึงบอตของคุณ หรือผู้ใช้เข้าร่วมช่อง คุณสมัครรับประเภทเหตุการณ์ที่ต้องการในแดชบอร์ดของ Slack App จากนั้นลงทะเบียนตัวจัดการใน Bolt โดยใช้ตัวตกแต่ง @app.event()
from slack_bolt import App
import os
app = App(
token=os.environ['SLACK_BOT_TOKEN'],
signing_secret=os.environ['SLACK_SIGNING_SECRET']
)
# Register event handlers with @app.event()
# The string argument must match the Slack event type exactly
@app.event('app_mention')
def handle_mention(event, say, logger):
logger.info(f'Mention event: {event}')
say(f'Hello <@{event["user"]}>!')
@app.event('message')
def handle_message(event, say):
# Fires for every message in subscribed channels
if event.get('subtype') is None: # ignore bot messages
print(f'Message: {event["text"]}')การจัดการเหตุการณ์ app_mention
เหตุการณ์ app_mention จะทำงานเมื่อมีคนพิมพ์ @YourBot ในช่อง event['text'] มีข้อความทั้งหมด รวมถึงการกล่าวถึงด้วย ให้ลบส่วนต้นของการกล่าวถึงเพื่อรับคำถามจริงของผู้ใช้
import re
@app.event('app_mention')
def handle_mention(event, say, client):
# event['text'] example: '<@U0123BOT> summarize this'
text = event.get('text', '')
user_id = event['user']
channel = event['channel']
# Remove the @mention to get the clean query
clean_text = re.sub(r'<@[A-Z0-9]+>', '', text).strip()
print(f'User {user_id} asked: {clean_text}')
if not clean_text:
say(f'Hi <@{user_id}>! How can I help you today?')
return
# Process the query
response = process_user_query(clean_text, user_id)
say(response)การเข้าถึงเพย์โหลดของเหตุการณ์
ตัวจัดการเหตุการณ์ทุกตัวจะได้รับพจนานุกรม event ซึ่งมีเพย์โหลดเหตุการณ์ดิบจาก Slack ฟิลด์สำคัญ ได้แก่ event['user'] (ID ผู้ใช้), event['channel'] (ID ช่อง), event['text'] (เนื้อหาข้อความ) และ event['ts'] (การประทับเวลา/ID ข้อความ)
@app.event('app_mention')
def handle_mention(event, say, client):
print('Event type:', event.get('type'))
print('User ID:', event.get('user')) # e.g. 'U0123ABC'
print('Channel:', event.get('channel')) # e.g. 'C0456DEF'
print('Text:', event.get('text')) # full message text
print('Timestamp:', event.get('ts')) # '1234567890.123456'
print('Thread TS:', event.get('thread_ts')) # if in a thread
# Get full user info from the user ID
user_info = client.users_info(user=event['user'])
real_name = user_info['user']['real_name']
email = user_info['user']['profile'].get('email', '')
say(f'Hello {real_name}!')คำสั่งสแลช — การลงทะเบียนและการตอบกลับ
คำสั่งสแลชช่วยให้ผู้ใช้เรียกใช้การทำงานของเอเจนต์จากช่อง Slack ใดก็ได้ ลงทะเบียน URL ของคำสั่งในแดชบอร์ดของ Slack App (ภายใต้ คำสั่งสแลช) จากนั้นจัดการด้วย @app.command('/command-name') ให้เรียก ack() ทันทีเสมอ — Slack จะหมดเวลาใน 3 วินาทีหากไม่ดำเนินการดังกล่าว
@app.command('/summarize')
def handle_summarize(ack, body, say, respond):
# CRITICAL: ack() must be called within 3 seconds
ack() # acknowledge the command immediately
# body contains the command payload
user_id = body['user_id']
channel_id = body['channel_id']
text = body.get('text', '').strip() # text after the command
print(f'User {user_id} ran /summarize with: "{text}"')
if not text:
respond('Usage: /summarize <text or URL to summarize>')
return
# Process and respond
summary = generate_summary(text)
say(f'Summary by <@{user_id}>:\n{summary}')ack() — กฎ 3 วินาที
Slack กำหนดให้แอปของคุณเรียก ack() (ยืนยันการรับ) สำหรับคำสั่งสแลชและเพย์โหลดแบบโต้ตอบที่เข้ามาทุกรายการภายใน 3 วินาที หากไม่ทำเช่นนั้น Slack จะแสดงข้อผิดพลาดให้ผู้ใช้เห็น สำหรับการดำเนินการที่ใช้เวลานาน ให้เรียก ack ทันที เริ่มประมวลผลในเธรดเบื้องหลัง แล้วตอบกลับด้วย respond() พร้อมผลลัพธ์
import threading
@app.command('/analyze')
def handle_analyze(ack, body, respond):
ack() # Must be within 3 seconds!
text = body.get('text', '').strip()
if not text:
respond('Please provide text to analyze.')
return
# For slow operations: run in background thread
def process_in_background():
result = slow_ai_analysis(text) # may take 10+ seconds
respond(f'Analysis complete:\n{result}')
thread = threading.Thread(target=process_in_background)
thread.daemon = True
thread.start()
# respond() is safe to call from a different thread
# ack() already sent, Slack won't time outsay() กับ respond() — ควรใช้แต่ละแบบเมื่อใด
มีฟังก์ชันสองรายการสำหรับโพสต์ข้อความกลับไปยัง Slack:
say()— โพสต์ไปยังช่องที่เกิดเหตุการณ์ และทุกคนมองเห็นrespond()— ใช้ได้เฉพาะในตัวจัดการคำสั่งสแลช และสามารถโพสต์ข้อความชั่วคราวที่มองเห็นได้เฉพาะผู้ใช้ที่เรียกใช้คำสั่ง
ใช้ respond(response_type='in_channel') สำหรับการตอบกลับแบบสาธารณะ และใช้ respond(response_type='ephemeral') สำหรับการตอบกลับแบบส่วนตัว
@app.command('/status')
def handle_status(ack, respond, body):
ack()
# Ephemeral: only visible to the user who ran the command
respond(
text='Agent status: Running | Queue: 3 tasks | Uptime: 4h 22m',
response_type='ephemeral' # private to command user
)
@app.command('/broadcast')
def handle_broadcast(ack, say, respond, body):
ack()
text = body.get('text', '')
# Public: visible to everyone in the channel
say(
text=f'<@{body["user_id"]}> broadcast: {text}',
channel=body['channel_id']
)
# Confirm privately to the sender
respond('Broadcast sent!', response_type='ephemeral')เหตุการณ์ข้อความและประเภทย่อย
เหตุการณ์ message ทั่วไปจะทำงานกับข้อความทุกประเภท รวมถึงข้อความจากบอต การแก้ไข และการลบข้อความ ใช้ฟิลด์ subtype เพื่อกรอง ประเภทย่อยที่พบบ่อย ได้แก่ bot_message, message_changed และ message_deleted หากไม่มี subtype แสดงว่าเป็นข้อความปกติจากผู้ใช้
@app.event('message')
def handle_message(event, say, client):
subtype = event.get('subtype')
# Ignore bot messages to prevent loops
if subtype == 'bot_message':
return
# Ignore message edits and deletes
if subtype in ('message_changed', 'message_deleted'):
return
# Only process direct messages (DMs) to the bot
channel_type = event.get('channel_type', '')
if channel_type == 'im':
text = event.get('text', '').strip()
user = event['user']
print(f'DM from {user}: {text}')
say(f'You said: {text}')การรับฟังรีแอ็กชัน
เหตุการณ์ reaction_added จะทำงานเมื่อมีคนเพิ่มรีแอ็กชันอีโมจิให้กับข้อความ คุณสามารถใช้เหตุการณ์นี้เพื่อเรียกใช้การทำงานของเอเจนต์ได้ เช่น เพิ่มรีแอ็กชัน 📌 เพื่อบันทึกข้อความ หรือเพิ่ม ✅ เพื่อทำเครื่องหมายว่างานเสร็จสิ้น
@app.event('reaction_added')
def handle_reaction(event, client, say):
reaction = event['reaction'] # e.g. 'thumbsup', 'white_check_mark'
user_id = event['user'] # who reacted
item = event['item'] # what was reacted to
print(f'User {user_id} reacted :{reaction}: to {item["type"]}')
if reaction == 'white_check_mark' and item['type'] == 'message':
# Fetch the original message
result = client.conversations_history(
channel=item['channel'],
oldest=item['ts'],
latest=item['ts'],
inclusive=True,
limit=1
)
messages = result.get('messages', [])
if messages:
text = messages[0].get('text', '')
print(f'Task completed: {text[:100]}')เพย์โหลดการกระทำจากส่วนประกอบแบบโต้ตอบ
เมื่อผู้ใช้คลิกปุ่มหรือเลือกรายการเมนู Slack จะส่งเพย์โหลดการกระทำมา ให้จัดการด้วย @app.action('action_id') รหัสการกระทำคือสตริงที่คุณกำหนดเมื่อสร้างส่วนประกอบของ Block Kit ให้เรียก ack() ทันทีเสมอ
@app.action('approve_task')
def handle_approve(ack, body, respond, client):
ack() # acknowledge within 3 seconds
action = body['actions'][0] # the button that was clicked
action_id = action['action_id'] # 'approve_task'
value = action.get('value', '') # data attached to the button
user_id = body['user']['id']
print(f'User {user_id} clicked {action_id} with value: {value}')
# Update the original message to show it was approved
client.chat_update(
channel=body['container']['channel_id'],
ts=body['container']['message_ts'],
text=f'Task approved by <@{user_id}>',
blocks=[] # remove buttons after action
)
respond('Task approved!', response_type='ephemeral')การกรองเหตุการณ์ตามช่องหรือผู้ใช้
ในพื้นที่ทำงานขนาดใหญ่ บอตของคุณอาจได้รับเหตุการณ์จากหลายช่อง ให้กรองตั้งแต่ต้นในตัวจัดการเพื่อประมวลผลเฉพาะเหตุการณ์ที่เกี่ยวข้อง ตรวจสอบ event['channel'] กับรายการที่อนุญาต หรือใช้ event['user'] เพื่อไม่รับเหตุการณ์จากผู้ใช้บางราย เช่น บอตตัวอื่น
import os
# Only respond in designated channels
ALLOWED_CHANNELS = set(
os.environ.get('ALLOWED_CHANNELS', '').split(',')
)
BOT_USER_IDS = set() # will be populated at startup
@app.event('app_mention')
def handle_mention(event, say, client):
channel = event.get('channel', '')
user = event.get('user', '')
# Skip if channel not in allowed list (if list is configured)
if ALLOWED_CHANNELS and channel not in ALLOWED_CHANNELS:
return
# Skip if the 'user' is actually a bot
if user in BOT_USER_IDS:
return
text = event.get('text', '').strip()
say(f'Processing: {text[:50]}')การรองรับการตอบกลับในเธรด
หากต้องการตอบกลับในเธรดแทนช่องหลัก ให้ส่ง thread_ts ไปยัง say() ใช้ event.get('thread_ts', event['ts']) เพื่อรับการประทับเวลาของเธรด — thread_ts จะมีอยู่เฉพาะเมื่อข้อความอยู่ในเธรดอยู่แล้ว หากไม่มีก็ให้ใช้ ts ของข้อความนั้นเองเพื่อเริ่มเธรดใหม่
@app.event('app_mention')
def handle_mention_in_thread(event, say):
user = event['user']
text = event.get('text', '').strip()
# Reply in the same thread (or start a new one)
thread_ts = event.get('thread_ts') or event.get('ts')
response_text = f'<@{user}>, processing your request...'
say(
text=response_text,
thread_ts=thread_ts # keeps the reply in the thread
)
# Do the actual work
result = do_agent_work(text)
say(
text=f'Done! Result:\n{result}',
thread_ts=thread_ts
)ตรวจสอบความเข้าใจอย่างรวดเร็ว: จังหวะเวลา ack()
ทดสอบความเข้าใจเกี่ยวกับการจัดการเหตุการณ์ของ Slack
สรุปเหตุการณ์และคำสั่งสแลช
ตอนนี้เอเจนต์ Slack ของคุณสามารถตอบสนองต่อการโต้ตอบของผู้ใช้ได้ทุกรูปแบบ:
- @app.event('app_mention') — จัดการการกล่าวถึง @bot และลบส่วนต้นของการกล่าวถึงด้วยนิพจน์ทั่วไป
- @app.command('/cmd') — จัดการคำสั่งสแลช และเรียก
ack()ภายใน 3 วินาทีเสมอ - say() — โพสต์แบบสาธารณะไปยังช่อง ส่วน respond() — ตอบกลับคำสั่งสแลชและอาจเป็นข้อความชั่วคราวได้
- @app.action('id') — จัดการการคลิกปุ่มและการโต้ตอบกับส่วนประกอบแบบโต้ตอบ
- @app.event('reaction_added') — เรียกใช้เมื่อมีรีแอ็กชันอีโมจิ
- ใช้
thread_tsใน say() เพื่อให้การตอบกลับอยู่ในเธรด - กรองตามช่องหรือผู้ใช้ตั้งแต่ต้น เพื่อหลีกเลี่ยงการประมวลผลเหตุการณ์ที่ไม่เกี่ยวข้อง
คำถามที่พบบ่อย
บทเรียน “การรับฟังเหตุการณ์และคำสั่งแบบเฉือน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การรับฟังเหตุการณ์และคำสั่งแบบเฉือน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การรับฟังเหตุการณ์และคำสั่งแบบเฉือน”
app_mention คำสั่งแบบเฉือน และตัวจัดการการดำเนินการใน Slack Bolt คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การรับฟังเหตุการณ์และคำสั่งแบบเฉือน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม
ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน Slack Bolt SDK
- การรับฟังเหตุการณ์และคำสั่งแบบเฉือน
- การส่งข้อความและบล็อกแบบ Rich
- การสร้างบอตแจ้งเตือนทีม