Skip to main content
Annie Mei uses the Spotify Web API to add Spotify track links to opening and ending themes from MyAnimeList.

Authentication

The bot uses Spotify’s client credentials flow for server-to-server authentication. Set:
Create these credentials in the Spotify Developer Dashboard.
Implementation: src/utils/spotify.rs

Batch enrichment

The /songs command parses up to 10 opening and 10 ending themes, combines both sections for enrichment, and passes the complete batch to enrich_songs_with_spotify. For each song with an artist, the integration:
  1. Checks Redis for a cached positive or negative result.
  2. Authenticates only when an uncached song needs a Spotify request.
  3. Reuses the authenticated Spotify client and access token for the remaining uncached songs in the batch.
  4. Makes at most one later authentication retry after a transient token failure.
  5. Restores the enriched songs to their opening and ending sections.
This avoids requesting a new access token for every theme song.

Search strategy

Annie Mei searches for the track and artist together:
The request uses the United States market and asks for up to five results. Annie Mei links the first track result. For each uncached song:
  1. Search with the romaji title.
  2. If Spotify returns no track and a kana title is available, search with the kana title using the same authenticated client.
  3. Use the first matching track URL, or display the song without a link.
The blocking Spotify and Redis work runs inside tokio::task::spawn_blocking so it does not block Tokio’s async worker threads.

Redis caching

Spotify lookups share the bot’s Redis cache. The cache key remains compatible with earlier releases:
The integration stores:
  • the Spotify URL for a successful match
  • None when an authenticated search produces no usable URL
Cache entries expire after 18,000 seconds (5 hours). A failed token request does not create a negative cache entry, so a later song or command can retry authentication. The Redis client uses a reusable pool with at most eight connections. Pool waits, connection establishment, reads, and writes use a two-second bound. Connections that encounter I/O failures are discarded rather than returned to the pool.

Failure behavior

Spotify enrichment is optional. If Spotify cannot authenticate, times out, or returns no track, Annie Mei still displays the MyAnimeList song title, artist, and episode range when those fields are available.
A missing Spotify link does not mean the theme song lookup failed. It means Annie Mei did not obtain a usable Spotify match for that song.

Dependency

The integration uses rspotify with its blocking ureq client and Rustls: