import fs from 'node:fs'; import fetch from 'node-fetch'; const botBearerFile = process.env.BOT_BEARER_FILE; const userBearerFile = process.env.USER_BEARER_FILE; const instance = process.env.INSTANCE || 'shigusegubu.club'; const videoId = process.env.VIDEO_ID; // const botBearer = fs.readFileSync(botBearerFile, 'utf-8'); // const userBearer = fs.readFileSync(userBearerFile, 'utf-8'); const globalState = { exit: false, currentlyLive: false, }; const headers = (bearer) => ({ accept: 'application/json', authorization: `Bearer ${bearer.trim()}`, 'cache-control': 'no-cache', 'content-type': 'application/json', pragma: 'no-cache', }); /* const app = await fetch(`https://${instance}/api/v1/apps`, { headers: { accept: 'application/json', 'cache-control': 'no-cache', 'content-type': 'application/json', pragma: 'no-cache', }, body: JSON.stringify({ client_name: 'HJ Stream Bot', redirect_uris: 'urn:ietf:wg:oauth:2.0:oob', scopes: 'write:scrobbles', }), method: 'POST', mode: 'cors', }) /* */ // console.log('APP REG STATUS', app.status) //const { client_id, client_secret } = await app.json() //console.log({ client_id, client_secret }) /* */ const bearer = await fetch(`https://${instance}/oauth/token`, { headers: { accept: 'application/json', 'cache-control': 'no-cache', 'content-type': 'application/json', pragma: 'no-cache', }, body: JSON.stringify({ client_id, client_secret, grant_type: 'client_credentials', }), method: 'POST', mode: 'cors', }) console.log('TOKEN STATUS', bearer.status) console.log('TOKEN RESPONSE', await bearer.json()) /* */ const post = ({ status, spoiler_text, visibility = 'direct', content_type = 'text/plain', }) => fetch(`https://${instance}/api/v1/statuses`, { headers: headers(botBearer), referrerPolicy: 'same-origin', body: JSON.stringify({ spoiler_text, status, source: "HJ's twitch bot", visibility, content_type, }), method: 'POST', mode: 'cors', credentials: 'include', }); const scrobble = ({ title, external_link }) => fetch(`https://${instance}/api/v1/pleroma/scrobble`, { headers: headers(userBearer), referrerPolicy: 'same-origin', body: JSON.stringify({ title, external_link, }), method: 'POST', mode: 'cors', credentials: 'include', }); // await post({ // spoiler_text: 'Debug', // status: '@hj twitch bot initialized', // }); process.on('SIGINT', () => { globalState.exit = true; process.exit(); }); const loop = async () => { const response = await fetch( `https://tube.ebin.club/api/v1/videos/${videoId}`, ); const { state } = await response.json(); const isLive = state.id === 1; // published // console.info('Live: ', isLive, globalState.currentlyLive); const stateChange = isLive !== globalState.currentlyLive; // console.info('State change', stateChange); globalState.currentlyLive = isLive; // console.info('State: ', state); if (stateChange) { if (isLive) { console.info('Went live!'); // const postResult = await post({ // spoiler_text: 'Stream announcment', // status: [ // '@hj just went live on peertube', // '', // `https://tube.ebin.club/w/${videoId}`, // ].join('\n'), // visibility: 'public', // }); // console.info('post: ' + postResult.status); const scrobbleResult = await scrobble({ // artist: 'Peertube', title: 'Streaming on PeerTube', external_link: `https://tube.ebin.club/w/${videoId}`, }); console.info('scrobble: ' + scrobbleResult.status); } else { console.info('Went offline...'); await scrobble({ title: 'Stream over', }); } } if (!globalState.exit) setTimeout(loop, 30 * 1000); }; loop(); console.info('Ready!');