@kyoji2/intercom-cli 0.1.0 → 0.1.6
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 +40 -1
- package/dist/index.js +21645 -20721
- package/package.json +7 -3
- package/src/cli/registry.ts +924 -0
- package/src/client.ts +10 -0
- package/src/commands/admins.ts +2 -2
- package/src/commands/articles.ts +8 -8
- package/src/commands/auth.ts +3 -3
- package/src/commands/companies.ts +6 -6
- package/src/commands/contacts.ts +13 -13
- package/src/commands/conversations.ts +72 -15
- package/src/commands/events.ts +4 -4
- package/src/commands/index.ts +24 -10
- package/src/commands/overview.ts +4 -2
- package/src/commands/replyPayload.ts +46 -0
- package/src/commands/tags.ts +6 -6
- package/src/commands/ticketTypes.ts +76 -0
- package/src/commands/tickets.ts +398 -0
- package/src/index.ts +19 -623
- package/src/utils/config.ts +31 -24
- package/src/utils/index.ts +1 -0
- package/src/utils/output.ts +1 -0
package/src/client.ts
CHANGED
|
@@ -47,6 +47,8 @@ function createDryRunProxy(client: IntercomClient, logger: Logger): IntercomClie
|
|
|
47
47
|
"away",
|
|
48
48
|
"tag",
|
|
49
49
|
"untag",
|
|
50
|
+
"reply",
|
|
51
|
+
"manage",
|
|
50
52
|
];
|
|
51
53
|
|
|
52
54
|
const createNestedProxy = <T extends object>(target: T, path: string[]): T => {
|
|
@@ -107,6 +109,14 @@ function getDryRunResponse(method: string): unknown {
|
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
export function handleIntercomError(error: unknown): never {
|
|
112
|
+
if (error instanceof SyntaxError) {
|
|
113
|
+
throw new CLIError(
|
|
114
|
+
"Invalid JSON input provided to command.",
|
|
115
|
+
400,
|
|
116
|
+
"Ensure your JSON data is valid and properly escaped for the shell.",
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
110
120
|
if (error instanceof IntercomError) {
|
|
111
121
|
let hint: string | undefined;
|
|
112
122
|
if (error.statusCode === 401) {
|
package/src/commands/admins.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface AdminGetOptions extends GlobalOptions {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export async function cmdAdminList(options: GlobalOptions): Promise<void> {
|
|
10
|
-
const token = await getTokenAsync();
|
|
10
|
+
const token = await getTokenAsync(options.configDir);
|
|
11
11
|
if (!token) {
|
|
12
12
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
13
13
|
}
|
|
@@ -40,7 +40,7 @@ export async function cmdAdminList(options: GlobalOptions): Promise<void> {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export async function cmdAdminGet(options: AdminGetOptions): Promise<void> {
|
|
43
|
-
const token = await getTokenAsync();
|
|
43
|
+
const token = await getTokenAsync(options.configDir);
|
|
44
44
|
if (!token) {
|
|
45
45
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
46
46
|
}
|
package/src/commands/articles.ts
CHANGED
|
@@ -34,8 +34,8 @@ export interface ArticleDeleteOptions extends GlobalOptions {
|
|
|
34
34
|
id: string;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
async function requireToken(): Promise<string> {
|
|
38
|
-
const token = await getTokenAsync();
|
|
37
|
+
async function requireToken(configDir: string): Promise<string> {
|
|
38
|
+
const token = await getTokenAsync(configDir);
|
|
39
39
|
if (!token) {
|
|
40
40
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
41
41
|
}
|
|
@@ -43,7 +43,7 @@ async function requireToken(): Promise<string> {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export async function cmdArticleList(options: ArticleListOptions): Promise<void> {
|
|
46
|
-
const token = await requireToken();
|
|
46
|
+
const token = await requireToken(options.configDir);
|
|
47
47
|
const spinner = ora("Listing articles...").start();
|
|
48
48
|
|
|
49
49
|
try {
|
|
@@ -76,7 +76,7 @@ export async function cmdArticleList(options: ArticleListOptions): Promise<void>
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export async function cmdArticleGet(options: ArticleGetOptions): Promise<void> {
|
|
79
|
-
const token = await requireToken();
|
|
79
|
+
const token = await requireToken(options.configDir);
|
|
80
80
|
const spinner = ora("Fetching article...").start();
|
|
81
81
|
|
|
82
82
|
try {
|
|
@@ -109,7 +109,7 @@ export async function cmdArticleGet(options: ArticleGetOptions): Promise<void> {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
export async function cmdArticleSearch(options: ArticleSearchOptions): Promise<void> {
|
|
112
|
-
const token = await requireToken();
|
|
112
|
+
const token = await requireToken(options.configDir);
|
|
113
113
|
const spinner = ora("Searching articles...").start();
|
|
114
114
|
|
|
115
115
|
try {
|
|
@@ -146,7 +146,7 @@ export async function cmdArticleSearch(options: ArticleSearchOptions): Promise<v
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
export async function cmdArticleCreate(options: ArticleCreateOptions): Promise<void> {
|
|
149
|
-
const token = await requireToken();
|
|
149
|
+
const token = await requireToken(options.configDir);
|
|
150
150
|
const spinner = ora("Creating article...").start();
|
|
151
151
|
|
|
152
152
|
try {
|
|
@@ -184,7 +184,7 @@ export async function cmdArticleCreate(options: ArticleCreateOptions): Promise<v
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
export async function cmdArticleUpdate(options: ArticleUpdateOptions): Promise<void> {
|
|
187
|
-
const token = await requireToken();
|
|
187
|
+
const token = await requireToken(options.configDir);
|
|
188
188
|
const spinner = ora("Updating article...").start();
|
|
189
189
|
|
|
190
190
|
try {
|
|
@@ -212,7 +212,7 @@ export async function cmdArticleUpdate(options: ArticleUpdateOptions): Promise<v
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
export async function cmdArticleDelete(options: ArticleDeleteOptions): Promise<void> {
|
|
215
|
-
const token = await requireToken();
|
|
215
|
+
const token = await requireToken(options.configDir);
|
|
216
216
|
const spinner = ora("Deleting article...").start();
|
|
217
217
|
|
|
218
218
|
try {
|
package/src/commands/auth.ts
CHANGED
|
@@ -43,7 +43,7 @@ export async function cmdLogin(options: LoginOptions): Promise<void> {
|
|
|
43
43
|
throw new CLIError("Could not verify token", 401, "The token may be invalid or expired.");
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
await saveConfig({ token });
|
|
46
|
+
await saveConfig(options.configDir, { token });
|
|
47
47
|
spinner.succeed("Logged in successfully");
|
|
48
48
|
|
|
49
49
|
output(
|
|
@@ -65,12 +65,12 @@ export async function cmdLogin(options: LoginOptions): Promise<void> {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
export async function cmdLogout(options: GlobalOptions): Promise<void> {
|
|
68
|
-
await deleteConfig();
|
|
68
|
+
await deleteConfig(options.configDir);
|
|
69
69
|
output({ status: "success", message: "Logged out successfully" }, options.format);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export async function cmdWhoami(options: GlobalOptions): Promise<void> {
|
|
73
|
-
const token = await getTokenAsync();
|
|
73
|
+
const token = await getTokenAsync(options.configDir);
|
|
74
74
|
if (!token) {
|
|
75
75
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
76
76
|
}
|
|
@@ -24,8 +24,8 @@ export interface CompanyUpdateOptions extends GlobalOptions {
|
|
|
24
24
|
json: string;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
async function requireToken(): Promise<string> {
|
|
28
|
-
const token = await getTokenAsync();
|
|
27
|
+
async function requireToken(configDir: string): Promise<string> {
|
|
28
|
+
const token = await getTokenAsync(configDir);
|
|
29
29
|
if (!token) {
|
|
30
30
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
31
31
|
}
|
|
@@ -33,7 +33,7 @@ async function requireToken(): Promise<string> {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export async function cmdCompanyCreate(options: CompanyCreateOptions): Promise<void> {
|
|
36
|
-
const token = await requireToken();
|
|
36
|
+
const token = await requireToken(options.configDir);
|
|
37
37
|
const spinner = ora("Creating company...").start();
|
|
38
38
|
|
|
39
39
|
try {
|
|
@@ -78,7 +78,7 @@ export async function cmdCompanyCreate(options: CompanyCreateOptions): Promise<v
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
export async function cmdCompanyGet(options: CompanyGetOptions): Promise<void> {
|
|
81
|
-
const token = await requireToken();
|
|
81
|
+
const token = await requireToken(options.configDir);
|
|
82
82
|
const spinner = ora("Fetching company...").start();
|
|
83
83
|
|
|
84
84
|
try {
|
|
@@ -114,7 +114,7 @@ export async function cmdCompanyGet(options: CompanyGetOptions): Promise<void> {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
export async function cmdCompanyList(options: CompanyListOptions): Promise<void> {
|
|
117
|
-
const token = await requireToken();
|
|
117
|
+
const token = await requireToken(options.configDir);
|
|
118
118
|
const spinner = ora("Listing companies...").start();
|
|
119
119
|
|
|
120
120
|
try {
|
|
@@ -147,7 +147,7 @@ export async function cmdCompanyList(options: CompanyListOptions): Promise<void>
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
export async function cmdCompanyUpdate(options: CompanyUpdateOptions): Promise<void> {
|
|
150
|
-
const token = await requireToken();
|
|
150
|
+
const token = await requireToken(options.configDir);
|
|
151
151
|
const spinner = ora("Updating company...").start();
|
|
152
152
|
|
|
153
153
|
try {
|
package/src/commands/contacts.ts
CHANGED
|
@@ -55,8 +55,8 @@ export interface ContactAttachCompanyOptions extends GlobalOptions {
|
|
|
55
55
|
companyId: string;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
async function requireToken(): Promise<string> {
|
|
59
|
-
const token = await getTokenAsync();
|
|
58
|
+
async function requireToken(configDir: string): Promise<string> {
|
|
59
|
+
const token = await getTokenAsync(configDir);
|
|
60
60
|
if (!token) {
|
|
61
61
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
62
62
|
}
|
|
@@ -64,7 +64,7 @@ async function requireToken(): Promise<string> {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
export async function cmdContactCreate(options: ContactCreateOptions): Promise<void> {
|
|
67
|
-
const token = await requireToken();
|
|
67
|
+
const token = await requireToken(options.configDir);
|
|
68
68
|
const spinner = ora("Creating contact...").start();
|
|
69
69
|
|
|
70
70
|
try {
|
|
@@ -105,7 +105,7 @@ export async function cmdContactCreate(options: ContactCreateOptions): Promise<v
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
export async function cmdContactGet(options: ContactGetOptions): Promise<void> {
|
|
108
|
-
const token = await requireToken();
|
|
108
|
+
const token = await requireToken(options.configDir);
|
|
109
109
|
const spinner = ora("Fetching contact...").start();
|
|
110
110
|
|
|
111
111
|
try {
|
|
@@ -141,7 +141,7 @@ export async function cmdContactGet(options: ContactGetOptions): Promise<void> {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
export async function cmdContactUpdate(options: ContactUpdateOptions): Promise<void> {
|
|
144
|
-
const token = await requireToken();
|
|
144
|
+
const token = await requireToken(options.configDir);
|
|
145
145
|
const spinner = ora("Updating contact...").start();
|
|
146
146
|
|
|
147
147
|
try {
|
|
@@ -179,7 +179,7 @@ export async function cmdContactUpdate(options: ContactUpdateOptions): Promise<v
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
export async function cmdContactDelete(options: ContactDeleteOptions): Promise<void> {
|
|
182
|
-
const token = await requireToken();
|
|
182
|
+
const token = await requireToken(options.configDir);
|
|
183
183
|
const spinner = ora("Deleting contact...").start();
|
|
184
184
|
|
|
185
185
|
try {
|
|
@@ -196,7 +196,7 @@ export async function cmdContactDelete(options: ContactDeleteOptions): Promise<v
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
export async function cmdContactSearch(options: ContactSearchOptions): Promise<void> {
|
|
199
|
-
const token = await requireToken();
|
|
199
|
+
const token = await requireToken(options.configDir);
|
|
200
200
|
const spinner = ora("Searching contacts...").start();
|
|
201
201
|
|
|
202
202
|
try {
|
|
@@ -246,7 +246,7 @@ export async function cmdContactSearch(options: ContactSearchOptions): Promise<v
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
export async function cmdContactList(options: ContactListOptions): Promise<void> {
|
|
249
|
-
const token = await requireToken();
|
|
249
|
+
const token = await requireToken(options.configDir);
|
|
250
250
|
const spinner = ora("Listing contacts...").start();
|
|
251
251
|
|
|
252
252
|
try {
|
|
@@ -277,7 +277,7 @@ export async function cmdContactList(options: ContactListOptions): Promise<void>
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
export async function cmdContactNote(options: ContactNoteOptions): Promise<void> {
|
|
280
|
-
const token = await requireToken();
|
|
280
|
+
const token = await requireToken(options.configDir);
|
|
281
281
|
const spinner = ora("Adding note...").start();
|
|
282
282
|
|
|
283
283
|
try {
|
|
@@ -305,7 +305,7 @@ export async function cmdContactNote(options: ContactNoteOptions): Promise<void>
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
export async function cmdContactNotes(options: ContactNotesListOptions): Promise<void> {
|
|
308
|
-
const token = await requireToken();
|
|
308
|
+
const token = await requireToken(options.configDir);
|
|
309
309
|
const spinner = ora("Fetching notes...").start();
|
|
310
310
|
|
|
311
311
|
try {
|
|
@@ -332,7 +332,7 @@ export async function cmdContactNotes(options: ContactNotesListOptions): Promise
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
export async function cmdContactTag(options: ContactTagOptions): Promise<void> {
|
|
335
|
-
const token = await requireToken();
|
|
335
|
+
const token = await requireToken(options.configDir);
|
|
336
336
|
const spinner = ora("Tagging contact...").start();
|
|
337
337
|
|
|
338
338
|
try {
|
|
@@ -358,7 +358,7 @@ export async function cmdContactTag(options: ContactTagOptions): Promise<void> {
|
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
export async function cmdContactUntag(options: ContactTagOptions): Promise<void> {
|
|
361
|
-
const token = await requireToken();
|
|
361
|
+
const token = await requireToken(options.configDir);
|
|
362
362
|
const spinner = ora("Removing tag...").start();
|
|
363
363
|
|
|
364
364
|
try {
|
|
@@ -384,7 +384,7 @@ export async function cmdContactUntag(options: ContactTagOptions): Promise<void>
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
export async function cmdContactAttachCompany(options: ContactAttachCompanyOptions): Promise<void> {
|
|
387
|
-
const token = await requireToken();
|
|
387
|
+
const token = await requireToken(options.configDir);
|
|
388
388
|
const spinner = ora("Attaching company...").start();
|
|
389
389
|
|
|
390
390
|
try {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ora from "ora";
|
|
2
2
|
import { createClient, handleIntercomError } from "../client.ts";
|
|
3
3
|
import { CLIError, type GlobalOptions, getTokenAsync, output } from "../utils/index.ts";
|
|
4
|
+
import { buildAdminReplyPayload } from "./replyPayload.ts";
|
|
4
5
|
|
|
5
6
|
export interface ConversationListOptions extends GlobalOptions {
|
|
6
7
|
limit?: string;
|
|
@@ -21,6 +22,7 @@ export interface ConversationReplyOptions extends GlobalOptions {
|
|
|
21
22
|
id: string;
|
|
22
23
|
adminId: string;
|
|
23
24
|
body: string;
|
|
25
|
+
messageType?: string;
|
|
24
26
|
json?: string;
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -46,8 +48,16 @@ export interface ConversationSnoozeOptions extends GlobalOptions {
|
|
|
46
48
|
until: string;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
export interface ConversationConvertOptions extends GlobalOptions {
|
|
52
|
+
id: string;
|
|
53
|
+
ticketTypeId: string;
|
|
54
|
+
title?: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
json?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function requireToken(configDir: string): Promise<string> {
|
|
60
|
+
const token = await getTokenAsync(configDir);
|
|
51
61
|
if (!token) {
|
|
52
62
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
53
63
|
}
|
|
@@ -55,7 +65,7 @@ async function requireToken(): Promise<string> {
|
|
|
55
65
|
}
|
|
56
66
|
|
|
57
67
|
export async function cmdConversationList(options: ConversationListOptions): Promise<void> {
|
|
58
|
-
const token = await requireToken();
|
|
68
|
+
const token = await requireToken(options.configDir);
|
|
59
69
|
const spinner = ora("Listing conversations...").start();
|
|
60
70
|
|
|
61
71
|
try {
|
|
@@ -91,7 +101,7 @@ export async function cmdConversationList(options: ConversationListOptions): Pro
|
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
export async function cmdConversationGet(options: ConversationGetOptions): Promise<void> {
|
|
94
|
-
const token = await requireToken();
|
|
104
|
+
const token = await requireToken(options.configDir);
|
|
95
105
|
const spinner = ora("Fetching conversation...").start();
|
|
96
106
|
|
|
97
107
|
try {
|
|
@@ -132,7 +142,7 @@ export async function cmdConversationGet(options: ConversationGetOptions): Promi
|
|
|
132
142
|
}
|
|
133
143
|
|
|
134
144
|
export async function cmdConversationSearch(options: ConversationSearchOptions): Promise<void> {
|
|
135
|
-
const token = await requireToken();
|
|
145
|
+
const token = await requireToken(options.configDir);
|
|
136
146
|
const spinner = ora("Searching conversations...").start();
|
|
137
147
|
|
|
138
148
|
try {
|
|
@@ -192,7 +202,7 @@ export async function cmdConversationSearch(options: ConversationSearchOptions):
|
|
|
192
202
|
}
|
|
193
203
|
|
|
194
204
|
export async function cmdConversationReply(options: ConversationReplyOptions): Promise<void> {
|
|
195
|
-
const token = await requireToken();
|
|
205
|
+
const token = await requireToken(options.configDir);
|
|
196
206
|
const spinner = ora("Sending reply...").start();
|
|
197
207
|
|
|
198
208
|
try {
|
|
@@ -200,12 +210,12 @@ export async function cmdConversationReply(options: ConversationReplyOptions): P
|
|
|
200
210
|
|
|
201
211
|
const result = await client.conversations.reply({
|
|
202
212
|
conversation_id: options.id,
|
|
203
|
-
body: {
|
|
204
|
-
|
|
205
|
-
type: "admin",
|
|
206
|
-
admin_id: options.adminId,
|
|
213
|
+
body: buildAdminReplyPayload({
|
|
214
|
+
adminId: options.adminId,
|
|
207
215
|
body: options.body,
|
|
208
|
-
|
|
216
|
+
messageType: options.messageType,
|
|
217
|
+
json: options.json,
|
|
218
|
+
}),
|
|
209
219
|
});
|
|
210
220
|
|
|
211
221
|
spinner.succeed("Reply sent");
|
|
@@ -225,7 +235,7 @@ export async function cmdConversationReply(options: ConversationReplyOptions): P
|
|
|
225
235
|
}
|
|
226
236
|
|
|
227
237
|
export async function cmdConversationAssign(options: ConversationAssignOptions): Promise<void> {
|
|
228
|
-
const token = await requireToken();
|
|
238
|
+
const token = await requireToken(options.configDir);
|
|
229
239
|
const spinner = ora("Assigning conversation...").start();
|
|
230
240
|
|
|
231
241
|
try {
|
|
@@ -257,7 +267,7 @@ export async function cmdConversationAssign(options: ConversationAssignOptions):
|
|
|
257
267
|
}
|
|
258
268
|
|
|
259
269
|
export async function cmdConversationClose(options: ConversationCloseOptions): Promise<void> {
|
|
260
|
-
const token = await requireToken();
|
|
270
|
+
const token = await requireToken(options.configDir);
|
|
261
271
|
const spinner = ora("Closing conversation...").start();
|
|
262
272
|
|
|
263
273
|
try {
|
|
@@ -288,7 +298,7 @@ export async function cmdConversationClose(options: ConversationCloseOptions): P
|
|
|
288
298
|
}
|
|
289
299
|
|
|
290
300
|
export async function cmdConversationOpen(options: ConversationOpenOptions): Promise<void> {
|
|
291
|
-
const token = await requireToken();
|
|
301
|
+
const token = await requireToken(options.configDir);
|
|
292
302
|
const spinner = ora("Opening conversation...").start();
|
|
293
303
|
|
|
294
304
|
try {
|
|
@@ -318,7 +328,7 @@ export async function cmdConversationOpen(options: ConversationOpenOptions): Pro
|
|
|
318
328
|
}
|
|
319
329
|
|
|
320
330
|
export async function cmdConversationSnooze(options: ConversationSnoozeOptions): Promise<void> {
|
|
321
|
-
const token = await requireToken();
|
|
331
|
+
const token = await requireToken(options.configDir);
|
|
322
332
|
const spinner = ora("Snoozing conversation...").start();
|
|
323
333
|
|
|
324
334
|
try {
|
|
@@ -348,3 +358,50 @@ export async function cmdConversationSnooze(options: ConversationSnoozeOptions):
|
|
|
348
358
|
handleIntercomError(error);
|
|
349
359
|
}
|
|
350
360
|
}
|
|
361
|
+
|
|
362
|
+
export async function cmdConversationConvert(options: ConversationConvertOptions): Promise<void> {
|
|
363
|
+
const token = await requireToken(options.configDir);
|
|
364
|
+
const spinner = ora("Converting conversation to ticket...").start();
|
|
365
|
+
|
|
366
|
+
try {
|
|
367
|
+
const client = createClient({ token, dryRun: options.dryRun });
|
|
368
|
+
|
|
369
|
+
let attributes: Record<string, unknown> | undefined;
|
|
370
|
+
if (options.json) {
|
|
371
|
+
attributes = JSON.parse(options.json);
|
|
372
|
+
} else if (options.title || options.description) {
|
|
373
|
+
attributes = {};
|
|
374
|
+
if (options.title) {
|
|
375
|
+
attributes._default_title_ = options.title;
|
|
376
|
+
}
|
|
377
|
+
if (options.description) {
|
|
378
|
+
attributes._default_description_ = options.description;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const ticket = await client.conversations.convertToTicket({
|
|
383
|
+
conversation_id: Number.parseInt(options.id, 10),
|
|
384
|
+
ticket_type_id: options.ticketTypeId,
|
|
385
|
+
attributes,
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
spinner.succeed("Conversation converted to ticket");
|
|
389
|
+
|
|
390
|
+
output(
|
|
391
|
+
{
|
|
392
|
+
id: ticket?.id,
|
|
393
|
+
ticket_id: ticket?.ticket_id,
|
|
394
|
+
category: ticket?.category,
|
|
395
|
+
ticket_type: ticket?.ticket_type,
|
|
396
|
+
ticket_state: ticket?.ticket_state,
|
|
397
|
+
ticket_attributes: ticket?.ticket_attributes,
|
|
398
|
+
open: ticket?.open,
|
|
399
|
+
created_at: ticket?.created_at,
|
|
400
|
+
},
|
|
401
|
+
options.format,
|
|
402
|
+
);
|
|
403
|
+
} catch (error) {
|
|
404
|
+
spinner.fail("Failed to convert conversation to ticket");
|
|
405
|
+
handleIntercomError(error);
|
|
406
|
+
}
|
|
407
|
+
}
|
package/src/commands/events.ts
CHANGED
|
@@ -13,8 +13,8 @@ export interface EventListOptions extends GlobalOptions {
|
|
|
13
13
|
userId: string;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
async function requireToken(): Promise<string> {
|
|
17
|
-
const token = await getTokenAsync();
|
|
16
|
+
async function requireToken(configDir: string): Promise<string> {
|
|
17
|
+
const token = await getTokenAsync(configDir);
|
|
18
18
|
if (!token) {
|
|
19
19
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
20
20
|
}
|
|
@@ -22,7 +22,7 @@ async function requireToken(): Promise<string> {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export async function cmdEventTrack(options: EventTrackOptions): Promise<void> {
|
|
25
|
-
const token = await requireToken();
|
|
25
|
+
const token = await requireToken(options.configDir);
|
|
26
26
|
const spinner = ora("Tracking event...").start();
|
|
27
27
|
|
|
28
28
|
try {
|
|
@@ -61,7 +61,7 @@ export async function cmdEventTrack(options: EventTrackOptions): Promise<void> {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export async function cmdEventList(options: EventListOptions): Promise<void> {
|
|
64
|
-
const token = await requireToken();
|
|
64
|
+
const token = await requireToken(options.configDir);
|
|
65
65
|
const spinner = ora("Fetching events...").start();
|
|
66
66
|
|
|
67
67
|
try {
|
package/src/commands/index.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
// Auth commands
|
|
2
|
-
|
|
3
1
|
export type { AdminGetOptions } from "./admins.ts";
|
|
4
|
-
// Admin commands
|
|
5
2
|
export { cmdAdminGet, cmdAdminList } from "./admins.ts";
|
|
6
3
|
export type {
|
|
7
4
|
ArticleCreateOptions,
|
|
@@ -11,7 +8,6 @@ export type {
|
|
|
11
8
|
ArticleSearchOptions,
|
|
12
9
|
ArticleUpdateOptions,
|
|
13
10
|
} from "./articles.ts";
|
|
14
|
-
// Article commands
|
|
15
11
|
export {
|
|
16
12
|
cmdArticleCreate,
|
|
17
13
|
cmdArticleDelete,
|
|
@@ -23,7 +19,6 @@ export {
|
|
|
23
19
|
export type { LoginOptions } from "./auth.ts";
|
|
24
20
|
export { cmdLogin, cmdLogout, cmdWhoami } from "./auth.ts";
|
|
25
21
|
export type { CompanyCreateOptions, CompanyGetOptions, CompanyListOptions, CompanyUpdateOptions } from "./companies.ts";
|
|
26
|
-
// Company commands
|
|
27
22
|
export { cmdCompanyCreate, cmdCompanyGet, cmdCompanyList, cmdCompanyUpdate } from "./companies.ts";
|
|
28
23
|
export type {
|
|
29
24
|
ContactAttachCompanyOptions,
|
|
@@ -37,7 +32,6 @@ export type {
|
|
|
37
32
|
ContactTagOptions,
|
|
38
33
|
ContactUpdateOptions,
|
|
39
34
|
} from "./contacts.ts";
|
|
40
|
-
// Contact commands
|
|
41
35
|
export {
|
|
42
36
|
cmdContactAttachCompany,
|
|
43
37
|
cmdContactCreate,
|
|
@@ -54,6 +48,7 @@ export {
|
|
|
54
48
|
export type {
|
|
55
49
|
ConversationAssignOptions,
|
|
56
50
|
ConversationCloseOptions,
|
|
51
|
+
ConversationConvertOptions,
|
|
57
52
|
ConversationGetOptions,
|
|
58
53
|
ConversationListOptions,
|
|
59
54
|
ConversationOpenOptions,
|
|
@@ -61,10 +56,10 @@ export type {
|
|
|
61
56
|
ConversationSearchOptions,
|
|
62
57
|
ConversationSnoozeOptions,
|
|
63
58
|
} from "./conversations.ts";
|
|
64
|
-
// Conversation commands
|
|
65
59
|
export {
|
|
66
60
|
cmdConversationAssign,
|
|
67
61
|
cmdConversationClose,
|
|
62
|
+
cmdConversationConvert,
|
|
68
63
|
cmdConversationGet,
|
|
69
64
|
cmdConversationList,
|
|
70
65
|
cmdConversationOpen,
|
|
@@ -73,10 +68,29 @@ export {
|
|
|
73
68
|
cmdConversationSnooze,
|
|
74
69
|
} from "./conversations.ts";
|
|
75
70
|
export type { EventListOptions, EventTrackOptions } from "./events.ts";
|
|
76
|
-
// Event commands
|
|
77
71
|
export { cmdEventList, cmdEventTrack } from "./events.ts";
|
|
78
|
-
// Overview commands
|
|
79
72
|
export { cmdContext, cmdSchema } from "./overview.ts";
|
|
80
73
|
export type { TagCreateOptions, TagDeleteOptions, TagGetOptions } from "./tags.ts";
|
|
81
|
-
// Tag commands
|
|
82
74
|
export { cmdTagCreate, cmdTagDelete, cmdTagGet, cmdTagList } from "./tags.ts";
|
|
75
|
+
export type {
|
|
76
|
+
TicketAssignOptions,
|
|
77
|
+
TicketCloseOptions,
|
|
78
|
+
TicketCreateOptions,
|
|
79
|
+
TicketDeleteOptions,
|
|
80
|
+
TicketGetOptions,
|
|
81
|
+
TicketReplyOptions,
|
|
82
|
+
TicketSearchOptions,
|
|
83
|
+
TicketUpdateOptions,
|
|
84
|
+
} from "./tickets.ts";
|
|
85
|
+
export {
|
|
86
|
+
cmdTicketAssign,
|
|
87
|
+
cmdTicketClose,
|
|
88
|
+
cmdTicketCreate,
|
|
89
|
+
cmdTicketDelete,
|
|
90
|
+
cmdTicketGet,
|
|
91
|
+
cmdTicketReply,
|
|
92
|
+
cmdTicketSearch,
|
|
93
|
+
cmdTicketUpdate,
|
|
94
|
+
} from "./tickets.ts";
|
|
95
|
+
export type { TicketTypeGetOptions, TicketTypeListOptions } from "./ticketTypes.ts";
|
|
96
|
+
export { cmdTicketTypeGet, cmdTicketTypeList } from "./ticketTypes.ts";
|
package/src/commands/overview.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { createClient, handleIntercomError } from "../client.ts";
|
|
|
3
3
|
import { CLIError, type GlobalOptions, getTokenAsync, output } from "../utils/index.ts";
|
|
4
4
|
|
|
5
5
|
export async function cmdContext(options: GlobalOptions): Promise<void> {
|
|
6
|
-
const token = await getTokenAsync();
|
|
6
|
+
const token = await getTokenAsync(options.configDir);
|
|
7
7
|
if (!token) {
|
|
8
8
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
9
9
|
}
|
|
@@ -118,7 +118,9 @@ export function cmdSchema(): void {
|
|
|
118
118
|
create_contact: 'intercom contact create --email "user@example.com" --name "John Doe"',
|
|
119
119
|
search_contacts: 'intercom contact search --email "user@example.com"',
|
|
120
120
|
list_conversations: "intercom conversation list --limit 10",
|
|
121
|
-
reply_conversation: 'intercom conversation reply <id> --admin <admin-id> --body "
|
|
121
|
+
reply_conversation: 'intercom conversation reply <id> --admin <admin-id> --body "Internal note" --type note',
|
|
122
|
+
reply_ticket:
|
|
123
|
+
'intercom ticket reply <id> --admin <admin-id> --body "Internal note" --json \'{"message_type":"note"}\'',
|
|
122
124
|
create_tag: 'intercom tag create "VIP Customer"',
|
|
123
125
|
search_articles: 'intercom article search "getting started"',
|
|
124
126
|
},
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { CLIError } from "../utils/index.ts";
|
|
2
|
+
|
|
3
|
+
type ReplyPayloadInput = {
|
|
4
|
+
adminId: string;
|
|
5
|
+
body: string;
|
|
6
|
+
messageType?: string;
|
|
7
|
+
json?: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ReplyBodyPayload = {
|
|
11
|
+
message_type: "comment" | "note";
|
|
12
|
+
type: "admin";
|
|
13
|
+
admin_id: string;
|
|
14
|
+
body: string;
|
|
15
|
+
} & Record<string, unknown>;
|
|
16
|
+
|
|
17
|
+
function validateReplyType(value: unknown, source: "--type" | "--json"): "comment" | "note" {
|
|
18
|
+
if (value !== "comment" && value !== "note") {
|
|
19
|
+
throw new CLIError(`Invalid ${source} value for message type: ${String(value)}`, 400, "Use comment or note.");
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function buildAdminReplyPayload(input: ReplyPayloadInput): ReplyBodyPayload {
|
|
25
|
+
const parsed = input.json ? JSON.parse(input.json) : {};
|
|
26
|
+
|
|
27
|
+
if (parsed === null || Array.isArray(parsed) || typeof parsed !== "object") {
|
|
28
|
+
throw new CLIError("Invalid --json value. Expected a JSON object.", 400);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const messageTypeFromJson =
|
|
32
|
+
Object.hasOwn(parsed, "message_type") && (parsed as Record<string, unknown>).message_type !== undefined
|
|
33
|
+
? validateReplyType((parsed as Record<string, unknown>).message_type, "--json")
|
|
34
|
+
: undefined;
|
|
35
|
+
const messageType = input.messageType
|
|
36
|
+
? validateReplyType(input.messageType, "--type")
|
|
37
|
+
: (messageTypeFromJson ?? "comment");
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
...(parsed as Record<string, unknown>),
|
|
41
|
+
message_type: messageType,
|
|
42
|
+
type: "admin",
|
|
43
|
+
admin_id: input.adminId,
|
|
44
|
+
body: input.body,
|
|
45
|
+
};
|
|
46
|
+
}
|
package/src/commands/tags.ts
CHANGED
|
@@ -14,8 +14,8 @@ export interface TagDeleteOptions extends GlobalOptions {
|
|
|
14
14
|
id: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
async function requireToken(): Promise<string> {
|
|
18
|
-
const token = await getTokenAsync();
|
|
17
|
+
async function requireToken(configDir: string): Promise<string> {
|
|
18
|
+
const token = await getTokenAsync(configDir);
|
|
19
19
|
if (!token) {
|
|
20
20
|
throw new CLIError("Not logged in", 401, "Run 'intercom login' to authenticate.");
|
|
21
21
|
}
|
|
@@ -23,7 +23,7 @@ async function requireToken(): Promise<string> {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export async function cmdTagList(options: GlobalOptions): Promise<void> {
|
|
26
|
-
const token = await requireToken();
|
|
26
|
+
const token = await requireToken(options.configDir);
|
|
27
27
|
const spinner = ora("Fetching tags...").start();
|
|
28
28
|
|
|
29
29
|
try {
|
|
@@ -49,7 +49,7 @@ export async function cmdTagList(options: GlobalOptions): Promise<void> {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
export async function cmdTagCreate(options: TagCreateOptions): Promise<void> {
|
|
52
|
-
const token = await requireToken();
|
|
52
|
+
const token = await requireToken(options.configDir);
|
|
53
53
|
const spinner = ora("Creating tag...").start();
|
|
54
54
|
|
|
55
55
|
try {
|
|
@@ -72,7 +72,7 @@ export async function cmdTagCreate(options: TagCreateOptions): Promise<void> {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
export async function cmdTagGet(options: TagGetOptions): Promise<void> {
|
|
75
|
-
const token = await requireToken();
|
|
75
|
+
const token = await requireToken(options.configDir);
|
|
76
76
|
const spinner = ora("Fetching tag...").start();
|
|
77
77
|
|
|
78
78
|
try {
|
|
@@ -95,7 +95,7 @@ export async function cmdTagGet(options: TagGetOptions): Promise<void> {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
export async function cmdTagDelete(options: TagDeleteOptions): Promise<void> {
|
|
98
|
-
const token = await requireToken();
|
|
98
|
+
const token = await requireToken(options.configDir);
|
|
99
99
|
const spinner = ora("Deleting tag...").start();
|
|
100
100
|
|
|
101
101
|
try {
|