import { XMLParser } from "fast-xml-parser"; import { promisify } from "node:util"; import { env } from "node:process"; import { createRequire } from "node:module"; import https from "node:https"; const ntlm: any = createRequire(import.meta.url)("httpntlm"); const postAsync = promisify(ntlm.post.bind(ntlm)); const SSL_OP_LEGACY_SERVER_CONNECT = 0x00000004; const AGENT = new https.Agent({ keepAlive: true, rejectUnauthorized: false, secureOptions: SSL_OP_LEGACY_SERVER_CONNECT, }); const EWS_URL = "https://mail.b1.ru/EWS/Exchange.asmx"; const PARSER = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: "@_", removeNSPrefix: true, textNodeName: "#text", }); function buildSoapEnvelope(body: string): string { return ` ${body} `; } async function ewsSoap(options: { body: string; soapAction: string }): Promise { const res = await postAsync({ url: EWS_URL, username: env.EWS_USERNAME ?? "polina.litvinova", domain: "corp", password: env.EWS_PASSWORD, agent: AGENT, headers: { "Content-Type": "text/xml; charset=utf-8", SOAPAction: options.soapAction, }, body: options.body, }); if (typeof res.body !== "string") { throw new Error(`NTLM request failed, status=${res.statusCode}`); } return PARSER.parse(res.body); } async function getFolder() { const soap = buildSoapEnvelope(`\ IdOnly `); const data = await ewsSoap({ body: soap, soapAction: "http://schemas.microsoft.com/exchange/services/2006/messages/GetFolder", }); const rm = data.Envelope?.Body?.GetFolderResponse?.ResponseMessages; const msg = rm?.GetFolderResponseMessage; const folder = msg?.Folders?.Folder; console.log(`DisplayName: ${folder?.DisplayName}`); console.log(`FolderId: ${folder?.FolderId?.["@_Id"]}`); console.log(`Total items: ${folder?.TotalCount}`); console.log(`Unread: ${folder?.UnreadCount}`); } async function getLastMessages() { const soap = buildSoapEnvelope(`\ AllProperties `); const data = await ewsSoap({ body: soap, soapAction: "http://schemas.microsoft.com/exchange/services/2006/messages/FindItem", }); const rm = data.Envelope?.Body?.FindItemResponse?.ResponseMessages; const msg = rm?.FindItemResponseMessage; const rootFolder = msg?.RootFolder; const items = rootFolder?.Items; const messagesList: any[] = items?.Message ? (Array.isArray(items.Message) ? items.Message : [items.Message]) : []; if (!messagesList.length) { console.log("\n--- No messages found ---"); return; } console.log(`\n--- ${messagesList.length} message(s) ---`); for (const m of messagesList) { const mbox = m.From?.Mailbox; const author = mbox ? `${mbox.Name ?? "(no name)"} <${mbox.EmailAddress ?? "(no email)"}>` : "(unknown)"; console.log(`\nSubject: ${m.Subject ?? "(no subject)"}`); console.log(`From: ${author}`); console.log(`Date: ${m.DateTimeReceived ?? "(unknown)"}`); console.log(`Preview: ${(m.Preview ?? "(no preview)").slice(0, 200)}`); } } async function main() { if (!env.EWS_PASSWORD) { console.error("Set EWS_PASSWORD environment variable"); process.exit(1); } try { await getFolder(); await getLastMessages(); } catch (err) { console.error("Error:", err); process.exit(1); } } main();