refactor: drop skill file, rework client
This commit was merged in pull request #3.
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
export interface Folder {
|
||||
name: string;
|
||||
id: string;
|
||||
totalCount: number;
|
||||
unreadCount: number;
|
||||
childFolderCount: number;
|
||||
}
|
||||
|
||||
type SoapRequest = (body: string, soapAction: string) => Promise<any>;
|
||||
|
||||
export async function extractFolders(
|
||||
soapRequest: SoapRequest,
|
||||
parentFolderId: string,
|
||||
recursive: boolean = false,
|
||||
): Promise<Folder[]> {
|
||||
const DISTINGUISHED_FOLDERS: Record<string, string> = {
|
||||
inbox: "inbox",
|
||||
"входящие": "inbox",
|
||||
sent: "sentitems",
|
||||
"отправленные": "sentitems",
|
||||
drafts: "drafts",
|
||||
"черновики": "drafts",
|
||||
deleted: "deleteditems",
|
||||
"удаленные": "deleteditems",
|
||||
junk: "junkemail",
|
||||
"нежелательная почта": "junkemail",
|
||||
outbox: "outbox",
|
||||
"исходящие": "outbox",
|
||||
calendar: "calendar",
|
||||
"календарь": "calendar",
|
||||
};
|
||||
|
||||
function buildSoapEnvelope(body: string): string {
|
||||
return `<?xml version="1.0" encoding="utf-8"?>
|
||||
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
|
||||
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
|
||||
<s:Body>
|
||||
${body}
|
||||
</s:Body>
|
||||
</s:Envelope>`;
|
||||
}
|
||||
|
||||
function extractResponseMessages(data: any): any[] {
|
||||
const body = data?.Envelope?.Body;
|
||||
if (!body) return [];
|
||||
const firstKey = Object.keys(body).find((k) => k.endsWith("Response"));
|
||||
if (!firstKey) return [];
|
||||
const rm = body[firstKey]?.ResponseMessages;
|
||||
if (!rm) return [];
|
||||
const msgKey = Object.keys(rm).find((k) => k.endsWith("ResponseMessage"));
|
||||
if (!msgKey) return [];
|
||||
const msgs = rm[msgKey];
|
||||
return Array.isArray(msgs) ? msgs : [msgs];
|
||||
}
|
||||
|
||||
const traversal = recursive ? "Deep" : "Shallow";
|
||||
const isDistinguished =
|
||||
DISTINGUISHED_FOLDERS[parentFolderId.toLowerCase()] !== undefined
|
||||
|| ["msgfolderroot"].includes(parentFolderId.toLowerCase());
|
||||
|
||||
const folderIdXml = isDistinguished
|
||||
? `<t:DistinguishedFolderId Id="${parentFolderId}"/>`
|
||||
: `<t:FolderId Id="${parentFolderId}"/>`;
|
||||
|
||||
const soap = buildSoapEnvelope(`\
|
||||
<m:FindFolder Traversal="${traversal}">
|
||||
<m:FolderShape>
|
||||
<t:BaseShape>Default</t:BaseShape>
|
||||
</m:FolderShape>
|
||||
<m:ParentFolderIds>
|
||||
${folderIdXml}
|
||||
</m:ParentFolderIds>
|
||||
<m:IndexedPageFolderView MaxEntriesReturned="200" Offset="0" BasePoint="Beginning"/>
|
||||
</m:FindFolder>`);
|
||||
|
||||
const data = await soapRequest(
|
||||
soap,
|
||||
"http://schemas.microsoft.com/exchange/services/2006/messages/FindFolder",
|
||||
);
|
||||
|
||||
const folders: Folder[] = [];
|
||||
|
||||
for (const msg of extractResponseMessages(data)) {
|
||||
const folderList = msg?.RootFolder?.Folders?.Folder;
|
||||
if (!folderList) continue;
|
||||
const list = Array.isArray(folderList) ? folderList : [folderList];
|
||||
|
||||
for (const f of list) {
|
||||
folders.push({
|
||||
name: f.DisplayName ?? "Unknown",
|
||||
id: f.FolderId?.["@_Id"] ?? "",
|
||||
totalCount: f.TotalCount ?? 0,
|
||||
unreadCount: f.UnreadCount ?? 0,
|
||||
childFolderCount: f.ChildFolderCount ?? 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return folders;
|
||||
}
|
||||
Reference in New Issue
Block a user