Auf Ereignisse und Slash Commands reagieren
app_mention, Slash Commands und Action-Handler in Slack Bolt.
Auf Ereignisse und Slash Commands reagieren ist eine kostenlose AI Agents-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Agents-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.
Übersicht über Slack-Ereignisabonnements
Slack sendet Ihrer App Ereignisse, wenn etwas geschieht – etwa wenn eine Nachricht gepostet wird, jemand Ihren Bot erwähnt oder ein Benutzer einem Kanal beitritt. Sie abonnieren bestimmte Ereignistypen im Slack-App-Dashboard und registrieren anschließend Handler in Bolt mit dem Decorator @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-Ereignisse verarbeiten
Das Ereignis app_mention wird ausgelöst, wenn jemand in einem Kanal @YourBot eingibt. event['text'] enthält die vollständige Nachricht einschließlich der Erwähnung. Entfernen Sie das Präfix der Erwähnung, um die eigentliche Anfrage des Benutzers zu erhalten.
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)Auf die event-Payload zugreifen
Jeder Event-Handler erhält das event-Dictionary, das die unverarbeiteten Slack-Ereignisdaten enthält. Wichtige Felder: event['user'] (Benutzer-ID), event['channel'] (Kanal-ID), event['text'] (Nachrichteninhalt), event['ts'] (Zeitstempel/Nachrichten-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}!')Slash Commands – Registrieren und Antworten
Mit Slash Commands können Benutzer Agent-Aktionen aus jedem Slack-Kanal heraus auslösen. Registrieren Sie die Befehls-URL im Slack-App-Dashboard (unter Slash Commands) und verarbeiten Sie den Befehl anschließend mit @app.command('/command-name'). Rufen Sie immer sofort ack() auf – Slack bricht den Vorgang nach 3 Sekunden ab, wenn Sie dies nicht tun.
@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() – Die 3-Sekunden-Regel
Slack verlangt, dass Ihre App jeden eingehenden Slash Command und jede interaktive Payload innerhalb von 3 Sekunden mit ack() bestätigt. Andernfalls zeigt Slack dem Benutzer einen Fehler an. Bei lang laufenden Vorgängen sollten Sie sofort bestätigen, die Verarbeitung in einem Hintergrund-Thread starten und anschließend mit respond() auf das Ergebnis antworten.
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() oder respond() – Wann wird welche Funktion verwendet
Zwei Funktionen posten Nachrichten zurück an Slack:
say()– postet in den Kanal, in dem das Ereignis aufgetreten ist; für alle sichtbarrespond()– nur in Slash-Command-Handlern verfügbar; kann ephemere Nachrichten posten, die nur für den Benutzer des Befehls sichtbar sind
Verwenden Sie respond(response_type='in_channel') für öffentliche Antworten und respond(response_type='ephemeral') für private Antworten.
@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')Nachrichtenereignisse und Subtypen
Das allgemeine message-Ereignis wird für alle Nachrichten ausgelöst, einschließlich Bot-Nachrichten, Bearbeitungen und Löschungen. Verwenden Sie das Feld subtype zum Filtern. Häufige Subtypen sind: bot_message, message_changed, message_deleted. Wenn subtype fehlt, handelt es sich um eine reguläre Benutzernachricht.
@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}')Auf Reaktionen reagieren
Das Ereignis reaction_added wird ausgelöst, wenn jemand eine Emoji-Reaktion zu einer Nachricht hinzufügt. Sie können damit Agent-Aktionen auslösen – beispielsweise eine 📌-Reaktion zum Speichern einer Nachricht oder eine ✅-Reaktion zum Markieren einer Aufgabe als erledigt.
@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]}')Aktions-Payloads interaktiver Komponenten
Wenn ein Benutzer auf eine Schaltfläche klickt oder ein Menüelement auswählt, sendet Slack eine Aktions-Payload. Verarbeiten Sie sie mit @app.action('action_id'). Die Aktions-ID ist die Zeichenfolge, die Sie beim Erstellen der Block-Kit-Komponente festgelegt haben. Rufen Sie immer sofort ack() auf.
@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')Ereignisse nach Kanal oder Benutzer filtern
In großen Workspaces empfängt Ihr Bot möglicherweise Ereignisse aus vielen Kanälen. Filtern Sie frühzeitig in Ihrem Handler, damit nur relevante Ereignisse verarbeitet werden. Vergleichen Sie event['channel'] mit einer Liste zulässiger Kanäle oder prüfen Sie event['user'], um bestimmte Benutzer wie andere Bots zu ignorieren.
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]}')Antworten in Threads
Um in einem Thread statt im Hauptkanal zu antworten, übergeben Sie thread_ts an say(). Verwenden Sie event.get('thread_ts', event['ts']), um den Zeitstempel des Threads abzurufen – thread_ts ist nur vorhanden, wenn sich die Nachricht bereits in einem Thread befindet. Andernfalls verwenden Sie den eigenen ts der Nachricht, um einen neuen Thread zu starten.
@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
)Kurzer Test: Timing von ack()
Testen Sie Ihr Verständnis der Verarbeitung von Slack-Ereignissen.
Zusammenfassung: Ereignisse und Slash Commands
Ihr Slack-Agent kann jetzt auf jede Benutzerinteraktion reagieren:
- @app.event('app_mention') – @bot-Erwähnungen verarbeiten; Präfix der Erwähnung mit einem regulären Ausdruck entfernen
- @app.command('/cmd') – Slash Commands verarbeiten; immer innerhalb von 3 Sekunden
ack()aufrufen - say() – öffentlich im Kanal posten; respond() – auf einen Slash Command antworten, bei Bedarf ephemer
- @app.action('id') – Klicks auf Schaltflächen und Interaktionen mit interaktiven Komponenten verarbeiten
- @app.event('reaction_added') – auf Emoji-Reaktionen reagieren
- Verwenden Sie
thread_tsin say(), damit Antworten in Threads bleiben - Filtern Sie frühzeitig nach Kanal und Benutzer, um irrelevante Ereignisse nicht zu verarbeiten
Häufig gestellte Fragen
Ist die Lektion „Auf Ereignisse und Slash Commands reagieren“ kostenlos?
Ja — der vollständige Text von „Auf Ereignisse und Slash Commands reagieren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Agents-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Auf Ereignisse und Slash Commands reagieren“?
app_mention, Slash Commands und Action-Handler in Slack Bolt. Du übst AI Agents mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um AI Agents zu starten?
Keine Vorkenntnisse erforderlich. AI Agents auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Auf Ereignisse und Slash Commands reagieren“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser AI Agents-Lektion Code schreiben und ausführen?
Ja. Jede AI Agents-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Grundlagen des Slack Bolt SDK
- Auf Ereignisse und Slash Commands reagieren
- Nachrichten und Rich Blocks senden
- Einen Benachrichtigungs-Bot für Teams erstellen