Created
April 15, 2023 23:20
-
-
Save 0916dhkim/be79e08305a4b330d5b98b86d2ad6310 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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