| |
| |
| |
| |
| |
| |
| |
| |
| import type { MailDetail } from "@clawemail/node-sdk"; |
| import { getMailClient } from "./claw-mail"; |
|
|
| export interface ClawFolder { |
| id: string; |
| name: string; |
| unreadCount?: number; |
| } |
|
|
| export interface ClawMessageSummary { |
| id: string; |
| from?: string; |
| subject?: string; |
| date?: string; |
| size?: number; |
| read?: boolean; |
| } |
|
|
| export interface ClawMessageDetails extends ClawMessageSummary { |
| to?: string; |
| cc?: string; |
| snippet?: string; |
| } |
|
|
| export interface ClawListOptions { |
| fid: string | number; |
| order?: string; |
| desc?: boolean; |
| limit?: number; |
| start?: number; |
| unread?: boolean; |
| } |
|
|
| export interface ClawSearchQuery { |
| fid?: string | number; |
| keyword?: string; |
| from?: string; |
| to?: string; |
| subject?: string; |
| since?: string; |
| before?: string; |
| unread?: boolean; |
| fts?: boolean; |
| limit?: number; |
| } |
|
|
| export type ClawForwardMode = "quote" | "attach" | "transmit"; |
|
|
| export interface ClawForwardInput { |
| id: string; |
| to: string[]; |
| cc?: string[]; |
| bcc?: string[]; |
| body?: string; |
| html?: boolean; |
| mode?: ClawForwardMode; |
| } |
|
|
| |
| |
| interface ClawTransport { |
| kind: "ajax" | "imap"; |
| listFolders(): Promise<ClawFolder[]>; |
| listMessages(options: ClawListOptions): Promise<ClawMessageSummary[]>; |
| getMessage(ids: string | string[]): Promise<ClawMessageDetails[]>; |
| searchMessages(query: ClawSearchQuery): Promise<ClawMessageSummary[]>; |
| moveMessages(ids: string[], target: string | number): Promise<void>; |
| markMessages(ids: string[], flags: { read?: boolean }): Promise<void>; |
| forwardMessage(msg: ClawForwardInput): Promise<{ status: "sent" }>; |
| } |
|
|
| function getTransport(email: string): ClawTransport { |
| const transport = (getMailClient(email) as unknown as { transport?: ClawTransport }).transport; |
| if (!transport || typeof transport.listFolders !== "function") { |
| throw new Error("当前安装的 Claw SDK 不支持高级邮箱操作(transport 不可用)"); |
| } |
| return transport; |
| } |
|
|
| |
| export async function listFolders(email: string): Promise<ClawFolder[]> { |
| return getTransport(email).listFolders(); |
| } |
|
|
| |
| export async function listFolderMessages(email: string, options: ClawListOptions): Promise<ClawMessageSummary[]> { |
| return getTransport(email).listMessages(options); |
| } |
|
|
| |
| export async function getMessageSummaries(email: string, ids: string[]): Promise<ClawMessageDetails[]> { |
| if (ids.length === 0) return []; |
| return getTransport(email).getMessage(ids); |
| } |
|
|
| |
| export async function searchMessages(email: string, query: ClawSearchQuery): Promise<ClawMessageSummary[]> { |
| return getTransport(email).searchMessages({ |
| fid: query.fid ?? "INBOX", |
| keyword: query.keyword, |
| from: query.from, |
| to: query.to, |
| subject: query.subject, |
| since: query.since, |
| before: query.before, |
| unread: query.unread, |
| fts: query.fts ?? Boolean(query.keyword), |
| limit: query.limit ?? 50 |
| }); |
| } |
|
|
| |
| export async function markMessages(email: string, ids: string[], read: boolean): Promise<void> { |
| if (ids.length === 0) return; |
| await getTransport(email).markMessages(ids, { read }); |
| } |
|
|
| |
| export async function moveMessages(email: string, ids: string[], target: string | number): Promise<void> { |
| if (ids.length === 0) return; |
| await getTransport(email).moveMessages(ids, target); |
| } |
|
|
| |
| export async function forwardMail(email: string, input: ClawForwardInput): Promise<{ status: "sent" }> { |
| if (!input.to?.length) { |
| throw new Error("转发收件人 to 不能为空"); |
| } |
| return getTransport(email).forwardMessage(input); |
| } |
|
|
| |
| export async function readRemoteMailDetail( |
| email: string, |
| providerMailId: string, |
| markRead = false |
| ): Promise<MailDetail> { |
| return getMailClient(email).mail.read({ id: providerMailId, markRead }); |
| } |
|
|