import { type TextBasedChannel, User } from 'discord.js'; /** * Sends a message to a channel using a temporary webhook (imitating the bot or custom persona). * * @param channel The channel to send the message to (must support webhooks). * @param payload The message payload (string content or JSON object for embeds/options). * @param clientUser The client user (bot) to fallback for avatar/name if not specified in payload. * @param reason The reason for creating the webhook (for audit logs). */ export async function sendWebhookMessage( channel: TextBasedChannel, payload: any, clientUser: User, reason: string ): Promise { if (!('createWebhook' in channel)) { throw new Error("Channel does not support webhooks."); } // Normalize payload if it's just a string, wrap it in content if (typeof payload === 'string') { payload = { content: payload }; } let webhook; try { webhook = await channel.createWebhook({ name: payload.username || `${clientUser.username}`, // Use payload name or bot name avatar: payload.avatar_url || payload.avatarURL || clientUser.displayAvatarURL(), reason: reason }); // Support snake_case keys for raw API compatibility if passed from config if (payload.avatar_url && !payload.avatarURL) { payload.avatarURL = payload.avatar_url; delete payload.avatar_url; } await webhook.send(payload); await webhook.delete(reason); } catch (error) { // Attempt cleanup if webhook was created but sending failed if (webhook) { try { await webhook.delete("Cleanup after failure"); } catch (cleanupError) { console.error("Failed to delete webhook during cleanup:", cleanupError); } } throw error; } }