Ditto can answer /ditto in your Discord server through its own bot. Some people want the answers to come from a bot they own instead: their name, their avatar, their application in the Discord Developer Portal. That is what “bring your own bot” means in Ditto, and this post walks through the setup we built for it.
Status: the guided setup described here is in review and not yet available in the app. The pieces underneath it (bot tokens in Ditto Secrets, checked with Discord before Ditto saves them, and servers bound to your own bot alongside other bots) are merged behind switches that are off while they roll out. We will update this post when the setup ships.
Why a guided setup
Connecting a bot to anything means a trip through the Discord Developer Portal, and the portal has a page for everything: General Information, Installation, OAuth2, Bot, and more. The pages you need are spread across that list, two of them only exist once you have created an application, and one setting has to wait until the very end. Pasting a list of portal docs into a chat does not help much with that.
So Ditto now walks you through it one step at a time, inside the conversation. Only the step you are on is open. Each one names the exact portal page, says what to do there, and tells you how you will know it worked.
The four steps
Ask Ditto in chat (“help me connect my own Discord bot”) and the whole setup appears as a card in the conversation. You never leave the chat or open another page in Ditto: the card has a field for your Application ID, a masked field for the bot token, the invite link, Connect, and the endpoint URL to copy. The same steps are also under Connectors → Discord → Use my own bot if you prefer to start there.
| Step | Where | What Ditto checks |
|---|---|---|
| 1. Create a bot and paste its token | Developer Portal: New Application, then the application’s Bot page, Reset Token | Discord accepts the token and says it belongs to a bot, before Ditto saves anything |
| 2. Invite the bot to a server | The bot’s own invite link, generated by Ditto | The server shows up in the bot’s server list (Check again) |
| 3. Connect the server to Ditto | In Ditto, Connect next to the server | Your own bot is in that server, and no other Ditto account has already connected that same bot there |
4. Turn on /ditto | The application’s General Information page, Interactions Endpoint URL | Discord verifies the URL when you save it |
The invite link in step 2 already asks for the scopes and permissions Ditto needs, so you do not have to build one in the OAuth2 URL generator. Connecting your bot leaves every other bot in the server connected, the Ditto bot included. Step 3 also works for more than one server: once the first is connected, Ditto lists your bot’s other servers with a Connect button each, plus an invite link for more.
Where your token goes
The bot token is the one secret in this flow, and it has exactly one destination: Ditto Secrets.
You paste it into the Bot token field in the setup card. The field is masked, has autocomplete off, and sends what you type to one place: your encrypted Secrets, as a Discord bot credential. If you have not set up Secrets yet, the card asks you to choose a Secrets passphrase first, in the same card. Before Ditto stores anything, it asks Discord who the token belongs to. If Discord rejects it, or it belongs to a user account instead of a bot, Ditto saves nothing and the card tells you what to do next. When Discord accepts it, Ditto stores it encrypted in your Secrets with a fixed policy: it can only be used to call Discord, and only by the Discord bot itself.
What the setup never does:
- It never asks you to paste the token into a chat message. The card’s field is not the message box, and nothing typed into it becomes part of the conversation, the transcript, or what the agent sees.
- It never shows the token back to you, in the setup, in an error, or in the agent’s replies.
- It clears the field as soon as the save answers.
- The card itself only renders when Ditto’s server says the setup tool produced it, so another tool or a crafted message cannot draw a lookalike token field.
If you paste a token into a chat message by mistake, treat it as exposed: reset it on the Bot page and paste the new one into the card’s token field.
The agent carries its own instructions
The card comes from a tool. When you ask about connecting your own bot, Ditto’s agent calls it, and the result is both the card you see and a set of instructions the agent reads: follow the card, never ask for the Application ID or token in a message, never send you off to Settings, and match any error code to its fix.
The card’s first field is your application’s Application ID, which you can copy from the General Information page. It is public, so it is safe to share, and if you already mentioned it in chat the agent can pass it to the tool too. With it, every link points at your application instead of the portal’s front door:
| Link | Without an Application ID | With one |
|---|---|---|
| Bot page | Applications list, then pick your app | discord.com/developers/applications/<id>/bot |
| General Information | Applications list, then pick your app | discord.com/developers/applications/<id>/information |
| Invite | Shown once your token is saved | Your bot’s own invite link |
| Interactions Endpoint URL | Shown once your token is saved | The exact URL to paste |
The tool refuses anything that looks like a bot token, without repeating it, and tells the agent to send you to the card’s token field instead. It also tells the agent not to ask you to turn on privileged gateway intents: Ditto drives your bot through slash commands over HTTP, so it does not need them.
The order matters
Two of the steps can only happen in one order, and the setup is built around that.
The token comes first. The invite link, the list of servers and the binding all start by looking up your bot in Secrets, so there is nothing to show until you save it.
The Interactions Endpoint URL comes last. When you save that URL, Discord sends it a signed test request. Ditto checks the signature with your application’s public key, which it records when you connect your first server. Save the URL before connecting a server and Ditto has no key to check it against, so Discord reports that it could not verify the URL. The setup puts this step fourth for that reason, and its troubleshooting note says so.
When something goes wrong
Every failure in this flow has its own error code, and each one comes with a fix. None of them includes your token or Discord’s raw response.
| What you see | What to do |
|---|---|
| That doesn’t look like a Discord bot token | Copy it from the Bot page with Reset Token. Not the Application ID, Public Key or client secret. |
| Discord didn’t accept that bot token | It was probably reset since you copied it. Reset it again and paste the new one. |
| That token belongs to a user account | Use the token from the application’s Bot page. |
| Your bot isn’t in that server yet | Open the invite link, authorize the server, then choose Check again. |
| Already connected to a different Ditto account | Another account connected this same bot to that server. That account has to disconnect it first; other bots there are not affected. |
| Discord says it can’t verify the Interactions Endpoint URL | Connect a server in Ditto first, check that you copied the URL exactly, then save again. |
Each error also carries a reference, so if you send feedback the team can find the exact failure without ever seeing your token.
What did not change
The guided setup sits on top of the bring-your-own-bot security model. It does not relax any part of it:
- Proof of control. You can only connect a server your bot is already in, using a token that is in your own Secrets and that Discord accepts again at that moment.
- Independent bots. Each bot in a server is its own connection. Yours sits alongside the Ditto bot and anyone else’s, a bot already connected by another Ditto account stays theirs, and disconnecting one leaves the others in place.
- Your bot, your key. Slash commands for your bot are verified with your application’s own public key, so a request signed by any other application, the Ditto bot included, fails the check.
- No mass mentions. Messages Ditto sends through a bot never ping
@everyoneor@here. - Removing a server disconnects it from Ditto and leaves your bot in the server, since the bot is yours.
What’s next
The setup is in review now, and we will update this post when it ships. If you want to try your own bot in the meantime, or tell us what would make the setup clearer, sign up for Ditto and use Send feedback in the app.