import fetch from 'node-fetch'; import { TelegramClient, Api as TgApi } from 'telegram'; import { StringSession } from 'telegram/sessions/index.js'; import 'dotenv/config'; import prompt from 'prompt'; import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const mdBaseUrl = process.env.MD_BASE_URL; const apiId = parseInt(process.env.API_ID); const apiHash = process.env.API_HASH; const songPrefix = process.env.SONG_PREFIX || ""; const sessionFile = path.join(__dirname, 'tg_session', 'session'); let sessionStore = new StringSession(""); try { const readSession = await fs.readFile(sessionFile, "utf8"); if (readSession) { sessionStore = new StringSession(readSession); } } catch (e) { console.error(e); } async function getCurrentSong() { return fetch(mdBaseUrl + '/api/status').then((data) => { return data.json(); }).then(data => { const players = []; // get all players of all sources data.sources.forEach(source => { if (!source.players) return; const sourcePlayers = Object.values(source.players); sourcePlayers.forEach(player => { players.push(player); }); }); // sort players in order of most recent new song const sortedPlayers = players.sort((a, b) => new Date(a.playFirstSeenAt).getTime() - new Date(b.playFirstSeenAt).getTime()); // default string let nowPlaying = "Nothing Playing"; // if a player exists, get it's song if (sortedPlayers.length !== 0) { const playData = sortedPlayers[0]?.play?.data; if (!playData) return ""; nowPlaying = `${playData.artists.join(', ')} - ${playData.track}`; } return nowPlaying; }); } async function initTelegram() { // check if we have what we need for telegram if (!apiId) { console.error("missing env var API_ID"); return; }; if (!apiHash) { console.error("missing env var API_HASH"); return; }; // setup client const client = new TelegramClient(sessionStore, apiId, apiHash, { connectionRetries: 5 }); prompt.start(); // start it, prompt for auth if needed await client.start({ phoneNumber: async () => { const res = await prompt.get({ description: 'phone number', type: 'string', required: true, hidden: false }); return res.question; }, password: async () => { const res = await prompt.get({ description: 'password', type: 'string', required: true, hidden: true }); return res.question; }, phoneCode: async () => { const res = await prompt.get({ description: 'phone code', type: 'string', required: true, hidden: false }); return res.question; }, onError: (err) => console.error(err) }); // save the session so we don't have to log in every time client.session.save(); await fs.writeFile(sessionFile, sessionStore.save()); return client; } // store client here const tg = await initTelegram(); // do we actually have a client? if (!!tg) { let song = ""; setInterval(async () => { const newSong = await getCurrentSong(); if (newSong === song) return; // don't do API calls if the song is the same as it was song = newSong; console.log(`new song: ${song}`); // update bio with new song tg.invoke(new TgApi.account.UpdateProfile({ about: songPrefix + song })); }, 5000); }