import { DISCORD_PROVIDER_ROLE_SCHEMA, DISCORD_ROLE_SCHEMA, toDiscordRole, } from "@automate.ax/integration-contracts/discord" import * as z from "zod" import { defineAction } from "../../../automation/actions" import { getDiscordApi } from "../lib/api" const ROLE_FIELDS_SCHEMA = z.object({ color: z.number().int().min(0).max(0xffffff).optional(), hoist: z.boolean().optional(), mentionable: z.boolean().optional(), name: z.string().trim().min(1).max(100).optional(), permissions: z.string().regex(/^\d+$/).optional(), }) /** Lists roles in a Discord server. */ export const listDiscordRoles = defineAction("List Discord roles") .describe("Lists every role in a server, including the everyone role.") .account("discord") .input(z.object({ guildId: z.string().regex(/^\d+$/) })) .output(DISCORD_ROLE_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => ( await getDiscordApi(account.secret).request( `guilds/${input.guildId}/roles`, { responseSchema: DISCORD_PROVIDER_ROLE_SCHEMA.array() }, ) ).map(toDiscordRole), ) /** Creates a Discord server role. */ export const createDiscordRole = defineAction("Create Discord role") .describe("Creates a server role with permissions and display settings.") .account("discord") .input( ROLE_FIELDS_SCHEMA.extend({ guildId: z.string().regex(/^\d+$/), name: z.string().trim().min(1).max(100), reason: z.string().max(512).optional(), }), ) .output(DISCORD_ROLE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => roleWrite(account.secret, input, "POST"), ) /** Updates a Discord server role. */ export const updateDiscordRole = defineAction("Update Discord role") .describe("Updates a role's name, permissions, color, or display settings.") .account("discord") .input( ROLE_FIELDS_SCHEMA.extend({ guildId: z.string().regex(/^\d+$/), reason: z.string().max(512).optional(), roleId: z.string().regex(/^\d+$/), }), ) .output(DISCORD_ROLE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => roleWrite(account.secret, input, "PATCH"), ) /** Deletes a Discord server role. */ export const deleteDiscordRole = defineAction("Delete Discord role") .describe("Deletes a server role.") .account("discord") .input( z.object({ guildId: z.string().regex(/^\d+$/), reason: z.string().max(512).optional(), roleId: z.string().regex(/^\d+$/), }), ) .output(z.void()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getDiscordApi(account.secret).request( `guilds/${input.guildId}/roles/${input.roleId}`, { method: "DELETE", reason: input.reason, responseSchema: z.void(), }, ), ) /** * Creates or updates a server role. * * @param secret - Connected Discord account secret. * @param input - Normalized role fields. * @param method - Discord write method. */ async function roleWrite( secret: Record, input: z.output & { guildId: string reason?: string roleId?: string }, method: "PATCH" | "POST", ) { return toDiscordRole( await getDiscordApi(secret).request( `guilds/${input.guildId}/roles${input.roleId ? `/${input.roleId}` : ""}`, { body: { color: input.color, hoist: input.hoist, mentionable: input.mentionable, name: input.name, permissions: input.permissions, }, method, reason: input.reason, responseSchema: DISCORD_PROVIDER_ROLE_SCHEMA, }, ), ) }