2026-07-01 20:43:49 +02:00
|
|
|
/**
|
|
|
|
|
* Mail plugin API client.
|
|
|
|
|
*
|
|
|
|
|
* All requests use the shared `apiClient` (`baseURL: '/api/v1'`) and target the
|
|
|
|
|
* Mail plugin routes under `/mail/...`.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { apiClient, apiDelete, apiGet, apiPatch, apiPost } from './client';
|
|
|
|
|
|
|
|
|
|
// ─── Types ─────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface MailAccount {
|
|
|
|
|
id: string;
|
|
|
|
|
email: string;
|
|
|
|
|
display_name: string;
|
|
|
|
|
imap_host: string;
|
|
|
|
|
imap_port: number;
|
|
|
|
|
smtp_host: string;
|
|
|
|
|
smtp_port: number;
|
|
|
|
|
is_shared: boolean;
|
|
|
|
|
is_active: boolean;
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
updated_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MailFolder {
|
|
|
|
|
id: string;
|
|
|
|
|
account_id: string;
|
|
|
|
|
name: string;
|
2026-07-15 14:36:45 +02:00
|
|
|
imap_name?: string;
|
2026-07-01 20:43:49 +02:00
|
|
|
parent_id: string | null;
|
|
|
|
|
unread_count: number;
|
|
|
|
|
total_count: number;
|
|
|
|
|
children?: MailFolder[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MailAttachment {
|
|
|
|
|
id: string;
|
|
|
|
|
mail_id: string;
|
|
|
|
|
filename: string;
|
|
|
|
|
mime_type: string;
|
2026-07-15 18:43:38 +02:00
|
|
|
size_bytes: number;
|
2026-07-01 20:43:49 +02:00
|
|
|
size: number;
|
|
|
|
|
content_id?: string | null;
|
|
|
|
|
is_inline: boolean;
|
2026-07-15 18:43:38 +02:00
|
|
|
dms_file_id?: string | null;
|
2026-07-01 20:43:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface Mail {
|
|
|
|
|
id: string;
|
|
|
|
|
folder_id: string; account_id: string;
|
|
|
|
|
from_address: string;
|
|
|
|
|
from_name: string;
|
|
|
|
|
to_addresses: string[];
|
|
|
|
|
cc_addresses: string[];
|
|
|
|
|
bcc_addresses: string[];
|
|
|
|
|
subject: string;
|
|
|
|
|
body_text: string;
|
|
|
|
|
body_html: string | null;
|
|
|
|
|
sanitized_html: string | null;
|
|
|
|
|
date: string;
|
|
|
|
|
is_seen: boolean;
|
|
|
|
|
is_flagged: boolean;
|
2026-07-15 19:44:41 +02:00
|
|
|
is_draft: boolean;
|
2026-07-01 20:43:49 +02:00
|
|
|
is_answered: boolean;
|
|
|
|
|
has_attachments: boolean;
|
|
|
|
|
attachments?: MailAttachment[];
|
|
|
|
|
labels?: MailLabel[];
|
|
|
|
|
thread_id?: string | null;
|
|
|
|
|
in_reply_to?: string | null;
|
|
|
|
|
message_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MailListResult {
|
|
|
|
|
mails: Mail[];
|
|
|
|
|
total: number;
|
|
|
|
|
page: number;
|
|
|
|
|
page_size: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MailTemplate {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
subject: string;
|
|
|
|
|
body: string;
|
|
|
|
|
variables: string[];
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
updated_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MailSignature {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
body_html: string;
|
|
|
|
|
is_default: boolean;
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
updated_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type RuleConditionType = 'from_contains' | 'to_contains' | 'subject_contains' | 'has_attachment' | 'body_contains';
|
|
|
|
|
export type RuleActionType = 'move_to_folder' | 'mark_as_read' | 'mark_as_flagged' | 'forward_to' | 'delete';
|
|
|
|
|
|
|
|
|
|
export interface RuleCondition {
|
|
|
|
|
type: RuleConditionType;
|
|
|
|
|
value: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface RuleAction {
|
|
|
|
|
type: RuleActionType;
|
|
|
|
|
value: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MailRule {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
account_id: string;
|
|
|
|
|
priority: number;
|
|
|
|
|
is_active: boolean;
|
|
|
|
|
conditions: RuleCondition[];
|
|
|
|
|
actions: RuleAction[];
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
updated_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MailLabel {
|
|
|
|
|
id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
color: string;
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface PgpKey {
|
|
|
|
|
id: string;
|
|
|
|
|
key_id: string;
|
|
|
|
|
fingerprint: string;
|
|
|
|
|
user_id: string;
|
|
|
|
|
is_private: boolean;
|
|
|
|
|
expires_at: string | null;
|
|
|
|
|
created_at?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ContactPgpKey {
|
|
|
|
|
contact_id: string;
|
|
|
|
|
contact_name: string;
|
|
|
|
|
key_id: string;
|
|
|
|
|
fingerprint: string;
|
|
|
|
|
added_at: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface VacationConfig {
|
|
|
|
|
enabled: boolean;
|
|
|
|
|
start_date: string | null;
|
|
|
|
|
end_date: string | null;
|
|
|
|
|
subject: string;
|
|
|
|
|
body: string;
|
|
|
|
|
dedup_days: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SharedMailboxUser {
|
|
|
|
|
user_id: string;
|
|
|
|
|
user_name: string;
|
|
|
|
|
permissions: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DelegateAccess {
|
|
|
|
|
id: string;
|
|
|
|
|
delegate_user_id: string;
|
|
|
|
|
delegate_user_name: string;
|
|
|
|
|
permissions: string[];
|
|
|
|
|
folder_ids: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SendPermission {
|
|
|
|
|
id: string;
|
|
|
|
|
grantee_user_id: string;
|
|
|
|
|
grantee_user_name: string;
|
|
|
|
|
from_address: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ThreadResult {
|
|
|
|
|
thread_id: string;
|
|
|
|
|
subject: string;
|
|
|
|
|
mails: Mail[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Payloads ──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface CreateAccountPayload {
|
|
|
|
|
email: string;
|
|
|
|
|
display_name: string;
|
|
|
|
|
imap_host: string;
|
|
|
|
|
imap_port: number;
|
|
|
|
|
smtp_host: string;
|
|
|
|
|
smtp_port: number;
|
|
|
|
|
password: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UpdateAccountPayload {
|
|
|
|
|
display_name?: string;
|
|
|
|
|
imap_host?: string;
|
|
|
|
|
imap_port?: number;
|
|
|
|
|
smtp_host?: string;
|
|
|
|
|
smtp_port?: number;
|
|
|
|
|
password?: string;
|
|
|
|
|
is_active?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateFolderPayload {
|
|
|
|
|
account_id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
parent_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UpdateFolderPayload {
|
|
|
|
|
name?: string;
|
|
|
|
|
parent_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SendMailPayload {
|
|
|
|
|
account_id: string;
|
|
|
|
|
to: string[];
|
|
|
|
|
cc?: string[];
|
|
|
|
|
bcc?: string[];
|
|
|
|
|
subject: string;
|
|
|
|
|
body: string;
|
|
|
|
|
is_html: boolean;
|
|
|
|
|
in_reply_to?: string | null;
|
|
|
|
|
attachments?: string[];
|
|
|
|
|
signature_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ReplyPayload {
|
|
|
|
|
account_id: string;
|
|
|
|
|
body: string;
|
|
|
|
|
is_html: boolean;
|
|
|
|
|
to?: string[];
|
|
|
|
|
cc?: string[];
|
|
|
|
|
signature_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ForwardPayload {
|
|
|
|
|
account_id: string;
|
|
|
|
|
to: string[];
|
|
|
|
|
body?: string;
|
|
|
|
|
is_html: boolean;
|
|
|
|
|
signature_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface FlagUpdatePayload {
|
2026-07-15 19:26:37 +02:00
|
|
|
is_seen?: boolean;
|
|
|
|
|
is_flagged?: boolean;
|
|
|
|
|
is_draft?: boolean;
|
|
|
|
|
is_answered?: boolean;
|
|
|
|
|
is_forwarded?: boolean;
|
2026-07-01 20:43:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LinkMailPayload {
|
|
|
|
|
contact_id?: string | null;
|
|
|
|
|
company_id?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateEventFromMailPayload {
|
|
|
|
|
title: string;
|
|
|
|
|
start: string;
|
|
|
|
|
end: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
location?: string;
|
|
|
|
|
calendar_id?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AssignLabelPayload {
|
|
|
|
|
label_id: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateTemplatePayload {
|
|
|
|
|
name: string;
|
|
|
|
|
subject: string;
|
|
|
|
|
body: string;
|
|
|
|
|
variables?: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SubstituteTemplatePayload {
|
|
|
|
|
template_id: string;
|
|
|
|
|
variables: Record<string, string>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SubstituteResult {
|
|
|
|
|
subject: string;
|
|
|
|
|
body: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateSignaturePayload {
|
|
|
|
|
name: string;
|
|
|
|
|
body_html: string;
|
|
|
|
|
is_default?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateRulePayload {
|
|
|
|
|
name: string;
|
|
|
|
|
account_id: string;
|
|
|
|
|
priority: number;
|
|
|
|
|
is_active: boolean;
|
|
|
|
|
conditions: RuleCondition[];
|
|
|
|
|
actions: RuleAction[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateLabelPayload {
|
|
|
|
|
name: string;
|
|
|
|
|
color: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface VacationPayload {
|
|
|
|
|
enabled: boolean;
|
|
|
|
|
start_date: string | null;
|
|
|
|
|
end_date: string | null;
|
|
|
|
|
subject: string;
|
|
|
|
|
body: string;
|
|
|
|
|
dedup_days?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ImportPgpKeyPayload {
|
|
|
|
|
private_key: string;
|
|
|
|
|
passphrase?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface StoreContactPgpKeyPayload {
|
|
|
|
|
public_key: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AssignSharedMailboxUsersPayload {
|
|
|
|
|
user_ids: string[];
|
|
|
|
|
permissions: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateDelegatePayload {
|
|
|
|
|
delegate_user_id: string;
|
|
|
|
|
permissions: string[];
|
|
|
|
|
folder_ids: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface GrantSendPermissionPayload {
|
|
|
|
|
grantee_user_id: string;
|
|
|
|
|
from_address: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Accounts ──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function fetchAccounts(): Promise<MailAccount[]> {
|
|
|
|
|
return apiGet<MailAccount[]>('/mail/accounts');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createAccount(payload: CreateAccountPayload): Promise<MailAccount> {
|
|
|
|
|
return apiPost<MailAccount>('/mail/accounts', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function updateAccount(accountId: string, payload: UpdateAccountPayload): Promise<MailAccount> {
|
|
|
|
|
return apiPatch<MailAccount>(`/mail/accounts/${accountId}`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteAccount(accountId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/mail/accounts/${accountId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchSharedAccounts(): Promise<MailAccount[]> {
|
|
|
|
|
return apiGet<MailAccount[]>('/mail/accounts/shared');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function assignSharedMailboxUsers(accountId: string, payload: AssignSharedMailboxUsersPayload): Promise<void> {
|
|
|
|
|
return apiPost<void>(`/mail/accounts/${accountId}/users`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createDelegate(accountId: string, payload: CreateDelegatePayload): Promise<DelegateAccess> {
|
|
|
|
|
return apiPost<DelegateAccess>(`/mail/accounts/${accountId}/delegates`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function grantSendPermission(accountId: string, payload: GrantSendPermissionPayload): Promise<SendPermission> {
|
|
|
|
|
return apiPost<SendPermission>(`/mail/accounts/${accountId}/send-permissions`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function testConnection(accountId: string): Promise<{ success: boolean; message: string }> {
|
|
|
|
|
return apiPost<{ success: boolean; message: string }>(`/mail/accounts/${accountId}/test-connection`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function triggerSync(accountId: string): Promise<{ success: boolean; synced_count: number }> {
|
|
|
|
|
return apiPost<{ success: boolean; synced_count: number }>(`/mail/accounts/${accountId}/sync`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Folders ────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function fetchFolders(accountId: string): Promise<MailFolder[]> {
|
|
|
|
|
const qs = new URLSearchParams({ account_id: accountId }).toString();
|
|
|
|
|
return apiGet<MailFolder[]>(`/mail/folders?${qs}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createFolder(payload: CreateFolderPayload): Promise<MailFolder> {
|
|
|
|
|
return apiPost<MailFolder>('/mail/folders', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function updateFolder(folderId: string, payload: UpdateFolderPayload): Promise<MailFolder> {
|
|
|
|
|
return apiPatch<MailFolder>(`/mail/folders/${folderId}`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteFolder(folderId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/mail/folders/${folderId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Mails ──────────────────────────────────────────────────────────────────
|
|
|
|
|
|
2026-07-15 20:17:27 +02:00
|
|
|
export function fetchMails(folderId: string, page: number, sortBy?: string, sortOrder?: string): Promise<MailListResult> {
|
|
|
|
|
const params = new URLSearchParams({ folder_id: folderId, page: String(page) });
|
|
|
|
|
if (sortBy) params.set('sort_by', sortBy);
|
|
|
|
|
if (sortOrder) params.set('sort_order', sortOrder);
|
|
|
|
|
return apiGet<MailListResult>(`/mail?${params.toString()}`);
|
2026-07-01 20:43:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getMail(mailId: string): Promise<Mail> {
|
|
|
|
|
return apiGet<Mail>(`/mail/${mailId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function sendMail(payload: SendMailPayload): Promise<{ id: string; success: boolean }> {
|
|
|
|
|
return apiPost<{ id: string; success: boolean }>('/mail/send', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function replyMail(mailId: string, payload: ReplyPayload): Promise<{ id: string; success: boolean }> {
|
|
|
|
|
return apiPost<{ id: string; success: boolean }>(`/mail/${mailId}/reply`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function forwardMail(mailId: string, payload: ForwardPayload): Promise<{ id: string; success: boolean }> {
|
|
|
|
|
return apiPost<{ id: string; success: boolean }>(`/mail/${mailId}/forward`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function updateFlags(mailId: string, payload: FlagUpdatePayload): Promise<void> {
|
|
|
|
|
return apiPatch<void>(`/mail/${mailId}/flags`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function linkMail(mailId: string, payload: LinkMailPayload): Promise<void> {
|
|
|
|
|
return apiPost<void>(`/mail/${mailId}/link`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createEventFromMail(mailId: string, payload: CreateEventFromMailPayload): Promise<{ id: string; success: boolean }> {
|
|
|
|
|
return apiPost<{ id: string; success: boolean }>(`/mail/${mailId}/create-event`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function assignLabel(mailId: string, payload: AssignLabelPayload): Promise<void> {
|
|
|
|
|
return apiPost<void>(`/mail/${mailId}/labels`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Search & Threads ──────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function searchMails(query: string): Promise<MailListResult> {
|
|
|
|
|
const qs = new URLSearchParams({ q: query }).toString();
|
|
|
|
|
return apiGet<MailListResult>(`/mail/search?${qs}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchThreads(accountId: string): Promise<ThreadResult[]> {
|
|
|
|
|
const qs = new URLSearchParams({ account_id: accountId }).toString();
|
|
|
|
|
return apiGet<ThreadResult[]>(`/mail/threads?${qs}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Attachments ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function getAttachmentDownloadUrl(mailId: string, attachmentId: string): string {
|
|
|
|
|
return `/api/v1/mail/${mailId}/attachments/${attachmentId}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function downloadAttachment(mailId: string, attachmentId: string): Promise<Blob> {
|
|
|
|
|
return apiClient.get<Blob>(`/mail/${mailId}/attachments/${attachmentId}`, {
|
|
|
|
|
responseType: 'blob',
|
|
|
|
|
}).then((res) => res.data);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-15 18:43:38 +02:00
|
|
|
export interface UploadedAttachment {
|
|
|
|
|
id: string;
|
|
|
|
|
filename: string;
|
|
|
|
|
mime_type: string;
|
|
|
|
|
size_bytes: number;
|
|
|
|
|
path: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function uploadAttachment(file: File): Promise<UploadedAttachment> {
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append('file', file);
|
|
|
|
|
return apiClient.post<UploadedAttachment>('/mail/upload-attachment', formData, {
|
|
|
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
|
|
}).then((res) => res.data);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-01 20:43:49 +02:00
|
|
|
// ─── Templates ──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function createTemplate(payload: CreateTemplatePayload): Promise<MailTemplate> {
|
|
|
|
|
return apiPost<MailTemplate>('/mail/templates', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchTemplates(): Promise<MailTemplate[]> {
|
|
|
|
|
return apiGet<MailTemplate[]>('/mail/templates');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function substituteTemplate(payload: SubstituteTemplatePayload): Promise<SubstituteResult> {
|
|
|
|
|
return apiPost<SubstituteResult>('/mail/templates/substitute', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Signatures ──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function createSignature(payload: CreateSignaturePayload): Promise<MailSignature> {
|
|
|
|
|
return apiPost<MailSignature>('/mail/signatures', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchSignatures(): Promise<MailSignature[]> {
|
|
|
|
|
return apiGet<MailSignature[]>('/mail/signatures');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteSignature(signatureId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/mail/signatures/${signatureId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function updateSignature(signatureId: string, payload: Partial<CreateSignaturePayload>): Promise<MailSignature> {
|
|
|
|
|
return apiPatch<MailSignature>(`/mail/signatures/${signatureId}`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Rules ───────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function createRule(payload: CreateRulePayload): Promise<MailRule> {
|
|
|
|
|
return apiPost<MailRule>('/mail/rules', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRules(): Promise<MailRule[]> {
|
|
|
|
|
return apiGet<MailRule[]>('/mail/rules');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteRule(ruleId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/mail/rules/${ruleId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Vacation ─────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function configureVacation(payload: VacationPayload): Promise<{ success: boolean }> {
|
|
|
|
|
return apiPost<{ success: boolean }>('/mail/vacation', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function testVacationDedup(): Promise<{ dedup_count: number }> {
|
|
|
|
|
return apiPost<{ dedup_count: number }>('/mail/vacation/test-dedup');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── PGP ──────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function importPgpKey(payload: ImportPgpKeyPayload): Promise<PgpKey> {
|
|
|
|
|
return apiPost<PgpKey>('/mail/pgp/keys', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchPgpKeys(): Promise<PgpKey[]> {
|
|
|
|
|
return apiGet<PgpKey[]>('/mail/pgp/keys');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function encryptMessage(payload: { recipient_key_id: string; message: string }): Promise<{ encrypted: string }> {
|
|
|
|
|
return apiPost<{ encrypted: string }>('/mail/pgp/encrypt', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function storeContactPgpKey(contactId: string, payload: StoreContactPgpKeyPayload): Promise<void> {
|
|
|
|
|
return apiPost<void>(`/mail/contacts/${contactId}/pgp-key`, payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchContactPgpKeys(): Promise<ContactPgpKey[]> {
|
|
|
|
|
return apiGet<ContactPgpKey[]>('/mail/contacts/pgp-keys');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Labels ───────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function createLabel(payload: CreateLabelPayload): Promise<MailLabel> {
|
|
|
|
|
return apiPost<MailLabel>('/mail/labels', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchLabels(): Promise<MailLabel[]> {
|
|
|
|
|
return apiGet<MailLabel[]>('/mail/labels');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteLabel(labelId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/mail/labels/${labelId}`);
|
|
|
|
|
}
|
2026-07-15 19:44:41 +02:00
|
|
|
|
|
|
|
|
// ─── Delete / Move / Drafts ──────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export function deleteMail(mailId: string): Promise<void> {
|
|
|
|
|
return apiDelete<void>(`/mail/${mailId}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function moveMail(mailId: string, targetFolderId: string): Promise<Mail> {
|
|
|
|
|
return apiPost<Mail>(`/mail/${mailId}/move`, { target_folder_id: targetFolderId });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MailDraftPayload {
|
|
|
|
|
account_id: string;
|
|
|
|
|
to: string[];
|
|
|
|
|
cc: string[];
|
|
|
|
|
bcc: string[];
|
|
|
|
|
subject: string;
|
|
|
|
|
body_text: string;
|
|
|
|
|
body_html: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveDraft(payload: MailDraftPayload): Promise<Mail> {
|
|
|
|
|
return apiPost<Mail>('/mail/drafts', payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function updateDraft(mailId: string, payload: MailDraftPayload): Promise<Mail> {
|
|
|
|
|
return apiPatch<Mail>(`/mail/drafts/${mailId}`, payload);
|
|
|
|
|
}
|