@nice2dev/ui-communication 1.0.5 → 1.0.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/dist/index.cjs +17 -2
- package/dist/index.d.ts +9 -1
- package/dist/index.mjs +4665 -2939
- package/dist/services/emailTrackingService.d.ts +279 -0
- package/dist/services/mailMergeService.d.ts +365 -0
- package/dist/services/pstnGatewayService.d.ts +341 -0
- package/dist/services/slackImportService.d.ts +426 -0
- package/package.json +1 -1
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Slack Import Service for migrating data from Slack
|
|
3
|
+
* @module @nice2dev/ui-communication/services/slackImportService
|
|
4
|
+
* @description Provides tools for importing Slack workspace data including
|
|
5
|
+
* channels, messages, users, files, and reactions.
|
|
6
|
+
*/
|
|
7
|
+
export type SlackChannelType = 'public' | 'private' | 'dm' | 'mpim';
|
|
8
|
+
export type ImportStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'cancelled';
|
|
9
|
+
export interface SlackUser {
|
|
10
|
+
id: string;
|
|
11
|
+
team_id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
real_name?: string;
|
|
14
|
+
email?: string;
|
|
15
|
+
profile?: {
|
|
16
|
+
display_name?: string;
|
|
17
|
+
image_72?: string;
|
|
18
|
+
image_192?: string;
|
|
19
|
+
title?: string;
|
|
20
|
+
phone?: string;
|
|
21
|
+
status_text?: string;
|
|
22
|
+
status_emoji?: string;
|
|
23
|
+
};
|
|
24
|
+
is_admin?: boolean;
|
|
25
|
+
is_owner?: boolean;
|
|
26
|
+
is_bot?: boolean;
|
|
27
|
+
deleted?: boolean;
|
|
28
|
+
tz?: string;
|
|
29
|
+
tz_label?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface SlackChannel {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
is_channel?: boolean;
|
|
35
|
+
is_private?: boolean;
|
|
36
|
+
is_mpim?: boolean;
|
|
37
|
+
is_im?: boolean;
|
|
38
|
+
is_archived?: boolean;
|
|
39
|
+
created: number;
|
|
40
|
+
creator?: string;
|
|
41
|
+
topic?: {
|
|
42
|
+
value: string;
|
|
43
|
+
creator: string;
|
|
44
|
+
};
|
|
45
|
+
purpose?: {
|
|
46
|
+
value: string;
|
|
47
|
+
creator: string;
|
|
48
|
+
};
|
|
49
|
+
members?: string[];
|
|
50
|
+
num_members?: number;
|
|
51
|
+
}
|
|
52
|
+
export interface SlackMessage {
|
|
53
|
+
type: string;
|
|
54
|
+
subtype?: string;
|
|
55
|
+
ts: string;
|
|
56
|
+
user?: string;
|
|
57
|
+
text: string;
|
|
58
|
+
thread_ts?: string;
|
|
59
|
+
reply_count?: number;
|
|
60
|
+
reply_users?: string[];
|
|
61
|
+
reactions?: SlackReaction[];
|
|
62
|
+
files?: SlackFile[];
|
|
63
|
+
attachments?: SlackAttachment[];
|
|
64
|
+
edited?: {
|
|
65
|
+
user: string;
|
|
66
|
+
ts: string;
|
|
67
|
+
};
|
|
68
|
+
blocks?: unknown[];
|
|
69
|
+
}
|
|
70
|
+
export interface SlackReaction {
|
|
71
|
+
name: string;
|
|
72
|
+
users: string[];
|
|
73
|
+
count: number;
|
|
74
|
+
}
|
|
75
|
+
export interface SlackFile {
|
|
76
|
+
id: string;
|
|
77
|
+
name: string;
|
|
78
|
+
title?: string;
|
|
79
|
+
mimetype: string;
|
|
80
|
+
filetype: string;
|
|
81
|
+
size: number;
|
|
82
|
+
url_private?: string;
|
|
83
|
+
url_private_download?: string;
|
|
84
|
+
created: number;
|
|
85
|
+
user?: string;
|
|
86
|
+
thumb_64?: string;
|
|
87
|
+
thumb_80?: string;
|
|
88
|
+
thumb_160?: string;
|
|
89
|
+
}
|
|
90
|
+
export interface SlackAttachment {
|
|
91
|
+
fallback?: string;
|
|
92
|
+
color?: string;
|
|
93
|
+
pretext?: string;
|
|
94
|
+
author_name?: string;
|
|
95
|
+
author_link?: string;
|
|
96
|
+
author_icon?: string;
|
|
97
|
+
title?: string;
|
|
98
|
+
title_link?: string;
|
|
99
|
+
text?: string;
|
|
100
|
+
fields?: Array<{
|
|
101
|
+
title: string;
|
|
102
|
+
value: string;
|
|
103
|
+
short?: boolean;
|
|
104
|
+
}>;
|
|
105
|
+
image_url?: string;
|
|
106
|
+
thumb_url?: string;
|
|
107
|
+
footer?: string;
|
|
108
|
+
footer_icon?: string;
|
|
109
|
+
ts?: number;
|
|
110
|
+
}
|
|
111
|
+
export interface SlackExportData {
|
|
112
|
+
users: SlackUser[];
|
|
113
|
+
channels: SlackChannel[];
|
|
114
|
+
messages: Map<string, SlackMessage[]>;
|
|
115
|
+
files?: SlackFile[];
|
|
116
|
+
}
|
|
117
|
+
export interface ImportMapping {
|
|
118
|
+
/** Map Slack user ID to new user ID */
|
|
119
|
+
users: Map<string, string>;
|
|
120
|
+
/** Map Slack channel ID to new channel ID */
|
|
121
|
+
channels: Map<string, string>;
|
|
122
|
+
/** Map Slack file ID to new file URL */
|
|
123
|
+
files: Map<string, string>;
|
|
124
|
+
}
|
|
125
|
+
export interface ImportOptions {
|
|
126
|
+
/** Import users */
|
|
127
|
+
importUsers?: boolean;
|
|
128
|
+
/** Import channels */
|
|
129
|
+
importChannels?: boolean;
|
|
130
|
+
/** Import messages */
|
|
131
|
+
importMessages?: boolean;
|
|
132
|
+
/** Import files */
|
|
133
|
+
importFiles?: boolean;
|
|
134
|
+
/** Import reactions */
|
|
135
|
+
importReactions?: boolean;
|
|
136
|
+
/** Import threads */
|
|
137
|
+
importThreads?: boolean;
|
|
138
|
+
/** Skip archived channels */
|
|
139
|
+
skipArchived?: boolean;
|
|
140
|
+
/** Skip direct messages */
|
|
141
|
+
skipDirectMessages?: boolean;
|
|
142
|
+
/** Only import specific channels */
|
|
143
|
+
channelFilter?: string[];
|
|
144
|
+
/** Import messages after this date */
|
|
145
|
+
messagesAfter?: Date;
|
|
146
|
+
/** Import messages before this date */
|
|
147
|
+
messagesBefore?: Date;
|
|
148
|
+
/** Download files locally */
|
|
149
|
+
downloadFiles?: boolean;
|
|
150
|
+
/** Preserve timestamps */
|
|
151
|
+
preserveTimestamps?: boolean;
|
|
152
|
+
/** Batch size for processing */
|
|
153
|
+
batchSize?: number;
|
|
154
|
+
}
|
|
155
|
+
export interface ImportProgress {
|
|
156
|
+
/** Current phase */
|
|
157
|
+
phase: 'users' | 'channels' | 'messages' | 'files' | 'complete';
|
|
158
|
+
/** Total items in current phase */
|
|
159
|
+
total: number;
|
|
160
|
+
/** Processed items */
|
|
161
|
+
processed: number;
|
|
162
|
+
/** Failed items */
|
|
163
|
+
failed: number;
|
|
164
|
+
/** Current item being processed */
|
|
165
|
+
current?: string;
|
|
166
|
+
/** Progress percentage */
|
|
167
|
+
percentage: number;
|
|
168
|
+
/** Is complete */
|
|
169
|
+
isComplete: boolean;
|
|
170
|
+
/** Errors encountered */
|
|
171
|
+
errors: ImportError[];
|
|
172
|
+
}
|
|
173
|
+
export interface ImportError {
|
|
174
|
+
phase: string;
|
|
175
|
+
itemId?: string;
|
|
176
|
+
itemType: 'user' | 'channel' | 'message' | 'file';
|
|
177
|
+
message: string;
|
|
178
|
+
details?: unknown;
|
|
179
|
+
}
|
|
180
|
+
export interface ImportResult {
|
|
181
|
+
/** Import status */
|
|
182
|
+
status: ImportStatus;
|
|
183
|
+
/** Statistics */
|
|
184
|
+
stats: {
|
|
185
|
+
usersImported: number;
|
|
186
|
+
channelsImported: number;
|
|
187
|
+
messagesImported: number;
|
|
188
|
+
filesImported: number;
|
|
189
|
+
reactionsImported: number;
|
|
190
|
+
threadsImported: number;
|
|
191
|
+
};
|
|
192
|
+
/** Mapping of old IDs to new IDs */
|
|
193
|
+
mapping: ImportMapping;
|
|
194
|
+
/** Errors encountered */
|
|
195
|
+
errors: ImportError[];
|
|
196
|
+
/** Started timestamp */
|
|
197
|
+
startedAt: Date;
|
|
198
|
+
/** Completed timestamp */
|
|
199
|
+
completedAt?: Date;
|
|
200
|
+
/** Duration in milliseconds */
|
|
201
|
+
duration?: number;
|
|
202
|
+
}
|
|
203
|
+
export interface SlackImportConfig {
|
|
204
|
+
/** Function to create a user in the target system */
|
|
205
|
+
createUser: (user: MappedUser) => Promise<{
|
|
206
|
+
success: boolean;
|
|
207
|
+
id?: string;
|
|
208
|
+
error?: string;
|
|
209
|
+
}>;
|
|
210
|
+
/** Function to create a channel in the target system */
|
|
211
|
+
createChannel: (channel: MappedChannel) => Promise<{
|
|
212
|
+
success: boolean;
|
|
213
|
+
id?: string;
|
|
214
|
+
error?: string;
|
|
215
|
+
}>;
|
|
216
|
+
/** Function to create a message in the target system */
|
|
217
|
+
createMessage: (message: MappedMessage) => Promise<{
|
|
218
|
+
success: boolean;
|
|
219
|
+
id?: string;
|
|
220
|
+
error?: string;
|
|
221
|
+
}>;
|
|
222
|
+
/** Function to upload a file */
|
|
223
|
+
uploadFile?: (file: SlackFile, content: ArrayBuffer) => Promise<{
|
|
224
|
+
success: boolean;
|
|
225
|
+
url?: string;
|
|
226
|
+
error?: string;
|
|
227
|
+
}>;
|
|
228
|
+
/** Function to download files from Slack */
|
|
229
|
+
downloadFile?: (url: string, token: string) => Promise<ArrayBuffer>;
|
|
230
|
+
/** Slack API token (for file downloads) */
|
|
231
|
+
slackToken?: string;
|
|
232
|
+
/** Rate limit (items per second) */
|
|
233
|
+
rateLimit?: number;
|
|
234
|
+
}
|
|
235
|
+
export interface MappedUser {
|
|
236
|
+
/** Original Slack user ID */
|
|
237
|
+
slackId: string;
|
|
238
|
+
/** Email */
|
|
239
|
+
email?: string;
|
|
240
|
+
/** Display name */
|
|
241
|
+
displayName: string;
|
|
242
|
+
/** Real name */
|
|
243
|
+
realName?: string;
|
|
244
|
+
/** Avatar URL */
|
|
245
|
+
avatarUrl?: string;
|
|
246
|
+
/** Title/role */
|
|
247
|
+
title?: string;
|
|
248
|
+
/** Phone */
|
|
249
|
+
phone?: string;
|
|
250
|
+
/** Timezone */
|
|
251
|
+
timezone?: string;
|
|
252
|
+
/** Is admin */
|
|
253
|
+
isAdmin: boolean;
|
|
254
|
+
/** Is bot */
|
|
255
|
+
isBot: boolean;
|
|
256
|
+
/** Is deactivated */
|
|
257
|
+
isDeactivated: boolean;
|
|
258
|
+
}
|
|
259
|
+
export interface MappedChannel {
|
|
260
|
+
/** Original Slack channel ID */
|
|
261
|
+
slackId: string;
|
|
262
|
+
/** Channel name */
|
|
263
|
+
name: string;
|
|
264
|
+
/** Channel type */
|
|
265
|
+
type: SlackChannelType;
|
|
266
|
+
/** Description/purpose */
|
|
267
|
+
description?: string;
|
|
268
|
+
/** Topic */
|
|
269
|
+
topic?: string;
|
|
270
|
+
/** Is archived */
|
|
271
|
+
isArchived: boolean;
|
|
272
|
+
/** Creator ID (mapped) */
|
|
273
|
+
creatorId?: string;
|
|
274
|
+
/** Member IDs (mapped) */
|
|
275
|
+
memberIds: string[];
|
|
276
|
+
/** Created timestamp */
|
|
277
|
+
createdAt?: Date;
|
|
278
|
+
}
|
|
279
|
+
export interface MappedMessage {
|
|
280
|
+
/** Channel ID (mapped) */
|
|
281
|
+
channelId: string;
|
|
282
|
+
/** Sender ID (mapped) */
|
|
283
|
+
senderId?: string;
|
|
284
|
+
/** Message content (converted from Slack format) */
|
|
285
|
+
content: string;
|
|
286
|
+
/** HTML content */
|
|
287
|
+
htmlContent?: string;
|
|
288
|
+
/** Thread parent ID (mapped) */
|
|
289
|
+
threadId?: string;
|
|
290
|
+
/** Is thread reply */
|
|
291
|
+
isThreadReply: boolean;
|
|
292
|
+
/** Attachments */
|
|
293
|
+
attachments: Array<{
|
|
294
|
+
type: 'file' | 'link' | 'image';
|
|
295
|
+
url?: string;
|
|
296
|
+
name?: string;
|
|
297
|
+
size?: number;
|
|
298
|
+
}>;
|
|
299
|
+
/** Reactions */
|
|
300
|
+
reactions: Array<{
|
|
301
|
+
emoji: string;
|
|
302
|
+
userIds: string[];
|
|
303
|
+
count: number;
|
|
304
|
+
}>;
|
|
305
|
+
/** Created timestamp */
|
|
306
|
+
createdAt?: Date;
|
|
307
|
+
/** Edited timestamp */
|
|
308
|
+
editedAt?: Date;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Service for importing Slack workspace data.
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```tsx
|
|
315
|
+
* const importService = new SlackImportService({
|
|
316
|
+
* createUser: async (user) => { ... },
|
|
317
|
+
* createChannel: async (channel) => { ... },
|
|
318
|
+
* createMessage: async (message) => { ... },
|
|
319
|
+
* });
|
|
320
|
+
*
|
|
321
|
+
* // Parse Slack export ZIP
|
|
322
|
+
* const data = await importService.parseSlackExport(zipFile);
|
|
323
|
+
*
|
|
324
|
+
* // Preview import
|
|
325
|
+
* const preview = importService.previewImport(data);
|
|
326
|
+
*
|
|
327
|
+
* // Execute import
|
|
328
|
+
* for await (const progress of importService.import(data, {
|
|
329
|
+
* importUsers: true,
|
|
330
|
+
* importChannels: true,
|
|
331
|
+
* importMessages: true,
|
|
332
|
+
* })) {
|
|
333
|
+
* console.log(`Progress: ${progress.percentage}%`);
|
|
334
|
+
* }
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
export declare class SlackImportService {
|
|
338
|
+
private config;
|
|
339
|
+
private abortController;
|
|
340
|
+
private mapping;
|
|
341
|
+
constructor(config: SlackImportConfig);
|
|
342
|
+
/**
|
|
343
|
+
* Parses a Slack export ZIP file.
|
|
344
|
+
*/
|
|
345
|
+
parseSlackExport(zipFile: File | ArrayBuffer): Promise<SlackExportData>;
|
|
346
|
+
/**
|
|
347
|
+
* Parses a Slack export from JSON files (alternative to ZIP).
|
|
348
|
+
*/
|
|
349
|
+
parseSlackExportFromJson(data: {
|
|
350
|
+
users?: SlackUser[];
|
|
351
|
+
channels?: SlackChannel[];
|
|
352
|
+
messages?: Record<string, SlackMessage[]>;
|
|
353
|
+
files?: SlackFile[];
|
|
354
|
+
}): SlackExportData;
|
|
355
|
+
/**
|
|
356
|
+
* Previews what will be imported without making changes.
|
|
357
|
+
*/
|
|
358
|
+
previewImport(data: SlackExportData, options?: ImportOptions): {
|
|
359
|
+
users: {
|
|
360
|
+
total: number;
|
|
361
|
+
filtered: number;
|
|
362
|
+
items: MappedUser[];
|
|
363
|
+
};
|
|
364
|
+
channels: {
|
|
365
|
+
total: number;
|
|
366
|
+
filtered: number;
|
|
367
|
+
items: MappedChannel[];
|
|
368
|
+
};
|
|
369
|
+
messages: {
|
|
370
|
+
total: number;
|
|
371
|
+
perChannel: Map<string, number>;
|
|
372
|
+
};
|
|
373
|
+
files: {
|
|
374
|
+
total: number;
|
|
375
|
+
totalSize: number;
|
|
376
|
+
};
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Executes the import process.
|
|
380
|
+
*/
|
|
381
|
+
import(data: SlackExportData, options?: ImportOptions): AsyncGenerator<ImportProgress, ImportResult, unknown>;
|
|
382
|
+
/**
|
|
383
|
+
* Cancels an ongoing import.
|
|
384
|
+
*/
|
|
385
|
+
cancel(): void;
|
|
386
|
+
private mapUser;
|
|
387
|
+
private mapChannel;
|
|
388
|
+
private mapMessage;
|
|
389
|
+
private convertSlackMessage;
|
|
390
|
+
private convertEmoji;
|
|
391
|
+
private filterMessages;
|
|
392
|
+
private extractZipContents;
|
|
393
|
+
private escapeHtml;
|
|
394
|
+
private delay;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Gets or creates the Slack import service singleton.
|
|
398
|
+
*/
|
|
399
|
+
export declare function getSlackImportService(config?: SlackImportConfig): SlackImportService;
|
|
400
|
+
/**
|
|
401
|
+
* Disposes the Slack import service singleton.
|
|
402
|
+
*/
|
|
403
|
+
export declare function disposeSlackImportService(): void;
|
|
404
|
+
export interface UseSlackImportOptions {
|
|
405
|
+
config?: SlackImportConfig;
|
|
406
|
+
}
|
|
407
|
+
export interface UseSlackImportReturn {
|
|
408
|
+
/** Parse Slack export from JSON */
|
|
409
|
+
parseJson: (data: Parameters<SlackImportService['parseSlackExportFromJson']>[0]) => SlackExportData;
|
|
410
|
+
/** Preview import */
|
|
411
|
+
preview: (data: SlackExportData, options?: ImportOptions) => ReturnType<SlackImportService['previewImport']>;
|
|
412
|
+
/** Execute import */
|
|
413
|
+
import: (data: SlackExportData, options?: ImportOptions) => AsyncGenerator<ImportProgress, ImportResult, unknown>;
|
|
414
|
+
/** Cancel import */
|
|
415
|
+
cancel: () => void;
|
|
416
|
+
/** Current progress */
|
|
417
|
+
progress: ImportProgress | null;
|
|
418
|
+
/** Is importing */
|
|
419
|
+
isImporting: boolean;
|
|
420
|
+
/** Last result */
|
|
421
|
+
result: ImportResult | null;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* React hook for Slack import functionality.
|
|
425
|
+
*/
|
|
426
|
+
export declare function useSlackImport(options?: UseSlackImportOptions): UseSlackImportReturn;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nice2dev/ui-communication",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "NiceCommunication — full-spectrum communication suite: chat bubble, messenger, voice/video calls, multi-party conference, and Teams-style workspace. Provider-agnostic RTC transport.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|