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:
- 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.
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.
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
No comments yet.