Ascolto degli eventi e dei comandi slash
app_mention, comandi slash e gestori delle azioni in Slack Bolt
Ascolto degli eventi e dei comandi slash è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.
Panoramica delle sottoscrizioni agli eventi di Slack
Slack invia alla Sua app degli eventi quando accadono determinate cose: quando viene pubblicato un messaggio, qualcuno menziona il Suo bot o un utente entra in un canale. Sottoscriva tipi di evento specifici nella dashboard di Slack, quindi registri i gestori in Bolt usando il decoratore @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"]}')Gestione degli eventi app_mention
L'evento app_mention viene attivato quando qualcuno scrive @YourBot in un canale. event['text'] contiene il messaggio completo, inclusa la menzione. Rimuova il prefisso della menzione per ottenere la query effettiva dell'utente.
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)Accesso al payload dell'evento
Ogni gestore di eventi riceve il dizionario event, che contiene il payload grezzo dell'evento Slack. Campi principali: event['user'] (ID utente), event['channel'] (ID del canale), event['text'] (contenuto del messaggio), event['ts'] (timestamp/ID del messaggio).
@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 — Registrazione e risposta
Gli slash command consentono agli utenti di attivare azioni dell'agente da qualsiasi canale Slack. Registri l'URL del comando nella dashboard di Slack, nella sezione Slash Commands, quindi lo gestisca con @app.command('/command-name'). Esegua sempre ack() immediatamente: Slack interrompe l'attesa dopo 3 secondi se non lo fa.
@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() — La regola dei 3 secondi
Slack richiede che la Sua app esegua ack() (confermi la ricezione) di ogni slash command e payload interattivo entro 3 secondi. In caso contrario, Slack mostra un errore all'utente. Per le operazioni di lunga durata, esegua subito ack, avvii l'elaborazione in un thread in background, quindi risponda usando respond() con il risultato.
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() vs respond() — Quando usare ciascuno
Due funzioni pubblicano messaggi su Slack:
say()— pubblica nel canale in cui si è verificato l'evento; è visibile a tuttirespond()— è disponibile solo nei gestori degli slash command; può pubblicare messaggi effimeri visibili solo all'utente che ha eseguito il comando
Utilizzi respond(response_type='in_channel') per le risposte pubbliche e respond(response_type='ephemeral') per quelle private.
@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')Eventi message e sottotipi
L'evento generico message viene attivato per tutti i messaggi, inclusi quelli dei bot, le modifiche e le eliminazioni. Utilizzi il campo subtype per filtrare. Sottotipi comuni: bot_message, message_changed, message_deleted. Se subtype è assente, si tratta di un normale messaggio di un utente.
@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}')Ascolto delle reazioni
L'evento reaction_added viene attivato quando qualcuno aggiunge una reazione con emoji a un messaggio. Può utilizzarlo per attivare azioni dell'agente, ad esempio aggiungendo una reazione 📌 per salvare un messaggio o una ✅ per contrassegnare un'attività come completata.
@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]}')Payload delle azioni dei componenti interattivi
Quando un utente fa clic su un pulsante o seleziona una voce di menu, Slack invia un payload dell'azione. Lo gestisca con @app.action('action_id'). L'ID dell'azione è la stringa impostata durante la creazione del componente Block Kit. Esegua sempre ack() immediatamente.
@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')Filtraggio degli eventi per canale o utente
Negli workspace di grandi dimensioni, il Suo bot potrebbe ricevere eventi da molti canali. Filtri all'inizio del gestore per elaborare solo gli eventi pertinenti. Verifichi event['channel'] rispetto a un elenco di canali consentiti oppure utilizzi event['user'] per ignorare determinati utenti, ad esempio altri bot.
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]}')Supporto alle risposte nei thread
Per rispondere in un thread, invece che nel canale principale, passi thread_ts a say(). Utilizzi event.get('thread_ts', event['ts']) per ottenere il timestamp del thread: thread_ts esiste solo se il messaggio si trova già in un thread; in caso contrario, utilizzi il ts del messaggio stesso per avviare un nuovo thread.
@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
)Verifica rapida: tempistica di ack()
Verifichi la Sua comprensione della gestione degli eventi Slack.
Riepilogo di eventi e Slash Commands
Ora il Suo agente Slack può rispondere a qualsiasi interazione dell'utente:
- @app.event('app_mention') — gestisce le menzioni di @bot; rimuova il prefisso della menzione con un'espressione regolare
- @app.command('/cmd') — gestisce gli slash command; esegua sempre
ack()entro 3 secondi - say() — pubblica nel canale in modo pubblico; respond() — risponde allo slash command e può inviare messaggi effimeri
- @app.action('id') — gestisce i clic sui pulsanti e le interazioni con i componenti interattivi
- @app.event('reaction_added') — si attiva in caso di reazioni con emoji
- Utilizzi
thread_tsin say() per mantenere le risposte nei thread - Filtri tempestivamente per canale o utente per evitare di elaborare eventi non pertinenti
Domande Frequenti
La lezione «Ascolto degli eventi e dei comandi slash» è gratuita?
Sì — il testo completo di «Ascolto degli eventi e dei comandi slash» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.
Cosa imparerò in «Ascolto degli eventi e dei comandi slash»?
app_mention, comandi slash e gestori delle azioni in Slack Bolt Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Agents?
Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Ascolto degli eventi e dei comandi slash»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Agents?
Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Nozioni di base di Slack Bolt SDK
- Ascolto degli eventi e dei comandi slash
- Invio di messaggi e blocchi avanzati
- Creazione di un bot per le notifiche del team