import { ACCESS_TOKEN, SERVER_URL, SOURCE_ROOM_ID, TARGET_ROOM_ID } from "./conf.js"; import {readFileSync, writeFileSync} from "fs"; async function fetchMatrix(url, options = {}) { options.headers ||= {}; options.headers.Authorization ||= `Bearer ${ACCESS_TOKEN}`; url = SERVER_URL + url; while (true) { console.debug("fetch", url); try { var res = await fetch(url, options); if (res.status == 429) { var {retry_after_ms} = await res.json(); } else break; } catch (error) { console.error(error); } await new Promise(r => setTimeout(r, retry_after_ms || 60000)); } if (!res.ok) throw new Error(`HTTP ${res.status} ${await res.text()}`); return res; } async function getMatrixEvents(room_id, until_event_id) { var events = []; do { var url = `/_matrix/client/v3/rooms/${encodeURIComponent(room_id)}/messages?dir=b&limit=50`;//use 1000 for initial fill if (end) url += `&from=${end}`; var {chunk, end} = await fetchMatrix(url).then(res => res.json()); console.log(`got ${chunk.length}`); for (let event of chunk) { if (until_event_id && event.event_id == until_event_id) return events; events.push(event); } } while (end) return events; } async function getNewMatrixEvents(room_id) { var fn = `last_event_id_${room_id.replace(/[^\w]/g,'')}`; try { var last_event_id = readFileSync(fn, "utf8"); } catch (error) { console.log(error.message); } var events = await getMatrixEvents(room_id, last_event_id); for (let event of events) { event.hasBeenProcessed = () => writeFileSync(fn, event.event_id); } return events; } var events = await getNewMatrixEvents(SOURCE_ROOM_ID); for (let event of events.reverse()) { if (typeof event.content == "object" && ["m.video","m.audio","m.file"].includes(event.content.msgtype)) { let event_url = `https://matrix.to/#/${encodeURIComponent(event.room_id)}/${encodeURIComponent(event.event_id)}`; await fetchMatrix(`/_matrix/client/v3/rooms/${encodeURIComponent(TARGET_ROOM_ID)}/send/m.room.message/${Math.random()}`, { method: "PUT", headers: {"Content-Type": "application/json"}, body: JSON.stringify({ msgtype: event.content.msgtype, filename: event.content.filename || event.content.body, body: event_url, info: event.content.info, url: event.content.url }) }); } event.hasBeenProcessed(); }