177 linhas
Sem EOL
7,2 KiB
TypeScript
177 linhas
Sem EOL
7,2 KiB
TypeScript
//thank you to https://git.lunya.pet/Lunya/Ai for the inspiration
|
|
import {
|
|
ActionRowBuilder,
|
|
ApplicationIntegrationType,
|
|
ButtonBuilder,
|
|
ButtonStyle,
|
|
ChatInputCommandInteraction,
|
|
ContainerBuilder,
|
|
InteractionContextType,
|
|
MediaGalleryBuilder,
|
|
MediaGalleryItemBuilder,
|
|
type MessageActionRowComponentBuilder,
|
|
MessageFlags,
|
|
SectionBuilder,
|
|
SlashCommandBuilder,
|
|
TextDisplayBuilder,
|
|
ThumbnailBuilder
|
|
} from "discord.js";
|
|
import type { Config } from "../config.ts";
|
|
import { trimWhitespace } from "../util.ts";
|
|
import { declareCommand } from "../command.ts";
|
|
import { z } from "zod";
|
|
|
|
const fediUserRegex = /@[^.@\s]+@(?:[^.@\s]+\.)+[^.@\s]+/
|
|
|
|
export default declareCommand({
|
|
async run(interaction: ChatInputCommandInteraction, config) {
|
|
await interaction.deferReply();
|
|
const fedistring = interaction.options.getString("string")!
|
|
if (!fediUserRegex.test(fedistring)) {
|
|
//we're just gonna assume this is a note id
|
|
const resp = await fetch(`https://${config.sharkeyInstance}/api/notes/show`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
noteId: fedistring,
|
|
})
|
|
}).then(res => res.json())
|
|
console.log(resp)
|
|
if ("error" in resp) {
|
|
await interaction.followUp(`nyaaaa 3:\n\`${resp.error.code}\``);
|
|
return;
|
|
}
|
|
let mainComponent
|
|
const components: (TextDisplayBuilder | ContainerBuilder | ActionRowBuilder<MessageActionRowComponentBuilder>)[] = [
|
|
mainComponent = new ContainerBuilder()
|
|
.setSpoiler(resp.cw !== null)
|
|
.addSectionComponents(
|
|
new SectionBuilder()
|
|
.setThumbnailAccessory(
|
|
new ThumbnailBuilder()
|
|
.setURL(resp.user.avatarUrl)
|
|
)
|
|
.addTextDisplayComponents(
|
|
/*
|
|
if host is null, its the same host as the api
|
|
why is it written like this? idfk
|
|
*/
|
|
new TextDisplayBuilder().setContent(`## ${resp.user.name} (@${resp.user.username}@${resp.user.host === null ? config.sharkeyInstance : resp.user.host})`),
|
|
),
|
|
),
|
|
new ActionRowBuilder<MessageActionRowComponentBuilder>()
|
|
.addComponents(
|
|
new ButtonBuilder()
|
|
.setStyle(ButtonStyle.Link)
|
|
.setLabel("view post")
|
|
/*
|
|
im done with this garbage. `resp.uri` is NOT EVEN THERE when THE FUCKING instance IS THE SAME
|
|
as the FUCKIOGN G WERDSKLP;GVFHEWRL'VGFHNCEW'RLFPVBHNGETFVBN
|
|
|
|
*/
|
|
.setURL(!resp.uri ? `https://${config.sharkeyInstance}/notes/${fedistring}` : resp.uri),
|
|
),
|
|
]
|
|
|
|
if (resp.text) {
|
|
mainComponent.addTextDisplayComponents(
|
|
new TextDisplayBuilder().setContent(resp.text),
|
|
)
|
|
}
|
|
|
|
if (resp.files.length > 0) {
|
|
const images = new MediaGalleryBuilder()
|
|
for (const file of resp.files) {
|
|
if (!file.type.startsWith("image/")) {
|
|
continue;
|
|
}
|
|
images.addItems(
|
|
new MediaGalleryItemBuilder()
|
|
.setURL(file.url)
|
|
.setDescription(file.comment)
|
|
.setSpoiler(file.isSensitive)
|
|
)
|
|
}
|
|
mainComponent.addMediaGalleryComponents(
|
|
images,
|
|
)
|
|
}
|
|
if (resp.cw !== null) {
|
|
components.unshift(new TextDisplayBuilder().setContent("cw: " + resp.cw))
|
|
}
|
|
await interaction.followUp({
|
|
components: components,
|
|
flags: [MessageFlags.IsComponentsV2],
|
|
});
|
|
return;
|
|
}
|
|
const userhost = trimWhitespace(fedistring.split("@").splice(1))
|
|
|
|
const resp = await fetch(`https://${config.sharkeyInstance}/api/users/show`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
username: userhost[0],
|
|
host: userhost[1],
|
|
})
|
|
}).then(res => res.json())
|
|
|
|
if ("error" in resp) {
|
|
await interaction.followUp(`nyaaaa 3:\n\`${resp.error.code}\``);
|
|
return;
|
|
}
|
|
const components = [
|
|
new ContainerBuilder()
|
|
.addSectionComponents(
|
|
new SectionBuilder()
|
|
.setThumbnailAccessory(
|
|
new ThumbnailBuilder()
|
|
.setURL(resp.avatarUrl)
|
|
)
|
|
.addTextDisplayComponents(
|
|
new TextDisplayBuilder().setContent(`## ${resp.name}`),
|
|
//same as above. host is null when its the same as the api
|
|
new TextDisplayBuilder().setContent(`@${resp.username}@${resp.host === null ? config.sharkeyInstance : resp.host}`),
|
|
),
|
|
)
|
|
.addTextDisplayComponents(
|
|
new TextDisplayBuilder().setContent(resp.description),
|
|
),
|
|
new ActionRowBuilder<MessageActionRowComponentBuilder>()
|
|
.addComponents(
|
|
new ButtonBuilder()
|
|
.setStyle(ButtonStyle.Link)
|
|
.setLabel("go to profile")
|
|
/*
|
|
the fucking `resp.url` is null when the host is the same as the api. who designed this???????
|
|
thankfully since we're working with a sharkey api, we're ssure this is how the link is
|
|
structured, so we can just make it the fuck up
|
|
*/
|
|
.setURL(resp.url === null ? `https://${config.sharkeyInstance}/@${resp.username}` : resp.url),
|
|
),
|
|
];
|
|
await interaction.followUp({
|
|
components,
|
|
flags: [MessageFlags.IsComponentsV2],
|
|
});
|
|
},
|
|
dependsOn: z.object({
|
|
sharkeyInstance: z.string()
|
|
}),
|
|
slashCommand: new SlashCommandBuilder()
|
|
.setName("fedilookup")
|
|
.setDescription("look up shit from fedi").setIntegrationTypes([
|
|
ApplicationIntegrationType.UserInstall
|
|
]).addStringOption(option => {
|
|
return option.setName("string").setDescription("either note id or user").setRequired(true);
|
|
})
|
|
.setContexts([
|
|
InteractionContextType.BotDM,
|
|
InteractionContextType.Guild,
|
|
InteractionContextType.PrivateChannel
|
|
])
|
|
}) |