Integrations

Integrations

This page covers the setup and integration of Spotify, Last.fm, Top Chart API, and Lavalink plugins with Meww.me.

Spotify

Spotify integration serves two purposes:

  1. Lavalink Source - Resolves Spotify URLs to playable audio via the LavaSrc plugin.
  2. Dashboard OAuth - Allows users to connect their Spotify account for playlist import and viewing.

Spotify API Credentials

  1. Go to the Spotify Developer Dashboard (opens in a new tab).
  2. Click Create App.
  3. Note the Client ID and Client Secret.
  4. Under Redirect URIs, add your dashboard callback URL.

Bot Configuration (config.yml)

lavalink:
  SPOTIFY:
    enable: true
    id: "your_spotify_client_id"
    secret: "your_spotify_client_secret"
    redirectUri: "https://your-domain.com/auth/spotify/callback"

These credentials are used by the bot for:

  • Refreshing Spotify access tokens (SpotifygetAccessToken.ts)
  • Dashboard Spotify OAuth flow (SpotifyOAuthService.ts)
  • Playlist import functionality

Lavalink Configuration (application.yml)

The Lavalink server also needs Spotify credentials for the LavaSrc plugin to resolve Spotify URLs to audio:

plugins:
  lavasrc:
    providers:
      - "ytsearch:\"%ISRC%\""
      - "ytsearch:%QUERY%"
    sources:
      spotify: true
    spotify:
      clientId: "your_spotify_client_id"
      clientSecret: "your_spotify_client_secret"
      countryCode: "US"

The bot's config.yml and Lavalink's application.yml use the same Spotify credentials but for different purposes:

  • Bot (config.yml) - metadata resolution, API calls, OAuth
  • Lavalink (application.yml) - audio source resolution via LavaSrc

Why Both Need Credentials

User pastes Spotify URL


Bot receives URL → Sends to Lavalink
        │                    │
        ▼                    ▼
Bot resolves metadata   Lavalink (LavaSrc) resolves
(title, artist, art)   Spotify → ISRC → YouTube audio
using Spotify API       using Spotify API

The bot needs Spotify API access for metadata, search, and playlist features. Lavalink needs it independently to convert Spotify tracks to playable audio from other sources (typically YouTube via ISRC matching).

Dashboard Spotify Features

When a user connects their Spotify account via the dashboard:

  • View their Spotify playlists
  • Import Spotify playlists into bot playlists
  • View top tracks and listening stats

The OAuth flow is handled by SpotifyOAuthService.ts in the dashboard backend.


Last.fm

Last.fm integration provides automatic scrobbling of tracks played through the bot.

Last.fm API Credentials

  1. Go to Last.fm API Account Creation (opens in a new tab).
  2. Create an application.
  3. Note the API Key and Shared Secret.
  4. Set the Callback URL to your WebServer's Last.fm endpoint.

Configuration (config.yml)

features:
  WebServer:
    enable: true
    Port: 2444
    BaseUrl: "https://ws.example.com"
    LAST_FM_SCROBBLED:
      Enable: true
      ApiKey: "your_lastfm_api_key"
      Secret: "your_lastfm_shared_secret"
      Callback: "https://ws.example.com/lastfm"
      scheduleScrobble: 60000
KeyTypeDescription
EnablebooleanEnable Last.fm scrobbling
ApiKeystringLast.fm API key
SecretstringLast.fm shared secret
CallbackstringPublic URL for the Last.fm OAuth callback. Must be accessible from the internet
scheduleScrobblenumberScrobble processing interval in milliseconds (default: 60000 = 1 minute)

How Scrobbling Works

User plays a track via the bot


trackStart event fires


ScrobbleToLastFM checks if user has a linked Last.fm account


If linked: queue the track for scrobbling


Scheduled scrobble job (every 60s) processes the queue


Sends scrobble to Last.fm API: track.scrobble

Linking a Last.fm Account

Users link their Last.fm account through one of two methods:

Discord Command

/lastfm connect

The bot sends a link to the Last.fm authorization page. After the user authorizes, they are redirected to the Callback URL, where the bot exchanges the token and stores the session key.

Dashboard

The guild settings page has a Last.fm section where users can connect and disconnect their account. This uses the same OAuth flow.

Account Data

When a user links their Last.fm account, the following is stored in the database:

FieldDescription
lastFmSessionKeyLast.fm session key for API calls
lastFmUsernameLast.fm username

Music Trivia Integration

The Last.fm API key is also used by the Music Trivia system for:

  • Fetching personalized recommendations via user.getRecommendedTracks
  • Fetching track/artist tags for genre classification via track.getTopTags and artist.getTopTags

If no Last.fm API key is configured, the trivia system silently falls back to the static song bank.


Lavalink Plugins

The Lavalink server uses several plugins for extended source support. These are configured in Lavalink's application.yml (reference file at additional-file/application.yml):

LavaSrc

Resolves tracks from Spotify, Apple Music, Deezer, Tidal, and Yandex Music.

plugins:
  lavasrc:
    sources:
      spotify: true
      applemusic: true
      deezer: true
      tidal: true
      yandexmusic: false
    spotify:
      clientId: "..."
      clientSecret: "..."
    applemusic:
      mediaAPIToken: "..."
    deezer:
      masterDecryptionKey: "..."
    tidal:
      countryCode: "US"

LavaSearch

Provides search functionality across multiple sources.

SponsorBlock

Skips sponsored segments in YouTube videos.

plugins:
  sponsorblock:
    categories:
      - "sponsor"
      - "selfpromo"
      - "interaction"
      - "intro"
      - "outro"
      - "preview"

YouTube Source

Required for YouTube playback. May require poToken configuration for reliable access.

plugins:
  youtube:
    enabled: true
    clients:
      - "MUSIC"
      - "WEB"
      - "ANDROID_TESTSUITE"

Top Chart API

The dashboard player features Top Tracks Today and Top Country Tracks sections. These are powered by the Meww.me Top Chart API (opens in a new tab), a JSON API service that scrapes daily Spotify chart data from Kworb.net and enriches it with Spotify metadata.

How It Works

The bot fetches chart data via SpotifyTopChartService.ts:

Dashboard Player
      |
      v
DashboardPlugin.ts → GET /api/top-chart?country=...
      |
      v
SpotifyTopChartService.ts
      |
      v
https://topchart-api.vercel.app/api/stats/tracks?country=...
      |
      v
Response: Top 50 tracks with rank, title, artist, cover art, Spotify URL

Results are cached in-memory for 1 hour per country. If a country-specific request fails, it falls back to the global chart.

Default API

By default, the bot uses the hosted instance at:

https://topchart-api.vercel.app/api/stats/tracks

This is configured in SpotifyTopChartService.ts:

const CHARTGURU_BASE = "https://topchart-api.vercel.app/api/stats/tracks";

Supported Countries

CodeCountryCodeCountry
globalGlobalkrSouth Korea
usUnited StatesinIndia
gbUnited KingdomauAustralia
idIndonesiaesSpain
jpJapanitItaly
deGermanycaCanada
frFranceseSweden
brBrazilphPhilippines
mxMexicotrTurkey
nlNetherlandsarArgentina

API Response Format

{
  "tracks": [
    {
      "trackId": "2plbrEY59IikOBgBGLjaoe",
      "name": "Die With A Smile",
      "mainArtistName": "Lady Gaga, Bruno Mars",
      "rank": 1,
      "previousRank": 1,
      "rankDelta": 0,
      "dailyStreams": 8500000,
      "totalStreams": 3200000000,
      "imageUrl": "https://i.scdn.co/image/...",
      "spotifyUrl": "https://open.spotify.com/track/..."
    }
  ]
}

API Endpoints

MethodEndpointDescription
GET/api/stats/tracksTop daily tracks with streams, rank, Spotify metadata
GET/api/stats/tracks/historyTrack stream/rank history
GET/api/stats/countriesList of supported countries
GET/api/stats/last-updatedTimestamp of last data refresh

Query parameters for /api/stats/tracks:

ParamDefaultDescription
countryglobalCountry code (e.g., id, us, gb)
limit25Number of results

Self-Hosting the Top Chart API

You can deploy your own instance of the Top Chart API from github.com/lrmn7/mewwme-top-chart (opens in a new tab).

Prerequisites

Quick Setup

# Clone the repository
git clone https://github.com/lrmn7/mewwme-top-chart.git
cd mewwme-top-chart
 
# Install dependencies
npm install
 
# Copy environment variables
cp .env.example .env

Edit .env:

SPOTIFY_CLIENT_ID=your_spotify_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
DATABASE_URL="mysql://user:password@host:3306/database"
ADMIN_SECRET=your_secret_here
SCRAPE_COUNTRIES=global,id,us,gb,jp,kr,de,fr,br,mx,in,au,es,it,ca,se,ph,tr,ar,nl
TOP_TRACKS_LIMIT=25
PORT=3301

Database setup:

npx prisma generate
npx prisma db push

Three database schema variants are provided:

  • prisma/schema.prisma - MySQL (default)
  • prisma/schema.postgresql.prisma - PostgreSQL
  • prisma/schema.sqlite.prisma - SQLite (local dev)

To switch database, copy the desired schema to schema.prisma and update DATABASE_URL.

Run the server:

# Development
npm run dev
 
# Production
npm run build
npm start

Deployment Architecture

The recommended deployment uses a hybrid architecture:

GitHub Actions (cron: 06:00 & 18:00 UTC)
  1. Scrape Kworb.net
  2. Enrich via Spotify API
  3. Write to MySQL
          |
          v
     MySQL Database
          |
          v
    Vercel (API server)
      /api/stats/tracks
      /api/stats/countries
          |
          v
    Discord Bot / Client
  • GitHub Actions handles data scraping on a cron schedule (no time limits)
  • Vercel serves the JSON API (fast, serverless)
  • MySQL database stores all track data (shared between both)

Alternatively, you can use any Node.js hosting (Hostinger, VPS, etc.) with the included server.js.

Connecting to Your Self-Hosted Instance

After deploying, update SpotifyTopChartService.ts in the bot backend to point to your own URL:

const CHARTGURU_BASE = "https://your-domain.com/api/stats/tracks";

Rebuild the bot and restart.