Skip to main content

Discord Source/Output for Waken -- gateway events in, REST message send out.

Project description

waken-discord

CI License: MIT

Discord Source/Output for Waken -- "nginx for AI agents." Unlike a Target adapter (waken-claude, waken-gemini, ...), Discord here is a channel: DiscordSource turns incoming Discord messages into waken Events, and DiscordOutput posts a Target's Response back to the channel it came from.

Install

pip install waken-discord

Needs a Discord bot application (Discord Developer Portal -> New Application -> Bot):

  • DISCORD_BOT_TOKEN -- the bot token from the Bot page.
  • The Message Content privileged gateway intent, enabled on that same Bot page (under "Privileged Gateway Intents"). This is a real, commonly missed step -- without it, Discord silently delivers every message with content as an empty string (except direct @mentions of the bot), no matter what the bot process itself requests.
  • The bot invited to your server with, at minimum, the bot scope and the Send Messages/Read Message History permissions.

Usage

from waken import Runtime
from waken_claude import ClaudeAdapter
from waken_discord import DiscordOutput, DiscordSource

runtime = Runtime()
runtime.target("claude", ClaudeAdapter())
runtime.source("discord", DiscordSource(target="claude"))
runtime.output("discord", DiscordOutput())
runtime.run()

DiscordSource/DiscordOutput both resolve DISCORD_BOT_TOKEN from the environment by default, or accept it as a constructor argument. Every incoming message becomes an Event(source="discord", target="claude", payload={"prompt": text}, session_id=runtime.session("discord", external_key=str(channel_id)), metadata={"channel_id": channel_id}) -- follow-up messages in the same channel resume the same waken session. DiscordOutput reads event.metadata["channel_id"] back off to know where to send the reply.

Messages from bots -- including DiscordOutput's own replies -- are filtered out before dispatch, otherwise a reply posted back into the channel would re-trigger DiscordSource and loop forever.

Design notes

A gateway connection for DiscordSource, REST-only for DiscordOutput. Discord bots receive messages over a persistent gateway WebSocket -- there's no webhook equivalent of "a message was posted" a bot can subscribe to instead, so DiscordSource holds that connection open, the same shape as waken-slack's Socket Mode connection: a background task started in start(), closed in stop().

Sending a message, however, is a plain REST call authenticated by the bot token -- it needs no gateway connection at all. DiscordOutput doesn't spin up a second discord.Client (which would mean logging in twice and paying for a connection it'd never use) to get one. Instead it talks directly to discord.http.HTTPClient, the lightweight, gateway-free HTTP client that discord.py itself builds internally and hangs every Client's own REST calls off of. It isn't re-exported from discord/__init__.py or documented as public API the way discord.Client is, but it's the only thing the library ships that fits "REST send, no gateway" -- there's no separate public discord.RESTClient. It ships under the same py.typed package as everything else, so it stays fully type-checked here regardless.

discord.Client.start(), not .run(). Client.run() is documented as "a blocking call that abstracts away the event loop initialisation from you" and calls asyncio.run(...) itself -- it wants to own the whole process's event loop, the same way Client.run()/SlackSource's SocketModeHandler.start_async() would. waken's Runtime already owns the loop this Source runs inside, so DiscordSource.start() instead schedules the lower-level client.start(token) coroutine (a shorthand for login() + connect(), and just a plain coroutine with no loop management of its own) as a background asyncio.Task, and awaits client.close() + that task on stop() -- the recipe discord.py itself documents for running inside an already-running event loop.

Why discord.py, not one of its forks. discord.py went through a period of being unmaintained a few years back, which is what spawned pycord/nextcord/disnake in the first place -- but it later resumed active maintenance, and remains, by a wide margin, the most widely used library in this space (checked directly against all three forks' PyPI release cadence and GitHub activity before picking it, not from memory).

Development

git clone https://github.com/WakenHQ/waken-discord
cd waken-discord
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

Tests mock discord.py's Client and discord.http.HTTPClient entirely -- no network access, real gateway connection, or Discord bot token needed to run the suite.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

waken_discord-0.1.0.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

waken_discord-0.1.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file waken_discord-0.1.0.tar.gz.

File metadata

  • Download URL: waken_discord-0.1.0.tar.gz
  • Upload date:
  • Size: 10.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for waken_discord-0.1.0.tar.gz
Algorithm Hash digest
SHA256 13dc275e4fcdf1f9245ff412027d4698d9b95daacb238e253d7a51338aecfed4
MD5 6f2df835b24b54ce0f2a0f95f76f8f5e
BLAKE2b-256 79134494c8d4d4d917500dd7a4ab4fd613a702fbf273ac47d8313313d018beb2

See more details on using hashes here.

Provenance

The following attestation bundles were made for waken_discord-0.1.0.tar.gz:

Publisher: publish.yml on WakenHQ/waken-discord

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file waken_discord-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: waken_discord-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for waken_discord-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ec6b795bdda11cc85f5acb343d1a9adfd07d71a14b30ffc59267213e707578c8
MD5 8bc45f5776a900a9b26eb6dde9287af3
BLAKE2b-256 a5f0c968a3c89cb378d61b9c371da524466abc3cfebbcbc47002f45207e457eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for waken_discord-0.1.0-py3-none-any.whl:

Publisher: publish.yml on WakenHQ/waken-discord

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page