712 lines
17 KiB
TypeScript
712 lines
17 KiB
TypeScript
import { request } from "#lib/api/client.js";
|
|
import type {
|
|
Account,
|
|
Alert,
|
|
Annotation,
|
|
AvatarHistoryView,
|
|
CallbackView,
|
|
CaptureToggles,
|
|
Chat,
|
|
ChatLinkView,
|
|
DayCount,
|
|
DiscoverItem,
|
|
Folder,
|
|
JobStatus,
|
|
JobView,
|
|
LinkView,
|
|
LoginState,
|
|
MediaVersion,
|
|
MediaView,
|
|
MessageAt,
|
|
MessageVersion,
|
|
MessageView,
|
|
PeerHistoryView,
|
|
PeerView,
|
|
PinnedView,
|
|
PolicyChatKind,
|
|
PolicyCreate,
|
|
PolicyRecord,
|
|
PolicyRule,
|
|
PolicyScope,
|
|
PresenceSample,
|
|
PresenceSession,
|
|
PresenceStats,
|
|
ReactionView,
|
|
ReadInfo,
|
|
ResponseStats,
|
|
ScopeTarget,
|
|
SearchHit,
|
|
StorageChat,
|
|
StorageFile,
|
|
StorageGroupName,
|
|
StorageScope,
|
|
StorageSummary,
|
|
StoryView,
|
|
TrashItem,
|
|
TrashOutcome,
|
|
VolumeBucket,
|
|
Watch,
|
|
WatchedBot,
|
|
} from "#lib/api/types.js";
|
|
import { accounts } from "#lib/stores/accounts.svelte.js";
|
|
|
|
interface Page {
|
|
limit?: number;
|
|
offset?: number;
|
|
}
|
|
|
|
export function listAccounts(): Promise<Account[]> {
|
|
return request<Account[]>("/accounts");
|
|
}
|
|
|
|
export function startLogin(phone: string): Promise<LoginState> {
|
|
return request<LoginState>("/accounts/login", {
|
|
body: { phone },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function startQrLogin(): Promise<LoginState> {
|
|
return request<LoginState>("/accounts/login/qr", { method: "POST" });
|
|
}
|
|
|
|
export function pollQrLogin(loginId: string): Promise<LoginState> {
|
|
return request<LoginState>(`/accounts/login/${loginId}/qr`);
|
|
}
|
|
|
|
export function submitLoginCode(
|
|
loginId: string,
|
|
code: string
|
|
): Promise<LoginState> {
|
|
return request<LoginState>(`/accounts/login/${loginId}/code`, {
|
|
body: { code },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function submitLoginPassword(
|
|
loginId: string,
|
|
password: string
|
|
): Promise<LoginState> {
|
|
return request<LoginState>(`/accounts/login/${loginId}/password`, {
|
|
body: { password },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function cancelLogin(loginId: string): Promise<void> {
|
|
return request<void>(`/accounts/login/${loginId}`, { method: "DELETE" });
|
|
}
|
|
|
|
export function renameAccountDevice(
|
|
accountId: number,
|
|
deviceModel: string
|
|
): Promise<Account> {
|
|
return request<Account>(`/accounts/${accountId}/device`, {
|
|
body: { device_model: deviceModel },
|
|
method: "PATCH",
|
|
});
|
|
}
|
|
|
|
export function logoutAccount(accountId: number): Promise<void> {
|
|
return request<void>(`/accounts/${accountId}`, { method: "DELETE" });
|
|
}
|
|
|
|
interface ChatPage extends Page {
|
|
folder_id?: number;
|
|
search?: string;
|
|
}
|
|
|
|
export function listChats(page: ChatPage = {}): Promise<Chat[]> {
|
|
return request<Chat[]>("/chats", { account: true, query: { ...page } });
|
|
}
|
|
|
|
export function getChat(chatId: number): Promise<Chat | null> {
|
|
return request<Chat | null>(`/chats/${chatId}`, { account: true });
|
|
}
|
|
|
|
export function listFolders(): Promise<Folder[]> {
|
|
return request<Folder[]>("/folders", { account: true });
|
|
}
|
|
|
|
export function listPolicies(): Promise<PolicyRecord[]> {
|
|
return request<PolicyRecord[]>("/policy", { account: true });
|
|
}
|
|
|
|
export function createPolicy(body: PolicyCreate): Promise<PolicyRecord> {
|
|
return request<PolicyRecord>("/policy", {
|
|
body: { ...body, account_id: accounts.selectedId },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function updatePolicy(
|
|
id: number,
|
|
toggles: CaptureToggles
|
|
): Promise<PolicyRecord> {
|
|
return request<PolicyRecord>(`/policy/${id}`, {
|
|
account: true,
|
|
body: toggles,
|
|
method: "PUT",
|
|
});
|
|
}
|
|
|
|
export function deletePolicy(id: number): Promise<void> {
|
|
return request<void>(`/policy/${id}`, { method: "DELETE" });
|
|
}
|
|
|
|
function scopeQuery(target: ScopeTarget): Record<string, number> {
|
|
return "chatId" in target
|
|
? { chat_id: target.chatId }
|
|
: { folder_id: target.folderId };
|
|
}
|
|
|
|
export function getPolicyOverview(): Promise<PolicyRule[]> {
|
|
return request<PolicyRule[]>("/policy/overview", { account: true });
|
|
}
|
|
|
|
export function getPolicyScope(target: ScopeTarget): Promise<PolicyScope> {
|
|
return request<PolicyScope>("/policy/scope", {
|
|
account: true,
|
|
query: scopeQuery(target),
|
|
});
|
|
}
|
|
|
|
export function effectivePolicy(query: {
|
|
chat_id: number;
|
|
is_bot?: boolean;
|
|
is_contact?: boolean | null;
|
|
kind: PolicyChatKind;
|
|
}): Promise<CaptureToggles> {
|
|
return request<CaptureToggles>("/policy/effective", {
|
|
account: true,
|
|
query,
|
|
});
|
|
}
|
|
|
|
export function listMessages(
|
|
chatId: number,
|
|
options: Page & {
|
|
include_deleted?: boolean;
|
|
before_id?: number;
|
|
after_id?: number;
|
|
} = {}
|
|
): Promise<MessageView[]> {
|
|
return request<MessageView[]>(`/chats/${chatId}/messages`, {
|
|
account: true,
|
|
query: { ...options },
|
|
});
|
|
}
|
|
|
|
export function getCurrentPresence(
|
|
peerId: number
|
|
): Promise<PresenceSample | null> {
|
|
return request<PresenceSample | null>("/presence/current", {
|
|
account: true,
|
|
query: { peer_id: peerId },
|
|
});
|
|
}
|
|
|
|
export function getPresenceStats(
|
|
peerId: number,
|
|
days: number,
|
|
tz: string,
|
|
page: Page = {}
|
|
): Promise<PresenceStats> {
|
|
return request<PresenceStats>("/presence/stats", {
|
|
account: true,
|
|
query: { days, peer_id: peerId, tz, ...page },
|
|
});
|
|
}
|
|
|
|
export function getPresenceSessions(
|
|
peerId: number,
|
|
days: number,
|
|
tz: string,
|
|
page: Page = {}
|
|
): Promise<PresenceSession[]> {
|
|
return request<PresenceSession[]>("/presence/sessions", {
|
|
account: true,
|
|
query: { days, peer_id: peerId, tz, ...page },
|
|
});
|
|
}
|
|
|
|
export function getMessageVolume(
|
|
chatId: number,
|
|
days: number,
|
|
tz: string
|
|
): Promise<VolumeBucket[]> {
|
|
return request<VolumeBucket[]>("/analytics/volume", {
|
|
account: true,
|
|
query: { chat_id: chatId, days, tz },
|
|
});
|
|
}
|
|
|
|
export function getResponseStats(chatId: number): Promise<ResponseStats> {
|
|
return request<ResponseStats>("/analytics/response-time", {
|
|
account: true,
|
|
query: { chat_id: chatId },
|
|
});
|
|
}
|
|
|
|
export function getPinned(chatId: number): Promise<PinnedView | null> {
|
|
return request<PinnedView | null>(`/chats/${chatId}/pinned`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function listMessageVersions(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<MessageVersion[]> {
|
|
return request<MessageVersion[]>(
|
|
`/chats/${chatId}/messages/${messageId}/versions`,
|
|
{ account: true }
|
|
);
|
|
}
|
|
|
|
export function listDeleted(
|
|
options: Page & { chat_id?: number } = {}
|
|
): Promise<MessageView[]> {
|
|
return request<MessageView[]>("/deleted", {
|
|
account: true,
|
|
query: { ...options },
|
|
});
|
|
}
|
|
|
|
export function getPeer(peerId: number): Promise<PeerView> {
|
|
return request<PeerView>(`/peers/${peerId}`, { account: true });
|
|
}
|
|
|
|
export function getPeerHistory(peerId: number): Promise<PeerHistoryView[]> {
|
|
return request<PeerHistoryView[]>(`/peers/${peerId}/history`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function getAvatarHistory(
|
|
kind: "peer" | "chat",
|
|
id: number
|
|
): Promise<AvatarHistoryView[]> {
|
|
return request<AvatarHistoryView[]>(`/avatars/${kind}/${id}/history`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function getChatMedia(
|
|
chatId: number,
|
|
kinds: string[],
|
|
page: { limit?: number; offset?: number } = {}
|
|
): Promise<MediaView[]> {
|
|
return request<MediaView[]>(`/chats/${chatId}/media`, {
|
|
account: true,
|
|
query: { kinds: kinds.join(","), ...page },
|
|
});
|
|
}
|
|
|
|
export function getChatLinks(
|
|
chatId: number,
|
|
page: { limit?: number; offset?: number } = {}
|
|
): Promise<ChatLinkView[]> {
|
|
return request<ChatLinkView[]>(`/chats/${chatId}/links`, {
|
|
account: true,
|
|
query: { ...page },
|
|
});
|
|
}
|
|
|
|
export function getReadInfo(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<ReadInfo> {
|
|
return request<ReadInfo>(`/messages/${chatId}/${messageId}/read`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function refreshReadInfo(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<{ job_id: number | null }> {
|
|
return request<{ job_id: number | null }>(
|
|
`/messages/${chatId}/${messageId}/read/refresh`,
|
|
{ body: { account_id: accounts.selectedId }, method: "POST" }
|
|
);
|
|
}
|
|
|
|
export function getMessageReactions(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<ReactionView[]> {
|
|
return request<ReactionView[]>(`/messages/${chatId}/${messageId}/reactions`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function getMessageCallbacks(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<CallbackView[]> {
|
|
return request<CallbackView[]>(`/messages/${chatId}/${messageId}/callbacks`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function getMessageLinks(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<LinkView[]> {
|
|
return request<LinkView[]>(`/messages/${chatId}/${messageId}/links`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function getChatCalendar(
|
|
chatId: number,
|
|
range: { date_from?: string; date_to?: string } = {}
|
|
): Promise<DayCount[]> {
|
|
return request<DayCount[]>(`/chats/${chatId}/calendar`, {
|
|
account: true,
|
|
query: { ...range },
|
|
});
|
|
}
|
|
|
|
export function getMessageAt(chatId: number, date: string): Promise<MessageAt> {
|
|
return request<MessageAt>(`/chats/${chatId}/message-at`, {
|
|
account: true,
|
|
query: { date },
|
|
});
|
|
}
|
|
|
|
export function getStories(
|
|
peerId: number | null,
|
|
page: Page = {}
|
|
): Promise<StoryView[]> {
|
|
return request<StoryView[]>("/stories", {
|
|
account: true,
|
|
query: { peer_id: peerId, ...page },
|
|
});
|
|
}
|
|
|
|
export function getPeers(ids: number[]): Promise<PeerView[]> {
|
|
if (ids.length === 0) {
|
|
return Promise.resolve([]);
|
|
}
|
|
return request<PeerView[]>("/peers/batch", {
|
|
account: true,
|
|
query: { ids: ids.join(",") },
|
|
});
|
|
}
|
|
|
|
export function getChatsBatch(ids: number[]): Promise<Chat[]> {
|
|
if (ids.length === 0) {
|
|
return Promise.resolve([]);
|
|
}
|
|
return request<Chat[]>("/chats/batch", {
|
|
account: true,
|
|
query: { ids: ids.join(",") },
|
|
});
|
|
}
|
|
|
|
export function enrichChat(chatId: number): Promise<{ job_id: number }> {
|
|
return request<{ job_id: number }>(`/chats/${chatId}/enrich`, {
|
|
body: { account_id: accounts.selectedId },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function getJob(jobId: number): Promise<JobView> {
|
|
return request<JobView>(`/jobs/${jobId}`, { account: true });
|
|
}
|
|
|
|
export function cancelJob(jobId: number): Promise<JobView> {
|
|
return request<JobView>(`/jobs/${jobId}/cancel`, { method: "POST" });
|
|
}
|
|
|
|
export function listJobs(status?: JobStatus): Promise<JobView[]> {
|
|
return request<JobView[]>("/jobs", {
|
|
account: true,
|
|
query: status ? { status } : {},
|
|
});
|
|
}
|
|
|
|
export function enqueueBackfill(
|
|
chatId: number,
|
|
media: boolean,
|
|
full = false
|
|
): Promise<{ job_id: number }> {
|
|
return request<{ job_id: number }>("/backfill", {
|
|
body: { account_id: accounts.selectedId, chat_id: chatId, full, media },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function enqueueStoriesBackfill(
|
|
peerId: number
|
|
): Promise<{ job_id: number }> {
|
|
return request<{ job_id: number }>("/stories/backfill", {
|
|
body: { account_id: accounts.selectedId, peer_id: peerId },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function discoverPeers(
|
|
query: string,
|
|
remote = false
|
|
): Promise<DiscoverItem[]> {
|
|
return request<DiscoverItem[]>("/discover", {
|
|
account: true,
|
|
query: { query, remote },
|
|
});
|
|
}
|
|
|
|
export function getDiscoverItem(chatId: number): Promise<DiscoverItem> {
|
|
return request<DiscoverItem>(`/discover/${chatId}`, { account: true });
|
|
}
|
|
|
|
export function trackChat(
|
|
chatId: number,
|
|
backfill = true
|
|
): Promise<DiscoverItem> {
|
|
return request<DiscoverItem>(`/chats/${chatId}/track`, {
|
|
body: { account_id: accounts.selectedId, backfill },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function syncContacts(): Promise<{ job_id: number }> {
|
|
return request<{ job_id: number }>("/contacts/sync", {
|
|
body: { account_id: accounts.selectedId },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function syncDialogs(): Promise<{ job_id: number }> {
|
|
return request<{ job_id: number }>("/dialogs/sync", {
|
|
body: { account_id: accounts.selectedId },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function getMediaVersions(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<MediaVersion[]> {
|
|
return request<MediaVersion[]>(`/media/versions/${chatId}/${messageId}`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function getMediaMeta(mediaId: number): Promise<MediaView> {
|
|
return request<MediaView>(`/media/${mediaId}/meta`);
|
|
}
|
|
|
|
export function getMessageMedia(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<MediaView> {
|
|
return request<MediaView>(`/media/message/${chatId}/${messageId}`, {
|
|
account: true,
|
|
});
|
|
}
|
|
|
|
export function searchMessages(
|
|
query: string,
|
|
options: Page & { chat_id?: number } = {}
|
|
): Promise<SearchHit[]> {
|
|
return request<SearchHit[]>("/search", {
|
|
account: true,
|
|
query: { query, ...options },
|
|
});
|
|
}
|
|
|
|
export function fetchMedia(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<{ job_id: number }> {
|
|
return request<{ job_id: number }>("/media/fetch", {
|
|
body: {
|
|
account_id: accounts.selectedId,
|
|
chat_id: chatId,
|
|
message_id: messageId,
|
|
},
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function transcribeMedia(
|
|
chatId: number,
|
|
messageId: number
|
|
): Promise<{ job_id: number }> {
|
|
return request<{ job_id: number }>("/media/transcribe", {
|
|
body: {
|
|
account_id: accounts.selectedId,
|
|
chat_id: chatId,
|
|
message_id: messageId,
|
|
},
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function listWatches(): Promise<Watch[]> {
|
|
return request<Watch[]>("/watches", { account: true });
|
|
}
|
|
|
|
export function createWatch(
|
|
kind: string,
|
|
params: Record<string, unknown>,
|
|
enabled: boolean
|
|
): Promise<Watch> {
|
|
return request<Watch>("/watches", {
|
|
body: { account_id: accounts.selectedId, enabled, kind, params },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function updateWatch(
|
|
id: number,
|
|
params: Record<string, unknown>,
|
|
enabled: boolean
|
|
): Promise<Watch> {
|
|
return request<Watch>(`/watches/${id}`, {
|
|
body: { enabled, params },
|
|
method: "PUT",
|
|
});
|
|
}
|
|
|
|
export function deleteWatch(id: number): Promise<void> {
|
|
return request<void>(`/watches/${id}`, { method: "DELETE" });
|
|
}
|
|
|
|
export function listAlerts(
|
|
options: Page & { seen?: boolean } = {}
|
|
): Promise<Alert[]> {
|
|
return request<Alert[]>("/alerts", { account: true, query: { ...options } });
|
|
}
|
|
|
|
export function markAlertSeen(id: number): Promise<void> {
|
|
return request<void>(`/alerts/${id}/seen`, { method: "POST" });
|
|
}
|
|
|
|
export function listAnnotations(
|
|
options: { chatId?: number; messageId?: number } = {}
|
|
): Promise<Annotation[]> {
|
|
return request<Annotation[]>("/annotations", {
|
|
account: true,
|
|
query: { chat_id: options.chatId, message_id: options.messageId },
|
|
});
|
|
}
|
|
|
|
export function createAnnotation(
|
|
chatId: number,
|
|
messageId: number,
|
|
text: string
|
|
): Promise<Annotation> {
|
|
return request<Annotation>("/annotations", {
|
|
body: {
|
|
account_id: accounts.selectedId,
|
|
chat_id: chatId,
|
|
message_id: messageId,
|
|
text,
|
|
},
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function updateAnnotation(
|
|
id: number,
|
|
text: string
|
|
): Promise<Annotation> {
|
|
return request<Annotation>(`/annotations/${id}`, {
|
|
body: { text },
|
|
method: "PUT",
|
|
});
|
|
}
|
|
|
|
export function deleteAnnotation(id: number): Promise<void> {
|
|
return request<void>(`/annotations/${id}`, { method: "DELETE" });
|
|
}
|
|
|
|
export function listWatchedBots(): Promise<WatchedBot[]> {
|
|
return request<WatchedBot[]>("/bots");
|
|
}
|
|
|
|
export function addWatchedBot(token: string): Promise<WatchedBot> {
|
|
return request<WatchedBot>("/bots", { body: { token }, method: "POST" });
|
|
}
|
|
|
|
export function removeWatchedBot(botId: number): Promise<void> {
|
|
return request<void>(`/bots/${botId}`, { method: "DELETE" });
|
|
}
|
|
|
|
export function getStorageSummary(
|
|
chatId: number | null = null
|
|
): Promise<StorageSummary> {
|
|
return request<StorageSummary>("/storage/summary", {
|
|
account: true,
|
|
query: { chat_id: chatId },
|
|
});
|
|
}
|
|
|
|
export function getStorageFiles(
|
|
group: StorageGroupName | null,
|
|
page: Page = {},
|
|
chatId: number | null = null
|
|
): Promise<StorageFile[]> {
|
|
return request<StorageFile[]>("/storage/files", {
|
|
account: true,
|
|
query: { chat_id: chatId, group, ...page },
|
|
});
|
|
}
|
|
|
|
export function getStorageChats(
|
|
group: StorageGroupName | null,
|
|
page: Page = {}
|
|
): Promise<StorageChat[]> {
|
|
return request<StorageChat[]>("/storage/chats", {
|
|
account: true,
|
|
query: { group, ...page },
|
|
});
|
|
}
|
|
|
|
export function getTrash(page: Page = {}): Promise<TrashItem[]> {
|
|
return request<TrashItem[]>("/storage/trash", {
|
|
account: true,
|
|
query: { ...page },
|
|
});
|
|
}
|
|
|
|
export function getStorageScope(target: ScopeTarget): Promise<StorageScope> {
|
|
return request<StorageScope>("/storage/scope", {
|
|
account: true,
|
|
query: scopeQuery(target),
|
|
});
|
|
}
|
|
|
|
export function trashScope(target: ScopeTarget): Promise<TrashOutcome> {
|
|
return request<TrashOutcome>("/storage/trash/scope", {
|
|
body: { account_id: accounts.selectedId, ...scopeQuery(target) },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function moveToTrash(mediaIds: number[]): Promise<TrashOutcome> {
|
|
return request<TrashOutcome>("/storage/trash", {
|
|
body: { account_id: accounts.selectedId, media_ids: mediaIds },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function restoreFromTrash(keys: string[] | null): Promise<TrashOutcome> {
|
|
return request<TrashOutcome>("/storage/trash/restore", {
|
|
body: { account_id: accounts.selectedId, keys },
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export function purgeTrash(keys: string[] | null): Promise<TrashOutcome> {
|
|
return request<TrashOutcome>("/storage/trash/purge", {
|
|
body: { account_id: accounts.selectedId, keys },
|
|
method: "POST",
|
|
});
|
|
}
|