export type TMailGatewayClientType = 'onebox' | 'cloudly' | 'custom' | (string & {}); export type TMailAddressPatternType = 'exactAddress' | 'domainWildcard' | 'localPartPattern'; export type TMailInboundTargetType = 'webhook' | 'smtpForward' | 'typedEndpoint' | 'discard' | 'reject'; export type TMailRecipientPolicyMode = 'acceptAll' | 'staticList' | 'cachedResolver' | 'appResolver'; export type TMailCredentialType = 'smtp' | 'api'; export type TMailCredentialStatus = 'active' | 'disabled' | 'rotated' | 'revoked'; export type TMailResourceStatus = 'active' | 'disabled' | 'pending' | 'failed'; export type TMailSpoolDirection = 'inbound' | 'outbound'; export type TMailSpoolStatus = 'accepted' | 'queued' | 'delivering' | 'delivered' | 'deferred' | 'failed' | 'deadLettered' | 'rejected'; export type TMailDeliveryTargetType = 'webhook' | 'smtpForward' | 'typedEndpoint' | 'mtaRelay' | 'discard' | 'reject'; export type TMailBounceType = 'hard' | 'soft' | 'complaint' | 'unknown'; export type TMailInboundProtocol = 'smtp' | 'submission' | 'api'; export type TMailRecipientResolutionAction = 'accept' | 'reject' | 'defer'; export type TMailDeliveryJournalEventType = 'accepted' | 'queued' | 'deliveryStarted' | 'deliverySucceeded' | 'deliveryDeferred' | 'deliveryFailed' | 'deadLettered' | 'rejected' | 'bounced' | 'complaint'; export type TMailSubmissionErrorCode = 'INVALID_REPLY_TO' | 'REPLY_TO_FIELD_HEADER_CONFLICT'; /** * Runtime owner of a mail resource. `appInstanceId` is the deployed WorkApp or service * instance, not an App Store template id. */ export interface IMailResourceOwner { gatewayClientType: TMailGatewayClientType; gatewayClientId: string; appInstanceId?: string; } export interface IMailAddressPattern { type: TMailAddressPatternType; domain: string; localPart?: string; localPartPattern?: string; } export interface IMailWebhookTarget { url: string; signingSecretRef?: string; timeoutMs?: number; headers?: Record; maxInlineBytes?: number; } export interface IMailSmtpForwardTarget { host: string; port: number; credentialRef?: string; preserveHeaders?: boolean; addHeaders?: Record; } export interface IMailTypedEndpointTarget { serviceRef?: string; method: string; queueName?: string; timeoutMs?: number; } export interface IMailInboundTarget { type: TMailInboundTargetType; webhook?: IMailWebhookTarget; smtpForward?: IMailSmtpForwardTarget; typedEndpoint?: IMailTypedEndpointTarget; reject?: { smtpCode: number; message: string; }; } export interface IMailRecipientResolverTarget { type: 'webhook' | 'typedEndpoint'; webhook?: IMailWebhookTarget; typedEndpoint?: IMailTypedEndpointTarget; } export interface IMailRecipientPolicy { mode: TMailRecipientPolicyMode; staticRecipients?: string[]; resolver?: IMailRecipientResolverTarget; cacheTtlMs?: number; unavailableResponse?: { smtpCode: number; message: string; }; } export interface IMailSpoolPolicy { enabled: boolean; maxRetryAgeMs?: number; retentionMs?: number; maxQueuedMessages?: number; maxQueuedBytes?: number; initialRetryDelayMs?: number; maxRetryDelayMs?: number; deadLetterOnExpiry?: boolean; } export interface IMailRateLimits { messagesPerMinute?: number; messagesPerHour?: number; messagesPerDay?: number; recipientsPerMessage?: number; } export interface IMailDomainAuthority { id: string; owner: IMailResourceOwner; domain: string; addressPattern: IMailAddressPattern; enabled: boolean; status: TMailResourceStatus; inboundTarget?: IMailInboundTarget; outboundPolicy?: { allowedFromPatterns: IMailAddressPattern[]; dkimSelector?: string; rateLimits?: IMailRateLimits; }; recipientPolicy: IMailRecipientPolicy; spoolPolicy?: IMailSpoolPolicy; createdAt: number; updatedAt: number; createdBy?: string; } export interface IMailAddressBinding { id: string; owner: IMailResourceOwner; address: string; localPart: string; domain: string; enabled: boolean; status: TMailResourceStatus; inboundTarget?: IMailInboundTarget; outboundIdentityId?: string; /** Public, non-secret credential state for reconciliation. */ outboundCredential?: IMailCredentialPublic; recipientPolicy?: IMailRecipientPolicy; spoolPolicy?: IMailSpoolPolicy; createdAt: number; updatedAt: number; createdBy?: string; } export interface IMailCredentialPublic { id: string; type: TMailCredentialType; status: TMailCredentialStatus; username?: string; scopes?: string[]; createdAt: number; updatedAt: number; lastRotatedAt?: number; } export interface IMailCredentialOneTimeSecret { credential: IMailCredentialPublic; secret: string; secretShownOnce: true; } export interface IMailOutboundIdentity { id: string; owner: IMailResourceOwner; enabled: boolean; status: TMailResourceStatus; allowedFromPatterns: IMailAddressPattern[]; defaultFrom?: string; domain?: string; dkimSelector?: string; credential?: IMailCredentialPublic; rateLimits?: IMailRateLimits; createdAt: number; updatedAt: number; createdBy?: string; } export interface IWorkAppMailBinding { id: string; owner: IMailResourceOwner & { appInstanceId: string; }; enabled: boolean; status: TMailResourceStatus; domainAuthorityIds?: string[]; addressBindingIds?: string[]; outboundIdentityIds?: string[]; defaultFrom?: string; inboundTarget?: IMailInboundTarget; createdAt: number; updatedAt: number; createdBy?: string; } export type TServiceMailSubmissionTlsMode = 'plain' | 'starttls' | 'implicitTls'; export interface IServiceMailInboundConfig { enabled?: boolean; /** Platformclient apps use typedEndpoint; third-party apps with their own SMTP server use smtpForward. */ targetType?: 'typedEndpoint' | 'smtpForward'; /** TypedRequest method exposed by platformclient over TypedSocket for inbound delivery. */ typedMethod?: string; /** Published Docker/Swarm port that dcrouter may SMTP-forward inbound mail to. */ publishedPort?: number; preserveHeaders?: boolean; addHeaders?: Record; } export interface IServiceMailOutboundConfig { enabled?: boolean; /** dcrouter credential id/username. Public metadata only; never store passwords here. */ credentialId?: string; username?: string; status?: TMailCredentialStatus; lastRotatedAt?: number; } export interface IServiceMailAddressConfig { address: string; enabled?: boolean; displayName?: string; inbound?: IServiceMailInboundConfig; outbound?: IServiceMailOutboundConfig; } export interface IServiceMailConfig { enabled?: boolean; defaultFrom?: string; addresses: IServiceMailAddressConfig[]; } export interface IMailEnvelope { mailFrom: string; rcptTo: string[]; } export interface IMailDeliveryTargetSummary { type: TMailDeliveryTargetType; label?: string; address?: string; url?: string; host?: string; port?: number; serviceRef?: string; method?: string; queueName?: string; } export interface IMailConnectionInfo { protocol: TMailInboundProtocol; remoteAddress?: string; proxyAddress?: string; heloName?: string; tls?: boolean; authUsername?: string; authenticatedCredentialId?: string; } export interface IMailRecipientResolution { recipient: string; action: TMailRecipientResolutionAction; owner?: IMailResourceOwner; domainAuthorityId?: string; addressBindingId?: string; target?: IMailInboundTarget; smtpCode?: number; message?: string; cacheTtlMs?: number; } export interface IMailSpoolItem { id: string; owner?: IMailResourceOwner; direction: TMailSpoolDirection; status: TMailSpoolStatus; envelope: IMailEnvelope; messageId?: string; subject?: string; target?: IMailDeliveryTargetSummary; attempts: number; nextAttemptAt?: number; lastError?: string; rawAvailableUntil?: number; createdAt: number; updatedAt: number; } export interface IMailDeliveryAttempt { id: string; spoolItemId: string; target: IMailDeliveryTargetSummary; status: TMailSpoolStatus; startedAt: number; completedAt?: number; smtpCode?: number; response?: string; error?: string; } export interface IMailBounceEvent { id: string; spoolItemId?: string; owner?: IMailResourceOwner; recipient: string; bounceType: TMailBounceType; diagnosticCode?: string; receivedAt: number; } export interface IMailDeliveryStatus { spoolItem?: IMailSpoolItem; attempts: IMailDeliveryAttempt[]; bounceEvents?: IMailBounceEvent[]; } export interface IMailDeliveryJournalEvent { id: string; spoolItemId: string; owner?: IMailResourceOwner; direction: TMailSpoolDirection; type: TMailDeliveryJournalEventType; status: TMailSpoolStatus; envelope?: IMailEnvelope; target?: IMailDeliveryTargetSummary; attemptId?: string; smtpCode?: number; response?: string; error?: string; message?: string; createdAt: number; } export interface IMailInboundMessagePayload { spoolItemId: string; owner?: IMailResourceOwner; envelope: IMailEnvelope; rawMessage: string; sizeBytes?: number; messageId?: string; subject?: string; headers?: Record; source?: IMailConnectionInfo; receivedAt: number; } export interface IMailOutboundAttachmentPayload { filename: string; contentType?: string; binaryAttachmentString: string; } export interface IMailOutboundMessagePayload { from: string; to: string[]; cc?: string[]; bcc?: string[]; /** One bare ASCII mailbox address. Display names and address lists are not supported. */ replyTo?: string; subject: string; text?: string; html?: string; headers?: Record; attachments?: IMailOutboundAttachmentPayload[]; }