import * as z from "zod" import { defineAction } from "../../../automation/actions" import { getGmailApi } from "@automate.ax/integration-contracts/gmail" import { GMAIL_DRAFT_READ_REQUIREMENT } from "../lib/scopes" import { DRAFT_IDENTIFIER_SCHEMA } from "@automate.ax/integration-contracts/gmail" /** * Searches Gmail drafts using Gmail's standard query syntax. * * Pagination is handled internally until the requested total limit is reached. */ export const searchGmailDrafts = defineAction("Search Gmail drafts") .describe("Searches Gmail drafts and returns their stable identities.") .account("google", GMAIL_DRAFT_READ_REQUIREMENT) .input( z.object({ /** Whether drafts in Spam and Trash may match. */ includeSpamTrash: z.boolean().optional(), /** Maximum total results returned across internally fetched pages. */ limit: z.number().int().min(1).max(10_000).optional(), /** Standard Gmail search-box query. */ query: z.string().optional(), }), ) .output(DRAFT_IDENTIFIER_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => { const gmailApi = getGmailApi(account.secret) const limit = input.limit ?? 100 const drafts: z.output[] = [] let pageToken: string | undefined do { const { data } = await gmailApi.users.drafts.list({ includeSpamTrash: input.includeSpamTrash ?? false, maxResults: Math.min(500, limit - drafts.length), pageToken, q: input.query, userId: "me", }) drafts.push( ...(data.drafts ?? []).flatMap((draft) => draft.id && draft.message?.id && draft.message.threadId ? [ { draftId: draft.id, historyId: draft.message.historyId ?? undefined, labelIds: draft.message.labelIds ?? [], messageId: draft.message.id, threadId: draft.message.threadId, }, ] : [], ), ) pageToken = data.nextPageToken ?? undefined } while (pageToken && drafts.length < limit) return drafts.slice(0, limit) })