Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/discord

src/smoke-test.ts

54 lines · 1.7 KB · TypeScript
import { discordBotRequest } from './bot.ts'
import { discordOauthRequest } from './oauth.ts'
import { inputRecord, requiredLane, type InputRecord } from './validation.ts'

type DiscordUser = {
	id?: string
	username?: string
	global_name?: string | null
	bot?: boolean
	email?: string
	verified?: boolean
}

function projectUser(lane: 'bot' | 'oauth', user: DiscordUser) {
	return {
		ok: true,
		lane,
		id: typeof user.id === 'string' ? user.id : null,
		username: typeof user.username === 'string' ? user.username : null,
		globalName: typeof user.global_name === 'string' ? user.global_name : null,
		bot: user.bot === true,
	}
}

async function loadMe(input: InputRecord) {
	const lane = requiredLane(input, 'bot')
	if (lane === 'oauth') {
		const user = (await discordOauthRequest('/users/@me', input)) as DiscordUser
		return projectUser(lane, user)
	}
	if (lane === 'bot') {
		const user = (await discordBotRequest('/users/@me', input)) as DiscordUser
		if (user.bot !== true) {
			throw new Error(
				'Expected a Discord bot token (Bot prefix). The `' +
					(typeof input.secretName === 'string' ? input.secretName : 'discordBotToken') +
					'` secret resolved to a user identity. Save a bot token from the Bot tab, not an OAuth user token.',
			)
		}
		return projectUser(lane, user)
	}
	const exhaustive: never = lane
	throw new Error('Unsupported Discord lane: ' + String(exhaustive))
}

/**
 * Verify Discord credentials with GET /users/@me.
 *
 * Default `lane` is `bot` (secret `discordBotToken`). Pass `lane: 'oauth'` to
 * check the saved `discord` OAuth integration instead.
 */
export default async function smokeTest(params: Record<string, unknown> = {}) {
	return loadMe(inputRecord(params))
}