// app.js import express from "express"; import crypto from "crypto"; import { RtcRole, RtcTokenBuilder } from "agora-access-token"; const app = express(); app.use(express.json()); const AGORA_APP_ID = process.env.AGORA_APP_ID; const AGORA_APP_CERTIFICATE = process.env.AGORA_APP_CERTIFICATE; // Root route app.get("/", (req, res) => { res.send("✅ Agora Token API is running on Hugging Face!"); }); // Token generation route app.post("/generate-token", (req, res) => { try { const { channelName, firebaseUid, role } = req.body; if (!channelName || !firebaseUid) { return res.status(400).json({ error: "channelName and firebaseUid are required.", }); } const agoraRole = role === "subscriber" ? RtcRole.SUBSCRIBER : RtcRole.PUBLISHER; // Convert Firebase UID → deterministic Agora UID const agoraUid = parseInt( crypto.createHash("md5").update(firebaseUid).digest("hex").slice(0, 6), 16 ); // Token expiry (1 hour) const expireTime = 3600; const now = Math.floor(Date.now() / 1000); const privilegeExpiredTs = now + expireTime; // Build token const token = RtcTokenBuilder.buildTokenWithUid( AGORA_APP_ID, AGORA_APP_CERTIFICATE, channelName, agoraUid, agoraRole, privilegeExpiredTs ); return res.status(200).json({ token, appId: AGORA_APP_ID, agoraUid, expireTime, }); } catch (err) { console.error("Error generating token:", err); return res.status(500).json({ error: err.message }); } }); app.listen(7860, "0.0.0.0", () => console.log("🚀 Server started on port 7860"));