import {
messageSummary,
pagingQuery,
postmarkRequest,
type PostmarkAuthOptions,
type PostmarkObject,
} from './core.ts'
function auth(input: PostmarkAuthOptions) {
return { account: input.account, secretName: input.secretName }
}
export type SearchOutboundInput = PostmarkAuthOptions & {
count?: number
offset?: number
recipient?: string
fromEmail?: string
tag?: string
status?: 'queued' | 'sent' | 'processed'
fromDate?: string
toDate?: string
subject?: string
messageStream?: string
metadata?: Record<string, string>
}
function outboundQuery(input: SearchOutboundInput) {
const paging = pagingQuery(input)
const query: Record<string, string | number | undefined> = {
...paging,
recipient: input.recipient,
fromemail: input.fromEmail,
tag: input.tag,
status: input.status,
fromdate: input.fromDate,
todate: input.toDate,
subject: input.subject,
messagestream: input.messageStream,
}
if (input.metadata) {
const entries = Object.entries(input.metadata).filter(([, value]) => value != null && value !== '')
if (entries.length > 1) {
throw new Error('Postmark outbound search accepts one metadata field at a time.')
}
for (const [key, value] of entries) {
query['metadata_' + key] = value
}
}
return query
}
/** GET /messages/outbound — search sent mail on the Server API token. */
export async function searchOutboundMessages(input: SearchOutboundInput = {}) {
const body = (await postmarkRequest({
path: '/messages/outbound',
tokenKind: 'server',
query: outboundQuery(input),
...auth(input),
})) as { TotalCount?: number; Messages?: PostmarkObject[] }
const messages = Array.isArray(body.Messages) ? body.Messages : []
return {
totalCount: body.TotalCount ?? messages.length,
messages: messages.map((message) => messageSummary(message)).filter(Boolean),
}
}
/** GET /messages/outbound/{id}/details — one outbound message. */
export async function getOutboundMessage(input: PostmarkAuthOptions & { messageId: string }) {
if (!input.messageId) throw new Error('getOutboundMessage: messageId is required')
return await postmarkRequest({
path: '/messages/outbound/' + encodeURIComponent(input.messageId) + '/details',
tokenKind: 'server',
...auth(input),
})
}
export type SearchInboundInput = PostmarkAuthOptions & {
count?: number
offset?: number
recipient?: string
fromEmail?: string
tag?: string
subject?: string
mailboxHash?: string
status?: 'blocked' | 'processed' | 'queued' | 'failed' | 'scheduled'
fromDate?: string
toDate?: string
}
/** GET /messages/inbound — search inbound mail on the Server API token. */
export async function searchInboundMessages(input: SearchInboundInput = {}) {
const paging = pagingQuery(input)
const body = (await postmarkRequest({
path: '/messages/inbound',
tokenKind: 'server',
query: {
...paging,
recipient: input.recipient,
fromemail: input.fromEmail,
tag: input.tag,
subject: input.subject,
mailboxhash: input.mailboxHash,
status: input.status,
fromdate: input.fromDate,
todate: input.toDate,
},
...auth(input),
})) as { TotalCount?: number; InboundMessages?: PostmarkObject[]; Messages?: PostmarkObject[] }
const messages = Array.isArray(body.InboundMessages)
? body.InboundMessages
: Array.isArray(body.Messages)
? body.Messages
: []
return {
totalCount: body.TotalCount ?? messages.length,
messages: messages.map((message) => messageSummary(message)).filter(Boolean),
}
}
/** GET /messages/inbound/{id}/details — one inbound message. */
export async function getInboundMessage(input: PostmarkAuthOptions & { messageId: string }) {
if (!input.messageId) throw new Error('getInboundMessage: messageId is required')
return await postmarkRequest({
path: '/messages/inbound/' + encodeURIComponent(input.messageId) + '/details',
tokenKind: 'server',
...auth(input),
})
}
export default searchOutboundMessages