{"id":21462220,"url":"https://github.com/mcdallas/rust-discord-bot","last_synced_at":"2025-07-20T17:04:41.765Z","repository":{"id":60198722,"uuid":"538554229","full_name":"mcdallas/rust-discord-bot","owner":"mcdallas","description":"A pure-Rust serverless discord chatbot hosted on Cloudflare Workers. ","archived":false,"fork":false,"pushed_at":"2023-07-21T11:40:37.000Z","size":42,"stargazers_count":78,"open_issues_count":0,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-15T05:55:12.422Z","etag":null,"topics":["cloudflare-workers","discord","discord-bot","rust","serverless","wasm","webassembly"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcdallas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-19T14:53:53.000Z","updated_at":"2025-06-18T21:11:33.000Z","dependencies_parsed_at":"2024-11-23T10:03:08.235Z","dependency_job_id":null,"html_url":"https://github.com/mcdallas/rust-discord-bot","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/mcdallas/rust-discord-bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcdallas%2Frust-discord-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcdallas%2Frust-discord-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcdallas%2Frust-discord-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcdallas%2Frust-discord-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcdallas","download_url":"https://codeload.github.com/mcdallas/rust-discord-bot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcdallas%2Frust-discord-bot/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266161906,"owners_count":23885928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-workers","discord","discord-bot","rust","serverless","wasm","webassembly"],"created_at":"2024-11-23T07:13:08.155Z","updated_at":"2025-07-20T17:04:41.740Z","avatar_url":"https://github.com/mcdallas.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# About\n\nA pure-Rust serverless discord chatbot hosted on Cloudflare Workers. With a free account you have up to 100k requests per day. For storing state you can use the bundled [`workers-rs`](https://github.com/cloudflare/workers-rs) crate to access KV or Durable objects.\n\nThis template is designed for compiling Rust to WebAssembly and publishing the resulting worker to \nCloudflare's [edge infrastructure](https://www.cloudflare.com/network/).\n\n\n## Setup\n\n1. Signup for a Cloudflare account, in the dashboard setup a subdomain (i.e `\u003cmydomain\u003e.workers.dev`)\n2. Setup a worker project named `bot` (i.e `bot.\u003cmydomain\u003e.workers.dev`) or pick your own name and update wrangler.toml\n3. Install [wrangler CLI](https://github.com/cloudflare/wrangler) with `cargo install wrangler` and authenticate with cloudflare via `wrangler config`\n4. Create a new discord app at https://discord.com/developers/applications and copy your token/application_id/public_key\n5. Pass those secrets to your bot with `wrangler secret put DISCORD_TOKEN`, `wrangler secret put DISCORD_PUBLIC_KEY`, `wrangler secret put DISCORD_APPLICATION_ID`\n6. [Add bot permissions](https://discord.com/developers/docs/tutorials/hosting-on-cloudflare-workers#adding-bot-permissions) and grab your Oauth url to invite the bot to your server\n7. Publish the demo app with `wrangler publish`. The template bot contains a single hello command with a dummy autocomplete argument.\n8. Put your bot domain `https://bot.\u003cmydomain\u003e.workers.dev` in the `INTERACTIONS ENDPOINT URL` in your discord app page from step 4\n9. After initial deployment and each time you add a new command on your bot you need to register it with the discord api. To do that simply `curl -X POST https://bot.\u003cmydomain\u003e.workers.dev/register`\n\nYou should now be able to run the `/hello` command on discord\n\n## Adding new commands\n\nTo add a new command simply implement the `Command` trait. For example to add a ping command\n\n1. create a file src/commands/ping.rs\n\n``` rust\nuse crate::interaction::{\n    InteractionApplicationCommandCallbackData, ApplicationCommandOption, ApplicationCommandOptionChoice, ApplicationCommandOptionType\n};\nuse crate::error::InteractionError;\nuse crate::command::{Command, CommandInput};\n\nuse async_trait::async_trait;\n\n\npub(crate) struct Ping {}\n\n#[async_trait(?Send)]\nimpl Command for Ping {\n    async fn respond(\u0026self, _input: \u0026CommandInput) -\u003e Result\u003cInteractionApplicationCommandCallbackData, InteractionError\u003e {\n        Ok(InteractionApplicationCommandCallbackData {\n            content: Some(\"Pong\".to_string()),\n            choices: None,\n            embeds: None\n        })\n    }\n\n    fn name(\u0026self) -\u003e String{\n        \"ping\".into()\n    }\n\n    fn description(\u0026self) -\u003e String {\n        \"Send a ping\".into()\n    }\n\n    fn options(\u0026self) -\u003e Option\u003cVec\u003cApplicationCommandOption\u003e\u003e {\n        // add any arguments/choices here, more info at https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-structure\n        None\n    }\n\n    async fn autocomplete(\u0026self, _input: \u0026CommandInput) -\u003e Result\u003cOption\u003cInteractionApplicationCommandCallbackData\u003e, InteractionError\u003e {\n        None\n    }\n}\n```\n2. add your new module in src/commands/mod.rs\n3. Register your command in  `init_commands` in src/command.rs \n``` rust\npub(crate) fn init_commands() -\u003e Vec\u003cBox\u003cdyn Command + Sync\u003e\u003e {\n    let mut v : Vec\u003cBox\u003cdyn Command + Sync\u003e\u003e = Vec::new();\n    v.push(Box::new(commands::hello::Hello {}));\n    // Add this line\n    v.push(Box::new(commands::ping::Ping {}));\n    v\n}\n```\n4. publish your package with `wrangler publish`\n5. register your new command with discord with `curl -X POST http://bot.\u003cmydomain\u003e.workers.dev/register`\n\nYou can store and access state using the `input` context object passed to the `respond` and `autocomplete` methods, for example:\n\n``` rust\nlet my_val = input.kv_get(\"my_namespace\", \"my_key\").await?; // the namespace must be first registered on cloudflare dashboard\ninput.kv_put(\"my_namespace\", \"foo\", \"bar\").await?;\n\n```\n\n## Local Dev \n\n\nWith `wrangler`, you can build, test, and deploy your Worker with the following commands: \n\n```bash\n# compiles your project to WebAssembly and will warn of any issues\nwrangler build \n\n# run your Worker in an ideal development workflow (with a local server, file watcher \u0026 more)\nwrangler dev\n\n# deploy your Worker globally to the Cloudflare network (update your wrangler.toml file for configuration)\nwrangler publish\n```\n\nyou can use `ngrok` to tunnel traffic into your local machine, more info [here](https://discord.com/developers/docs/tutorials/hosting-on-cloudflare-workers#setting-up-ngrok)\n\n## Actions Deployments\n\nYou can create an a action to automatically deploy your worker \u0026 register your commands on each push to main.\n\nCreate a Cloudflare API token and use the `Edit Cloudflare Workers` template.\n\nThen, create a repository secret with your API Token under `CF_API_TOKEN` and add the following inside `.github/workflows/deploy.yml`:\n\n``` yaml\nname: Deploy to Cloudflare Workers\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n    deploy:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Checkout Repository\n            - uses: actions/checkout@v3\n\n            - name: Deploy to Cloudflare Workers\n              env:\n                  CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}\n              run: npm i -g wrangler \u0026\u0026 npx wrangler publish\n\n            - name: Curl the worker\n              run: curl -X POST https://\u003cyour_worker_domain\u003e/register\n```\n\n\n## WebAssembly\n\n`workers-rs` (the Rust SDK for Cloudflare Workers used in this template) is meant to be executed as \ncompiled WebAssembly, and as such so **must** all the code you write and depend upon. All crates and\nmodules used in Rust-based Workers projects have to compile to the `wasm32-unknown-unknown` triple. \n\nRead more about this on the [`workers-rs` project README](https://github.com/cloudflare/workers-rs).\n\n## Credits\n\nbased on [stateless-discord-bot](https://github.com/siketyan/stateless-discord-bot)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcdallas%2Frust-discord-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcdallas%2Frust-discord-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcdallas%2Frust-discord-bot/lists"}