@skillhq/concierge 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -0
- package/dist/cli/program.d.ts +3 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +46 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/shared.d.ts +18 -0
- package/dist/cli/shared.d.ts.map +1 -0
- package/dist/cli/shared.js +2 -0
- package/dist/cli/shared.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/call.d.ts +7 -0
- package/dist/commands/call.d.ts.map +1 -0
- package/dist/commands/call.js +409 -0
- package/dist/commands/call.js.map +1 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +120 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/find-contact.d.ts +4 -0
- package/dist/commands/find-contact.d.ts.map +1 -0
- package/dist/commands/find-contact.js +57 -0
- package/dist/commands/find-contact.js.map +1 -0
- package/dist/commands/server.d.ts +7 -0
- package/dist/commands/server.d.ts.map +1 -0
- package/dist/commands/server.js +212 -0
- package/dist/commands/server.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/call/audio/mulaw.d.ts +35 -0
- package/dist/lib/call/audio/mulaw.d.ts.map +1 -0
- package/dist/lib/call/audio/mulaw.js +109 -0
- package/dist/lib/call/audio/mulaw.js.map +1 -0
- package/dist/lib/call/audio/pcm-utils.d.ts +62 -0
- package/dist/lib/call/audio/pcm-utils.d.ts.map +1 -0
- package/dist/lib/call/audio/pcm-utils.js +149 -0
- package/dist/lib/call/audio/pcm-utils.js.map +1 -0
- package/dist/lib/call/audio/resample.d.ts +34 -0
- package/dist/lib/call/audio/resample.d.ts.map +1 -0
- package/dist/lib/call/audio/resample.js +97 -0
- package/dist/lib/call/audio/resample.js.map +1 -0
- package/dist/lib/call/audio/streaming-decoder.d.ts +45 -0
- package/dist/lib/call/audio/streaming-decoder.d.ts.map +1 -0
- package/dist/lib/call/audio/streaming-decoder.js +110 -0
- package/dist/lib/call/audio/streaming-decoder.js.map +1 -0
- package/dist/lib/call/call-server.d.ts +110 -0
- package/dist/lib/call/call-server.d.ts.map +1 -0
- package/dist/lib/call/call-server.js +681 -0
- package/dist/lib/call/call-server.js.map +1 -0
- package/dist/lib/call/call-session.d.ts +133 -0
- package/dist/lib/call/call-session.d.ts.map +1 -0
- package/dist/lib/call/call-session.js +890 -0
- package/dist/lib/call/call-session.js.map +1 -0
- package/dist/lib/call/call-types.d.ts +133 -0
- package/dist/lib/call/call-types.d.ts.map +1 -0
- package/dist/lib/call/call-types.js +16 -0
- package/dist/lib/call/call-types.js.map +1 -0
- package/dist/lib/call/conversation-ai.d.ts +56 -0
- package/dist/lib/call/conversation-ai.d.ts.map +1 -0
- package/dist/lib/call/conversation-ai.js +276 -0
- package/dist/lib/call/conversation-ai.js.map +1 -0
- package/dist/lib/call/eval/codec-test.d.ts +45 -0
- package/dist/lib/call/eval/codec-test.d.ts.map +1 -0
- package/dist/lib/call/eval/codec-test.js +169 -0
- package/dist/lib/call/eval/codec-test.js.map +1 -0
- package/dist/lib/call/eval/conversation-scripts.d.ts +55 -0
- package/dist/lib/call/eval/conversation-scripts.d.ts.map +1 -0
- package/dist/lib/call/eval/conversation-scripts.js +359 -0
- package/dist/lib/call/eval/conversation-scripts.js.map +1 -0
- package/dist/lib/call/eval/eval-runner.d.ts +64 -0
- package/dist/lib/call/eval/eval-runner.d.ts.map +1 -0
- package/dist/lib/call/eval/eval-runner.js +369 -0
- package/dist/lib/call/eval/eval-runner.js.map +1 -0
- package/dist/lib/call/eval/index.d.ts +9 -0
- package/dist/lib/call/eval/index.d.ts.map +1 -0
- package/dist/lib/call/eval/index.js +9 -0
- package/dist/lib/call/eval/index.js.map +1 -0
- package/dist/lib/call/eval/integration-test-suite.d.ts +71 -0
- package/dist/lib/call/eval/integration-test-suite.d.ts.map +1 -0
- package/dist/lib/call/eval/integration-test-suite.js +519 -0
- package/dist/lib/call/eval/integration-test-suite.js.map +1 -0
- package/dist/lib/call/eval/turn-taking-test.d.ts +84 -0
- package/dist/lib/call/eval/turn-taking-test.d.ts.map +1 -0
- package/dist/lib/call/eval/turn-taking-test.js +260 -0
- package/dist/lib/call/eval/turn-taking-test.js.map +1 -0
- package/dist/lib/call/index.d.ts +12 -0
- package/dist/lib/call/index.d.ts.map +1 -0
- package/dist/lib/call/index.js +17 -0
- package/dist/lib/call/index.js.map +1 -0
- package/dist/lib/call/providers/deepgram.d.ts +81 -0
- package/dist/lib/call/providers/deepgram.d.ts.map +1 -0
- package/dist/lib/call/providers/deepgram.js +279 -0
- package/dist/lib/call/providers/deepgram.js.map +1 -0
- package/dist/lib/call/providers/elevenlabs.d.ts +78 -0
- package/dist/lib/call/providers/elevenlabs.d.ts.map +1 -0
- package/dist/lib/call/providers/elevenlabs.js +272 -0
- package/dist/lib/call/providers/elevenlabs.js.map +1 -0
- package/dist/lib/call/providers/local-deps.d.ts +18 -0
- package/dist/lib/call/providers/local-deps.d.ts.map +1 -0
- package/dist/lib/call/providers/local-deps.js +114 -0
- package/dist/lib/call/providers/local-deps.js.map +1 -0
- package/dist/lib/call/providers/twilio.d.ts +53 -0
- package/dist/lib/call/providers/twilio.d.ts.map +1 -0
- package/dist/lib/call/providers/twilio.js +173 -0
- package/dist/lib/call/providers/twilio.js.map +1 -0
- package/dist/lib/concierge-client-types.d.ts +68 -0
- package/dist/lib/concierge-client-types.d.ts.map +1 -0
- package/dist/lib/concierge-client-types.js +2 -0
- package/dist/lib/concierge-client-types.js.map +1 -0
- package/dist/lib/concierge-client.d.ts +29 -0
- package/dist/lib/concierge-client.d.ts.map +1 -0
- package/dist/lib/concierge-client.js +534 -0
- package/dist/lib/concierge-client.js.map +1 -0
- package/dist/lib/config.d.ts +9 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +66 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/output.d.ts +7 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +114 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/utils/contact-extractor.d.ts +12 -0
- package/dist/lib/utils/contact-extractor.d.ts.map +1 -0
- package/dist/lib/utils/contact-extractor.js +159 -0
- package/dist/lib/utils/contact-extractor.js.map +1 -0
- package/dist/lib/utils/formatters.d.ts +15 -0
- package/dist/lib/utils/formatters.d.ts.map +1 -0
- package/dist/lib/utils/formatters.js +107 -0
- package/dist/lib/utils/formatters.js.map +1 -0
- package/dist/lib/utils/url-parser.d.ts +11 -0
- package/dist/lib/utils/url-parser.d.ts.map +1 -0
- package/dist/lib/utils/url-parser.js +103 -0
- package/dist/lib/utils/url-parser.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Twilio provider for phone calls
|
|
3
|
+
*/
|
|
4
|
+
import Twilio from 'twilio';
|
|
5
|
+
/**
|
|
6
|
+
* Preflight check for Twilio call readiness.
|
|
7
|
+
* Verifies credentials, account status, and that the configured from number exists on the account.
|
|
8
|
+
*/
|
|
9
|
+
export async function preflightTwilioCallSetup(config) {
|
|
10
|
+
const client = Twilio(config.twilioAccountSid, config.twilioAuthToken);
|
|
11
|
+
const formattedFrom = formatPhoneNumber(config.twilioPhoneNumber);
|
|
12
|
+
try {
|
|
13
|
+
const account = await client.api.v2010.accounts(config.twilioAccountSid).fetch();
|
|
14
|
+
const accountStatus = account.status;
|
|
15
|
+
if (accountStatus && accountStatus !== 'active') {
|
|
16
|
+
return {
|
|
17
|
+
ok: false,
|
|
18
|
+
provider: 'twilio',
|
|
19
|
+
accountStatus,
|
|
20
|
+
message: `Twilio preflight failed: account status is "${accountStatus}".`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const ownedNumbers = await client.incomingPhoneNumbers.list({
|
|
24
|
+
phoneNumber: formattedFrom,
|
|
25
|
+
limit: 1,
|
|
26
|
+
});
|
|
27
|
+
const fromNumberVerified = ownedNumbers.length > 0;
|
|
28
|
+
if (!fromNumberVerified) {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
provider: 'twilio',
|
|
32
|
+
accountStatus,
|
|
33
|
+
fromNumberVerified,
|
|
34
|
+
message: `Twilio preflight failed: configured from-number ${formattedFrom} was not found on this Twilio account.`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
ok: true,
|
|
39
|
+
provider: 'twilio',
|
|
40
|
+
accountStatus,
|
|
41
|
+
fromNumberVerified,
|
|
42
|
+
message: `Twilio preflight passed: account active and from-number ${formattedFrom} is configured.`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
provider: 'twilio',
|
|
50
|
+
message: `Twilio preflight failed: ${message}`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Initiate an outbound call via Twilio
|
|
56
|
+
*/
|
|
57
|
+
export async function initiateCall(config, toNumber, callId) {
|
|
58
|
+
const client = Twilio(config.twilioAccountSid, config.twilioAuthToken);
|
|
59
|
+
// TwiML URL for the call - points to our webhook that returns Media Streams TwiML
|
|
60
|
+
const twimlUrl = `${config.publicUrl}/twilio/voice?callId=${encodeURIComponent(callId)}`;
|
|
61
|
+
// Status callback URL
|
|
62
|
+
const statusCallbackUrl = `${config.publicUrl}/twilio/status?callId=${encodeURIComponent(callId)}`;
|
|
63
|
+
const call = await client.calls.create({
|
|
64
|
+
to: toNumber,
|
|
65
|
+
from: config.twilioPhoneNumber,
|
|
66
|
+
url: twimlUrl,
|
|
67
|
+
method: 'POST',
|
|
68
|
+
statusCallback: statusCallbackUrl,
|
|
69
|
+
statusCallbackEvent: ['initiated', 'ringing', 'answered', 'completed'],
|
|
70
|
+
statusCallbackMethod: 'POST',
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
callSid: call.sid,
|
|
74
|
+
status: call.status,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Generate TwiML for Media Streams connection
|
|
79
|
+
*/
|
|
80
|
+
export function generateMediaStreamsTwiml(config, callId) {
|
|
81
|
+
const wsUrl = `${config.publicUrl.replace('https://', 'wss://').replace('http://', 'ws://')}/media-stream?callId=${encodeURIComponent(callId)}`;
|
|
82
|
+
// Using template literal for TwiML - cleaner than string concatenation
|
|
83
|
+
// track="inbound_track" is REQUIRED to receive the caller's audio for STT
|
|
84
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
85
|
+
<Response>
|
|
86
|
+
<Connect>
|
|
87
|
+
<Stream url="${escapeXml(wsUrl)}" track="inbound_track">
|
|
88
|
+
<Parameter name="callId" value="${escapeXml(callId)}" />
|
|
89
|
+
</Stream>
|
|
90
|
+
</Connect>
|
|
91
|
+
</Response>`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Generate TwiML to say something and hang up (for errors)
|
|
95
|
+
*/
|
|
96
|
+
export function generateErrorTwiml(message) {
|
|
97
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
98
|
+
<Response>
|
|
99
|
+
<Say voice="alice">${escapeXml(message)}</Say>
|
|
100
|
+
<Hangup />
|
|
101
|
+
</Response>`;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Hang up an active call
|
|
105
|
+
*/
|
|
106
|
+
export async function hangupCall(config, callSid) {
|
|
107
|
+
const client = Twilio(config.twilioAccountSid, config.twilioAuthToken);
|
|
108
|
+
await client.calls(callSid).update({
|
|
109
|
+
status: 'completed',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get call status
|
|
114
|
+
*/
|
|
115
|
+
export async function getCallStatus(config, callSid) {
|
|
116
|
+
const client = Twilio(config.twilioAccountSid, config.twilioAuthToken);
|
|
117
|
+
const call = await client.calls(callSid).fetch();
|
|
118
|
+
return call.status;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Parse Twilio webhook body
|
|
122
|
+
*/
|
|
123
|
+
export function parseWebhookBody(body) {
|
|
124
|
+
if (typeof body === 'string') {
|
|
125
|
+
// Parse URL-encoded body
|
|
126
|
+
const params = new URLSearchParams(body);
|
|
127
|
+
const result = {};
|
|
128
|
+
for (const [key, value] of params) {
|
|
129
|
+
result[key] = value;
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
return body;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Validate Twilio webhook signature (optional but recommended for production)
|
|
137
|
+
*/
|
|
138
|
+
export function validateWebhookSignature(config, signature, url, params) {
|
|
139
|
+
return Twilio.validateRequest(config.twilioAuthToken, signature, url, params);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Format phone number to E.164 format
|
|
143
|
+
*/
|
|
144
|
+
export function formatPhoneNumber(phone) {
|
|
145
|
+
// Remove all non-digit characters except leading +
|
|
146
|
+
let cleaned = phone.replace(/[^\d+]/g, '');
|
|
147
|
+
// Ensure it starts with +
|
|
148
|
+
if (!cleaned.startsWith('+')) {
|
|
149
|
+
// Assume US number if no country code
|
|
150
|
+
if (cleaned.length === 10) {
|
|
151
|
+
cleaned = `+1${cleaned}`;
|
|
152
|
+
}
|
|
153
|
+
else if (cleaned.length === 11 && cleaned.startsWith('1')) {
|
|
154
|
+
cleaned = `+${cleaned}`;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
cleaned = `+${cleaned}`;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return cleaned;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Escape XML special characters
|
|
164
|
+
*/
|
|
165
|
+
function escapeXml(str) {
|
|
166
|
+
return str
|
|
167
|
+
.replace(/&/g, '&')
|
|
168
|
+
.replace(/</g, '<')
|
|
169
|
+
.replace(/>/g, '>')
|
|
170
|
+
.replace(/"/g, '"')
|
|
171
|
+
.replace(/'/g, ''');
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=twilio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"twilio.js","sourceRoot":"","sources":["../../../../src/lib/call/providers/twilio.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAgB5B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAkB;IAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAElE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,KAAK,EAAE,CAAC;QACjF,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;QAErC,IAAI,aAAa,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;YAChD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,QAAQ,EAAE,QAAQ;gBAClB,aAAa;gBACb,OAAO,EAAE,+CAA+C,aAAa,IAAI;aAC1E,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC;YAC1D,WAAW,EAAE,aAAa;YAC1B,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QACH,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;QAEnD,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,QAAQ,EAAE,QAAQ;gBAClB,aAAa;gBACb,kBAAkB;gBAClB,OAAO,EAAE,mDAAmD,aAAa,wCAAwC;aAClH,CAAC;QACJ,CAAC;QAED,OAAO;YACL,EAAE,EAAE,IAAI;YACR,QAAQ,EAAE,QAAQ;YAClB,aAAa;YACb,kBAAkB;YAClB,OAAO,EAAE,2DAA2D,aAAa,iBAAiB;SACnG,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,4BAA4B,OAAO,EAAE;SAC/C,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAkB,EAAE,QAAgB,EAAE,MAAc;IACrF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IAEvE,kFAAkF;IAClF,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,SAAS,wBAAwB,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;IAEzF,sBAAsB;IACtB,MAAM,iBAAiB,GAAG,GAAG,MAAM,CAAC,SAAS,yBAAyB,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;IAEnG,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QACrC,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,MAAM,CAAC,iBAAiB;QAC9B,GAAG,EAAE,QAAQ;QACb,MAAM,EAAE,MAAM;QACd,cAAc,EAAE,iBAAiB;QACjC,mBAAmB,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC;QACtE,oBAAoB,EAAE,MAAM;KAC7B,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,GAAG;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAkB,EAAE,MAAc;IAC1E,MAAM,KAAK,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,wBAAwB,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;IAEhJ,uEAAuE;IACvE,0EAA0E;IAC1E,OAAO;;;mBAGU,SAAS,CAAC,KAAK,CAAC;wCACK,SAAS,CAAC,MAAM,CAAC;;;YAG7C,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,OAAO;;uBAEc,SAAS,CAAC,OAAO,CAAC;;YAE7B,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAkB,EAAE,OAAe;IAClE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IAEvE,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QACjC,MAAM,EAAE,WAAW;KACpB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAkB,EAAE,OAAe;IACrE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;IACjD,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAqC;IACpE,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,yBAAyB;QACzB,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;QACD,OAAO,MAAuC,CAAC;IACjD,CAAC;IACD,OAAO,IAAqC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAkB,EAClB,SAAiB,EACjB,GAAW,EACX,MAA8B;IAE9B,OAAO,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,eAAe,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,mDAAmD;IACnD,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAE3C,0BAA0B;IAC1B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,sCAAsC;QACtC,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YAC1B,OAAO,GAAG,KAAK,OAAO,EAAE,CAAC;QAC3B,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5D,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export type Platform = 'airbnb' | 'booking' | 'vrbo' | 'expedia' | 'unknown';
|
|
2
|
+
export interface LocationInfo {
|
|
3
|
+
city?: string;
|
|
4
|
+
region?: string;
|
|
5
|
+
country?: string;
|
|
6
|
+
address?: string;
|
|
7
|
+
coordinates?: {
|
|
8
|
+
lat: number;
|
|
9
|
+
lng: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface PropertyInfo {
|
|
13
|
+
platform: Platform;
|
|
14
|
+
name: string;
|
|
15
|
+
location: LocationInfo;
|
|
16
|
+
hostName?: string;
|
|
17
|
+
listingUrl: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ContactInfo {
|
|
20
|
+
phone: string[];
|
|
21
|
+
email: string[];
|
|
22
|
+
whatsapp?: string;
|
|
23
|
+
instagram?: string;
|
|
24
|
+
facebook?: string;
|
|
25
|
+
website?: string;
|
|
26
|
+
googleMapsUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
export type SourceType = 'listing' | 'website' | 'google-places' | 'instagram' | 'facebook' | 'google-search';
|
|
29
|
+
export type ConfidenceLevel = 'high' | 'medium' | 'low';
|
|
30
|
+
export interface SourceInfo {
|
|
31
|
+
type: SourceType;
|
|
32
|
+
url?: string;
|
|
33
|
+
confidence: ConfidenceLevel;
|
|
34
|
+
note?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface ContactDossier {
|
|
37
|
+
property: PropertyInfo;
|
|
38
|
+
contacts: ContactInfo;
|
|
39
|
+
sources: SourceInfo[];
|
|
40
|
+
searchedAt: string;
|
|
41
|
+
}
|
|
42
|
+
export type Result<T> = {
|
|
43
|
+
success: true;
|
|
44
|
+
data: T;
|
|
45
|
+
} | {
|
|
46
|
+
success: false;
|
|
47
|
+
error: string;
|
|
48
|
+
};
|
|
49
|
+
export interface ConciergeConfig {
|
|
50
|
+
googlePlacesApiKey?: string;
|
|
51
|
+
instagramSessionId?: string;
|
|
52
|
+
timeoutMs?: number;
|
|
53
|
+
twilioAccountSid?: string;
|
|
54
|
+
twilioAuthToken?: string;
|
|
55
|
+
twilioPhoneNumber?: string;
|
|
56
|
+
deepgramApiKey?: string;
|
|
57
|
+
elevenLabsApiKey?: string;
|
|
58
|
+
elevenLabsVoiceId?: string;
|
|
59
|
+
ngrokAuthToken?: string;
|
|
60
|
+
callServerPort?: number;
|
|
61
|
+
anthropicApiKey?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface FetchOptions {
|
|
64
|
+
timeout?: number;
|
|
65
|
+
headers?: Record<string, string>;
|
|
66
|
+
}
|
|
67
|
+
export type Constructor<T = object> = new (...args: any[]) => T;
|
|
68
|
+
//# sourceMappingURL=concierge-client-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concierge-client-types.d.ts","sourceRoot":"","sources":["../../src/lib/concierge-client-types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAG7E,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAGD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,eAAe,CAAC;AAC9G,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAExD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,WAAW,CAAC;IACtB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAGvF,MAAM,WAAW,eAAe;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAGD,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAID,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concierge-client-types.js","sourceRoot":"","sources":["../../src/lib/concierge-client-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ConciergeConfig, ContactDossier, Result } from './concierge-client-types.js';
|
|
2
|
+
export interface FindContactOptions {
|
|
3
|
+
html?: string;
|
|
4
|
+
verbose?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare class ConciergeClient {
|
|
7
|
+
private config;
|
|
8
|
+
constructor(config?: Partial<ConciergeConfig>);
|
|
9
|
+
private get timeout();
|
|
10
|
+
private fetchWithTimeout;
|
|
11
|
+
private fetchJson;
|
|
12
|
+
private log;
|
|
13
|
+
findContacts(url: string, options?: FindContactOptions): Promise<Result<ContactDossier>>;
|
|
14
|
+
private parseAirbnbHtml;
|
|
15
|
+
private parseBookingHtml;
|
|
16
|
+
private parseVrboHtml;
|
|
17
|
+
private parseExpediaHtml;
|
|
18
|
+
private parseJsonLd;
|
|
19
|
+
private searchGooglePlaces;
|
|
20
|
+
private scrapeWebsiteContacts;
|
|
21
|
+
private scrapeContactPage;
|
|
22
|
+
private lookupInstagramProfile;
|
|
23
|
+
private formatLocation;
|
|
24
|
+
private buildSearchQuery;
|
|
25
|
+
private mergePartialContacts;
|
|
26
|
+
private hasAnyPartialContact;
|
|
27
|
+
private deduplicateSources;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=concierge-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concierge-client.d.ts","sourceRoot":"","sources":["../../src/lib/concierge-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAId,MAAM,EAEP,MAAM,6BAA6B,CAAC;AAMrC,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA4BD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAK7C,OAAO,KAAK,OAAO,GAElB;YAEa,gBAAgB;YAwChB,SAAS;IAqCvB,OAAO,CAAC,GAAG;IAML,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAyGlG,OAAO,CAAC,eAAe;IAoCvB,OAAO,CAAC,gBAAgB;IAgCxB,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,gBAAgB;IA+BxB,OAAO,CAAC,WAAW;YAiCL,kBAAkB;YAmElB,qBAAqB;YAuBrB,iBAAiB;YAiDjB,sBAAsB;IAwDpC,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,kBAAkB;CAS3B"}
|