Back to Home

Telegram bot for music UPC codes: 10 platforms

Telegram bot extracts UPC and ISRC codes of releases from 10 platforms via link parsing and API. Describes architecture with regex, Redis cache, retry logic for Spotify. Lessons on working with fragmented APIs and undocumented endpoints.

Bot for UPC/ISRC: parsing 10 music APIs
Advertisement 728x90

Building a Telegram Bot to Extract UPC and ISRC Codes from Music Platforms

This Telegram bot extracts UPC and ISRC codes from music releases across 10 major platforms. It supports Spotify, Apple Music, Yandex Music, YouTube Music, Deezer, Tidal, SoundCloud, VK Music, Zvuk, and Amazon Music. The need arose due to the lack of straightforward access to UPC codes through distributors or platform interfaces. The bot processes links, release IDs, and text queries, returning accurate codes in just 1–2 seconds thanks to intelligent caching.

UPC identifies releases (albums, singles), while ISRC uniquely tags individual tracks. These identifiers are essential for distributor migration, rights registration, and royalty tracking.

System Architecture

The system is modular:

Google AdInline article slot
  • URL Parser: Identifies the platform using regular expressions.
  • Platform Resolver: Fetches metadata via official or reverse-engineered APIs.
  • UPC/ISRC Matcher: Cross-validates data from multiple sources.
  • Storage: Redis for caching (TTL: 24 hours), PostgreSQL for analytics.

This design enables scalable processing and reduces external API load.

import re
from dataclasses import dataclass
from enum import Enum

class Platform(Enum):
    SPOTIFY = "spotify"
    APPLE_MUSIC = "apple_music"
    YANDEX_MUSIC = "yandex_music"
    YOUTUBE_MUSIC = "youtube_music"
    DEEZER = "deezer"
    TIDAL = "tidal"
    SOUNDCLOUD = "soundcloud"
    VK_MUSIC = "vk_music"
    ZVUK = "zvuk"
    AMAZON_MUSIC = "amazon_music"

@dataclass
class ParsedLink:
    platform: Platform
    content_type: str  # "album", "track", "artist"
    content_id: str

PATTERNS = [
    # Spotify
    (r"open\.spotify\.com/(album|track)/([a-zA-Z0-9]+)",
     Platform.SPOTIFY),
    # Apple Music
    (r"music\.apple\.com/.+/(album|song)/.+?/(")",
     Platform.APPLE_MUSIC),
    # and others...
]

Handling Links and Short URLs

The parser uses over 10 regex patterns to match URL formats. Shortened links (e.g., spotify.link, youtu.be) are resolved via HEAD requests with automatic redirect following:

async def resolve_short_url(url: str) -> str:
    async with aiohttp.ClientSession() as session:
        async with session.head(
            url, allow_redirects=True, timeout=5
        ) as resp:
            return str(resp.url)

Supported content types include albums, tracks, and artists. For tracks, the bot automatically locates the parent release.

Google AdInline article slot

Working with Spotify’s API

Spotify Web API returns UPC in external_ids.upc for albums and ISRC in track data. Challenges include:

  • Missing UPC in responses — retrying across markets (US, GB, DE, JP).
  • Unstable UPC search for region-specific releases.
  • Rate limit: 180 requests per minute.

Redis caching significantly reduces API strain:

async def get_album_data(album_id: str) -> dict | None:
    cache_key = f"album:{album_id}"
    cached = await redis.get(cache_key)
    if cached:
        return json.loads(cached)
    
    for market in ["US", "GB", "DE", "JP"]:
        album = await spotify.get_album(album_id, market=market)
        upc = album.get("external_ids", {}).get("upc")
        if upc:
            # Save to cache
            await redis.set(cache_key, json.dumps(result), ex=86400)
            return result
    return None

Undocumented APIs: Yandex Music and VK

With no public APIs available, endpoints were reverse-engineered from mobile app traffic. UPC is found in album metadata; ISRC in track-level data. Response formats change unexpectedly (twice in three months), requiring constant monitoring.

Google AdInline article slot

Version Detection for Releases

The bot finds all UPCs linked to a single ISRC — including singles, albums, and compilations. This is crucial for preserving streaming history when switching distributors.

The /full command returns:

  • All UPC versions of the release.
  • ISRCs of every track.
  • Label, release date, genre.
  • Track BPM (via Spotify Audio Features).

User Input Processing

Supports multiple input types:

  • Direct links (parsed automatically).
  • 12–13 digit numbers (UPC lookup).
  • Text queries (search by name + inline buttons).

Examples: "upc Morozhern", direct URLs, unstructured phrases.

Lessons Learned & Improvements

Performance stats (3 months):

  • 500 users/month.
  • Average response time: 1.5 seconds (0.3 seconds with cache).
  • Success rate: 89%.

Recommendations:

  • Integrate MusicBrainz for data verification.
  • Implement a message queue for peak loads.
  • Add health checks for API availability.

Architectural insights:

  • Always use at least two data sources.
  • Apply aggressive caching.
  • Undocumented APIs create technical debt.

Key Takeaways:

  • Separating parsing from platform resolution simplifies maintenance.
  • Market-based retries fix incomplete Spotify responses.
  • Redis caching is mandatory under rate limits.
  • Multi-UPC per ISRC is vital for artists.
  • Monitoring undocumented APIs must be daily.

— Editorial Team

Advertisement 728x90

Read Next