@datasynx/agentic-crm 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/cli.js +111 -4
- package/dist/cli.js.map +1 -1
- package/dist/{index-Dspvybo0.d.cts → index-B5_QnkG8.d.cts} +24 -24
- package/dist/index-B5_QnkG8.d.cts.map +1 -0
- package/dist/{index-BBAlKZg6.d.ts → index-FzDsNSSb.d.ts} +3 -3
- package/dist/{index-BBAlKZg6.d.ts.map → index-FzDsNSSb.d.ts.map} +1 -1
- package/dist/index.d.cts +24 -24
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/login-CYgla6-A.js +73 -0
- package/dist/login-CYgla6-A.js.map +1 -0
- package/dist/microsoft-DgbVlHdT.js +159 -0
- package/dist/microsoft-DgbVlHdT.js.map +1 -0
- package/dist/token-resolver-BRLOmRvF.js +50 -0
- package/dist/token-resolver-BRLOmRvF.js.map +1 -0
- package/package.json +1 -1
- package/dist/index-Dspvybo0.d.cts.map +0 -1
package/README.md
CHANGED
|
@@ -243,10 +243,17 @@ right customer by sender/recipient domain** (or to one customer with a slug). On
|
|
|
243
243
|
mailbox connection, all customers populated, same attachment + search pipeline.
|
|
244
244
|
|
|
245
245
|
```bash
|
|
246
|
-
|
|
247
|
-
|
|
246
|
+
# One-time OAuth (Gmail & Microsoft 365 require it for IMAP in 2026):
|
|
247
|
+
dxcrm mailbox login gmail --user you@gmail.com
|
|
248
|
+
dxcrm mailbox login microsoft --user you@org.com
|
|
249
|
+
|
|
250
|
+
# Then auto-route the whole mailbox to customers by domain:
|
|
251
|
+
dxcrm mailbox sync --account gmail:you@gmail.com
|
|
248
252
|
```
|
|
249
253
|
|
|
254
|
+
Tokens are stored locally and auto-refreshed. A password-based IMAP server works too
|
|
255
|
+
(`DXCRM_IMAP_HOST` / `DXCRM_IMAP_USER` / `DXCRM_IMAP_PASS`).
|
|
256
|
+
|
|
250
257
|
<br/>
|
|
251
258
|
|
|
252
259
|
## What it's not
|
package/dist/cli.js
CHANGED
|
@@ -32,6 +32,7 @@ import { createHash } from "crypto";
|
|
|
32
32
|
import Table from "cli-table3";
|
|
33
33
|
import os from "os";
|
|
34
34
|
import { execSync, spawn } from "child_process";
|
|
35
|
+
import readline from "readline";
|
|
35
36
|
//#region src/commands/create.ts
|
|
36
37
|
async function createCustomer(opts) {
|
|
37
38
|
const id = slugify(opts.name, { lower: true });
|
|
@@ -4427,6 +4428,17 @@ complianceCommand.command("status", { isDefault: true }).description("Show the a
|
|
|
4427
4428
|
});
|
|
4428
4429
|
//#endregion
|
|
4429
4430
|
//#region src/commands/mailbox.ts
|
|
4431
|
+
/** Default IMAP endpoints for OAuth providers. */
|
|
4432
|
+
const PROVIDER_IMAP_HOST = {
|
|
4433
|
+
gmail: {
|
|
4434
|
+
host: "imap.gmail.com",
|
|
4435
|
+
port: 993
|
|
4436
|
+
},
|
|
4437
|
+
microsoft: {
|
|
4438
|
+
host: "outlook.office365.com",
|
|
4439
|
+
port: 993
|
|
4440
|
+
}
|
|
4441
|
+
};
|
|
4430
4442
|
/** Read IMAP mailbox connection settings from the environment. */
|
|
4431
4443
|
function imapConfigFromEnv(env = process.env) {
|
|
4432
4444
|
const host = env["DXCRM_IMAP_HOST"];
|
|
@@ -4448,15 +4460,54 @@ function imapConfigFromEnv(env = process.env) {
|
|
|
4448
4460
|
}
|
|
4449
4461
|
};
|
|
4450
4462
|
}
|
|
4463
|
+
/** Parse a "provider:user" account string. */
|
|
4464
|
+
function parseAccount(account) {
|
|
4465
|
+
const idx = account.indexOf(":");
|
|
4466
|
+
if (idx < 0) return null;
|
|
4467
|
+
const provider = account.slice(0, idx);
|
|
4468
|
+
const user = account.slice(idx + 1);
|
|
4469
|
+
if (provider !== "gmail" && provider !== "microsoft" || !user) return null;
|
|
4470
|
+
return {
|
|
4471
|
+
provider,
|
|
4472
|
+
user
|
|
4473
|
+
};
|
|
4474
|
+
}
|
|
4475
|
+
/** Build an IMAP config for a stored OAuth account, refreshing the token if needed. */
|
|
4476
|
+
async function resolveAccountConfig(dataDir, account, env = process.env, mailbox) {
|
|
4477
|
+
const parsed = parseAccount(account);
|
|
4478
|
+
if (!parsed) throw new Error(`Invalid --account '${account}'. Use 'gmail:you@gmail.com' or 'microsoft:you@org.com'.`);
|
|
4479
|
+
const { getFreshAccessToken } = await import("./token-resolver-BRLOmRvF.js");
|
|
4480
|
+
const accessToken = await getFreshAccessToken(dataDir, parsed.provider, parsed.user, { env });
|
|
4481
|
+
const { host, port } = PROVIDER_IMAP_HOST[parsed.provider];
|
|
4482
|
+
return {
|
|
4483
|
+
host,
|
|
4484
|
+
port,
|
|
4485
|
+
secure: true,
|
|
4486
|
+
mailbox: mailbox ?? env["DXCRM_IMAP_MAILBOX"] ?? "INBOX",
|
|
4487
|
+
auth: {
|
|
4488
|
+
user: parsed.user,
|
|
4489
|
+
accessToken
|
|
4490
|
+
}
|
|
4491
|
+
};
|
|
4492
|
+
}
|
|
4451
4493
|
/**
|
|
4452
4494
|
* Sync an IMAP mailbox (any provider). With a slug, all mail goes to that one
|
|
4453
4495
|
* customer; without, mail is auto-routed to customers by sender/recipient
|
|
4454
|
-
* domain and unmatched mail is reported as unrouted.
|
|
4496
|
+
* domain and unmatched mail is reported as unrouted. Use `account` to sync a
|
|
4497
|
+
* stored OAuth mailbox (Gmail/Outlook) instead of env-configured IMAP.
|
|
4455
4498
|
*/
|
|
4456
4499
|
async function runMailboxSync(opts) {
|
|
4457
|
-
const
|
|
4500
|
+
const env = opts.env ?? process.env;
|
|
4501
|
+
let config;
|
|
4502
|
+
try {
|
|
4503
|
+
config = opts.account ? await resolveAccountConfig(opts.dataDir, opts.account, env) : imapConfigFromEnv(env);
|
|
4504
|
+
} catch (err) {
|
|
4505
|
+
const msg = err.message;
|
|
4506
|
+
console.error(error(msg));
|
|
4507
|
+
return { error: msg };
|
|
4508
|
+
}
|
|
4458
4509
|
if (!config) {
|
|
4459
|
-
const msg = "IMAP not configured. Set DXCRM_IMAP_HOST, DXCRM_IMAP_USER and DXCRM_IMAP_PASS (or DXCRM_IMAP_TOKEN).";
|
|
4510
|
+
const msg = "IMAP not configured. Set DXCRM_IMAP_HOST, DXCRM_IMAP_USER and DXCRM_IMAP_PASS (or DXCRM_IMAP_TOKEN), or use --account.";
|
|
4460
4511
|
console.error(error(msg));
|
|
4461
4512
|
return { error: msg };
|
|
4462
4513
|
}
|
|
@@ -4473,11 +4524,67 @@ async function runMailboxSync(opts) {
|
|
|
4473
4524
|
if (!opts.slug && result.unrouted > 0) console.log(info(` ${result.unrouted} message(s) matched no customer. Add their domains via 'dxcrm create <slug> --domain <domain>'.`));
|
|
4474
4525
|
return result;
|
|
4475
4526
|
}
|
|
4527
|
+
function ask(question) {
|
|
4528
|
+
const rl = readline.createInterface({
|
|
4529
|
+
input: process.stdin,
|
|
4530
|
+
output: process.stdout
|
|
4531
|
+
});
|
|
4532
|
+
return new Promise((resolve) => rl.question(question, (a) => (rl.close(), resolve(a))));
|
|
4533
|
+
}
|
|
4534
|
+
/** Interactive `dxcrm mailbox login <provider>` flow. */
|
|
4535
|
+
async function runLogin(provider, user) {
|
|
4536
|
+
const dataDir = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4537
|
+
const print = (l) => console.log(l);
|
|
4538
|
+
if (provider === "gmail") {
|
|
4539
|
+
const clientId = process.env["DXCRM_GOOGLE_CLIENT_ID"];
|
|
4540
|
+
const clientSecret = process.env["DXCRM_GOOGLE_CLIENT_SECRET"];
|
|
4541
|
+
if (!clientId || !clientSecret) {
|
|
4542
|
+
console.error(error("Set DXCRM_GOOGLE_CLIENT_ID and DXCRM_GOOGLE_CLIENT_SECRET (OAuth desktop app)."));
|
|
4543
|
+
return;
|
|
4544
|
+
}
|
|
4545
|
+
const account = user ?? (await ask("Gmail address: ")).trim();
|
|
4546
|
+
const { runGmailLogin } = await import("./login-CYgla6-A.js");
|
|
4547
|
+
await runGmailLogin({
|
|
4548
|
+
dataDir,
|
|
4549
|
+
clientId,
|
|
4550
|
+
clientSecret,
|
|
4551
|
+
user: account,
|
|
4552
|
+
prompt: ask,
|
|
4553
|
+
print
|
|
4554
|
+
});
|
|
4555
|
+
console.log(success(`✓ Gmail authorized for ${bold(account)}. Sync: dxcrm mailbox sync --account gmail:${account}`));
|
|
4556
|
+
return;
|
|
4557
|
+
}
|
|
4558
|
+
if (provider === "microsoft") {
|
|
4559
|
+
const clientId = process.env["DXCRM_MS_CLIENT_ID"];
|
|
4560
|
+
if (!clientId) {
|
|
4561
|
+
console.error(error("Set DXCRM_MS_CLIENT_ID (Azure app registration, public client)."));
|
|
4562
|
+
return;
|
|
4563
|
+
}
|
|
4564
|
+
const tenant = process.env["DXCRM_MS_TENANT"] ?? "common";
|
|
4565
|
+
const account = user ?? (await ask("Outlook/Microsoft address: ")).trim();
|
|
4566
|
+
const { runMicrosoftLogin } = await import("./login-CYgla6-A.js");
|
|
4567
|
+
await runMicrosoftLogin({
|
|
4568
|
+
dataDir,
|
|
4569
|
+
clientId,
|
|
4570
|
+
user: account,
|
|
4571
|
+
tenant,
|
|
4572
|
+
print
|
|
4573
|
+
});
|
|
4574
|
+
console.log(success(`✓ Microsoft authorized for ${bold(account)}. Sync: dxcrm mailbox sync --account microsoft:${account}`));
|
|
4575
|
+
return;
|
|
4576
|
+
}
|
|
4577
|
+
console.error(error(`Unknown provider '${provider}'. Use 'gmail' or 'microsoft'.`));
|
|
4578
|
+
}
|
|
4476
4579
|
const mailboxCommand = new Command("mailbox").description("Sync any IMAP mailbox (Gmail, Outlook, custom) into the CRM");
|
|
4477
|
-
mailboxCommand.command("
|
|
4580
|
+
mailboxCommand.command("login").description("Authorize a Gmail or Microsoft mailbox via OAuth (stores tokens locally)").argument("<provider>", "gmail | microsoft").option("--user <email>", "Mailbox address (otherwise prompted)").action(async (provider, options) => {
|
|
4581
|
+
await runLogin(provider, options.user);
|
|
4582
|
+
});
|
|
4583
|
+
mailboxCommand.command("sync").description("Sync an IMAP mailbox; auto-routes to customers by domain unless a slug is given").argument("[slug]", "Route all mail to this customer (omit to auto-route by domain)").option("--account <provider:user>", "Use a stored OAuth mailbox (e.g. gmail:you@gmail.com)").option("--since <date>", "Only sync messages after this date (YYYY-MM-DD)").option("--no-attachments", "Skip downloading/converting/indexing attachments").action(async (slug, options) => {
|
|
4478
4584
|
await runMailboxSync({
|
|
4479
4585
|
dataDir: process.env["DXCRM_DATA_DIR"] ?? process.cwd(),
|
|
4480
4586
|
slug,
|
|
4587
|
+
...options.account ? { account: options.account } : {},
|
|
4481
4588
|
...options.since ? { since: new Date(options.since) } : {},
|
|
4482
4589
|
includeAttachments: options.attachments !== false
|
|
4483
4590
|
});
|