sproutkit-code 1.14.0 → 1.15.1
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.js +59 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -407,7 +407,7 @@ var require_db = __commonJS({
|
|
|
407
407
|
} catch {
|
|
408
408
|
}
|
|
409
409
|
}
|
|
410
|
-
for (const col of ["receptionist_id TEXT", "receptionist_url TEXT", "receptionist_price_pence INTEGER"]) {
|
|
410
|
+
for (const col of ["receptionist_id TEXT", "receptionist_url TEXT", "receptionist_price_pence INTEGER", "receptionist_line TEXT"]) {
|
|
411
411
|
try {
|
|
412
412
|
db2.exec(`ALTER TABLE leads ADD COLUMN ${col}`);
|
|
413
413
|
} catch {
|
|
@@ -84479,6 +84479,7 @@ var require_pitch_text = __commonJS({
|
|
|
84479
84479
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
84480
84480
|
exports2.withVideo = withVideo;
|
|
84481
84481
|
exports2.withReceptionist = withReceptionist;
|
|
84482
|
+
exports2.prettyNumber = prettyNumber;
|
|
84482
84483
|
function withVideo(message, videoUrl) {
|
|
84483
84484
|
if (!videoUrl)
|
|
84484
84485
|
return message.replace(/\n?[^\n]*\{video\}[^\n]*/g, "");
|
|
@@ -84494,12 +84495,13 @@ ${line}`;
|
|
|
84494
84495
|
lines.splice(at + 1, 0, "", line);
|
|
84495
84496
|
return lines.join("\n");
|
|
84496
84497
|
}
|
|
84497
|
-
function withReceptionist(message, url) {
|
|
84498
|
+
function withReceptionist(message, url, demoNumber, businessName) {
|
|
84499
|
+
void demoNumber;
|
|
84498
84500
|
if (!url)
|
|
84499
84501
|
return message.replace(/\n?[^\n]*\{receptionist\}[^\n]*/g, "");
|
|
84500
84502
|
if (message.includes("{receptionist}"))
|
|
84501
84503
|
return message.replace(/\{receptionist\}/g, url);
|
|
84502
|
-
const line = `I've also set up an AI receptionist that would answer your calls 24/7.
|
|
84504
|
+
const line = `I've also set up an AI receptionist for ${businessName ?? "you"} that would answer your calls 24/7 when you can't. You can talk to it here: ${url}`;
|
|
84503
84505
|
const lines = message.split("\n");
|
|
84504
84506
|
const at = lines.findIndex((l) => /https?:\/\//.test(l));
|
|
84505
84507
|
if (at < 0)
|
|
@@ -84509,6 +84511,20 @@ ${line}`;
|
|
|
84509
84511
|
lines.splice(at + 1, 0, "", line);
|
|
84510
84512
|
return lines.join("\n");
|
|
84511
84513
|
}
|
|
84514
|
+
function prettyNumber(e164) {
|
|
84515
|
+
const d = e164.replace(/[^\d+]/g, "");
|
|
84516
|
+
if (d.startsWith("+44")) {
|
|
84517
|
+
const n = "0" + d.slice(3);
|
|
84518
|
+
if (/^0(1\d1|11\d)/.test(n))
|
|
84519
|
+
return `${n.slice(0, 4)} ${n.slice(4, 7)} ${n.slice(7)}`;
|
|
84520
|
+
if (/^02/.test(n))
|
|
84521
|
+
return `${n.slice(0, 3)} ${n.slice(3, 7)} ${n.slice(7)}`;
|
|
84522
|
+
return `${n.slice(0, 5)} ${n.slice(5)}`;
|
|
84523
|
+
}
|
|
84524
|
+
if (d.startsWith("+1") && d.length === 12)
|
|
84525
|
+
return `(${d.slice(2, 5)}) ${d.slice(5, 8)}-${d.slice(8)}`;
|
|
84526
|
+
return e164;
|
|
84527
|
+
}
|
|
84512
84528
|
}
|
|
84513
84529
|
});
|
|
84514
84530
|
|
|
@@ -84696,7 +84712,9 @@ var require_receptionist = __commonJS({
|
|
|
84696
84712
|
exports2.buildConfig = buildConfig;
|
|
84697
84713
|
exports2.createTrial = createTrial;
|
|
84698
84714
|
exports2.listReceptionists = listReceptionists;
|
|
84715
|
+
exports2.listAll = listAll;
|
|
84699
84716
|
exports2.activateReceptionist = activateReceptionist;
|
|
84717
|
+
exports2.forwardingSheet = forwardingSheet;
|
|
84700
84718
|
exports2.removeReceptionist = removeReceptionist;
|
|
84701
84719
|
var db_1 = require_db();
|
|
84702
84720
|
var agency_1 = require_agency();
|
|
@@ -84826,20 +84844,39 @@ ${source.slice(0, 6e4)}`
|
|
|
84826
84844
|
const r = await api("POST", "/api/receptionists", {
|
|
84827
84845
|
leadRef: String(leadId),
|
|
84828
84846
|
config,
|
|
84829
|
-
ownerEmail
|
|
84847
|
+
ownerEmail,
|
|
84848
|
+
prospectPhones: config.phone ? [config.phone] : []
|
|
84830
84849
|
});
|
|
84831
|
-
(0, db_1.getDb)().run("UPDATE leads SET receptionist_id = ?, receptionist_url = ?, receptionist_price_pence = COALESCE(receptionist_price_pence, 4900) WHERE id = ?", [
|
|
84832
|
-
|
|
84833
|
-
r.trialUrl,
|
|
84834
|
-
leadId
|
|
84835
|
-
]);
|
|
84836
|
-
return { trialUrl: r.trialUrl, id: r.receptionist.id };
|
|
84850
|
+
(0, db_1.getDb)().run("UPDATE leads SET receptionist_id = ?, receptionist_url = ?, receptionist_line = ?, receptionist_price_pence = COALESCE(receptionist_price_pence, 4900) WHERE id = ?", [r.receptionist.id, r.trialUrl, r.demoNumber, leadId]);
|
|
84851
|
+
return { trialUrl: r.trialUrl, id: r.receptionist.id, demoNumber: r.demoNumber };
|
|
84837
84852
|
}
|
|
84838
84853
|
async function listReceptionists() {
|
|
84839
|
-
return (await
|
|
84840
|
-
}
|
|
84841
|
-
async function
|
|
84842
|
-
return api("
|
|
84854
|
+
return (await listAll()).receptionists;
|
|
84855
|
+
}
|
|
84856
|
+
async function listAll() {
|
|
84857
|
+
return api("GET", "/api/receptionists");
|
|
84858
|
+
}
|
|
84859
|
+
async function activateReceptionist(id, country, ownerEmail, ownerMobile, emergencies) {
|
|
84860
|
+
return api("POST", `/api/receptionists/${id}/activate`, { country, ownerEmail, ownerMobile, emergencies });
|
|
84861
|
+
}
|
|
84862
|
+
function forwardingSheet(receptionistNumber, country) {
|
|
84863
|
+
const n = receptionistNumber.replace(/[^\d+]/g, "");
|
|
84864
|
+
const lines = [
|
|
84865
|
+
`Send missed calls to your AI receptionist`,
|
|
84866
|
+
``,
|
|
84867
|
+
`On your business mobile, dial each code and press call. Your phone still rings first \u2014 the receptionist only picks up when you can't.`,
|
|
84868
|
+
``,
|
|
84869
|
+
`1. When you don't answer: **61*${n}#`,
|
|
84870
|
+
`2. When you're busy: **67*${n}#`,
|
|
84871
|
+
`3. When you have no signal: **62*${n}#`,
|
|
84872
|
+
``,
|
|
84873
|
+
`Check each one is on: *#61# *#67# *#62#`,
|
|
84874
|
+
`To turn it all off again: ##004#`
|
|
84875
|
+
];
|
|
84876
|
+
if (country === "US") {
|
|
84877
|
+
lines.push(``, `On Verizon instead: dial *71${n.replace(/^\+1/, "")} (no answer and busy). To turn it off: *73.`);
|
|
84878
|
+
}
|
|
84879
|
+
return lines.join("\n");
|
|
84843
84880
|
}
|
|
84844
84881
|
async function removeReceptionist(id, leadId) {
|
|
84845
84882
|
await api("DELETE", `/api/receptionists/${id}`);
|
|
@@ -98371,12 +98408,12 @@ If you'd rather not hear from me again, just reply and let me know.`;
|
|
|
98371
98408
|
}
|
|
98372
98409
|
case "prepare_outreach": {
|
|
98373
98410
|
const explicit = input.ids;
|
|
98374
|
-
const rows = explicit && explicit.length > 0 ? db2.all(`SELECT id, name, phone, email, address, city, site_url, lead_kind, booking_platform, booking_url, pitch_video_url, receptionist_url FROM leads WHERE id IN (${explicit.map(() => "?").join(",")})`, explicit) : db2.all(
|
|
98411
|
+
const rows = explicit && explicit.length > 0 ? db2.all(`SELECT id, name, phone, email, address, city, site_url, lead_kind, booking_platform, booking_url, pitch_video_url, receptionist_url, receptionist_line FROM leads WHERE id IN (${explicit.map(() => "?").join(",")})`, explicit) : db2.all(
|
|
98375
98412
|
// Eligible = we have something to show them: either a demo site
|
|
98376
98413
|
// we built (site_url) OR a booking page we built (booking_url).
|
|
98377
98414
|
// Booking leads never get a site_url, so requiring it silently
|
|
98378
98415
|
// excluded every one-shot booking customer.
|
|
98379
|
-
"SELECT id, name, phone, email, address, city, site_url, lead_kind, booking_platform, booking_url, pitch_video_url, receptionist_url FROM leads WHERE status IN ('site_built','discovered') AND ((site_url IS NOT NULL AND site_url != '') OR (booking_url IS NOT NULL AND booking_url != '')) ORDER BY score DESC NULLS LAST, id DESC",
|
|
98416
|
+
"SELECT id, name, phone, email, address, city, site_url, lead_kind, booking_platform, booking_url, pitch_video_url, receptionist_url, receptionist_line FROM leads WHERE status IN ('site_built','discovered') AND ((site_url IS NOT NULL AND site_url != '') OR (booking_url IS NOT NULL AND booking_url != '')) ORDER BY score DESC NULLS LAST, id DESC",
|
|
98380
98417
|
[]
|
|
98381
98418
|
);
|
|
98382
98419
|
const eligible = rows.filter((r) => r.site_url || r.booking_url);
|
|
@@ -98408,15 +98445,18 @@ If you'd rather not hear from me again, just reply and let me know.`;
|
|
|
98408
98445
|
}
|
|
98409
98446
|
}
|
|
98410
98447
|
let receptionistUrl = r.receptionist_url ?? null;
|
|
98448
|
+
let receptionistLine = r.receptionist_line ?? null;
|
|
98411
98449
|
if (!isBookingLead && !receptionistUrl && r.site_url && getDecryptedSetting("receptionist_auto") === "1") {
|
|
98412
98450
|
ctx.emitProgress?.({ channel: "outreach:progress", payload: { msg: `Setting up ${r.name}'s AI receptionist\u2026` } });
|
|
98413
98451
|
try {
|
|
98414
|
-
|
|
98452
|
+
const t = await (0, receptionist_1.createTrial)(r.id);
|
|
98453
|
+
receptionistUrl = t.trialUrl;
|
|
98454
|
+
receptionistLine = t.demoNumber;
|
|
98415
98455
|
} catch {
|
|
98416
98456
|
receptionistUrl = null;
|
|
98417
98457
|
}
|
|
98418
98458
|
}
|
|
98419
|
-
const message = (0, pitch_text_1.withVideo)((0, pitch_text_1.withReceptionist)((isBookingLead ? bookingTemplate : template).replace(/\{name\}/g, r.name).replace(/\{site_url\}/g, (isBookingLead ? r.booking_url : r.site_url) ?? r.site_url ?? "").replace(/\{booking_how\}/g, r.booking_platform || "WhatsApp/phone"), isBookingLead ? null : receptionistUrl), isBookingLead ? null : videoUrl);
|
|
98459
|
+
const message = (0, pitch_text_1.withVideo)((0, pitch_text_1.withReceptionist)((isBookingLead ? bookingTemplate : template).replace(/\{name\}/g, r.name).replace(/\{site_url\}/g, (isBookingLead ? r.booking_url : r.site_url) ?? r.site_url ?? "").replace(/\{booking_how\}/g, r.booking_platform || "WhatsApp/phone"), isBookingLead ? null : receptionistUrl, isBookingLead ? null : receptionistLine, r.name), isBookingLead ? null : videoUrl);
|
|
98420
98460
|
const e164 = toE164(r.phone ?? "");
|
|
98421
98461
|
if (!r.email && smtp && (preferEmail || !e164)) {
|
|
98422
98462
|
ctx.emitProgress?.({
|
|
@@ -100427,7 +100467,7 @@ var require_package2 = __commonJS({
|
|
|
100427
100467
|
"package.json"(exports2, module2) {
|
|
100428
100468
|
module2.exports = {
|
|
100429
100469
|
name: "sproutkit-code",
|
|
100430
|
-
version: "1.
|
|
100470
|
+
version: "1.15.1",
|
|
100431
100471
|
description: "Sproutkit in your terminal \u2014 find leads, build sites, run outreach, all via chat.",
|
|
100432
100472
|
bin: {
|
|
100433
100473
|
sproutkit: "./dist/index.js"
|