0Pricing
AI Agents · Pelajaran

Menyimak Acara dan Perintah Slash

app_mention, perintah slash, dan pengendali tindakan dalam Slack Bolt.

Menyimak Acara dan Perintah Slash adalah pelajaran AI Agents gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Agents, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Agents mencakup 4 pelajaran total.

Ikhtisar Langganan Peristiwa Slack

Slack mengirimkan peristiwa ke aplikasi Anda ketika sesuatu terjadi — pesan diposting, seseorang menyebut bot Anda, atau pengguna bergabung ke sebuah kanal. Anda berlangganan jenis peristiwa tertentu di dasbor Aplikasi Slack, lalu mendaftarkan penangan di Bolt menggunakan dekorator @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"]}')

Menangani Peristiwa app_mention

Peristiwa app_mention aktif ketika seseorang mengetikkan @YourBot di sebuah kanal. event['text'] berisi seluruh pesan, termasuk penyebutan tersebut. Hapus awalan penyebutan untuk mendapatkan kueri sebenarnya dari pengguna.

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)

Mengakses Muatan Peristiwa

Setiap penangan peristiwa menerima kamus event yang berisi muatan mentah peristiwa Slack. Kolom kuncinya adalah: event['user'] (ID pengguna), event['channel'] (ID kanal), event['text'] (isi pesan), event['ts'] (stempel waktu/ID pesan).

@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}!')

Perintah Slash — Mendaftarkan dan Merespons

Perintah slash memungkinkan pengguna memicu tindakan agen dari kanal Slack mana pun. Daftarkan URL perintah di dasbor Aplikasi Slack (di bagian Perintah Slash), lalu tangani dengan @app.command('/command-name'). Selalu panggil ack() segera — Slack akan menganggap permintaan melewati batas waktu dalam 3 detik jika Anda tidak melakukannya.

@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() — Aturan 3 Detik

Slack mengharuskan aplikasi Anda memanggil ack() (mengakui penerimaan) untuk setiap perintah slash dan muatan interaktif yang masuk dalam waktu 3 detik. Jika tidak, Slack akan menampilkan kesalahan kepada pengguna. Untuk operasi yang berlangsung lama, panggil ack segera, mulai pemrosesan di utas latar belakang, lalu berikan respons menggunakan respond() beserta hasilnya.

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 out

say() vs respond() — Kapan Menggunakan Masing-Masing

Dua fungsi mengirimkan pesan kembali ke Slack:

  • say() — memposting ke kanal tempat peristiwa terjadi; terlihat oleh semua orang
  • respond() — hanya tersedia dalam penangan perintah slash; dapat memposting pesan sementara yang hanya terlihat oleh pengguna perintah

Gunakan respond(response_type='in_channel') untuk respons publik dan respond(response_type='ephemeral') untuk respons pribadi.

@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')

Peristiwa Pesan dan Subjenisnya

Peristiwa umum message aktif untuk semua pesan, termasuk pesan bot, pengeditan, dan penghapusan. Gunakan kolom subtype untuk memfilternya. Subjenis yang umum adalah: bot_message, message_changed, message_deleted. Jika subtype tidak ada, pesan tersebut merupakan pesan pengguna biasa.

@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}')

Mendengarkan Reaksi

Peristiwa reaction_added aktif ketika seseorang menambahkan reaksi emoji ke sebuah pesan. Anda dapat menggunakannya untuk memicu tindakan agen — misalnya, menambahkan reaksi 📌 untuk menyimpan pesan, atau ✅ untuk menandai tugas selesai.

@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]}')

Muatan Tindakan dari Komponen Interaktif

Ketika pengguna mengeklik tombol atau memilih item menu, Slack mengirimkan muatan tindakan. Tangani dengan @app.action('action_id'). ID tindakan adalah string yang Anda tetapkan saat membuat komponen Block Kit. Selalu panggil ack() segera.

@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')

Memfilter Peristiwa berdasarkan Kanal atau Pengguna

Di ruang kerja yang besar, bot Anda mungkin menerima peristiwa dari banyak kanal. Lakukan pemfilteran sejak awal di penangan Anda agar hanya memproses peristiwa yang relevan. Periksa event['channel'] terhadap daftar yang diizinkan, atau periksa event['user'] untuk mengabaikan pengguna tertentu (seperti bot lain).

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]}')

Dukungan Balasan Utas

Untuk membalas dalam utas, bukan di kanal utama, teruskan thread_ts ke say(). Gunakan event.get('thread_ts', event['ts']) untuk mendapatkan stempel waktu utas — thread_ts hanya ada jika pesan sudah berada dalam utas; jika tidak, gunakan ts milik pesan untuk memulai utas baru.

@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
    )

Pemeriksaan Singkat: Waktu ack()

Uji pemahaman Anda tentang penanganan peristiwa Slack.

Ringkasan Peristiwa dan Perintah Slash

Agen Slack Anda kini dapat merespons interaksi pengguna apa pun:

  • @app.event('app_mention') — menangani penyebutan @bot; hapus awalan penyebutan dengan ekspresi reguler
  • @app.command('/cmd') — menangani perintah slash; selalu panggil ack() dalam waktu 3 detik
  • say() — memposting secara publik ke kanal; respond() — membalas perintah slash (dapat bersifat sementara)
  • @app.action('id') — menangani klik tombol dan interaksi komponen interaktif
  • @app.event('reaction_added') — memicu tindakan berdasarkan reaksi emoji
  • Gunakan thread_ts dalam say() agar balasan tetap berada dalam utas
  • Filter berdasarkan kanal/pengguna sejak awal agar tidak memproses peristiwa yang tidak relevan

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menyimak Acara dan Perintah Slash” gratis?

Ya — teks lengkap “Menyimak Acara dan Perintah Slash” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Agents, upgrade ke CoddyKit PRO. Kursus AI Agents mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menyimak Acara dan Perintah Slash”?

app_mention, perintah slash, dan pengendali tindakan dalam Slack Bolt. Kamu berlatih AI Agents dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Agents?

Tidak diperlukan pengalaman sebelumnya. AI Agents di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Menyimak Acara dan Perintah Slash” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Agents ini?

Ya. Setiap pelajaran AI Agents menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Dasar-Dasar Slack Bolt SDK
  2. Menyimak Acara dan Perintah Slash
  3. Mengirim Pesan dan Blok Kaya
  4. Membangun Bot Notifikasi Tim
← Kembali ke AI Agents