import { getMessage, searchMessages } from 'kody:@kody/google/gmail'
import { DEFAULT_INBOX_MAX, DEFAULT_INBOX_QUERY, skippedSection } from '../format.ts'
import { googleInboxSetupError } from '../google-setup.ts'
import type { BriefingInput, BriefingItem, BriefingSection } from '../types.ts'
type GmailList = { messages?: Array<{ id?: string; threadId?: string }> }
type GmailHeader = { name?: string; value?: string }
type GmailMessage = {
id?: string
payload?: { headers?: GmailHeader[] }
snippet?: string
}
function header(message: GmailMessage, name: string): string {
const headers = message.payload?.headers || []
return (
headers.find((entry) => String(entry.name || '').toLowerCase() === name.toLowerCase())
?.value || ''
)
}
export async function inboxSection(input: BriefingInput): Promise<BriefingSection> {
const account = input.inbox?.account?.trim() || 'personal'
const query = input.inbox?.query?.trim() || DEFAULT_INBOX_QUERY
const max = Math.min(Math.max(Number(input.inbox?.max) || DEFAULT_INBOX_MAX, 1), 20)
if (!account) {
return skippedSection(
'inbox',
'Pass inbox.account after connecting bring-your-own Google OAuth with Gmail read scopes.',
)
}
try {
const listed = (await searchMessages({
account,
query,
maxResults: max,
})) as GmailList
const ids = (listed.messages || []).map((row) => row.id).filter((id): id is string => Boolean(id))
const items: BriefingItem[] = []
for (const id of ids.slice(0, max)) {
const message = (await getMessage({
account,
id,
format: 'metadata',
metadataHeaders: ['Subject', 'From', 'Date'],
})) as GmailMessage
const subject = header(message, 'Subject') || '(no subject)'
const from = header(message, 'From')
items.push({
title: subject,
detail: from || message.snippet || undefined,
label: 'unread',
severity: 'notice',
})
}
return {
id: 'inbox',
title: 'Inbox',
status: items.length ? 'ok' : 'empty',
summary: items.length
? `${items.length} message${items.length === 1 ? '' : 's'} for \`${query}\``
: `No messages for \`${query}\``,
items,
}
} catch (error) {
throw googleInboxSetupError(error, account)
}
}