Skip to content

Instantly share code, notes, and snippets.

@0916dhkim
Created April 15, 2023 23:20
Show Gist options
  • Save 0916dhkim/be79e08305a4b330d5b98b86d2ad6310 to your computer and use it in GitHub Desktop.
Save 0916dhkim/be79e08305a4b330d5b98b86d2ad6310 to your computer and use it in GitHub Desktop.
import * as ics from "ics";
import Discord, { GatewayIntentBits, REST, Routes } from "discord.js";
import {Readable} from "stream";
import moment from "moment";
import { z } from "zod";
const eventResponseSchema = z.object({
id: z.string(),
name: z.string(),
description: z.string(),
scheduled_start_time: z.string(),
scheduled_end_time: z.string(),
entity_metadata: z.object({
location: z.string().nullish(),
}),
}).array();
const client = new Discord.Client({
intents: [GatewayIntentBits.Guilds],
});
const rest = new REST({ version: '10' }).setToken(process.env.TOKEN);
client.on('ready', () => {
console.log(`Logged in as ${client.user?.tag}!`);
});
client.on('interactionCreate', async interaction => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
if (interaction.guildId == null) {
console.error("Guild ID is null or undefined.");
} else {
const response = eventResponseSchema.parse(
await rest.get(Routes.guildScheduledEvents(interaction.guildId))
);
await interaction.reply({
files: [{
contentType: "text/calendar",
name: "events.ics",
attachment: stringToStream(eventsToIcs(response)),
}]
})
}
}
});
function eventsToIcs(events: z.infer<typeof eventResponseSchema>): string {
const { error, value } = ics.createEvents(events.map((eventData) => ({
title: eventData.name,
description: eventData.description,
location: eventData.entity_metadata.location ?? undefined,
start: isoDateToDateArray(eventData.scheduled_start_time),
startInputType: "utc",
startOutputType: "utc",
end: isoDateToDateArray(eventData.scheduled_end_time),
endInputType: "utc",
endOutputType: "utc",
})));
if (value == null) {
if (error) {
throw error;
} else {
throw new Error("Failed to convert.");
}
}
return value;
}
function stringToStream(str: string): Readable {
const stream = new Readable();
stream.push(str);
stream.push(null);
return stream;
}
function isoDateToDateArray(isoDate: string): ics.DateArray {
const date = moment(isoDate).utc();
const dateArray: ics.DateArray = [
date.year(),
date.month() + 1,
date.date(),
date.hour(),
date.minute(),
];
return dateArray;
}
client.login(process.env.TOKEN);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment