Skip to content

ndm13/aid-embed-fix

Repository files navigation

Better AI Dungeon Embeds

Release status Check for Deno Updates CodeQL Automated Testing
axdungeon.com status aidungeon.link status Discord

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

A demo video showing posting a scenario link, typing s/i/x, then the link changing to the better embed version

Examples

Type Default Implementation Fixed Version
/scenario/:id/:slug A screenshot of a Discord embed: title text 'AI Dungeon'; description 'AI Dungeon, an infinitely generated text adventure...'; a small image to the right side showing a screenshot of the homepage A screenshot of a Discord embed: site name 'AI Dungeon Scenario'; author name 'aidungeon'; title text 'Original Quickstart'; description 'The set of classic prompts featuring various characters in Larion, zombie curing scientists and more!'; a large image of an isometric dungeon underneath
/adventure/:id/:slug A screenshot of a Discord embed: title text 'AI Dungeon'; description 'AI Dungeon, an infinitely generated text adventure...'; a small image to the right side showing a screenshot of the homepage A screenshot of a Discord embed: site name 'AI Dungeon Adventure'; author name 'uxbnkuribo'; title text 'An Unforgettable Luncheon with a guest appearance by Chief Wiggum'; description 'Seymour Skinner has Superintendent Chalmers over for an unforgettable luncheon. Only one problem- Chief Wiggum and the Springfield police force show up almost immediately! Will Chief Wiggum's presence hinder Skinner's ability to steam a good ham?'; a large image of Skinner and Chalmers sitting at a table with the Aurora Borealis in the background underneath
/profile/:username A screenshot of a Discord embed: title text 'AI Dungeon'; description 'AI Dungeon, an infinitely generated text adventure...'; a small image to the right side showing a screenshot of the homepage A screenshot of a Discord embed: site name 'AI Dungeon Profile': title text 'aidungeon'; description 'Official AI Dungeon account.'; a small image to the right side showing the AI Dungeon logo profile icon'

Custom Covers

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!

Releases

This project builds a Docker image for every release. These images are hosted on ghcr.io.

Deployment

Docker (preferred)

With Docker Compose or Portainer:

services:
  aid-embed-fix:
    image: ghcr.io/ndm13/aid-embed-fix
    ports:
      - 8000:8000
    restart: unless-stopped

With docker run:

docker run -p 8000:8000 --restart unless-stopped ghcr.io/ndm13/aid-embed-fix

Compile and run locally

The 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
./server

Run the server.ts file directly

The 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.ts

Configuration

The 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!

Technical Details

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.

Query Parameters

We pass share for profile, scenario, and adventure queries, and contentType for profile queries. All other query parameters are discarded when forwarding the request.

For Contributors

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!

About

Better embeds for AI Dungeon links

Resources

License

Stars

Watchers

Forks

Packages