@chanl/cli 3.0.0 → 3.1.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/dist/__tests__/cli-p0-scenarios.test.d.ts +2 -0
- package/dist/__tests__/cli-p0-scenarios.test.js +123 -0
- package/dist/__tests__/cli-p0-scenarios.test.js.map +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/agents.js +98 -0
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/customers.d.ts +8 -0
- package/dist/commands/customers.js +289 -0
- package/dist/commands/customers.js.map +1 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/messaging.d.ts +12 -0
- package/dist/commands/messaging.js +208 -0
- package/dist/commands/messaging.js.map +1 -0
- package/dist/commands/scenarios.js +121 -0
- package/dist/commands/scenarios.js.map +1 -1
- package/dist/commands/whatsapp.d.ts +8 -0
- package/dist/commands/whatsapp.js +332 -0
- package/dist/commands/whatsapp.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { readFileSync } from "fs";
|
|
4
|
+
import { createSdk } from "../utils/sdk-factory.js";
|
|
5
|
+
import {
|
|
6
|
+
printError,
|
|
7
|
+
printSuccess,
|
|
8
|
+
printInfo,
|
|
9
|
+
printBlank,
|
|
10
|
+
printSimpleTable,
|
|
11
|
+
printLabel,
|
|
12
|
+
isJsonOutput,
|
|
13
|
+
printJson,
|
|
14
|
+
formatDate
|
|
15
|
+
} from "../utils/output.js";
|
|
16
|
+
function createCustomersCommand() {
|
|
17
|
+
const customers = new Command("customers").description("Manage the customer record \u2014 the profile every conversation attaches to").addHelpText(
|
|
18
|
+
"after",
|
|
19
|
+
`
|
|
20
|
+
What are Customers?
|
|
21
|
+
The customer record is Chanl's primary surface: every conversation
|
|
22
|
+
(voice, chat, WhatsApp) attaches to a customer. Records carry contact
|
|
23
|
+
info, sourced attributes, and channel identities.
|
|
24
|
+
|
|
25
|
+
Quick Start:
|
|
26
|
+
$ chanl customers list # List customers
|
|
27
|
+
$ chanl customers list --search dean # Free-text search
|
|
28
|
+
$ chanl customers get <id> # View a record
|
|
29
|
+
$ chanl customers create --phone +14155551234 --first-name Dean
|
|
30
|
+
$ chanl customers resolve --phone +14155551234 # Find-or-create by phone/email
|
|
31
|
+
$ chanl customers delete <id> # Delete a record`
|
|
32
|
+
);
|
|
33
|
+
customers.command("list").description("List customers in the workspace").option("-s, --search <text>", "Free-text search (name, phone, email)").option("--limit <number>", "Number of items per page", "20").option("-p, --page <number>", "Page number", "1").addHelpText(
|
|
34
|
+
"after",
|
|
35
|
+
`
|
|
36
|
+
Examples:
|
|
37
|
+
$ chanl customers list # First page
|
|
38
|
+
$ chanl customers list --search dean # Search by name/phone/email
|
|
39
|
+
$ chanl customers list --json # Output as JSON`
|
|
40
|
+
).action(handleCustomersList);
|
|
41
|
+
customers.command("get <id>").description("Get customer details").action(handleCustomersGet);
|
|
42
|
+
customers.command("create").description("Create a customer").option("--first-name <name>", "First name").option("--last-name <name>", "Last name").option("--email <email>", "Email address").option("--phone <e164>", "Phone number in E.164 format (+14155551234)").option("--agent <agentId>", "Route this customer to a specific agent").option("-f, --file <path>", "Path to JSON file with customer data (overrides flags)").addHelpText(
|
|
43
|
+
"after",
|
|
44
|
+
`
|
|
45
|
+
Examples:
|
|
46
|
+
$ chanl customers create --phone +14155551234 --first-name Dean
|
|
47
|
+
$ chanl customers create -f customer.json`
|
|
48
|
+
).action(handleCustomersCreate);
|
|
49
|
+
customers.command("update <id>").description("Update a customer").option("--first-name <name>", "First name").option("--last-name <name>", "Last name").option("--email <email>", "Email address").option("--phone <e164>", "Phone number in E.164 format").option("--agent <agentId>", "Route this customer to a specific agent").option("-f, --file <path>", "Path to JSON file with fields to update (overrides flags)").action(handleCustomersUpdate);
|
|
50
|
+
customers.command("resolve").description("Resolve by phone/email \u2014 returns existing customer or creates one").option("--phone <e164>", "Phone number in E.164 format").option("--email <email>", "Email address").option("--first-name <name>", "First name (used only on create)").option("--last-name <name>", "Last name (used only on create)").addHelpText(
|
|
51
|
+
"after",
|
|
52
|
+
`
|
|
53
|
+
Examples:
|
|
54
|
+
$ chanl customers resolve --phone +14155551234
|
|
55
|
+
$ chanl customers resolve --email dean@example.com --first-name Dean`
|
|
56
|
+
).action(handleCustomersResolve);
|
|
57
|
+
customers.command("delete <id>").description("Delete a customer").action(handleCustomersDelete);
|
|
58
|
+
return customers;
|
|
59
|
+
}
|
|
60
|
+
function customerDisplayName(c) {
|
|
61
|
+
const name = [c.firstName, c.lastName].filter(Boolean).join(" ");
|
|
62
|
+
return name || c.displayName || "-";
|
|
63
|
+
}
|
|
64
|
+
async function handleCustomersList(options) {
|
|
65
|
+
const sdk = createSdk();
|
|
66
|
+
if (!sdk) return;
|
|
67
|
+
const spinner = ora("Fetching customers...").start();
|
|
68
|
+
try {
|
|
69
|
+
const response = await sdk.customers.list({
|
|
70
|
+
search: options.search,
|
|
71
|
+
limit: parseInt(options.limit, 10),
|
|
72
|
+
page: parseInt(options.page, 10)
|
|
73
|
+
});
|
|
74
|
+
spinner.stop();
|
|
75
|
+
if (!response.success || !response.data) {
|
|
76
|
+
printError("Failed to fetch customers", response.message);
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const { data: customers, pagination } = response.data;
|
|
81
|
+
if (isJsonOutput()) {
|
|
82
|
+
printJson(response.data);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (customers.length === 0) {
|
|
86
|
+
printInfo("No customers found");
|
|
87
|
+
printInfo("Use 'chanl customers create' or 'chanl customers resolve' to add one");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
printBlank();
|
|
91
|
+
printSimpleTable(
|
|
92
|
+
["ID", "Name", "Phone", "Email", "Type", "Last seen"],
|
|
93
|
+
customers.map((c) => [
|
|
94
|
+
c.id.slice(-12),
|
|
95
|
+
customerDisplayName(c).slice(0, 24),
|
|
96
|
+
c.phoneNumber || "-",
|
|
97
|
+
(c.email || "-").slice(0, 28),
|
|
98
|
+
c.contactType || "-",
|
|
99
|
+
c.lastSeenAt ? formatDate(c.lastSeenAt) : "-"
|
|
100
|
+
])
|
|
101
|
+
);
|
|
102
|
+
printBlank();
|
|
103
|
+
if (pagination) {
|
|
104
|
+
printInfo(`Total: ${pagination.total} customers (Page ${pagination.page} of ${pagination.totalPages})`);
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
spinner.fail("Failed to fetch customers");
|
|
108
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
109
|
+
printError("Error", message);
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function handleCustomersGet(id) {
|
|
114
|
+
const sdk = createSdk();
|
|
115
|
+
if (!sdk) return;
|
|
116
|
+
const spinner = ora("Fetching customer...").start();
|
|
117
|
+
try {
|
|
118
|
+
const response = await sdk.customers.get(id);
|
|
119
|
+
spinner.stop();
|
|
120
|
+
if (!response.success || !response.data) {
|
|
121
|
+
printError("Failed to fetch customer", response.message);
|
|
122
|
+
process.exitCode = 1;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (isJsonOutput()) {
|
|
126
|
+
printJson(response.data);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const c = response.data;
|
|
130
|
+
printBlank();
|
|
131
|
+
printLabel("ID", c.id);
|
|
132
|
+
printLabel("Name", customerDisplayName(c));
|
|
133
|
+
printLabel("Phone", c.phoneNumber || "-");
|
|
134
|
+
printLabel("Email", c.email || "-");
|
|
135
|
+
printLabel("Type", c.contactType || "-");
|
|
136
|
+
printLabel("Agent override", c.agentId || "-");
|
|
137
|
+
printLabel("Language", c.language || "-");
|
|
138
|
+
printLabel("Last seen", c.lastSeenAt ? formatDate(c.lastSeenAt) : "-");
|
|
139
|
+
printLabel("Created", formatDate(c.createdAt));
|
|
140
|
+
if (c.customAttributes && Object.keys(c.customAttributes).length > 0) {
|
|
141
|
+
printBlank();
|
|
142
|
+
printInfo("Attributes:");
|
|
143
|
+
for (const [key, value] of Object.entries(c.customAttributes)) {
|
|
144
|
+
printLabel(` ${key}`, typeof value === "object" ? JSON.stringify(value) : String(value));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
printBlank();
|
|
148
|
+
} catch (error) {
|
|
149
|
+
spinner.fail("Failed to fetch customer");
|
|
150
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
151
|
+
printError("Error", message);
|
|
152
|
+
process.exitCode = 1;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function customerDataFromOptions(options) {
|
|
156
|
+
if (options.file) {
|
|
157
|
+
return JSON.parse(readFileSync(options.file, "utf-8"));
|
|
158
|
+
}
|
|
159
|
+
const data = {};
|
|
160
|
+
if (options.firstName) data.firstName = options.firstName;
|
|
161
|
+
if (options.lastName) data.lastName = options.lastName;
|
|
162
|
+
if (options.email) data.email = options.email;
|
|
163
|
+
if (options.phone) data.phoneNumber = options.phone;
|
|
164
|
+
if (options.agent) data.agentId = options.agent;
|
|
165
|
+
return data;
|
|
166
|
+
}
|
|
167
|
+
async function handleCustomersCreate(options) {
|
|
168
|
+
const sdk = createSdk();
|
|
169
|
+
if (!sdk) return;
|
|
170
|
+
const data = customerDataFromOptions(options);
|
|
171
|
+
if (Object.keys(data).length === 0) {
|
|
172
|
+
printError("Nothing to create", "Provide --phone/--email/--first-name flags or -f <file>");
|
|
173
|
+
process.exitCode = 1;
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const spinner = ora("Creating customer...").start();
|
|
177
|
+
try {
|
|
178
|
+
const response = await sdk.customers.create(data);
|
|
179
|
+
spinner.stop();
|
|
180
|
+
if (!response.success || !response.data) {
|
|
181
|
+
printError("Failed to create customer", response.message);
|
|
182
|
+
process.exitCode = 1;
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (isJsonOutput()) {
|
|
186
|
+
printJson(response.data);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
printSuccess(`Customer created: ${response.data.id}`);
|
|
190
|
+
printInfo(`View it: chanl customers get ${response.data.id}`);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
spinner.fail("Failed to create customer");
|
|
193
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
194
|
+
printError("Error", message);
|
|
195
|
+
process.exitCode = 1;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async function handleCustomersUpdate(id, options) {
|
|
199
|
+
const sdk = createSdk();
|
|
200
|
+
if (!sdk) return;
|
|
201
|
+
const data = customerDataFromOptions(options);
|
|
202
|
+
if (Object.keys(data).length === 0) {
|
|
203
|
+
printError("Nothing to update", "Provide flags or -f <file>");
|
|
204
|
+
process.exitCode = 1;
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const spinner = ora("Updating customer...").start();
|
|
208
|
+
try {
|
|
209
|
+
const response = await sdk.customers.update(id, data);
|
|
210
|
+
spinner.stop();
|
|
211
|
+
if (!response.success || !response.data) {
|
|
212
|
+
printError("Failed to update customer", response.message);
|
|
213
|
+
process.exitCode = 1;
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (isJsonOutput()) {
|
|
217
|
+
printJson(response.data);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
printSuccess(`Customer updated: ${id}`);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
spinner.fail("Failed to update customer");
|
|
223
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
224
|
+
printError("Error", message);
|
|
225
|
+
process.exitCode = 1;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async function handleCustomersResolve(options) {
|
|
229
|
+
const sdk = createSdk();
|
|
230
|
+
if (!sdk) return;
|
|
231
|
+
if (!options.phone && !options.email) {
|
|
232
|
+
printError("Phone or email required", "Use --phone +E164 or --email");
|
|
233
|
+
process.exitCode = 1;
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const spinner = ora("Resolving customer...").start();
|
|
237
|
+
try {
|
|
238
|
+
const response = await sdk.customers.resolve({
|
|
239
|
+
phone: options.phone,
|
|
240
|
+
email: options.email,
|
|
241
|
+
firstName: options.firstName,
|
|
242
|
+
lastName: options.lastName
|
|
243
|
+
});
|
|
244
|
+
spinner.stop();
|
|
245
|
+
if (!response.success || !response.data) {
|
|
246
|
+
printError("Failed to resolve customer", response.message);
|
|
247
|
+
process.exitCode = 1;
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (isJsonOutput()) {
|
|
251
|
+
printJson(response.data);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const { customer, created } = response.data;
|
|
255
|
+
printSuccess(
|
|
256
|
+
created ? `Customer created: ${customer.id}` : `Existing customer: ${customer.id} (${customerDisplayName(customer)})`
|
|
257
|
+
);
|
|
258
|
+
printInfo(`View it: chanl customers get ${customer.id}`);
|
|
259
|
+
} catch (error) {
|
|
260
|
+
spinner.fail("Failed to resolve customer");
|
|
261
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
262
|
+
printError("Error", message);
|
|
263
|
+
process.exitCode = 1;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async function handleCustomersDelete(id) {
|
|
267
|
+
const sdk = createSdk();
|
|
268
|
+
if (!sdk) return;
|
|
269
|
+
const spinner = ora("Deleting customer...").start();
|
|
270
|
+
try {
|
|
271
|
+
const response = await sdk.customers.delete(id);
|
|
272
|
+
spinner.stop();
|
|
273
|
+
if (!response.success) {
|
|
274
|
+
printError("Failed to delete customer", response.message);
|
|
275
|
+
process.exitCode = 1;
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
printSuccess(`Customer deleted: ${id}`);
|
|
279
|
+
} catch (error) {
|
|
280
|
+
spinner.fail("Failed to delete customer");
|
|
281
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
282
|
+
printError("Error", message);
|
|
283
|
+
process.exitCode = 1;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
export {
|
|
287
|
+
createCustomersCommand
|
|
288
|
+
};
|
|
289
|
+
//# sourceMappingURL=customers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commands/customers.ts"],"sourcesContent":["import { Command } from 'commander';\nimport ora from 'ora';\nimport { readFileSync } from 'fs';\nimport type { Customer, CreateCustomerData } from '@chanl/sdk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printError,\n printSuccess,\n printInfo,\n printBlank,\n printSimpleTable,\n printLabel,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n/**\n * Create the customers command group\n */\nexport function createCustomersCommand(): Command {\n const customers = new Command('customers')\n .description('Manage the customer record — the profile every conversation attaches to')\n .addHelpText(\n 'after',\n `\nWhat are Customers?\n The customer record is Chanl's primary surface: every conversation\n (voice, chat, WhatsApp) attaches to a customer. Records carry contact\n info, sourced attributes, and channel identities.\n\nQuick Start:\n $ chanl customers list # List customers\n $ chanl customers list --search dean # Free-text search\n $ chanl customers get <id> # View a record\n $ chanl customers create --phone +14155551234 --first-name Dean\n $ chanl customers resolve --phone +14155551234 # Find-or-create by phone/email\n $ chanl customers delete <id> # Delete a record`\n );\n\n // customers list\n customers\n .command('list')\n .description('List customers in the workspace')\n .option('-s, --search <text>', 'Free-text search (name, phone, email)')\n .option('--limit <number>', 'Number of items per page', '20')\n .option('-p, --page <number>', 'Page number', '1')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl customers list # First page\n $ chanl customers list --search dean # Search by name/phone/email\n $ chanl customers list --json # Output as JSON`\n )\n .action(handleCustomersList);\n\n // customers get <id>\n customers\n .command('get <id>')\n .description('Get customer details')\n .action(handleCustomersGet);\n\n // customers create\n customers\n .command('create')\n .description('Create a customer')\n .option('--first-name <name>', 'First name')\n .option('--last-name <name>', 'Last name')\n .option('--email <email>', 'Email address')\n .option('--phone <e164>', 'Phone number in E.164 format (+14155551234)')\n .option('--agent <agentId>', 'Route this customer to a specific agent')\n .option('-f, --file <path>', 'Path to JSON file with customer data (overrides flags)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl customers create --phone +14155551234 --first-name Dean\n $ chanl customers create -f customer.json`\n )\n .action(handleCustomersCreate);\n\n // customers update <id>\n customers\n .command('update <id>')\n .description('Update a customer')\n .option('--first-name <name>', 'First name')\n .option('--last-name <name>', 'Last name')\n .option('--email <email>', 'Email address')\n .option('--phone <e164>', 'Phone number in E.164 format')\n .option('--agent <agentId>', 'Route this customer to a specific agent')\n .option('-f, --file <path>', 'Path to JSON file with fields to update (overrides flags)')\n .action(handleCustomersUpdate);\n\n // customers resolve\n customers\n .command('resolve')\n .description('Resolve by phone/email — returns existing customer or creates one')\n .option('--phone <e164>', 'Phone number in E.164 format')\n .option('--email <email>', 'Email address')\n .option('--first-name <name>', 'First name (used only on create)')\n .option('--last-name <name>', 'Last name (used only on create)')\n .addHelpText(\n 'after',\n `\nExamples:\n $ chanl customers resolve --phone +14155551234\n $ chanl customers resolve --email dean@example.com --first-name Dean`\n )\n .action(handleCustomersResolve);\n\n // customers delete <id>\n customers\n .command('delete <id>')\n .description('Delete a customer')\n .action(handleCustomersDelete);\n\n return customers;\n}\n\nfunction customerDisplayName(c: Customer): string {\n const name = [c.firstName, c.lastName].filter(Boolean).join(' ');\n return name || c.displayName || '-';\n}\n\nasync function handleCustomersList(options: {\n search?: string;\n limit: string;\n page: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching customers...').start();\n\n try {\n const response = await sdk.customers.list({\n search: options.search,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n });\n\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch customers', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { data: customers, pagination } = response.data;\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n if (customers.length === 0) {\n printInfo('No customers found');\n printInfo(\"Use 'chanl customers create' or 'chanl customers resolve' to add one\");\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Name', 'Phone', 'Email', 'Type', 'Last seen'],\n customers.map((c: Customer) => [\n c.id.slice(-12),\n customerDisplayName(c).slice(0, 24),\n c.phoneNumber || '-',\n (c.email || '-').slice(0, 28),\n c.contactType || '-',\n c.lastSeenAt ? formatDate(c.lastSeenAt) : '-',\n ])\n );\n\n printBlank();\n if (pagination) {\n printInfo(`Total: ${pagination.total} customers (Page ${pagination.page} of ${pagination.totalPages})`);\n }\n } catch (error) {\n spinner.fail('Failed to fetch customers');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nasync function handleCustomersGet(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching customer...').start();\n\n try {\n const response = await sdk.customers.get(id);\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch customer', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const c = response.data;\n printBlank();\n printLabel('ID', c.id);\n printLabel('Name', customerDisplayName(c));\n printLabel('Phone', c.phoneNumber || '-');\n printLabel('Email', c.email || '-');\n printLabel('Type', c.contactType || '-');\n printLabel('Agent override', c.agentId || '-');\n printLabel('Language', c.language || '-');\n printLabel('Last seen', c.lastSeenAt ? formatDate(c.lastSeenAt) : '-');\n printLabel('Created', formatDate(c.createdAt));\n if (c.customAttributes && Object.keys(c.customAttributes).length > 0) {\n printBlank();\n printInfo('Attributes:');\n for (const [key, value] of Object.entries(c.customAttributes)) {\n printLabel(` ${key}`, typeof value === 'object' ? JSON.stringify(value) : String(value));\n }\n }\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch customer');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nfunction customerDataFromOptions(options: {\n firstName?: string;\n lastName?: string;\n email?: string;\n phone?: string;\n agent?: string;\n file?: string;\n}): CreateCustomerData {\n if (options.file) {\n return JSON.parse(readFileSync(options.file, 'utf-8')) as CreateCustomerData;\n }\n const data: CreateCustomerData = {};\n if (options.firstName) data.firstName = options.firstName;\n if (options.lastName) data.lastName = options.lastName;\n if (options.email) data.email = options.email;\n if (options.phone) data.phoneNumber = options.phone;\n if (options.agent) data.agentId = options.agent;\n return data;\n}\n\nasync function handleCustomersCreate(options: {\n firstName?: string;\n lastName?: string;\n email?: string;\n phone?: string;\n agent?: string;\n file?: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const data = customerDataFromOptions(options);\n if (Object.keys(data).length === 0) {\n printError('Nothing to create', 'Provide --phone/--email/--first-name flags or -f <file>');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Creating customer...').start();\n\n try {\n const response = await sdk.customers.create(data);\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to create customer', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n printSuccess(`Customer created: ${response.data.id}`);\n printInfo(`View it: chanl customers get ${response.data.id}`);\n } catch (error) {\n spinner.fail('Failed to create customer');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nasync function handleCustomersUpdate(\n id: string,\n options: {\n firstName?: string;\n lastName?: string;\n email?: string;\n phone?: string;\n agent?: string;\n file?: string;\n }\n): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const data = customerDataFromOptions(options);\n if (Object.keys(data).length === 0) {\n printError('Nothing to update', 'Provide flags or -f <file>');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Updating customer...').start();\n\n try {\n const response = await sdk.customers.update(id, data);\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to update customer', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n printSuccess(`Customer updated: ${id}`);\n } catch (error) {\n spinner.fail('Failed to update customer');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nasync function handleCustomersResolve(options: {\n phone?: string;\n email?: string;\n firstName?: string;\n lastName?: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n if (!options.phone && !options.email) {\n printError('Phone or email required', 'Use --phone +E164 or --email');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Resolving customer...').start();\n\n try {\n const response = await sdk.customers.resolve({\n phone: options.phone,\n email: options.email,\n firstName: options.firstName,\n lastName: options.lastName,\n });\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to resolve customer', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const { customer, created } = response.data;\n printSuccess(\n created\n ? `Customer created: ${customer.id}`\n : `Existing customer: ${customer.id} (${customerDisplayName(customer)})`\n );\n printInfo(`View it: chanl customers get ${customer.id}`);\n } catch (error) {\n spinner.fail('Failed to resolve customer');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n\nasync function handleCustomersDelete(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Deleting customer...').start();\n\n try {\n const response = await sdk.customers.delete(id);\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to delete customer', response.message);\n process.exitCode = 1;\n return;\n }\n\n printSuccess(`Customer deleted: ${id}`);\n } catch (error) {\n spinner.fail('Failed to delete customer');\n const message = error instanceof Error ? error.message : 'Unknown error';\n printError('Error', message);\n process.exitCode = 1;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export { createScenariosCommand } from './scenarios.js';
|
|
|
6
6
|
export { createCallCommand } from './call.js';
|
|
7
7
|
export { createCallsCommand } from './calls.js';
|
|
8
8
|
export { createPersonasCommand } from './personas.js';
|
|
9
|
+
export { createCustomersCommand } from './customers.js';
|
|
10
|
+
export { createConversationsCommand, createMessagesCommand } from './messaging.js';
|
|
11
|
+
export { createWhatsAppCommand } from './whatsapp.js';
|
|
9
12
|
export { createAgentsCommand } from './agents.js';
|
|
10
13
|
export { createHealthCommand } from './health.js';
|
|
11
14
|
export { createMcpCommand } from './mcp.js';
|
package/dist/commands/index.js
CHANGED
|
@@ -6,6 +6,9 @@ import { createScenariosCommand } from "./scenarios.js";
|
|
|
6
6
|
import { createCallCommand } from "./call.js";
|
|
7
7
|
import { createCallsCommand } from "./calls.js";
|
|
8
8
|
import { createPersonasCommand } from "./personas.js";
|
|
9
|
+
import { createCustomersCommand } from "./customers.js";
|
|
10
|
+
import { createConversationsCommand, createMessagesCommand } from "./messaging.js";
|
|
11
|
+
import { createWhatsAppCommand } from "./whatsapp.js";
|
|
9
12
|
import { createAgentsCommand } from "./agents.js";
|
|
10
13
|
import { createHealthCommand } from "./health.js";
|
|
11
14
|
import { createMcpCommand } from "./mcp.js";
|
|
@@ -22,18 +25,22 @@ export {
|
|
|
22
25
|
createCallsCommand,
|
|
23
26
|
createChatCommand,
|
|
24
27
|
createConfigCommand,
|
|
28
|
+
createConversationsCommand,
|
|
29
|
+
createCustomersCommand,
|
|
25
30
|
createHealthCommand,
|
|
26
31
|
createKnowledgeCommand,
|
|
27
32
|
createLoginCommand,
|
|
28
33
|
createLogoutCommand,
|
|
29
34
|
createMcpCommand,
|
|
30
35
|
createMemoryCommand,
|
|
36
|
+
createMessagesCommand,
|
|
31
37
|
createPersonasCommand,
|
|
32
38
|
createPromptsCommand,
|
|
33
39
|
createScenariosCommand,
|
|
34
40
|
createScorecardsCommand,
|
|
35
41
|
createToolsCommand,
|
|
36
42
|
createToolsetsCommand,
|
|
43
|
+
createWhatsAppCommand,
|
|
37
44
|
createWorkspacesCommand
|
|
38
45
|
};
|
|
39
46
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/index.ts"],"sourcesContent":["/**\n * Command exports for the Chanl CLI\n */\n\nexport { createAuthCommand, createLoginCommand, createLogoutCommand } from './auth.js';\nexport { createConfigCommand } from './config.js';\nexport { createToolsCommand } from './tools.js';\nexport { createToolsetsCommand } from './toolsets.js';\nexport { createScenariosCommand } from './scenarios.js';\nexport { createCallCommand } from './call.js';\nexport { createCallsCommand } from './calls.js';\nexport { createPersonasCommand } from './personas.js';\nexport { createAgentsCommand } from './agents.js';\nexport { createHealthCommand } from './health.js';\nexport { createMcpCommand } from './mcp.js';\nexport { createScorecardsCommand } from './scorecards.js';\nexport { createKnowledgeCommand } from './knowledge.js';\nexport { createMemoryCommand } from './memory.js';\nexport { createChatCommand } from './chat.js';\nexport { createPromptsCommand } from './prompts.js';\nexport { createWorkspacesCommand } from './workspaces.js';\n"],"mappings":"AAIA,SAAS,mBAAmB,oBAAoB,2BAA2B;AAC3E,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,yBAAyB;AAClC,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/index.ts"],"sourcesContent":["/**\n * Command exports for the Chanl CLI\n */\n\nexport { createAuthCommand, createLoginCommand, createLogoutCommand } from './auth.js';\nexport { createConfigCommand } from './config.js';\nexport { createToolsCommand } from './tools.js';\nexport { createToolsetsCommand } from './toolsets.js';\nexport { createScenariosCommand } from './scenarios.js';\nexport { createCallCommand } from './call.js';\nexport { createCallsCommand } from './calls.js';\nexport { createPersonasCommand } from './personas.js';\nexport { createCustomersCommand } from './customers.js';\nexport { createConversationsCommand, createMessagesCommand } from './messaging.js';\nexport { createWhatsAppCommand } from './whatsapp.js';\nexport { createAgentsCommand } from './agents.js';\nexport { createHealthCommand } from './health.js';\nexport { createMcpCommand } from './mcp.js';\nexport { createScorecardsCommand } from './scorecards.js';\nexport { createKnowledgeCommand } from './knowledge.js';\nexport { createMemoryCommand } from './memory.js';\nexport { createChatCommand } from './chat.js';\nexport { createPromptsCommand } from './prompts.js';\nexport { createWorkspacesCommand } from './workspaces.js';\n"],"mappings":"AAIA,SAAS,mBAAmB,oBAAoB,2BAA2B;AAC3E,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,yBAAyB;AAClC,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B,6BAA6B;AAClE,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create the conversations command group
|
|
5
|
+
*/
|
|
6
|
+
declare function createConversationsCommand(): Command;
|
|
7
|
+
/**
|
|
8
|
+
* Create the messages command group
|
|
9
|
+
*/
|
|
10
|
+
declare function createMessagesCommand(): Command;
|
|
11
|
+
|
|
12
|
+
export { createConversationsCommand, createMessagesCommand };
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { createSdk } from "../utils/sdk-factory.js";
|
|
4
|
+
import {
|
|
5
|
+
printError,
|
|
6
|
+
printSuccess,
|
|
7
|
+
printInfo,
|
|
8
|
+
printBlank,
|
|
9
|
+
printSimpleTable,
|
|
10
|
+
printLabel,
|
|
11
|
+
isJsonOutput,
|
|
12
|
+
printJson,
|
|
13
|
+
formatDate
|
|
14
|
+
} from "../utils/output.js";
|
|
15
|
+
function createConversationsCommand() {
|
|
16
|
+
const conversations = new Command("conversations").description("Browse messaging conversations (WhatsApp, SMS, chat)").addHelpText(
|
|
17
|
+
"after",
|
|
18
|
+
`
|
|
19
|
+
Quick Start:
|
|
20
|
+
$ chanl conversations list # Recent conversations
|
|
21
|
+
$ chanl conversations list --channel whatsapp # Filter by channel type
|
|
22
|
+
$ chanl conversations get <id> # Conversation + messages
|
|
23
|
+
$ chanl conversations close <id> # Close a conversation
|
|
24
|
+
|
|
25
|
+
Send messages with: chanl messages send`
|
|
26
|
+
);
|
|
27
|
+
conversations.command("list").description("List conversations").option("-c, --channel <type>", "Filter by channel type (whatsapp, sms, chat)").option("--status <status>", "Filter by status (open, closed)").option("--limit <number>", "Number of items per page", "20").option("-p, --page <number>", "Page number", "1").action(handleConversationsList);
|
|
28
|
+
conversations.command("get <id>").description("Show a conversation with its messages").option("--limit <number>", "Messages per page", "50").action(handleConversationsGet);
|
|
29
|
+
conversations.command("close <id>").description("Close a conversation").action(handleConversationsClose);
|
|
30
|
+
return conversations;
|
|
31
|
+
}
|
|
32
|
+
function createMessagesCommand() {
|
|
33
|
+
const messages = new Command("messages").description("Send outbound messages on a channel").addHelpText(
|
|
34
|
+
"after",
|
|
35
|
+
`
|
|
36
|
+
Session vs template (WhatsApp):
|
|
37
|
+
Free-form (--body) delivers only inside the 24h window opened by the
|
|
38
|
+
customer's last inbound message. Outside it, use an approved template
|
|
39
|
+
(--template HX... --var 1=Dean); a free-form attempt fails with a
|
|
40
|
+
63016-class provider error.
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
$ chanl messages send --channel <channelId> --to +14155551234 --body "Hi!"
|
|
44
|
+
$ chanl messages send --channel <channelId> --to +14155551234 \\
|
|
45
|
+
--template HX0123456789abcdef --var 1=Dean --var 2=tomorrow`
|
|
46
|
+
);
|
|
47
|
+
messages.command("send").description("Send a message (free-form body or template)").requiredOption("--channel <channelId>", "Channel id to send through").requiredOption("--to <address>", "Recipient (E.164 for phone channels)").option("--body <text>", "Free-form message body (24h session window)").option("--media <url>", "Media URL to attach").option("--template <contentSid>", "Approved template SID (HX...)").option("--var <key=value...>", "Template variable (repeatable)", collectVars, {}).action(handleMessagesSend);
|
|
48
|
+
return messages;
|
|
49
|
+
}
|
|
50
|
+
function collectVars(value, acc) {
|
|
51
|
+
const idx = value.indexOf("=");
|
|
52
|
+
if (idx === -1) {
|
|
53
|
+
throw new Error(`--var expects key=value, got "${value}"`);
|
|
54
|
+
}
|
|
55
|
+
acc[value.slice(0, idx)] = value.slice(idx + 1);
|
|
56
|
+
return acc;
|
|
57
|
+
}
|
|
58
|
+
async function handleConversationsList(options) {
|
|
59
|
+
const sdk = createSdk();
|
|
60
|
+
if (!sdk) return;
|
|
61
|
+
const spinner = ora("Fetching conversations...").start();
|
|
62
|
+
try {
|
|
63
|
+
const response = await sdk.conversations.list({
|
|
64
|
+
channelType: options.channel,
|
|
65
|
+
status: options.status,
|
|
66
|
+
limit: parseInt(options.limit, 10),
|
|
67
|
+
page: parseInt(options.page, 10)
|
|
68
|
+
});
|
|
69
|
+
spinner.stop();
|
|
70
|
+
if (!response.success || !response.data) {
|
|
71
|
+
printError("Failed to fetch conversations", response.message);
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const { items, pagination } = response.data;
|
|
76
|
+
if (isJsonOutput()) {
|
|
77
|
+
printJson(response.data);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (items.length === 0) {
|
|
81
|
+
printInfo("No conversations found");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
printBlank();
|
|
85
|
+
printSimpleTable(
|
|
86
|
+
["ID", "Channel", "Customer", "Status", "Last message"],
|
|
87
|
+
items.map((c) => [
|
|
88
|
+
c.id.slice(-12),
|
|
89
|
+
c.channelType || "-",
|
|
90
|
+
c.customerAddress || c.customerId?.slice(-8) || "-",
|
|
91
|
+
c.status || "-",
|
|
92
|
+
c.lastMessageAt ? formatDate(c.lastMessageAt) : "-"
|
|
93
|
+
])
|
|
94
|
+
);
|
|
95
|
+
printBlank();
|
|
96
|
+
if (pagination) {
|
|
97
|
+
printInfo(`Total: ${pagination.total} conversations (Page ${pagination.page} of ${pagination.totalPages})`);
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
spinner.fail("Failed to fetch conversations");
|
|
101
|
+
printError("Error", error instanceof Error ? error.message : "Unknown error");
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function handleConversationsGet(id, options) {
|
|
106
|
+
const sdk = createSdk();
|
|
107
|
+
if (!sdk) return;
|
|
108
|
+
const spinner = ora("Fetching conversation...").start();
|
|
109
|
+
try {
|
|
110
|
+
const response = await sdk.conversations.get(id, { limit: parseInt(options.limit, 10) });
|
|
111
|
+
spinner.stop();
|
|
112
|
+
if (!response.success || !response.data) {
|
|
113
|
+
printError("Failed to fetch conversation", response.message);
|
|
114
|
+
process.exitCode = 1;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (isJsonOutput()) {
|
|
118
|
+
printJson(response.data);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const { conversation, messages } = response.data;
|
|
122
|
+
printBlank();
|
|
123
|
+
printLabel("ID", conversation.id);
|
|
124
|
+
printLabel("Channel", conversation.channelType || "-");
|
|
125
|
+
printLabel("Customer", conversation.customerAddress || "-");
|
|
126
|
+
printLabel("Status", conversation.status || "-");
|
|
127
|
+
printBlank();
|
|
128
|
+
if (!messages || messages.length === 0) {
|
|
129
|
+
printInfo("No messages yet");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
printSimpleTable(
|
|
133
|
+
["Time", "Dir", "Body", "Status"],
|
|
134
|
+
messages.map((m) => [
|
|
135
|
+
formatDate(m.createdAt),
|
|
136
|
+
m.direction === "inbound" ? "\u2192 in" : "\u2190 out",
|
|
137
|
+
(m.body || (m.mediaUrl ? "[media]" : "")).slice(0, 48),
|
|
138
|
+
m.status || "-"
|
|
139
|
+
])
|
|
140
|
+
);
|
|
141
|
+
printBlank();
|
|
142
|
+
} catch (error) {
|
|
143
|
+
spinner.fail("Failed to fetch conversation");
|
|
144
|
+
printError("Error", error instanceof Error ? error.message : "Unknown error");
|
|
145
|
+
process.exitCode = 1;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function handleConversationsClose(id) {
|
|
149
|
+
const sdk = createSdk();
|
|
150
|
+
if (!sdk) return;
|
|
151
|
+
const spinner = ora("Closing conversation...").start();
|
|
152
|
+
try {
|
|
153
|
+
const response = await sdk.conversations.close(id);
|
|
154
|
+
spinner.stop();
|
|
155
|
+
if (!response.success) {
|
|
156
|
+
printError("Failed to close conversation", response.message);
|
|
157
|
+
process.exitCode = 1;
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
printSuccess(`Conversation closed: ${id}`);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
spinner.fail("Failed to close conversation");
|
|
163
|
+
printError("Error", error instanceof Error ? error.message : "Unknown error");
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async function handleMessagesSend(options) {
|
|
168
|
+
const sdk = createSdk();
|
|
169
|
+
if (!sdk) return;
|
|
170
|
+
if (!options.body && !options.template) {
|
|
171
|
+
printError("Nothing to send", "Provide --body or --template HX...");
|
|
172
|
+
process.exitCode = 1;
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const spinner = ora("Sending message...").start();
|
|
176
|
+
try {
|
|
177
|
+
const response = await sdk.conversations.send({
|
|
178
|
+
channelId: options.channel,
|
|
179
|
+
to: options.to,
|
|
180
|
+
body: options.body,
|
|
181
|
+
mediaUrl: options.media,
|
|
182
|
+
contentSid: options.template,
|
|
183
|
+
contentVariables: Object.keys(options.var).length > 0 ? options.var : void 0
|
|
184
|
+
});
|
|
185
|
+
spinner.stop();
|
|
186
|
+
if (!response.success || !response.data) {
|
|
187
|
+
printError("Failed to send message", response.message);
|
|
188
|
+
process.exitCode = 1;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (isJsonOutput()) {
|
|
192
|
+
printJson(response.data);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
printSuccess(`Message sent to ${options.to}`);
|
|
196
|
+
const m = response.data;
|
|
197
|
+
if (m.id) printInfo(`Message id: ${m.id}${m.status ? ` (${m.status})` : ""}`);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
spinner.fail("Failed to send message");
|
|
200
|
+
printError("Error", error instanceof Error ? error.message : "Unknown error");
|
|
201
|
+
process.exitCode = 1;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
export {
|
|
205
|
+
createConversationsCommand,
|
|
206
|
+
createMessagesCommand
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=messaging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commands/messaging.ts"],"sourcesContent":["import { Command } from 'commander';\nimport ora from 'ora';\nimport type { Conversation } from '@chanl/sdk';\nimport { createSdk } from '../utils/sdk-factory.js';\nimport {\n printError,\n printSuccess,\n printInfo,\n printBlank,\n printSimpleTable,\n printLabel,\n isJsonOutput,\n printJson,\n formatDate,\n} from '../utils/output.js';\n\n/**\n * Create the conversations command group\n */\nexport function createConversationsCommand(): Command {\n const conversations = new Command('conversations')\n .description('Browse messaging conversations (WhatsApp, SMS, chat)')\n .addHelpText(\n 'after',\n `\nQuick Start:\n $ chanl conversations list # Recent conversations\n $ chanl conversations list --channel whatsapp # Filter by channel type\n $ chanl conversations get <id> # Conversation + messages\n $ chanl conversations close <id> # Close a conversation\n\nSend messages with: chanl messages send`\n );\n\n conversations\n .command('list')\n .description('List conversations')\n .option('-c, --channel <type>', 'Filter by channel type (whatsapp, sms, chat)')\n .option('--status <status>', 'Filter by status (open, closed)')\n .option('--limit <number>', 'Number of items per page', '20')\n .option('-p, --page <number>', 'Page number', '1')\n .action(handleConversationsList);\n\n conversations\n .command('get <id>')\n .description('Show a conversation with its messages')\n .option('--limit <number>', 'Messages per page', '50')\n .action(handleConversationsGet);\n\n conversations\n .command('close <id>')\n .description('Close a conversation')\n .action(handleConversationsClose);\n\n return conversations;\n}\n\n/**\n * Create the messages command group\n */\nexport function createMessagesCommand(): Command {\n const messages = new Command('messages')\n .description('Send outbound messages on a channel')\n .addHelpText(\n 'after',\n `\nSession vs template (WhatsApp):\n Free-form (--body) delivers only inside the 24h window opened by the\n customer's last inbound message. Outside it, use an approved template\n (--template HX... --var 1=Dean); a free-form attempt fails with a\n 63016-class provider error.\n\nExamples:\n $ chanl messages send --channel <channelId> --to +14155551234 --body \"Hi!\"\n $ chanl messages send --channel <channelId> --to +14155551234 \\\\\n --template HX0123456789abcdef --var 1=Dean --var 2=tomorrow`\n );\n\n messages\n .command('send')\n .description('Send a message (free-form body or template)')\n .requiredOption('--channel <channelId>', 'Channel id to send through')\n .requiredOption('--to <address>', 'Recipient (E.164 for phone channels)')\n .option('--body <text>', 'Free-form message body (24h session window)')\n .option('--media <url>', 'Media URL to attach')\n .option('--template <contentSid>', 'Approved template SID (HX...)')\n .option('--var <key=value...>', 'Template variable (repeatable)', collectVars, {})\n .action(handleMessagesSend);\n\n return messages;\n}\n\nfunction collectVars(value: string, acc: Record<string, string>): Record<string, string> {\n const idx = value.indexOf('=');\n if (idx === -1) {\n throw new Error(`--var expects key=value, got \"${value}\"`);\n }\n acc[value.slice(0, idx)] = value.slice(idx + 1);\n return acc;\n}\n\nasync function handleConversationsList(options: {\n channel?: string;\n status?: string;\n limit: string;\n page: string;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching conversations...').start();\n\n try {\n const response = await sdk.conversations.list({\n channelType: options.channel,\n status: options.status,\n limit: parseInt(options.limit, 10),\n page: parseInt(options.page, 10),\n });\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch conversations', response.message);\n process.exitCode = 1;\n return;\n }\n\n const { items, pagination } = response.data;\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n if (items.length === 0) {\n printInfo('No conversations found');\n return;\n }\n\n printBlank();\n printSimpleTable(\n ['ID', 'Channel', 'Customer', 'Status', 'Last message'],\n items.map((c: Conversation) => [\n c.id.slice(-12),\n c.channelType || '-',\n c.customerAddress || c.customerId?.slice(-8) || '-',\n c.status || '-',\n c.lastMessageAt ? formatDate(c.lastMessageAt) : '-',\n ])\n );\n printBlank();\n if (pagination) {\n printInfo(`Total: ${pagination.total} conversations (Page ${pagination.page} of ${pagination.totalPages})`);\n }\n } catch (error) {\n spinner.fail('Failed to fetch conversations');\n printError('Error', error instanceof Error ? error.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n\nasync function handleConversationsGet(id: string, options: { limit: string }): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Fetching conversation...').start();\n\n try {\n const response = await sdk.conversations.get(id, { limit: parseInt(options.limit, 10) });\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to fetch conversation', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n const { conversation, messages } = response.data;\n printBlank();\n printLabel('ID', conversation.id);\n printLabel('Channel', conversation.channelType || '-');\n printLabel('Customer', conversation.customerAddress || '-');\n printLabel('Status', conversation.status || '-');\n printBlank();\n\n if (!messages || messages.length === 0) {\n printInfo('No messages yet');\n return;\n }\n\n printSimpleTable(\n ['Time', 'Dir', 'Body', 'Status'],\n messages.map((m) => [\n formatDate(m.createdAt),\n m.direction === 'inbound' ? '→ in' : '← out',\n (m.body || (m.mediaUrl ? '[media]' : '')).slice(0, 48),\n m.status || '-',\n ])\n );\n printBlank();\n } catch (error) {\n spinner.fail('Failed to fetch conversation');\n printError('Error', error instanceof Error ? error.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n\nasync function handleConversationsClose(id: string): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n const spinner = ora('Closing conversation...').start();\n\n try {\n const response = await sdk.conversations.close(id);\n spinner.stop();\n\n if (!response.success) {\n printError('Failed to close conversation', response.message);\n process.exitCode = 1;\n return;\n }\n printSuccess(`Conversation closed: ${id}`);\n } catch (error) {\n spinner.fail('Failed to close conversation');\n printError('Error', error instanceof Error ? error.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n\nasync function handleMessagesSend(options: {\n channel: string;\n to: string;\n body?: string;\n media?: string;\n template?: string;\n var: Record<string, string>;\n}): Promise<void> {\n const sdk = createSdk();\n if (!sdk) return;\n\n if (!options.body && !options.template) {\n printError('Nothing to send', 'Provide --body or --template HX...');\n process.exitCode = 1;\n return;\n }\n\n const spinner = ora('Sending message...').start();\n\n try {\n const response = await sdk.conversations.send({\n channelId: options.channel,\n to: options.to,\n body: options.body,\n mediaUrl: options.media,\n contentSid: options.template,\n contentVariables: Object.keys(options.var).length > 0 ? options.var : undefined,\n });\n spinner.stop();\n\n if (!response.success || !response.data) {\n printError('Failed to send message', response.message);\n process.exitCode = 1;\n return;\n }\n\n if (isJsonOutput()) {\n printJson(response.data);\n return;\n }\n\n printSuccess(`Message sent to ${options.to}`);\n const m = response.data;\n if (m.id) printInfo(`Message id: ${m.id}${m.status ? ` (${m.status})` : ''}`);\n } catch (error) {\n spinner.fail('Failed to send message');\n printError('Error', error instanceof Error ? error.message : 'Unknown error');\n process.exitCode = 1;\n }\n}\n"],"mappings":"AAAA,SAAS,eAAe;AACxB,OAAO,SAAS;AAEhB,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKA,SAAS,6BAAsC;AACpD,QAAM,gBAAgB,IAAI,QAAQ,eAAe,EAC9C,YAAY,sDAAsD,EAClE;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQF;AAEF,gBACG,QAAQ,MAAM,EACd,YAAY,oBAAoB,EAChC,OAAO,wBAAwB,8CAA8C,EAC7E,OAAO,qBAAqB,iCAAiC,EAC7D,OAAO,oBAAoB,4BAA4B,IAAI,EAC3D,OAAO,uBAAuB,eAAe,GAAG,EAChD,OAAO,uBAAuB;AAEjC,gBACG,QAAQ,UAAU,EAClB,YAAY,uCAAuC,EACnD,OAAO,oBAAoB,qBAAqB,IAAI,EACpD,OAAO,sBAAsB;AAEhC,gBACG,QAAQ,YAAY,EACpB,YAAY,sBAAsB,EAClC,OAAO,wBAAwB;AAElC,SAAO;AACT;AAKO,SAAS,wBAAiC;AAC/C,QAAM,WAAW,IAAI,QAAQ,UAAU,EACpC,YAAY,qCAAqC,EACjD;AAAA,IACC;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWF;AAEF,WACG,QAAQ,MAAM,EACd,YAAY,6CAA6C,EACzD,eAAe,yBAAyB,4BAA4B,EACpE,eAAe,kBAAkB,sCAAsC,EACvE,OAAO,iBAAiB,6CAA6C,EACrE,OAAO,iBAAiB,qBAAqB,EAC7C,OAAO,2BAA2B,+BAA+B,EACjE,OAAO,wBAAwB,kCAAkC,aAAa,CAAC,CAAC,EAChF,OAAO,kBAAkB;AAE5B,SAAO;AACT;AAEA,SAAS,YAAY,OAAe,KAAqD;AACvF,QAAM,MAAM,MAAM,QAAQ,GAAG;AAC7B,MAAI,QAAQ,IAAI;AACd,UAAM,IAAI,MAAM,iCAAiC,KAAK,GAAG;AAAA,EAC3D;AACA,MAAI,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,MAAM,MAAM,MAAM,CAAC;AAC9C,SAAO;AACT;AAEA,eAAe,wBAAwB,SAKrB;AAChB,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,IAAK;AAEV,QAAM,UAAU,IAAI,2BAA2B,EAAE,MAAM;AAEvD,MAAI;AACF,UAAM,WAAW,MAAM,IAAI,cAAc,KAAK;AAAA,MAC5C,aAAa,QAAQ;AAAA,MACrB,QAAQ,QAAQ;AAAA,MAChB,OAAO,SAAS,QAAQ,OAAO,EAAE;AAAA,MACjC,MAAM,SAAS,QAAQ,MAAM,EAAE;AAAA,IACjC,CAAC;AACD,YAAQ,KAAK;AAEb,QAAI,CAAC,SAAS,WAAW,CAAC,SAAS,MAAM;AACvC,iBAAW,iCAAiC,SAAS,OAAO;AAC5D,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,UAAM,EAAE,OAAO,WAAW,IAAI,SAAS;AAEvC,QAAI,aAAa,GAAG;AAClB,gBAAU,SAAS,IAAI;AACvB;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,GAAG;AACtB,gBAAU,wBAAwB;AAClC;AAAA,IACF;AAEA,eAAW;AACX;AAAA,MACE,CAAC,MAAM,WAAW,YAAY,UAAU,cAAc;AAAA,MACtD,MAAM,IAAI,CAAC,MAAoB;AAAA,QAC7B,EAAE,GAAG,MAAM,GAAG;AAAA,QACd,EAAE,eAAe;AAAA,QACjB,EAAE,mBAAmB,EAAE,YAAY,MAAM,EAAE,KAAK;AAAA,QAChD,EAAE,UAAU;AAAA,QACZ,EAAE,gBAAgB,WAAW,EAAE,aAAa,IAAI;AAAA,MAClD,CAAC;AAAA,IACH;AACA,eAAW;AACX,QAAI,YAAY;AACd,gBAAU,UAAU,WAAW,KAAK,wBAAwB,WAAW,IAAI,OAAO,WAAW,UAAU,GAAG;AAAA,IAC5G;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,+BAA+B;AAC5C,eAAW,SAAS,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAC5E,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAe,uBAAuB,IAAY,SAA2C;AAC3F,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,IAAK;AAEV,QAAM,UAAU,IAAI,0BAA0B,EAAE,MAAM;AAEtD,MAAI;AACF,UAAM,WAAW,MAAM,IAAI,cAAc,IAAI,IAAI,EAAE,OAAO,SAAS,QAAQ,OAAO,EAAE,EAAE,CAAC;AACvF,YAAQ,KAAK;AAEb,QAAI,CAAC,SAAS,WAAW,CAAC,SAAS,MAAM;AACvC,iBAAW,gCAAgC,SAAS,OAAO;AAC3D,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,QAAI,aAAa,GAAG;AAClB,gBAAU,SAAS,IAAI;AACvB;AAAA,IACF;AAEA,UAAM,EAAE,cAAc,SAAS,IAAI,SAAS;AAC5C,eAAW;AACX,eAAW,MAAM,aAAa,EAAE;AAChC,eAAW,WAAW,aAAa,eAAe,GAAG;AACrD,eAAW,YAAY,aAAa,mBAAmB,GAAG;AAC1D,eAAW,UAAU,aAAa,UAAU,GAAG;AAC/C,eAAW;AAEX,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,gBAAU,iBAAiB;AAC3B;AAAA,IACF;AAEA;AAAA,MACE,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAAA,MAChC,SAAS,IAAI,CAAC,MAAM;AAAA,QAClB,WAAW,EAAE,SAAS;AAAA,QACtB,EAAE,cAAc,YAAY,cAAS;AAAA,SACpC,EAAE,SAAS,EAAE,WAAW,YAAY,KAAK,MAAM,GAAG,EAAE;AAAA,QACrD,EAAE,UAAU;AAAA,MACd,CAAC;AAAA,IACH;AACA,eAAW;AAAA,EACb,SAAS,OAAO;AACd,YAAQ,KAAK,8BAA8B;AAC3C,eAAW,SAAS,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAC5E,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAe,yBAAyB,IAA2B;AACjE,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,IAAK;AAEV,QAAM,UAAU,IAAI,yBAAyB,EAAE,MAAM;AAErD,MAAI;AACF,UAAM,WAAW,MAAM,IAAI,cAAc,MAAM,EAAE;AACjD,YAAQ,KAAK;AAEb,QAAI,CAAC,SAAS,SAAS;AACrB,iBAAW,gCAAgC,SAAS,OAAO;AAC3D,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,iBAAa,wBAAwB,EAAE,EAAE;AAAA,EAC3C,SAAS,OAAO;AACd,YAAQ,KAAK,8BAA8B;AAC3C,eAAW,SAAS,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAC5E,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAe,mBAAmB,SAOhB;AAChB,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,IAAK;AAEV,MAAI,CAAC,QAAQ,QAAQ,CAAC,QAAQ,UAAU;AACtC,eAAW,mBAAmB,oCAAoC;AAClE,YAAQ,WAAW;AACnB;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,oBAAoB,EAAE,MAAM;AAEhD,MAAI;AACF,UAAM,WAAW,MAAM,IAAI,cAAc,KAAK;AAAA,MAC5C,WAAW,QAAQ;AAAA,MACnB,IAAI,QAAQ;AAAA,MACZ,MAAM,QAAQ;AAAA,MACd,UAAU,QAAQ;AAAA,MAClB,YAAY,QAAQ;AAAA,MACpB,kBAAkB,OAAO,KAAK,QAAQ,GAAG,EAAE,SAAS,IAAI,QAAQ,MAAM;AAAA,IACxE,CAAC;AACD,YAAQ,KAAK;AAEb,QAAI,CAAC,SAAS,WAAW,CAAC,SAAS,MAAM;AACvC,iBAAW,0BAA0B,SAAS,OAAO;AACrD,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,QAAI,aAAa,GAAG;AAClB,gBAAU,SAAS,IAAI;AACvB;AAAA,IACF;AAEA,iBAAa,mBAAmB,QAAQ,EAAE,EAAE;AAC5C,UAAM,IAAI,SAAS;AACnB,QAAI,EAAE,GAAI,WAAU,eAAe,EAAE,EAAE,GAAG,EAAE,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE,EAAE;AAAA,EAC9E,SAAS,OAAO;AACd,YAAQ,KAAK,wBAAwB;AACrC,eAAW,SAAS,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAC5E,YAAQ,WAAW;AAAA,EACrB;AACF;","names":[]}
|