Tired of your AI Dungeon links having zero usable information? This link fixer will give your embeds the detail they deserve! Works for user profiles, scenarios, and adventures!
Running on play.axdungeon.com/beta.axdungeon.com/alpha.axdungeon.com (type s/i/x after posting a link) and play.aidungeon.link/
beta.aidungeon.link/alpha.aidungeon.link (replace the .com with .link)!
| Type | Default Implementation | Fixed Version |
|---|---|---|
/scenario/:id/:slug |
![]() |
![]() |
/adventure/:id/:slug |
![]() |
![]() |
/profile/:username |
![]() |
![]() |
As of v0.2.1, you can now override the default cover returned by AI Dungeon. You use an image hosted on Catbox
or Imgur, or remove the image entirely.
| Service | Example Link | URL Parameter | Instructions |
|---|---|---|---|
| Catbox | https://files.catbox.moe/ecb5xa.png |
?cover=catbox:ecb5xa.png |
1. Upload the image of your choosing. 2. Click on the URL below the progress bar to copy the link. 3. The part of the URL after the / is your ID. Add the URL parameter cover=catbox:[your ID], with an optional extension (assumes .jpg by default). |
| Imgur | https://imgur.com/G2oq1zB |
?cover=imgur:G2oq1zB |
1. Upload the image of your choosing. 2. Hover your mouse over the image and click the Copy link button.3. The part of the URL after the / is your ID. Add the URL parameter cover=imgur:[your ID], with an optional extension (assumes .jpg by default). |
| None | n/a | ?cover=none |
Add the URL parameter cover=none to remove the cover art from the embed. |
If the cover service is not valid, or the ID is empty, then the service will show the original cover art instead.
Note: AI Dungeon uses HIVE and other image content filters to moderate inappropriate content. This explicitly bypasses those filters. Be aware of the appropriateness of the images you use and where you post them!
This project builds a Docker image for every
release. These images are hosted on ghcr.io.
With Docker Compose or Portainer:
services:
aid-embed-fix:
image: ghcr.io/ndm13/aid-embed-fix
ports:
- 8000:8000
restart: unless-stoppedWith docker run:
docker run -p 8000:8000 --restart unless-stopped ghcr.io/ndm13/aid-embed-fixThe server requires the contents of the static and templates folders when compiled.
git clone https://github.com/ndm13/aid-embed-fix.git # or download files manually
cd aid-embed-fix
deno install
deno compile --allow-env --allow-read --allow-net server.ts
./serverThe server additionally requires the contents of the src folder when being run through Deno.
git clone https://github.com/ndm13/aid-embed-fix.git # or download files manually
cd aid-embed-fix
deno install
deno run --allow-env --allow-read --allow-net ./src/server.tsThe defaults provided should work for most deployments. The credentials will authenticate and pull data from the
play.aidungeon.com (production) server, but with minimal effort this can be configured to work with the beta server
as well (or hypothetically any other instance that allows anonymous access).
Properties are first checked from the command line, then from environment variables, and finally the default values.
These values are visible in config.ts.
| Name | Command Line Flag | Environment Variable | Description |
|---|---|---|---|
| Firebase Identity Toolkit key | --firebaseITK |
FIREBASE_ITK |
This is passed as the key= parameter for Firebase auth requests. |
| Firebase Client Version | --firebaseClientVersion |
FIREBASE_CLIENT_VERSION |
This is passed as the X-Client-Version header for Firebase auth requests. |
| Firebase Client Token | --firebaseClientToken |
FIREBASE_CLIENT_TOKEN |
This is passed as the X-Firebase-Client header for Firebase auth requests. |
| Origin/Referrer | --origin |
ORIGIN |
This is used as the origin for all Firebase requests, the referrer for all GraphQL requests, and the hostname for all redirects (unless overridden by a hostname prefix). |
| GraphQL Endpoint | --gqlEndpoint |
GQL_ENDPOINT |
This is the endpoint for all GraphQL queries. |
| User Agent | --userAgent |
USER_AGENT |
This is the user agent that will be used for all requests. Docker images will assign the correct version number on build. |
| OEmbed Protocol | --oembedProtocol |
OEMBED_PROTOCOL |
When running behind some reverse proxies, protocol detection can return an http link instead of https. This ensures that the links to oembed.json use the correct protocol. Change this to http if serving the app over http. |
| Listening Interface | --listen |
LISTEN |
The interface to use for incoming requests. |
| Enabled Metrics | --metrics |
METRICS |
Determines which metrics are in scope. none disables capture, api or router enable those respectively, and all enables everything. |
| Metrics Key | --metricsKey |
METRICS_KEY |
A secret URL parameter (?key=) that will be used to access the /metrics endpoint. If omitted, a random UUID will be used and output to the console on startup. To disable the key, pass an empty string. |
| Log Level | --logLevel |
LOG_LEVEL |
The logging level for the application. |
| Enable Analytics | --analytics |
ANALYTICS |
Determines whether analytics will be collected and sent to Supabase. |
| Supabase URL | --supabaseUrl |
SUPABASE_URL |
The URL of the Supabase instance for analytics ingest. |
| Supabase Key | --supabaseKey |
SUPABASE_KEY |
The API key for the Supabase instance for analytics ingest. |
| Ingest Secret | --ingestSecret |
INGEST_SECRET |
The secret used by the analytics ingest RPC function. |
Note that when changing environments, you will likely need different Firebase credentials (ITK and Token) as each instance authenticates as a separate app. Each environment also uses a separate GraphQL endpoint.
When the server launches, it will print the interface and port on which it's listening. Query /healthcheck to get
stats!
There are two core components to the project: the AI Dungeon API and an Oak middleware webserver. Everything else is scaffolding.
The AI Dungeon API was reverse engineered from authentication/GraphQL queries on play.aidungeon.com. These queries
have been stripped to retrieve a minimal amount of information - much less than a typical page load. Firebase sessions
are reduced by keeping an anonymous session active during high use times and letting it expire/creating a new one
during off-peak hours. The design is otherwise completely stateless: no persistent storage, easy scalability.
Requests are redirected to the origin site when possible. When a page is requested by a non-Discord user agent, a 301
redirect is issued (this behavior can be bypassed by adding no_ua as a query parameter, if testing another platform).
If the page is loaded by a browser, a JavaScript redirect will take place immediately, with history replacement. And
if for some reason all logic fails and the user sees the page we present to Discord, it still looks nice enough.
We pass share for profile, scenario, and adventure queries, and contentType for profile queries. All other query
parameters are discarded when forwarding the request.
My biggest blind spot is testing. Discord is a big community for AI Dungeon, but I'm sure there are other platforms
where links are shared with subpar embeds. Please go ahead and test them (with ?no_ua on the end) and let me know if
they work well or need additional properties. I'm open for pull requests too, if anyone wants to put in some work!




