Skip to content

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

Package listing

@kody/intercom

src/accounts.ts

94 lines · 3.1 KB · TypeScript
import { parseAuth, listIntercomIntegrationNames, listUserSecretNames } from './auth.ts'
import type { IntercomAuthInput, IntercomAuthMode } from './types.ts'
import { requireRecord } from './types.ts'
import {
	ACCESS_TOKEN_SETUP_URL,
	DEFAULT_INTEGRATION_NAME,
	DEFAULT_TOKEN_SECRET,
	INTERCOM_CALLBACK_URL,
	INTERCOM_PERMISSIONS,
	INTERCOM_REQUIRED_HOSTS,
	OAUTH_CONNECT_URL,
	accessTokenSetupUrl,
	oauthConnectUrl,
	resolveApiBaseUrl,
	resolveIntegrationName,
	resolveRegion,
	resolveSecretName,
} from './setup.ts'

export type IntercomAccountResolution = {
	integrationName: string
	secretName: string
	oauthConnected: boolean
	accessTokenSaved: boolean
	preferredAuth: IntercomAuthMode | null
	region: ReturnType<typeof resolveRegion>
	apiBaseUrl: string
	connectUrl: string
	accessTokenUrl: string
	callbackUrl: string
	requiredHosts: Array<string>
	permissions: typeof INTERCOM_PERMISSIONS
}

/**
 * Resolve which Intercom OAuth integration or access token to use.
 *
 * - `integration` / `integrationName` wins when set (exact name, e.g. `intercom-work`)
 * - `account: 'work'` → `intercom-work`
 * - `account: 'default'` / `'intercom'` / omitted → `intercom`
 * - Access-token secret defaults to `intercomAccessToken`, or
 *   `intercomAccessToken-<purpose>` for `intercom-<purpose>` integrations
 *
 * @example
 * import listIntercomAccounts from 'kody:@kody/intercom/accounts'
 * const accounts = await listIntercomAccounts()
 */
export async function accounts(
	params: IntercomAuthInput = {},
): Promise<IntercomAccountResolution> {
	const integrationName = resolveIntegrationName(params)
	const secretName = resolveSecretName(params)
	const [secrets, integrations] = await Promise.all([
		listUserSecretNames(),
		listIntercomIntegrationNames(),
	])
	const oauthConnected = integrations.includes(integrationName)
	const accessTokenSaved = secrets.has(secretName)
	const forced = params.auth
	let preferredAuth: IntercomAuthMode | null = null
	if (forced === 'oauth' && oauthConnected) preferredAuth = 'oauth'
	else if (forced === 'accessToken' && accessTokenSaved) preferredAuth = 'accessToken'
	else if (oauthConnected) preferredAuth = 'oauth'
	else if (accessTokenSaved) preferredAuth = 'accessToken'

	return {
		integrationName,
		secretName,
		oauthConnected,
		accessTokenSaved,
		preferredAuth,
		region: resolveRegion(params),
		apiBaseUrl: resolveApiBaseUrl(params),
		connectUrl: oauthConnectUrl(integrationName, params),
		accessTokenUrl: accessTokenSetupUrl(secretName),
		callbackUrl: INTERCOM_CALLBACK_URL,
		requiredHosts: [...INTERCOM_REQUIRED_HOSTS],
		permissions: INTERCOM_PERMISSIONS,
	}
}

export { DEFAULT_INTEGRATION_NAME, DEFAULT_TOKEN_SECRET, OAUTH_CONNECT_URL, ACCESS_TOKEN_SETUP_URL }

/**
 * Resolve which Intercom OAuth integration or access token to use.
 * @example
 * import listIntercomAccounts from 'kody:@kody/intercom/accounts'
 * const info = await listIntercomAccounts({ account: 'work' })
 */
export default async function accountsEntrypoint(
	params: IntercomAuthInput & Record<string, unknown> = {},
) {
	return accounts(parseAuth(requireRecord(params, 'accounts')))
}