A decentralized music tracking and discovery platform built on AT Protocol 馃幍 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
at feat/discord-embed 69 lines 1.8 kB view raw
1import chalk from "chalk"; 2import { RockskyClient } from "client"; 3import fs from "fs/promises"; 4import md5 from "md5"; 5import os from "os"; 6import path from "path"; 7 8export async function scrobble(track, artist, { timestamp }) { 9 const tokenPath = path.join(os.homedir(), ".rocksky", "token.json"); 10 try { 11 await fs.access(tokenPath); 12 } catch (err) { 13 console.error( 14 `You are not logged in. Please run ${chalk.greenBright( 15 "`rocksky login <username>.bsky.social`" 16 )} first.` 17 ); 18 return; 19 } 20 21 const tokenData = await fs.readFile(tokenPath, "utf-8"); 22 const { token } = JSON.parse(tokenData); 23 if (!token) { 24 console.error( 25 `You are not logged in. Please run ${chalk.greenBright( 26 "`rocksky login <username>.bsky.social`" 27 )} first.` 28 ); 29 return; 30 } 31 32 const client = new RockskyClient(token); 33 const apikeys = await client.getApiKeys(); 34 35 if (!apikeys || apikeys.length === 0 || !apikeys[0].enabled) { 36 console.error( 37 `You don't have any API keys. Please create one using ${chalk.greenBright( 38 "`rocksky create apikey`" 39 )} command.` 40 ); 41 return; 42 } 43 44 const signature = md5( 45 `api_key${ 46 apikeys[0].apiKey 47 }artist[0]${artist}methodtrack.scrobblesk${token}timestamp[0]${ 48 timestamp || Math.floor(Date.now() / 1000) 49 }track[0]${track}${apikeys[0].sharedSecret}` 50 ); 51 52 const response = await client.scrobble( 53 apikeys[0].apiKey, 54 signature, 55 track, 56 artist, 57 timestamp 58 ); 59 60 console.log( 61 `Scrobbled ${chalk.greenBright(track)} by ${chalk.greenBright( 62 artist 63 )} at ${chalk.greenBright( 64 new Date( 65 (timestamp || Math.floor(Date.now() / 1000)) * 1000 66 ).toLocaleString() 67 )}` 68 ); 69}