catalist-support-agent 1.0.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/admin-portal.d.ts +43 -0
- package/dist/admin-portal.d.ts.map +1 -0
- package/dist/admin-portal.js +166 -0
- package/dist/admin-portal.js.map +1 -0
- package/dist/analysis/entities.d.ts +73 -0
- package/dist/analysis/entities.d.ts.map +1 -0
- package/dist/analysis/entities.js +378 -0
- package/dist/analysis/entities.js.map +1 -0
- package/dist/analysis/index.d.ts +44 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +243 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/intent.d.ts +49 -0
- package/dist/analysis/intent.d.ts.map +1 -0
- package/dist/analysis/intent.js +320 -0
- package/dist/analysis/intent.js.map +1 -0
- package/dist/analysis/sentiment.d.ts +57 -0
- package/dist/analysis/sentiment.d.ts.map +1 -0
- package/dist/analysis/sentiment.js +351 -0
- package/dist/analysis/sentiment.js.map +1 -0
- package/dist/brand/compliance.d.ts +122 -0
- package/dist/brand/compliance.d.ts.map +1 -0
- package/dist/brand/compliance.js +378 -0
- package/dist/brand/compliance.js.map +1 -0
- package/dist/brand/forbidden-terms.d.ts +99 -0
- package/dist/brand/forbidden-terms.d.ts.map +1 -0
- package/dist/brand/forbidden-terms.js +265 -0
- package/dist/brand/forbidden-terms.js.map +1 -0
- package/dist/brand/index.d.ts +10 -0
- package/dist/brand/index.d.ts.map +1 -0
- package/dist/brand/index.js +12 -0
- package/dist/brand/index.js.map +1 -0
- package/dist/config.d.ts +325 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +492 -0
- package/dist/config.js.map +1 -0
- package/dist/delivery/index.d.ts +84 -0
- package/dist/delivery/index.d.ts.map +1 -0
- package/dist/delivery/index.js +435 -0
- package/dist/delivery/index.js.map +1 -0
- package/dist/embeddings/cache.d.ts +96 -0
- package/dist/embeddings/cache.d.ts.map +1 -0
- package/dist/embeddings/cache.js +193 -0
- package/dist/embeddings/cache.js.map +1 -0
- package/dist/embeddings/index.d.ts +152 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +337 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/openai-client.d.ts +67 -0
- package/dist/embeddings/openai-client.d.ts.map +1 -0
- package/dist/embeddings/openai-client.js +190 -0
- package/dist/embeddings/openai-client.js.map +1 -0
- package/dist/errors.d.ts +302 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +508 -0
- package/dist/errors.js.map +1 -0
- package/dist/escalation/index.d.ts +93 -0
- package/dist/escalation/index.d.ts.map +1 -0
- package/dist/escalation/index.js +436 -0
- package/dist/escalation/index.js.map +1 -0
- package/dist/extraction/deduplication.d.ts +97 -0
- package/dist/extraction/deduplication.d.ts.map +1 -0
- package/dist/extraction/deduplication.js +271 -0
- package/dist/extraction/deduplication.js.map +1 -0
- package/dist/extraction/gmail-extractor.d.ts +160 -0
- package/dist/extraction/gmail-extractor.d.ts.map +1 -0
- package/dist/extraction/gmail-extractor.js +396 -0
- package/dist/extraction/gmail-extractor.js.map +1 -0
- package/dist/extraction/gmail-token-manager.d.ts +36 -0
- package/dist/extraction/gmail-token-manager.d.ts.map +1 -0
- package/dist/extraction/gmail-token-manager.js +146 -0
- package/dist/extraction/gmail-token-manager.js.map +1 -0
- package/dist/extraction/index.d.ts +13 -0
- package/dist/extraction/index.d.ts.map +1 -0
- package/dist/extraction/index.js +20 -0
- package/dist/extraction/index.js.map +1 -0
- package/dist/extraction/pii-handler.d.ts +100 -0
- package/dist/extraction/pii-handler.d.ts.map +1 -0
- package/dist/extraction/pii-handler.js +295 -0
- package/dist/extraction/pii-handler.js.map +1 -0
- package/dist/extraction/pipeline.d.ts +94 -0
- package/dist/extraction/pipeline.d.ts.map +1 -0
- package/dist/extraction/pipeline.js +380 -0
- package/dist/extraction/pipeline.js.map +1 -0
- package/dist/extraction/quality-filter.d.ts +99 -0
- package/dist/extraction/quality-filter.d.ts.map +1 -0
- package/dist/extraction/quality-filter.js +370 -0
- package/dist/extraction/quality-filter.js.map +1 -0
- package/dist/extraction/rate-limiter.d.ts +90 -0
- package/dist/extraction/rate-limiter.d.ts.map +1 -0
- package/dist/extraction/rate-limiter.js +242 -0
- package/dist/extraction/rate-limiter.js.map +1 -0
- package/dist/extraction/state-manager.d.ts +126 -0
- package/dist/extraction/state-manager.d.ts.map +1 -0
- package/dist/extraction/state-manager.js +344 -0
- package/dist/extraction/state-manager.js.map +1 -0
- package/dist/generation/index.d.ts +75 -0
- package/dist/generation/index.d.ts.map +1 -0
- package/dist/generation/index.js +641 -0
- package/dist/generation/index.js.map +1 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +233 -0
- package/dist/index.js.map +1 -0
- package/dist/intake/index.d.ts +15 -0
- package/dist/intake/index.d.ts.map +1 -0
- package/dist/intake/index.js +19 -0
- package/dist/intake/index.js.map +1 -0
- package/dist/intake/normalizer.d.ts +163 -0
- package/dist/intake/normalizer.d.ts.map +1 -0
- package/dist/intake/normalizer.js +309 -0
- package/dist/intake/normalizer.js.map +1 -0
- package/dist/intake/postmark.d.ts +72 -0
- package/dist/intake/postmark.d.ts.map +1 -0
- package/dist/intake/postmark.js +276 -0
- package/dist/intake/postmark.js.map +1 -0
- package/dist/intake/slack.d.ts +106 -0
- package/dist/intake/slack.d.ts.map +1 -0
- package/dist/intake/slack.js +378 -0
- package/dist/intake/slack.js.map +1 -0
- package/dist/intake/twilio.d.ts +86 -0
- package/dist/intake/twilio.d.ts.map +1 -0
- package/dist/intake/twilio.js +283 -0
- package/dist/intake/twilio.js.map +1 -0
- package/dist/knowledge/index.d.ts +100 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +516 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/knowledge/invoice-resolver.d.ts +62 -0
- package/dist/knowledge/invoice-resolver.d.ts.map +1 -0
- package/dist/knowledge/invoice-resolver.js +267 -0
- package/dist/knowledge/invoice-resolver.js.map +1 -0
- package/dist/types.d.ts +535 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +48 -0
- package/dist/types.js.map +1 -0
- package/ga-service-account.json +13 -0
- package/gmail-knowledge-migration.sql +149 -0
- package/nul +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postmark.js","sourceRoot":"","sources":["../../src/intake/postmark.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slack Event Handler
|
|
3
|
+
*
|
|
4
|
+
* Receives incoming Slack events via Events API, validates signatures,
|
|
5
|
+
* and normalizes message events into the standard message format.
|
|
6
|
+
*/
|
|
7
|
+
import type { InboundMessage } from '../types.js';
|
|
8
|
+
import { type SlackMessageEvent, type SlackEventWrapper } from './normalizer.js';
|
|
9
|
+
export interface SlackProcessResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
message?: InboundMessage;
|
|
12
|
+
contentHash?: string;
|
|
13
|
+
hasForbiddenTerms: boolean;
|
|
14
|
+
detectedTerms: string[];
|
|
15
|
+
error?: string;
|
|
16
|
+
isChallenge?: boolean;
|
|
17
|
+
challengeResponse?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface SlackUrlVerification {
|
|
20
|
+
type: 'url_verification';
|
|
21
|
+
challenge: string;
|
|
22
|
+
token: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validate Slack webhook signature using HMAC-SHA256
|
|
26
|
+
*
|
|
27
|
+
* Slack signs webhooks using:
|
|
28
|
+
* - Signing secret
|
|
29
|
+
* - Timestamp (to prevent replay attacks)
|
|
30
|
+
* - Request body
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateSlackSignature(signature: string, timestamp: string, body: string, signingSecret: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Validate Slack webhook request
|
|
35
|
+
*/
|
|
36
|
+
export declare function validateSlackWebhook(signature: string, timestamp: string, body: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Check if event is URL verification challenge
|
|
39
|
+
*/
|
|
40
|
+
export declare function isUrlVerification(event: unknown): event is SlackUrlVerification;
|
|
41
|
+
/**
|
|
42
|
+
* Check if event is a valid message event
|
|
43
|
+
*/
|
|
44
|
+
export declare function isMessageEvent(event: SlackEventWrapper): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Check if message is a direct message (DM)
|
|
47
|
+
*/
|
|
48
|
+
export declare function isDirectMessage(event: SlackMessageEvent): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Check if message is from a bot
|
|
51
|
+
*/
|
|
52
|
+
export declare function isBotMessage(event: SlackMessageEvent): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Process a Slack message event
|
|
55
|
+
*/
|
|
56
|
+
export declare function processSlackMessage(eventWrapper: SlackEventWrapper): Promise<SlackProcessResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Full webhook handler for Slack events
|
|
59
|
+
*/
|
|
60
|
+
export declare function handleSlackEvent(rawBody: string, signature: string, timestamp: string): Promise<SlackProcessResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Parse Slack message text to extract mentions
|
|
63
|
+
*/
|
|
64
|
+
export declare function extractMentions(text: string): string[];
|
|
65
|
+
/**
|
|
66
|
+
* Parse Slack message text to extract channel references
|
|
67
|
+
*/
|
|
68
|
+
export declare function extractChannelReferences(text: string): string[];
|
|
69
|
+
/**
|
|
70
|
+
* Parse Slack message text to extract links
|
|
71
|
+
*/
|
|
72
|
+
export declare function extractLinks(text: string): Array<{
|
|
73
|
+
url: string;
|
|
74
|
+
label?: string;
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Clean Slack message text (remove formatting, expand entities)
|
|
78
|
+
*/
|
|
79
|
+
export declare function cleanSlackText(text: string): string;
|
|
80
|
+
/**
|
|
81
|
+
* Determine if this is a B2B customer DM channel
|
|
82
|
+
* In practice, this would check against known customer Slack workspaces
|
|
83
|
+
*/
|
|
84
|
+
export declare function isB2BCustomerChannel(teamId: string, channelId: string): {
|
|
85
|
+
isB2B: boolean;
|
|
86
|
+
reason?: string;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Check if message should be processed (not from internal team, etc.)
|
|
90
|
+
*/
|
|
91
|
+
export declare function shouldProcessSlackMessage(eventWrapper: SlackEventWrapper): {
|
|
92
|
+
shouldProcess: boolean;
|
|
93
|
+
reason?: string;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Format text for Slack (basic markdown to Slack mrkdwn)
|
|
97
|
+
*/
|
|
98
|
+
export declare function formatForSlack(text: string): string;
|
|
99
|
+
/**
|
|
100
|
+
* Generate Slack Block Kit message structure
|
|
101
|
+
*/
|
|
102
|
+
export declare function generateSlackBlocks(text: string, options?: {
|
|
103
|
+
includeActions?: boolean;
|
|
104
|
+
conversationId?: string;
|
|
105
|
+
}): unknown[];
|
|
106
|
+
//# sourceMappingURL=slack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../src/intake/slack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slack Event Handler
|
|
3
|
+
*
|
|
4
|
+
* Receives incoming Slack events via Events API, validates signatures,
|
|
5
|
+
* and normalizes message events into the standard message format.
|
|
6
|
+
*/
|
|
7
|
+
import { createHmac, timingSafeEqual } from 'crypto';
|
|
8
|
+
import { config } from '../config.js';
|
|
9
|
+
import { IntakeError, WebhookValidationError } from '../errors.js';
|
|
10
|
+
import { normalizeSlackMessage, generateContentHash, validateMessageContent, scanAndAnnotateMessage, } from './normalizer.js';
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Signature Validation
|
|
13
|
+
// =============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Validate Slack webhook signature using HMAC-SHA256
|
|
16
|
+
*
|
|
17
|
+
* Slack signs webhooks using:
|
|
18
|
+
* - Signing secret
|
|
19
|
+
* - Timestamp (to prevent replay attacks)
|
|
20
|
+
* - Request body
|
|
21
|
+
*/
|
|
22
|
+
export function validateSlackSignature(signature, timestamp, body, signingSecret) {
|
|
23
|
+
if (!signature || !timestamp || !signingSecret) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
// Check timestamp is recent (within 5 minutes)
|
|
27
|
+
const timestampSeconds = parseInt(timestamp, 10);
|
|
28
|
+
const now = Math.floor(Date.now() / 1000);
|
|
29
|
+
if (Math.abs(now - timestampSeconds) > 300) {
|
|
30
|
+
// Request is older than 5 minutes
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// Build the signature base string
|
|
34
|
+
const sigBase = `v0:${timestamp}:${body}`;
|
|
35
|
+
// Generate expected signature
|
|
36
|
+
const expectedSignature = 'v0=' + createHmac('sha256', signingSecret).update(sigBase).digest('hex');
|
|
37
|
+
// Timing-safe comparison
|
|
38
|
+
try {
|
|
39
|
+
const sig1 = Buffer.from(signature);
|
|
40
|
+
const sig2 = Buffer.from(expectedSignature);
|
|
41
|
+
if (sig1.length !== sig2.length) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return timingSafeEqual(sig1, sig2);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validate Slack webhook request
|
|
52
|
+
*/
|
|
53
|
+
export function validateSlackWebhook(signature, timestamp, body) {
|
|
54
|
+
const signingSecret = config.slack.signingSecret;
|
|
55
|
+
if (!signingSecret) {
|
|
56
|
+
// If no signing secret configured, skip signature validation
|
|
57
|
+
// This is not recommended for production
|
|
58
|
+
console.warn('Slack signing secret not configured - skipping signature validation');
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return validateSlackSignature(signature, timestamp, body, signingSecret);
|
|
62
|
+
}
|
|
63
|
+
// =============================================================================
|
|
64
|
+
// Event Processing
|
|
65
|
+
// =============================================================================
|
|
66
|
+
/**
|
|
67
|
+
* Check if event is URL verification challenge
|
|
68
|
+
*/
|
|
69
|
+
export function isUrlVerification(event) {
|
|
70
|
+
return (typeof event === 'object' &&
|
|
71
|
+
event !== null &&
|
|
72
|
+
'type' in event &&
|
|
73
|
+
event.type === 'url_verification');
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if event is a valid message event
|
|
77
|
+
*/
|
|
78
|
+
export function isMessageEvent(event) {
|
|
79
|
+
return (event.type === 'event_callback' &&
|
|
80
|
+
event.event?.type === 'message' &&
|
|
81
|
+
!event.event.subtype && // Ignore edited messages, deleted messages, etc.
|
|
82
|
+
!!event.event.text &&
|
|
83
|
+
!!event.event.user);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Check if message is a direct message (DM)
|
|
87
|
+
*/
|
|
88
|
+
export function isDirectMessage(event) {
|
|
89
|
+
return event.channel_type === 'im';
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check if message is from a bot
|
|
93
|
+
*/
|
|
94
|
+
export function isBotMessage(event) {
|
|
95
|
+
// Messages from bots have a bot_id field or subtype of 'bot_message'
|
|
96
|
+
return event.subtype === 'bot_message' || ('bot_id' in event && !!event.bot_id);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Process a Slack message event
|
|
100
|
+
*/
|
|
101
|
+
export async function processSlackMessage(eventWrapper) {
|
|
102
|
+
try {
|
|
103
|
+
const event = eventWrapper.event;
|
|
104
|
+
// Validate it's a processable message
|
|
105
|
+
if (!event.text?.trim()) {
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
hasForbiddenTerms: false,
|
|
109
|
+
detectedTerms: [],
|
|
110
|
+
error: 'Empty message',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
// Skip bot messages
|
|
114
|
+
if (isBotMessage(event)) {
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
hasForbiddenTerms: false,
|
|
118
|
+
detectedTerms: [],
|
|
119
|
+
error: 'Bot message ignored',
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// Normalize the message into standard format
|
|
123
|
+
const message = normalizeSlackMessage(event, eventWrapper.team_id);
|
|
124
|
+
// Validate content exists
|
|
125
|
+
validateMessageContent(message);
|
|
126
|
+
// Generate content hash for deduplication
|
|
127
|
+
const contentHash = generateContentHash(message);
|
|
128
|
+
// Scan for forbidden terms
|
|
129
|
+
const { hasForbiddenTerms, detectedTerms } = scanAndAnnotateMessage(message);
|
|
130
|
+
return {
|
|
131
|
+
success: true,
|
|
132
|
+
message,
|
|
133
|
+
contentHash,
|
|
134
|
+
hasForbiddenTerms,
|
|
135
|
+
detectedTerms,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (error instanceof IntakeError) {
|
|
140
|
+
return {
|
|
141
|
+
success: false,
|
|
142
|
+
hasForbiddenTerms: false,
|
|
143
|
+
detectedTerms: [],
|
|
144
|
+
error: error.message,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
success: false,
|
|
149
|
+
hasForbiddenTerms: false,
|
|
150
|
+
detectedTerms: [],
|
|
151
|
+
error: error instanceof Error ? error.message : 'Unknown error processing Slack message',
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Full webhook handler for Slack events
|
|
157
|
+
*/
|
|
158
|
+
export async function handleSlackEvent(rawBody, signature, timestamp) {
|
|
159
|
+
// Validate webhook signature
|
|
160
|
+
if (!validateSlackWebhook(signature, timestamp, rawBody)) {
|
|
161
|
+
throw new WebhookValidationError('slack', {
|
|
162
|
+
context: { reason: 'Invalid Slack signature' },
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
// Parse JSON body
|
|
166
|
+
let payload;
|
|
167
|
+
try {
|
|
168
|
+
payload = JSON.parse(rawBody);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return {
|
|
172
|
+
success: false,
|
|
173
|
+
hasForbiddenTerms: false,
|
|
174
|
+
detectedTerms: [],
|
|
175
|
+
error: 'Invalid JSON payload',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
// Handle URL verification challenge
|
|
179
|
+
if (isUrlVerification(payload)) {
|
|
180
|
+
return {
|
|
181
|
+
success: true,
|
|
182
|
+
hasForbiddenTerms: false,
|
|
183
|
+
detectedTerms: [],
|
|
184
|
+
isChallenge: true,
|
|
185
|
+
challengeResponse: payload.challenge,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
// Validate event structure
|
|
189
|
+
const eventWrapper = payload;
|
|
190
|
+
if (!isMessageEvent(eventWrapper)) {
|
|
191
|
+
return {
|
|
192
|
+
success: false,
|
|
193
|
+
hasForbiddenTerms: false,
|
|
194
|
+
detectedTerms: [],
|
|
195
|
+
error: 'Not a processable message event',
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
// Process the message
|
|
199
|
+
return processSlackMessage(eventWrapper);
|
|
200
|
+
}
|
|
201
|
+
// =============================================================================
|
|
202
|
+
// Slack Utilities
|
|
203
|
+
// =============================================================================
|
|
204
|
+
/**
|
|
205
|
+
* Parse Slack message text to extract mentions
|
|
206
|
+
*/
|
|
207
|
+
export function extractMentions(text) {
|
|
208
|
+
// Slack mentions format: <@U12345678>
|
|
209
|
+
const mentionPattern = /<@([A-Z0-9]+)>/g;
|
|
210
|
+
const mentions = [];
|
|
211
|
+
let match;
|
|
212
|
+
while ((match = mentionPattern.exec(text)) !== null) {
|
|
213
|
+
if (match[1]) {
|
|
214
|
+
mentions.push(match[1]);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return mentions;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Parse Slack message text to extract channel references
|
|
221
|
+
*/
|
|
222
|
+
export function extractChannelReferences(text) {
|
|
223
|
+
// Slack channel format: <#C12345678|channel-name>
|
|
224
|
+
const channelPattern = /<#([A-Z0-9]+)\|?[^>]*>/g;
|
|
225
|
+
const channels = [];
|
|
226
|
+
let match;
|
|
227
|
+
while ((match = channelPattern.exec(text)) !== null) {
|
|
228
|
+
if (match[1]) {
|
|
229
|
+
channels.push(match[1]);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return channels;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Parse Slack message text to extract links
|
|
236
|
+
*/
|
|
237
|
+
export function extractLinks(text) {
|
|
238
|
+
// Slack link format: <https://example.com|Optional Label>
|
|
239
|
+
const linkPattern = /<(https?:\/\/[^|>]+)(?:\|([^>]+))?>/g;
|
|
240
|
+
const links = [];
|
|
241
|
+
let match;
|
|
242
|
+
while ((match = linkPattern.exec(text)) !== null) {
|
|
243
|
+
if (match[1]) {
|
|
244
|
+
links.push({
|
|
245
|
+
url: match[1],
|
|
246
|
+
label: match[2],
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return links;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Clean Slack message text (remove formatting, expand entities)
|
|
254
|
+
*/
|
|
255
|
+
export function cleanSlackText(text) {
|
|
256
|
+
return text
|
|
257
|
+
// Replace user mentions with @user
|
|
258
|
+
.replace(/<@([A-Z0-9]+)>/g, '@user')
|
|
259
|
+
// Replace channel mentions with #channel
|
|
260
|
+
.replace(/<#([A-Z0-9]+)\|([^>]+)>/g, '#$2')
|
|
261
|
+
.replace(/<#([A-Z0-9]+)>/g, '#channel')
|
|
262
|
+
// Replace links with just the URL or label
|
|
263
|
+
.replace(/<(https?:\/\/[^|>]+)\|([^>]+)>/g, '$2')
|
|
264
|
+
.replace(/<(https?:\/\/[^>]+)>/g, '$1')
|
|
265
|
+
// Replace special markup
|
|
266
|
+
.replace(/<!here>/g, '@here')
|
|
267
|
+
.replace(/<!channel>/g, '@channel')
|
|
268
|
+
.replace(/<!everyone>/g, '@everyone')
|
|
269
|
+
// Decode common entities
|
|
270
|
+
.replace(/&/g, '&')
|
|
271
|
+
.replace(/</g, '<')
|
|
272
|
+
.replace(/>/g, '>');
|
|
273
|
+
}
|
|
274
|
+
// =============================================================================
|
|
275
|
+
// Slack DM Context
|
|
276
|
+
// =============================================================================
|
|
277
|
+
/**
|
|
278
|
+
* Determine if this is a B2B customer DM channel
|
|
279
|
+
* In practice, this would check against known customer Slack workspaces
|
|
280
|
+
*/
|
|
281
|
+
export function isB2BCustomerChannel(teamId, channelId) {
|
|
282
|
+
// This would typically check against a database of connected B2B accounts
|
|
283
|
+
// For now, we assume all DMs are from potential B2B customers
|
|
284
|
+
// Could add logic like:
|
|
285
|
+
// - Check if team_id is in our list of connected workspace
|
|
286
|
+
// - Check if the channel is a known customer support channel
|
|
287
|
+
// - etc.
|
|
288
|
+
return {
|
|
289
|
+
isB2B: true,
|
|
290
|
+
reason: 'Direct message channel',
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Check if message should be processed (not from internal team, etc.)
|
|
295
|
+
*/
|
|
296
|
+
export function shouldProcessSlackMessage(eventWrapper) {
|
|
297
|
+
const event = eventWrapper.event;
|
|
298
|
+
// Skip bot messages
|
|
299
|
+
if (isBotMessage(event)) {
|
|
300
|
+
return {
|
|
301
|
+
shouldProcess: false,
|
|
302
|
+
reason: 'Bot message',
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
// Skip messages without text
|
|
306
|
+
if (!event.text?.trim()) {
|
|
307
|
+
return {
|
|
308
|
+
shouldProcess: false,
|
|
309
|
+
reason: 'Empty message',
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
// Skip non-DM channels (we only handle B2B customer DMs)
|
|
313
|
+
if (event.channel_type && event.channel_type !== 'im') {
|
|
314
|
+
return {
|
|
315
|
+
shouldProcess: false,
|
|
316
|
+
reason: 'Not a direct message',
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
// Check if it's from a B2B customer
|
|
320
|
+
const b2bCheck = isB2BCustomerChannel(eventWrapper.team_id, event.channel);
|
|
321
|
+
if (!b2bCheck.isB2B) {
|
|
322
|
+
return {
|
|
323
|
+
shouldProcess: false,
|
|
324
|
+
reason: b2bCheck.reason || 'Not a B2B customer channel',
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
shouldProcess: true,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
// =============================================================================
|
|
332
|
+
// Response Formatting for Slack
|
|
333
|
+
// =============================================================================
|
|
334
|
+
/**
|
|
335
|
+
* Format text for Slack (basic markdown to Slack mrkdwn)
|
|
336
|
+
*/
|
|
337
|
+
export function formatForSlack(text) {
|
|
338
|
+
return text
|
|
339
|
+
// Bold: **text** -> *text*
|
|
340
|
+
.replace(/\*\*([^*]+)\*\*/g, '*$1*')
|
|
341
|
+
// Italic: _text_ stays the same
|
|
342
|
+
// Code: `code` stays the same
|
|
343
|
+
// Links: [text](url) -> <url|text>
|
|
344
|
+
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<$2|$1>');
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Generate Slack Block Kit message structure
|
|
348
|
+
*/
|
|
349
|
+
export function generateSlackBlocks(text, options) {
|
|
350
|
+
const blocks = [
|
|
351
|
+
{
|
|
352
|
+
type: 'section',
|
|
353
|
+
text: {
|
|
354
|
+
type: 'mrkdwn',
|
|
355
|
+
text: formatForSlack(text),
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
];
|
|
359
|
+
if (options?.includeActions && options.conversationId) {
|
|
360
|
+
blocks.push({
|
|
361
|
+
type: 'actions',
|
|
362
|
+
elements: [
|
|
363
|
+
{
|
|
364
|
+
type: 'button',
|
|
365
|
+
text: {
|
|
366
|
+
type: 'plain_text',
|
|
367
|
+
text: 'View in Portal',
|
|
368
|
+
emoji: true,
|
|
369
|
+
},
|
|
370
|
+
url: `${config.escalation.adminBaseUrl}/support/${options.conversationId}`,
|
|
371
|
+
action_id: 'view_in_portal',
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
return blocks;
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=slack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../src/intake/slack.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEnE,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GAGvB,MAAM,iBAAiB,CAAC;AAuBzB,gFAAgF;AAChF,uBAAuB;AACvB,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,SAAiB,EACjB,SAAiB,EACjB,IAAY,EACZ,aAAqB;IAErB,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa,EAAE,CAAC;QAC/C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,+CAA+C;IAC/C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,GAAG,EAAE,CAAC;QAC3C,kCAAkC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,kCAAkC;IAClC,MAAM,OAAO,GAAG,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;IAE1C,8BAA8B;IAC9B,MAAM,iBAAiB,GAAG,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEpG,yBAAyB;IACzB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAE5C,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,SAAiB,EACjB,IAAY;IAEZ,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;IAEjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,6DAA6D;QAC7D,yCAAyC;QACzC,OAAO,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,sBAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;AAC3E,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACd,KAA2B,CAAC,IAAI,KAAK,kBAAkB,CACzD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAwB;IACrD,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,gBAAgB;QAC/B,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,SAAS;QAC/B,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,iDAAiD;QACzE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;QAClB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CACnB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAwB;IACtD,OAAO,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,qEAAqE;IACrE,OAAO,KAAK,CAAC,OAAO,KAAK,aAAa,IAAI,CAAC,QAAQ,IAAI,KAAK,IAAI,CAAC,CAAE,KAA6B,CAAC,MAAM,CAAC,CAAC;AAC3G,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,YAA+B;IAE/B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC;QAEjC,sCAAsC;QACtC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;YACxB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,iBAAiB,EAAE,KAAK;gBACxB,aAAa,EAAE,EAAE;gBACjB,KAAK,EAAE,eAAe;aACvB,CAAC;QACJ,CAAC;QAED,oBAAoB;QACpB,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,iBAAiB,EAAE,KAAK;gBACxB,aAAa,EAAE,EAAE;gBACjB,KAAK,EAAE,qBAAqB;aAC7B,CAAC;QACJ,CAAC;QAED,6CAA6C;QAC7C,MAAM,OAAO,GAAG,qBAAqB,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAEnE,0BAA0B;QAC1B,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAEhC,0CAA0C;QAC1C,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAEjD,2BAA2B;QAC3B,MAAM,EAAE,iBAAiB,EAAE,aAAa,EAAE,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAE7E,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO;YACP,WAAW;YACX,iBAAiB;YACjB,aAAa;SACd,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,iBAAiB,EAAE,KAAK;gBACxB,aAAa,EAAE,EAAE;gBACjB,KAAK,EAAE,KAAK,CAAC,OAAO;aACrB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,iBAAiB,EAAE,KAAK;YACxB,aAAa,EAAE,EAAE;YACjB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wCAAwC;SACzF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,SAAiB,EACjB,SAAiB;IAEjB,6BAA6B;IAC7B,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,sBAAsB,CAAC,OAAO,EAAE;YACxC,OAAO,EAAE,EAAE,MAAM,EAAE,yBAAyB,EAAE;SAC/C,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB;IAClB,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO,EAAE,KAAK;YACd,iBAAiB,EAAE,KAAK;YACxB,aAAa,EAAE,EAAE;YACjB,KAAK,EAAE,sBAAsB;SAC9B,CAAC;IACJ,CAAC;IAED,oCAAoC;IACpC,IAAI,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,OAAO,EAAE,IAAI;YACb,iBAAiB,EAAE,KAAK;YACxB,aAAa,EAAE,EAAE;YACjB,WAAW,EAAE,IAAI;YACjB,iBAAiB,EAAE,OAAO,CAAC,SAAS;SACrC,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,MAAM,YAAY,GAAG,OAA4B,CAAC;IAClD,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,iBAAiB,EAAE,KAAK;YACxB,aAAa,EAAE,EAAE;YACjB,KAAK,EAAE,iCAAiC;SACzC,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;AAC3C,CAAC;AAED,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,sCAAsC;IACtC,MAAM,cAAc,GAAG,iBAAiB,CAAC;IACzC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,KAAK,CAAC;IAEV,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,kDAAkD;IAClD,MAAM,cAAc,GAAG,yBAAyB,CAAC;IACjD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,KAAK,CAAC;IAEV,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,0DAA0D;IAC1D,MAAM,WAAW,GAAG,sCAAsC,CAAC;IAC3D,MAAM,KAAK,GAA2C,EAAE,CAAC;IACzD,IAAI,KAAK,CAAC;IAEV,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACjD,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC;gBACT,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;gBACb,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI;QACT,mCAAmC;SAClC,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;QACpC,yCAAyC;SACxC,OAAO,CAAC,0BAA0B,EAAE,KAAK,CAAC;SAC1C,OAAO,CAAC,iBAAiB,EAAE,UAAU,CAAC;QACvC,2CAA2C;SAC1C,OAAO,CAAC,iCAAiC,EAAE,IAAI,CAAC;SAChD,OAAO,CAAC,uBAAuB,EAAE,IAAI,CAAC;QACvC,yBAAyB;SACxB,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC;SAC5B,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC;SAClC,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC;QACrC,yBAAyB;SACxB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,SAAiB;IAIpE,0EAA0E;IAC1E,8DAA8D;IAE9D,wBAAwB;IACxB,2DAA2D;IAC3D,6DAA6D;IAC7D,SAAS;IAET,OAAO;QACL,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,wBAAwB;KACjC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,YAA+B;IAIvE,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC;IAEjC,oBAAoB;IACpB,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,aAAa,EAAE,KAAK;YACpB,MAAM,EAAE,aAAa;SACtB,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;QACxB,OAAO;YACL,aAAa,EAAE,KAAK;YACpB,MAAM,EAAE,eAAe;SACxB,CAAC;IACJ,CAAC;IAED,yDAAyD;IACzD,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QACtD,OAAO;YACL,aAAa,EAAE,KAAK;YACpB,MAAM,EAAE,sBAAsB;SAC/B,CAAC;IACJ,CAAC;IAED,oCAAoC;IACpC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3E,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACpB,OAAO;YACL,aAAa,EAAE,KAAK;YACpB,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,4BAA4B;SACxD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,aAAa,EAAE,IAAI;KACpB,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,gCAAgC;AAChC,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI;QACT,2BAA2B;SAC1B,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC;QACpC,gCAAgC;QAChC,8BAA8B;QAC9B,mCAAmC;SAClC,OAAO,CAAC,0BAA0B,EAAE,SAAS,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,OAGC;IAED,MAAM,MAAM,GAAc;QACxB;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC;aAC3B;SACF;KACF,CAAC;IAEF,IAAI,OAAO,EAAE,cAAc,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE;wBACJ,IAAI,EAAE,YAAY;wBAClB,IAAI,EAAE,gBAAgB;wBACtB,KAAK,EAAE,IAAI;qBACZ;oBACD,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY,YAAY,OAAO,CAAC,cAAc,EAAE;oBAC1E,SAAS,EAAE,gBAAgB;iBAC5B;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Twilio SMS Webhook Handler
|
|
3
|
+
*
|
|
4
|
+
* Receives incoming SMS messages via Twilio webhook, validates signatures,
|
|
5
|
+
* and normalizes SMS content into the standard message format.
|
|
6
|
+
*/
|
|
7
|
+
import type { InboundMessage } from '../types.js';
|
|
8
|
+
import { type TwilioInboundSms } from './normalizer.js';
|
|
9
|
+
export interface TwilioProcessResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
message?: InboundMessage;
|
|
12
|
+
contentHash?: string;
|
|
13
|
+
hasForbiddenTerms: boolean;
|
|
14
|
+
detectedTerms: string[];
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Validate Twilio webhook signature using HMAC-SHA1
|
|
19
|
+
*
|
|
20
|
+
* Twilio signs webhooks using the auth token and the full URL + params
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateTwilioSignature(signature: string, url: string, params: Record<string, string>, authToken: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Validate Twilio webhook request
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateTwilioWebhook(signature: string, url: string, params: Record<string, string>): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Parse Twilio webhook body (URL-encoded)
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseTwilioBody(body: string): TwilioInboundSms;
|
|
31
|
+
/**
|
|
32
|
+
* Process an inbound Twilio SMS
|
|
33
|
+
*/
|
|
34
|
+
export declare function processTwilioSms(payload: TwilioInboundSms): Promise<TwilioProcessResult>;
|
|
35
|
+
/**
|
|
36
|
+
* Full webhook handler for Twilio inbound SMS
|
|
37
|
+
*/
|
|
38
|
+
export declare function handleTwilioInbound(rawBody: string, signature: string, webhookUrl: string): Promise<TwilioProcessResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Check if message is a STOP/unsubscribe request
|
|
41
|
+
*/
|
|
42
|
+
export declare function isOptOutMessage(body: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Check if message is a help request
|
|
45
|
+
*/
|
|
46
|
+
export declare function isHelpRequest(body: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Classify SMS message type
|
|
49
|
+
*/
|
|
50
|
+
export declare function classifySms(sms: TwilioInboundSms): {
|
|
51
|
+
shouldProcess: boolean;
|
|
52
|
+
reason?: string;
|
|
53
|
+
classification: 'support' | 'opt_out' | 'help' | 'empty';
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Check if SMS includes media attachments (MMS)
|
|
57
|
+
*/
|
|
58
|
+
export declare function hasMmsAttachments(sms: TwilioInboundSms): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Extract MMS media URLs
|
|
61
|
+
*/
|
|
62
|
+
export declare function extractMmsMedia(sms: TwilioInboundSms): Array<{
|
|
63
|
+
url: string;
|
|
64
|
+
contentType: string;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* Extract country code from phone number
|
|
68
|
+
*/
|
|
69
|
+
export declare function extractCountryCode(phone: string): string | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Determine if phone number is US/Canada
|
|
72
|
+
*/
|
|
73
|
+
export declare function isNorthAmericanNumber(phone: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Generate TwiML response for immediate reply
|
|
76
|
+
*/
|
|
77
|
+
export declare function generateTwimlResponse(message?: string): string;
|
|
78
|
+
/**
|
|
79
|
+
* Generate TwiML for opt-out confirmation
|
|
80
|
+
*/
|
|
81
|
+
export declare function generateOptOutResponse(): string;
|
|
82
|
+
/**
|
|
83
|
+
* Generate TwiML for help response
|
|
84
|
+
*/
|
|
85
|
+
export declare function generateHelpResponse(): string;
|
|
86
|
+
//# sourceMappingURL=twilio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"twilio.d.ts","sourceRoot":"","sources":["../../src/intake/twilio.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAMzB,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CA6BT;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAST;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAS9D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAsC9B;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAqB9B;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAerD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKnD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,gBAAgB,GAAG;IAClD,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;CAC1D,CA8BA;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAGhE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,gBAAgB,GACpB,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB7C;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAwBpE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG5D;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAe9D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAI/C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C"}
|