import * as z from "zod" import { defineAction } from "../../../automation/actions" import { EMAIL_BODY_SCHEMA, normalizeEmailBody } from "../../../lib/email" import { EMAIL_ORIGIN_TOKEN } from "../../../lib/email-origin" import { buildRawMessage, getGmailApi, toMessageMetadata, } from "@automate.ax/integration-contracts/gmail" import { GMAIL_SEND_REQUIREMENT } from "../lib/scopes" import { COMPOSE_OPTIONS_SCHEMA, MESSAGE_METADATA_SCHEMA, RECIPIENTS_SCHEMA, } from "@automate.ax/integration-contracts/gmail" /** * Sends a Gmail message, optionally in an existing conversation. * * Supports named recipients, send-as aliases, custom headers, priority, inline * attachments, and plain text, Markdown, or HTML bodies. */ export const sendGmailEmail = defineAction("Send Gmail email") .describe("Sends a richly formatted Gmail message.") .account("google", GMAIL_SEND_REQUIREMENT) .input( COMPOSE_OPTIONS_SCHEMA.extend({ /** Message subject line. */ subject: z.string(), /** Existing thread ID. Supply matching subject and RFC reply headers. */ threadId: z.string().min(1).optional(), /** One or more primary recipients. */ to: RECIPIENTS_SCHEMA, }).and(EMAIL_BODY_SCHEMA), ) .output(MESSAGE_METADATA_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input, runtime }) => toMessageMetadata( ( await getGmailApi(account.secret).users.messages.send({ requestBody: { threadId: input.threadId, raw: await buildRawMessage({ ...input, ...normalizeEmailBody(input), automationOriginToken: runtime[EMAIL_ORIGIN_TOKEN], }), }, userId: "me", }) ).data, "sent message", ), )