presence: cv2ify

This commit is contained in:
Cynthia Foxwell 2025-05-01 21:35:19 -06:00
parent f0d23e2367
commit 5a235ad023
Signed by: Cynosphere
SSH key fingerprint: SHA256:H3SM8ufP/uxqLwKSH7xY89TDnbR9uOHzjLoBr0tlajk

View file

@ -2,13 +2,19 @@ const Command = require("#lib/command.js");
const sharp = require("sharp"); const sharp = require("sharp");
const {ActivityTypeNames, CDNEndpoints, Games, HangStatusStrings, HANG_STATUS_ICONS} = require("#util/dconstants.js"); const {
ActivityTypeNames,
CDNEndpoints,
Games,
/*HangStatusStrings,
HANG_STATUS_ICONS*/
} = require("#util/dconstants.js");
const {Icons} = require("#util/constants.js"); const {Icons} = require("#util/constants.js");
const {formatUsername} = require("#util/misc.js"); const {formatUsername, getTopColor} = require("#util/misc.js");
const {lookupUser} = require("#util/selection.js"); const {lookupUser} = require("#util/selection.js");
const {formatTime} = require("#util/time.js"); const {formatTime} = require("#util/time.js");
const HangStatusImages = {}; /*const HangStatusImages = {};
(async () => { (async () => {
for (const key of Object.keys(HANG_STATUS_ICONS)) { for (const key of Object.keys(HANG_STATUS_ICONS)) {
const svg = await fetch(HANG_STATUS_ICONS[key]) const svg = await fetch(HANG_STATUS_ICONS[key])
@ -16,7 +22,7 @@ const HangStatusImages = {};
.then((b) => Buffer.from(b)); .then((b) => Buffer.from(b));
HangStatusImages[key] = await sharp(svg, {density: 2400}).resize(128).toBuffer(); HangStatusImages[key] = await sharp(svg, {density: 2400}).resize(128).toBuffer();
} }
})(); })();*/
const NOWPLAYING_BAR_LENGTH = 32; const NOWPLAYING_BAR_LENGTH = 32;
const NOWPLAYING_BAR_CHAR = "\u2014"; const NOWPLAYING_BAR_CHAR = "\u2014";
@ -85,33 +91,64 @@ presence.callback = async function (msg, line) {
icons.push(Icons.presence[platform][status]); icons.push(Icons.presence[platform][status]);
} }
const embeds = []; const components = [];
const files = []; const files = [];
for (const index in target.activities) { for (const index in target.activities) {
const activity = target.activities[index]; const activity = target.activities[index];
if (activity.type == 4) { if (activity.type == 4) {
const embed = {}; let label;
if (activity.details) {
switch (activity.details) {
case "listen":
label = "\ud83c\udfb5 On repeat";
break;
case "watch":
label = "\ud83d\udcfa Watching lately";
break;
case "play":
label = "\ud83c\udfae Playing lately";
break;
case "think":
label = "\ud83d\udca1 Shower thought";
break;
case "love":
label = "\u2764\ufe0f Loving lately";
break;
}
}
let status = "";
if (label) status = `-# ${label}\n`;
let url;
if (activity.emoji) { if (activity.emoji) {
if (activity.emoji.id) { if (activity.emoji.id) {
const url = CDNEndpoints.EMOJI(activity.emoji.id, activity.emoji.animated); url = CDNEndpoints.EMOJI(activity.emoji.id, activity.emoji.animated);
embed.author = { } else {
url, url = `https://jdecked.github.io/twemoji/v/latest/72x72/${[...activity.emoji.name]
icon_url: url, .map((char) => char.codePointAt().toString(16))
name: activity.state ?? "\u200b", .join("-")}.png`;
}
}
status += activity.state ?? "\u200b";
status += `\n\n-# <t:${Math.floor(activity.created_at / 1000)}:f>`;
const content = {
type: 10,
content: status,
}; };
} else {
embed.title = `${activity.emoji.name} ${activity.state ?? ""}`;
}
} else {
embed.title = activity.state ?? "";
}
embed.timestamp = new Date(activity.created_at).toISOString(); if (url) {
components.push({
embeds.push(embed); type: 9,
} else if (activity.type == 6) { components: [content],
accessory: {type: 11, media: {url}},
});
} else {
components.push(content);
}
/*} else if (activity.type == 6) {
const embed = {}; const embed = {};
embed.title = "Hang Status"; embed.title = "Hang Status";
@ -135,12 +172,11 @@ presence.callback = async function (msg, line) {
embed.timestamp = new Date(activity.created_at).toISOString(); embed.timestamp = new Date(activity.created_at).toISOString();
embeds.push(embed); embeds.push(embed);*/
} else { } else {
const embed = { const comp = [];
title: `${ActivityTypeNames[activity.type]} **${activity.name}**`, comp.push({type: 10, content: `${ActivityTypeNames[activity.type]} **${activity.name}**`});
fields: [],
};
const descLines = []; const descLines = [];
if (activity.type == 2) { if (activity.type == 2) {
if (activity.details) { if (activity.details) {
@ -207,32 +243,25 @@ presence.callback = async function (msg, line) {
} }
if (activity.assets?.large_text && activity.type != 2) { if (activity.assets?.large_text && activity.type != 2) {
embed.fields.push({ descLines.push("### Large Text", activity.assets.large_text);
name: "Large Text",
value: activity.assets.large_text,
});
} }
if (activity.assets?.small_text) { if (activity.assets?.small_text) {
embed.fields.push({ descLines.push("### Small Text", activity.assets.small_text);
name: "Small Text",
value: activity.assets.small_text,
});
} }
if (activity.application_id) { descLines.push(
embed.fields.push({ `\n-# ${activity.application_id ? activity.application_id + " \u2022 " : ""}<t:${Math.floor(
name: "Application ID", activity.created_at / 1000
value: `\`${activity.application_id}\``, )}:f>`
}); );
}
embed.description = descLines.join("\n"); const content = {type: 10, content: descLines.join("\n")};
let thumbnail;
const image_links = [];
if (activity.assets) { if (activity.assets) {
if (activity.assets.large_image != null) { if (activity.assets.large_image != null) {
const image_links = [];
let largeUrl; let largeUrl;
if (activity.assets.large_image.startsWith("mp:")) { if (activity.assets.large_image.startsWith("mp:")) {
largeUrl = activity.assets.large_image.replace("mp:", "https://media.discordapp.net/"); largeUrl = activity.assets.large_image.replace("mp:", "https://media.discordapp.net/");
@ -242,7 +271,7 @@ presence.callback = async function (msg, line) {
largeUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.large_image); largeUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.large_image);
} }
image_links.push(`[Large Image](${fixMediaProxyURL(largeUrl)})`); image_links.push({label: "Large Image", url: fixMediaProxyURL(largeUrl)});
let smallUrl; let smallUrl;
if (activity.assets.small_image != null) { if (activity.assets.small_image != null) {
@ -254,18 +283,18 @@ presence.callback = async function (msg, line) {
smallUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.small_image); smallUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.small_image);
} }
image_links.push(`[Small Image](${fixMediaProxyURL(smallUrl)})`); image_links.push({label: "Small Image", url: fixMediaProxyURL(smallUrl)});
} }
const largeImage = await fetch(largeUrl) const largeImage = await fetch(largeUrl)
.then((res) => res.arrayBuffer()) .then((res) => res.arrayBuffer())
.then((b) => Buffer.from(b)); .then((b) => Buffer.from(b));
const presenceImage = sharp(largeImage).resize(60, 60); const presenceImage = sharp(largeImage).resize(100, 100);
if (smallUrl) { if (smallUrl) {
const smallImage = await fetch(smallUrl) const smallImage = await fetch(smallUrl)
.then((res) => res.arrayBuffer()) .then((res) => res.arrayBuffer())
.then((b) => Buffer.from(b)); .then((b) => Buffer.from(b));
const smallImageBuffer = await sharp(smallImage).resize(20, 20).toBuffer(); const smallImageBuffer = await sharp(smallImage).resize(32, 32).toBuffer();
presenceImage.composite([ presenceImage.composite([
{ {
@ -279,13 +308,7 @@ presence.callback = async function (msg, line) {
contents: await presenceImage.toBuffer(), contents: await presenceImage.toBuffer(),
name: `${index}.png`, name: `${index}.png`,
}); });
embed.thumbnail = { thumbnail = `attachment://${index}.png`;
url: `attachment://${index}.png`,
};
embed.fields.push({
name: "\u200b",
value: image_links.join("\u3000\u3000"),
});
} else if (!activity.assets.large_image && activity.assets.small_image != null) { } else if (!activity.assets.large_image && activity.assets.small_image != null) {
let smallUrl; let smallUrl;
if (activity.assets.small_image.startsWith("mp:")) { if (activity.assets.small_image.startsWith("mp:")) {
@ -296,48 +319,64 @@ presence.callback = async function (msg, line) {
smallUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.small_image); smallUrl = CDNEndpoints.APP_ASSET(activity.application_id, activity.assets.small_image);
} }
const smallImage = await fetch(smallUrl) thumbnail = fixMediaProxyURL(smallUrl);
.then((res) => res.arrayBuffer()) image_links.push({label: "Small Image", url: thumbnail});
.then((b) => Buffer.from(b));
const presenceImage = await sharp(smallImage).resize(40, 40).toBuffer();
files.push({
contents: presenceImage,
name: `${index}.png`,
});
embed.thumbnail = {
url: `attachment://${index}.png`,
};
embed.fields.push({
name: "\u200b",
value: `[Small Image](${fixMediaProxyURL(smallUrl)})`,
});
} }
} }
if (activity.application_id && !activity.assets?.large_image && !activity.assets?.small_image) { if (activity.application_id && !activity.assets?.large_image && !activity.assets?.small_image) {
const game = Games.find((game) => game.id == activity.application_id); const game = Games.find((game) => game.id == activity.application_id);
if (game?.icon) { if (game?.icon) {
embed.thumbnail = { thumbnail = `${CDNEndpoints.APP_ICON(game.id, game.icon)}?keep_aspect_ratio=false`;
url: `${CDNEndpoints.APP_ICON(game.id, game.icon)}?size=40&keep_aspect_ratio=false`, image_links.push({label: "App Icon", url: thumbnail});
}; }
embed.fields.push({ }
name: "\u200b",
value: `[App Icon](${embed.thumbnail.url.replace("size=40&", "")})`, if (thumbnail != null) {
comp.push({
type: 9,
components: [content],
accessory: {type: 11, media: {url: thumbnail}},
}); });
} else {
comp.push(content);
}
if (image_links.length > 0) {
for (const link of image_links) {
link.type = 2;
link.style = 5;
}
comp.push({type: 1, components: image_links});
}
components.push(comp);
} }
} }
embed.timestamp = new Date(activity.created_at).toISOString(); const finalComponents = [{type: 10, content: `Presence for **${formatUsername(target)}**: ${icons.join(" ")}`}];
if (components.length > 0) {
const card = {type: 17, components: [], accent_color: getTopColor(msg, target)};
embeds.push(embed); for (const [index, component] of components.entries()) {
if (Array.isArray(component)) {
card.components.push(...component);
} else {
card.components.push(component);
} }
if (index !== components.length - 1) {
card.components.push({type: 14});
}
}
finalComponents.push(card);
} }
return { return {
content: `Presence for **${formatUsername(target)}**: ${icons.join(" ")}`, flags: 1 << 15,
embeds, components: finalComponents,
files, files,
}; };
} else { } else {