diff --git a/assets/public/widget.html b/assets/public/widget.html
new file mode 100644
index 000000000..a03f4b368
--- /dev/null
+++ b/assets/public/widget.html
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+ Spacebar Widget
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/api/Server.ts b/src/api/Server.ts
index f81898e81..9cc1820f3 100644
--- a/src/api/Server.ts
+++ b/src/api/Server.ts
@@ -115,8 +115,8 @@ export class SpacebarServer extends Server {
app.use("/imageproxy/:hash/:size/:url", ImageProxy);
app.get("/", (req, res) => res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "index.html")));
-
app.get("/verify-email", (req, res) => res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "verify.html")));
+ app.get("/widget", (req, res) => res.sendFile(path.join(PUBLIC_ASSETS_FOLDER, "widget.html")));
app.get("/_spacebar/api/schemas.json", (req, res) => {
res.sendFile(path.join(ASSETS_FOLDER, "schemas.json"));
diff --git a/src/api/routes/guilds/#guild_id/widget.json.ts b/src/api/routes/guilds/#guild_id/widget.json.ts
index 8f41417a8..dea8f29f1 100644
--- a/src/api/routes/guilds/#guild_id/widget.json.ts
+++ b/src/api/routes/guilds/#guild_id/widget.json.ts
@@ -17,7 +17,7 @@
*/
import { randomString, route } from "@spacebar/api";
-import { Channel, DiscordApiErrors, Guild, Invite, Member, Permissions } from "@spacebar/util";
+import { Channel, Config, DiscordApiErrors, Guild, Invite, Member, Permissions } from "@spacebar/util";
import { Request, Response, Router } from "express";
const router: Router = Router({ mergeParams: true });
@@ -99,7 +99,17 @@ router.get(
// Fetch members
// TODO: Understand how Discord's max 100 random member sample works, and apply to here (see top of this file)
- const members = await Member.find({ where: { guild_id: guild_id } });
+ const members = await Member.find({ where: { guild_id: guild_id }, relations: { user: { sessions: true } } });
+ const memberData = members.map((x) => {
+ return {
+ id: x.id,
+ username: x.user.username,
+ discriminator: x.user.discriminator,
+ avatar: x.user.avatar,
+ status: "online", // TODO
+ avatar_url: x.user.avatar ? `${Config.get().cdn.endpointPublic}/avatars/${x.id}/${x.user.avatar}.png` : undefined,
+ };
+ });
// Construct object to respond with
const data = {
@@ -107,8 +117,8 @@ router.get(
name: guild.name,
instant_invite: invite?.code,
channels: channels,
- members: members,
- presence_count: guild.presence_count,
+ members: memberData,
+ presence_count: guild.presence_count || members.filter((m) => m.user.sessions.filter((s) => (s.last_seen?.getTime() ?? 0) > Date.now() - 1000 * 60)).length,
};
res.set("Cache-Control", "public, max-age=300");