@pocketping/sdk-node 1.5.0 → 1.6.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/index.cjs +207 -2
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +207 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1597,10 +1597,140 @@ var WebhookHandler = class {
|
|
|
1597
1597
|
}
|
|
1598
1598
|
};
|
|
1599
1599
|
|
|
1600
|
+
// src/errors.ts
|
|
1601
|
+
var PocketPingSetupError = class extends Error {
|
|
1602
|
+
constructor(options) {
|
|
1603
|
+
const message = `[PocketPing] ${options.bridge} configuration error: ${options.missing} is required`;
|
|
1604
|
+
super(message);
|
|
1605
|
+
this.name = "PocketPingSetupError";
|
|
1606
|
+
this.bridge = options.bridge;
|
|
1607
|
+
this.missing = options.missing;
|
|
1608
|
+
this.guide = options.guide;
|
|
1609
|
+
this.docsUrl = options.docsUrl || `https://pocketping.io/docs/${options.bridge.toLowerCase()}`;
|
|
1610
|
+
console.error(this.getFormattedGuide());
|
|
1611
|
+
}
|
|
1612
|
+
getFormattedGuide() {
|
|
1613
|
+
return `
|
|
1614
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
1615
|
+
\u2502 \u26A0\uFE0F ${this.bridge} Setup Required
|
|
1616
|
+
\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
|
|
1617
|
+
\u2502
|
|
1618
|
+
\u2502 Missing: ${this.missing}
|
|
1619
|
+
\u2502
|
|
1620
|
+
${this.guide.split("\n").map((line) => `\u2502 ${line}`).join("\n")}
|
|
1621
|
+
\u2502
|
|
1622
|
+
\u2502 \u{1F4D6} Full guide: ${this.docsUrl}
|
|
1623
|
+
\u2502
|
|
1624
|
+
\u2502 \u{1F4A1} Quick fix: npx @pocketping/cli init ${this.bridge.toLowerCase()}
|
|
1625
|
+
\u2502
|
|
1626
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
1627
|
+
`;
|
|
1628
|
+
}
|
|
1629
|
+
};
|
|
1630
|
+
var SETUP_GUIDES = {
|
|
1631
|
+
discord: {
|
|
1632
|
+
botToken: `
|
|
1633
|
+
To set up Discord Bot mode:
|
|
1634
|
+
|
|
1635
|
+
1. Go to https://discord.com/developers/applications
|
|
1636
|
+
2. Create a new application
|
|
1637
|
+
3. Go to Bot \u2192 Add Bot \u2192 Reset Token
|
|
1638
|
+
4. Copy the token and set DISCORD_BOT_TOKEN
|
|
1639
|
+
|
|
1640
|
+
Enable MESSAGE CONTENT INTENT in Bot settings!
|
|
1641
|
+
`,
|
|
1642
|
+
channelId: `
|
|
1643
|
+
To get your Discord Channel ID:
|
|
1644
|
+
|
|
1645
|
+
1. Enable Developer Mode in Discord:
|
|
1646
|
+
User Settings \u2192 Advanced \u2192 Developer Mode
|
|
1647
|
+
2. Right-click on your channel \u2192 Copy ID
|
|
1648
|
+
3. Set DISCORD_CHANNEL_ID in your .env
|
|
1649
|
+
|
|
1650
|
+
Tip: Use a Forum channel for organized threads!
|
|
1651
|
+
`,
|
|
1652
|
+
webhookUrl: `
|
|
1653
|
+
To get a Discord Webhook URL:
|
|
1654
|
+
|
|
1655
|
+
1. Go to your channel settings
|
|
1656
|
+
2. Integrations \u2192 Webhooks \u2192 New Webhook
|
|
1657
|
+
3. Copy the Webhook URL
|
|
1658
|
+
|
|
1659
|
+
Note: Webhooks are send-only. Use Bot mode for full features.
|
|
1660
|
+
`
|
|
1661
|
+
},
|
|
1662
|
+
slack: {
|
|
1663
|
+
botToken: `
|
|
1664
|
+
To set up Slack Bot mode:
|
|
1665
|
+
|
|
1666
|
+
1. Go to https://api.slack.com/apps
|
|
1667
|
+
2. Create New App \u2192 From scratch
|
|
1668
|
+
3. OAuth & Permissions \u2192 Add Bot Token Scopes:
|
|
1669
|
+
- chat:write, channels:read, channels:join
|
|
1670
|
+
- channels:history, groups:history, users:read
|
|
1671
|
+
4. Install to Workspace \u2192 Copy Bot Token (xoxb-...)
|
|
1672
|
+
`,
|
|
1673
|
+
channelId: `
|
|
1674
|
+
To get your Slack Channel ID:
|
|
1675
|
+
|
|
1676
|
+
1. Right-click on your channel in Slack
|
|
1677
|
+
2. View channel details
|
|
1678
|
+
3. Scroll down to find Channel ID (starts with C or G)
|
|
1679
|
+
|
|
1680
|
+
For private channels: /invite @YourBotName first
|
|
1681
|
+
`,
|
|
1682
|
+
webhookUrl: `
|
|
1683
|
+
To get a Slack Webhook URL:
|
|
1684
|
+
|
|
1685
|
+
1. Go to https://api.slack.com/apps
|
|
1686
|
+
2. Incoming Webhooks \u2192 Add New Webhook
|
|
1687
|
+
3. Select a channel \u2192 Copy Webhook URL
|
|
1688
|
+
|
|
1689
|
+
Note: Webhooks are send-only. Use Bot mode for full features.
|
|
1690
|
+
`
|
|
1691
|
+
},
|
|
1692
|
+
telegram: {
|
|
1693
|
+
botToken: `
|
|
1694
|
+
To create a Telegram Bot:
|
|
1695
|
+
|
|
1696
|
+
1. Open @BotFather in Telegram
|
|
1697
|
+
2. Send /newbot
|
|
1698
|
+
3. Choose a name and username
|
|
1699
|
+
4. Copy the Bot Token you receive
|
|
1700
|
+
|
|
1701
|
+
Set TELEGRAM_BOT_TOKEN in your .env
|
|
1702
|
+
`,
|
|
1703
|
+
chatId: `
|
|
1704
|
+
To get your Telegram Chat ID:
|
|
1705
|
+
|
|
1706
|
+
1. Create a group and enable Topics (for forums)
|
|
1707
|
+
2. Add your bot to the group as admin
|
|
1708
|
+
3. Add @getidsbot to the group
|
|
1709
|
+
4. Copy the Chat ID (starts with -100)
|
|
1710
|
+
|
|
1711
|
+
The bot needs "Manage Topics" permission!
|
|
1712
|
+
`
|
|
1713
|
+
}
|
|
1714
|
+
};
|
|
1715
|
+
|
|
1600
1716
|
// src/bridges/telegram.ts
|
|
1601
1717
|
var TelegramBridge = class {
|
|
1602
1718
|
constructor(botToken, chatId, options = {}) {
|
|
1603
1719
|
this.name = "telegram";
|
|
1720
|
+
if (!botToken) {
|
|
1721
|
+
throw new PocketPingSetupError({
|
|
1722
|
+
bridge: "Telegram",
|
|
1723
|
+
missing: "botToken",
|
|
1724
|
+
guide: SETUP_GUIDES.telegram.botToken
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1727
|
+
if (!chatId) {
|
|
1728
|
+
throw new PocketPingSetupError({
|
|
1729
|
+
bridge: "Telegram",
|
|
1730
|
+
missing: "chatId",
|
|
1731
|
+
guide: SETUP_GUIDES.telegram.chatId
|
|
1732
|
+
});
|
|
1733
|
+
}
|
|
1604
1734
|
this.botToken = botToken;
|
|
1605
1735
|
this.chatId = chatId;
|
|
1606
1736
|
this.parseMode = options.parseMode ?? "HTML";
|
|
@@ -1769,12 +1899,14 @@ ${dataStr}
|
|
|
1769
1899
|
text = `<b>User Identified</b>
|
|
1770
1900
|
<b>ID:</b> ${this.escapeHtml(identity.id)}
|
|
1771
1901
|
` + (identity.name ? `<b>Name:</b> ${this.escapeHtml(identity.name)}
|
|
1772
|
-
` : "") + (identity.email ? `<b>Email:</b> ${this.escapeHtml(identity.email)}
|
|
1902
|
+
` : "") + (identity.email ? `<b>Email:</b> ${this.escapeHtml(identity.email)}
|
|
1903
|
+
` : "") + (session.userPhone ? `<b>Phone:</b> ${this.escapeHtml(session.userPhone)}` : "");
|
|
1773
1904
|
} else {
|
|
1774
1905
|
text = `*User Identified*
|
|
1775
1906
|
*ID:* ${this.escapeMarkdown(identity.id)}
|
|
1776
1907
|
` + (identity.name ? `*Name:* ${this.escapeMarkdown(identity.name)}
|
|
1777
|
-
` : "") + (identity.email ? `*Email:* ${this.escapeMarkdown(identity.email)}
|
|
1908
|
+
` : "") + (identity.email ? `*Email:* ${this.escapeMarkdown(identity.email)}
|
|
1909
|
+
` : "") + (session.userPhone ? `*Phone:* ${this.escapeMarkdown(session.userPhone)}` : "");
|
|
1778
1910
|
}
|
|
1779
1911
|
try {
|
|
1780
1912
|
await this.sendMessage(text.trim());
|
|
@@ -1872,6 +2004,20 @@ var DiscordBridge = class _DiscordBridge {
|
|
|
1872
2004
|
* Create a Discord bridge using a webhook URL
|
|
1873
2005
|
*/
|
|
1874
2006
|
static webhook(webhookUrl, options = {}) {
|
|
2007
|
+
if (!webhookUrl) {
|
|
2008
|
+
throw new PocketPingSetupError({
|
|
2009
|
+
bridge: "Discord",
|
|
2010
|
+
missing: "webhookUrl",
|
|
2011
|
+
guide: SETUP_GUIDES.discord.webhookUrl
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
if (!webhookUrl.startsWith("https://discord.com/api/webhooks/")) {
|
|
2015
|
+
throw new PocketPingSetupError({
|
|
2016
|
+
bridge: "Discord",
|
|
2017
|
+
missing: "valid webhookUrl",
|
|
2018
|
+
guide: "Webhook URL must start with https://discord.com/api/webhooks/\n\n" + SETUP_GUIDES.discord.webhookUrl
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
1875
2021
|
return new _DiscordBridge({
|
|
1876
2022
|
mode: "webhook",
|
|
1877
2023
|
webhookUrl,
|
|
@@ -1883,6 +2029,20 @@ var DiscordBridge = class _DiscordBridge {
|
|
|
1883
2029
|
* Create a Discord bridge using a bot token
|
|
1884
2030
|
*/
|
|
1885
2031
|
static bot(botToken, channelId, options = {}) {
|
|
2032
|
+
if (!botToken) {
|
|
2033
|
+
throw new PocketPingSetupError({
|
|
2034
|
+
bridge: "Discord",
|
|
2035
|
+
missing: "botToken",
|
|
2036
|
+
guide: SETUP_GUIDES.discord.botToken
|
|
2037
|
+
});
|
|
2038
|
+
}
|
|
2039
|
+
if (!channelId) {
|
|
2040
|
+
throw new PocketPingSetupError({
|
|
2041
|
+
bridge: "Discord",
|
|
2042
|
+
missing: "channelId",
|
|
2043
|
+
guide: SETUP_GUIDES.discord.channelId
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
1886
2046
|
return new _DiscordBridge({
|
|
1887
2047
|
mode: "bot",
|
|
1888
2048
|
botToken,
|
|
@@ -2128,6 +2288,9 @@ ${JSON.stringify(event.data, null, 2)}
|
|
|
2128
2288
|
if (identity.email) {
|
|
2129
2289
|
fields.push({ name: "Email", value: identity.email, inline: true });
|
|
2130
2290
|
}
|
|
2291
|
+
if (session.userPhone) {
|
|
2292
|
+
fields.push({ name: "Phone", value: session.userPhone, inline: true });
|
|
2293
|
+
}
|
|
2131
2294
|
const embed = {
|
|
2132
2295
|
title: "User Identified",
|
|
2133
2296
|
color: 5793266,
|
|
@@ -2213,6 +2376,20 @@ var SlackBridge = class _SlackBridge {
|
|
|
2213
2376
|
* Create a Slack bridge using a webhook URL
|
|
2214
2377
|
*/
|
|
2215
2378
|
static webhook(webhookUrl, options = {}) {
|
|
2379
|
+
if (!webhookUrl) {
|
|
2380
|
+
throw new PocketPingSetupError({
|
|
2381
|
+
bridge: "Slack",
|
|
2382
|
+
missing: "webhookUrl",
|
|
2383
|
+
guide: SETUP_GUIDES.slack.webhookUrl
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
if (!webhookUrl.startsWith("https://hooks.slack.com/")) {
|
|
2387
|
+
throw new PocketPingSetupError({
|
|
2388
|
+
bridge: "Slack",
|
|
2389
|
+
missing: "valid webhookUrl",
|
|
2390
|
+
guide: "Webhook URL must start with https://hooks.slack.com/\n\n" + SETUP_GUIDES.slack.webhookUrl
|
|
2391
|
+
});
|
|
2392
|
+
}
|
|
2216
2393
|
return new _SlackBridge({
|
|
2217
2394
|
mode: "webhook",
|
|
2218
2395
|
webhookUrl,
|
|
@@ -2225,6 +2402,27 @@ var SlackBridge = class _SlackBridge {
|
|
|
2225
2402
|
* Create a Slack bridge using a bot token
|
|
2226
2403
|
*/
|
|
2227
2404
|
static bot(botToken, channelId, options = {}) {
|
|
2405
|
+
if (!botToken) {
|
|
2406
|
+
throw new PocketPingSetupError({
|
|
2407
|
+
bridge: "Slack",
|
|
2408
|
+
missing: "botToken",
|
|
2409
|
+
guide: SETUP_GUIDES.slack.botToken
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
if (!botToken.startsWith("xoxb-")) {
|
|
2413
|
+
throw new PocketPingSetupError({
|
|
2414
|
+
bridge: "Slack",
|
|
2415
|
+
missing: "valid botToken",
|
|
2416
|
+
guide: "Bot token must start with xoxb-\n\n" + SETUP_GUIDES.slack.botToken
|
|
2417
|
+
});
|
|
2418
|
+
}
|
|
2419
|
+
if (!channelId) {
|
|
2420
|
+
throw new PocketPingSetupError({
|
|
2421
|
+
bridge: "Slack",
|
|
2422
|
+
missing: "channelId",
|
|
2423
|
+
guide: SETUP_GUIDES.slack.channelId
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2228
2426
|
return new _SlackBridge({
|
|
2229
2427
|
mode: "bot",
|
|
2230
2428
|
botToken,
|
|
@@ -2516,6 +2714,13 @@ ${identity.name}`
|
|
|
2516
2714
|
${identity.email}`
|
|
2517
2715
|
});
|
|
2518
2716
|
}
|
|
2717
|
+
if (session.userPhone) {
|
|
2718
|
+
fields.push({
|
|
2719
|
+
type: "mrkdwn",
|
|
2720
|
+
text: `*Phone:*
|
|
2721
|
+
${session.userPhone}`
|
|
2722
|
+
});
|
|
2723
|
+
}
|
|
2519
2724
|
const blocks = [
|
|
2520
2725
|
{
|
|
2521
2726
|
type: "header",
|
package/dist/index.d.cts
CHANGED
|
@@ -207,6 +207,10 @@ interface Session {
|
|
|
207
207
|
metadata?: SessionMetadata;
|
|
208
208
|
/** User identity if identified via PocketPing.identify() */
|
|
209
209
|
identity?: UserIdentity;
|
|
210
|
+
/** User phone from pre-chat form (E.164 format: +33612345678) */
|
|
211
|
+
userPhone?: string;
|
|
212
|
+
/** User phone country code (ISO: FR, US, etc.) */
|
|
213
|
+
userPhoneCountry?: string;
|
|
210
214
|
}
|
|
211
215
|
interface SessionMetadata {
|
|
212
216
|
url?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -207,6 +207,10 @@ interface Session {
|
|
|
207
207
|
metadata?: SessionMetadata;
|
|
208
208
|
/** User identity if identified via PocketPing.identify() */
|
|
209
209
|
identity?: UserIdentity;
|
|
210
|
+
/** User phone from pre-chat form (E.164 format: +33612345678) */
|
|
211
|
+
userPhone?: string;
|
|
212
|
+
/** User phone country code (ISO: FR, US, etc.) */
|
|
213
|
+
userPhoneCountry?: string;
|
|
210
214
|
}
|
|
211
215
|
interface SessionMetadata {
|
|
212
216
|
url?: string;
|
package/dist/index.js
CHANGED
|
@@ -1566,10 +1566,140 @@ var WebhookHandler = class {
|
|
|
1566
1566
|
}
|
|
1567
1567
|
};
|
|
1568
1568
|
|
|
1569
|
+
// src/errors.ts
|
|
1570
|
+
var PocketPingSetupError = class extends Error {
|
|
1571
|
+
constructor(options) {
|
|
1572
|
+
const message = `[PocketPing] ${options.bridge} configuration error: ${options.missing} is required`;
|
|
1573
|
+
super(message);
|
|
1574
|
+
this.name = "PocketPingSetupError";
|
|
1575
|
+
this.bridge = options.bridge;
|
|
1576
|
+
this.missing = options.missing;
|
|
1577
|
+
this.guide = options.guide;
|
|
1578
|
+
this.docsUrl = options.docsUrl || `https://pocketping.io/docs/${options.bridge.toLowerCase()}`;
|
|
1579
|
+
console.error(this.getFormattedGuide());
|
|
1580
|
+
}
|
|
1581
|
+
getFormattedGuide() {
|
|
1582
|
+
return `
|
|
1583
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
|
|
1584
|
+
\u2502 \u26A0\uFE0F ${this.bridge} Setup Required
|
|
1585
|
+
\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
|
|
1586
|
+
\u2502
|
|
1587
|
+
\u2502 Missing: ${this.missing}
|
|
1588
|
+
\u2502
|
|
1589
|
+
${this.guide.split("\n").map((line) => `\u2502 ${line}`).join("\n")}
|
|
1590
|
+
\u2502
|
|
1591
|
+
\u2502 \u{1F4D6} Full guide: ${this.docsUrl}
|
|
1592
|
+
\u2502
|
|
1593
|
+
\u2502 \u{1F4A1} Quick fix: npx @pocketping/cli init ${this.bridge.toLowerCase()}
|
|
1594
|
+
\u2502
|
|
1595
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
|
|
1596
|
+
`;
|
|
1597
|
+
}
|
|
1598
|
+
};
|
|
1599
|
+
var SETUP_GUIDES = {
|
|
1600
|
+
discord: {
|
|
1601
|
+
botToken: `
|
|
1602
|
+
To set up Discord Bot mode:
|
|
1603
|
+
|
|
1604
|
+
1. Go to https://discord.com/developers/applications
|
|
1605
|
+
2. Create a new application
|
|
1606
|
+
3. Go to Bot \u2192 Add Bot \u2192 Reset Token
|
|
1607
|
+
4. Copy the token and set DISCORD_BOT_TOKEN
|
|
1608
|
+
|
|
1609
|
+
Enable MESSAGE CONTENT INTENT in Bot settings!
|
|
1610
|
+
`,
|
|
1611
|
+
channelId: `
|
|
1612
|
+
To get your Discord Channel ID:
|
|
1613
|
+
|
|
1614
|
+
1. Enable Developer Mode in Discord:
|
|
1615
|
+
User Settings \u2192 Advanced \u2192 Developer Mode
|
|
1616
|
+
2. Right-click on your channel \u2192 Copy ID
|
|
1617
|
+
3. Set DISCORD_CHANNEL_ID in your .env
|
|
1618
|
+
|
|
1619
|
+
Tip: Use a Forum channel for organized threads!
|
|
1620
|
+
`,
|
|
1621
|
+
webhookUrl: `
|
|
1622
|
+
To get a Discord Webhook URL:
|
|
1623
|
+
|
|
1624
|
+
1. Go to your channel settings
|
|
1625
|
+
2. Integrations \u2192 Webhooks \u2192 New Webhook
|
|
1626
|
+
3. Copy the Webhook URL
|
|
1627
|
+
|
|
1628
|
+
Note: Webhooks are send-only. Use Bot mode for full features.
|
|
1629
|
+
`
|
|
1630
|
+
},
|
|
1631
|
+
slack: {
|
|
1632
|
+
botToken: `
|
|
1633
|
+
To set up Slack Bot mode:
|
|
1634
|
+
|
|
1635
|
+
1. Go to https://api.slack.com/apps
|
|
1636
|
+
2. Create New App \u2192 From scratch
|
|
1637
|
+
3. OAuth & Permissions \u2192 Add Bot Token Scopes:
|
|
1638
|
+
- chat:write, channels:read, channels:join
|
|
1639
|
+
- channels:history, groups:history, users:read
|
|
1640
|
+
4. Install to Workspace \u2192 Copy Bot Token (xoxb-...)
|
|
1641
|
+
`,
|
|
1642
|
+
channelId: `
|
|
1643
|
+
To get your Slack Channel ID:
|
|
1644
|
+
|
|
1645
|
+
1. Right-click on your channel in Slack
|
|
1646
|
+
2. View channel details
|
|
1647
|
+
3. Scroll down to find Channel ID (starts with C or G)
|
|
1648
|
+
|
|
1649
|
+
For private channels: /invite @YourBotName first
|
|
1650
|
+
`,
|
|
1651
|
+
webhookUrl: `
|
|
1652
|
+
To get a Slack Webhook URL:
|
|
1653
|
+
|
|
1654
|
+
1. Go to https://api.slack.com/apps
|
|
1655
|
+
2. Incoming Webhooks \u2192 Add New Webhook
|
|
1656
|
+
3. Select a channel \u2192 Copy Webhook URL
|
|
1657
|
+
|
|
1658
|
+
Note: Webhooks are send-only. Use Bot mode for full features.
|
|
1659
|
+
`
|
|
1660
|
+
},
|
|
1661
|
+
telegram: {
|
|
1662
|
+
botToken: `
|
|
1663
|
+
To create a Telegram Bot:
|
|
1664
|
+
|
|
1665
|
+
1. Open @BotFather in Telegram
|
|
1666
|
+
2. Send /newbot
|
|
1667
|
+
3. Choose a name and username
|
|
1668
|
+
4. Copy the Bot Token you receive
|
|
1669
|
+
|
|
1670
|
+
Set TELEGRAM_BOT_TOKEN in your .env
|
|
1671
|
+
`,
|
|
1672
|
+
chatId: `
|
|
1673
|
+
To get your Telegram Chat ID:
|
|
1674
|
+
|
|
1675
|
+
1. Create a group and enable Topics (for forums)
|
|
1676
|
+
2. Add your bot to the group as admin
|
|
1677
|
+
3. Add @getidsbot to the group
|
|
1678
|
+
4. Copy the Chat ID (starts with -100)
|
|
1679
|
+
|
|
1680
|
+
The bot needs "Manage Topics" permission!
|
|
1681
|
+
`
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
|
|
1569
1685
|
// src/bridges/telegram.ts
|
|
1570
1686
|
var TelegramBridge = class {
|
|
1571
1687
|
constructor(botToken, chatId, options = {}) {
|
|
1572
1688
|
this.name = "telegram";
|
|
1689
|
+
if (!botToken) {
|
|
1690
|
+
throw new PocketPingSetupError({
|
|
1691
|
+
bridge: "Telegram",
|
|
1692
|
+
missing: "botToken",
|
|
1693
|
+
guide: SETUP_GUIDES.telegram.botToken
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
if (!chatId) {
|
|
1697
|
+
throw new PocketPingSetupError({
|
|
1698
|
+
bridge: "Telegram",
|
|
1699
|
+
missing: "chatId",
|
|
1700
|
+
guide: SETUP_GUIDES.telegram.chatId
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1573
1703
|
this.botToken = botToken;
|
|
1574
1704
|
this.chatId = chatId;
|
|
1575
1705
|
this.parseMode = options.parseMode ?? "HTML";
|
|
@@ -1738,12 +1868,14 @@ ${dataStr}
|
|
|
1738
1868
|
text = `<b>User Identified</b>
|
|
1739
1869
|
<b>ID:</b> ${this.escapeHtml(identity.id)}
|
|
1740
1870
|
` + (identity.name ? `<b>Name:</b> ${this.escapeHtml(identity.name)}
|
|
1741
|
-
` : "") + (identity.email ? `<b>Email:</b> ${this.escapeHtml(identity.email)}
|
|
1871
|
+
` : "") + (identity.email ? `<b>Email:</b> ${this.escapeHtml(identity.email)}
|
|
1872
|
+
` : "") + (session.userPhone ? `<b>Phone:</b> ${this.escapeHtml(session.userPhone)}` : "");
|
|
1742
1873
|
} else {
|
|
1743
1874
|
text = `*User Identified*
|
|
1744
1875
|
*ID:* ${this.escapeMarkdown(identity.id)}
|
|
1745
1876
|
` + (identity.name ? `*Name:* ${this.escapeMarkdown(identity.name)}
|
|
1746
|
-
` : "") + (identity.email ? `*Email:* ${this.escapeMarkdown(identity.email)}
|
|
1877
|
+
` : "") + (identity.email ? `*Email:* ${this.escapeMarkdown(identity.email)}
|
|
1878
|
+
` : "") + (session.userPhone ? `*Phone:* ${this.escapeMarkdown(session.userPhone)}` : "");
|
|
1747
1879
|
}
|
|
1748
1880
|
try {
|
|
1749
1881
|
await this.sendMessage(text.trim());
|
|
@@ -1841,6 +1973,20 @@ var DiscordBridge = class _DiscordBridge {
|
|
|
1841
1973
|
* Create a Discord bridge using a webhook URL
|
|
1842
1974
|
*/
|
|
1843
1975
|
static webhook(webhookUrl, options = {}) {
|
|
1976
|
+
if (!webhookUrl) {
|
|
1977
|
+
throw new PocketPingSetupError({
|
|
1978
|
+
bridge: "Discord",
|
|
1979
|
+
missing: "webhookUrl",
|
|
1980
|
+
guide: SETUP_GUIDES.discord.webhookUrl
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
if (!webhookUrl.startsWith("https://discord.com/api/webhooks/")) {
|
|
1984
|
+
throw new PocketPingSetupError({
|
|
1985
|
+
bridge: "Discord",
|
|
1986
|
+
missing: "valid webhookUrl",
|
|
1987
|
+
guide: "Webhook URL must start with https://discord.com/api/webhooks/\n\n" + SETUP_GUIDES.discord.webhookUrl
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1844
1990
|
return new _DiscordBridge({
|
|
1845
1991
|
mode: "webhook",
|
|
1846
1992
|
webhookUrl,
|
|
@@ -1852,6 +1998,20 @@ var DiscordBridge = class _DiscordBridge {
|
|
|
1852
1998
|
* Create a Discord bridge using a bot token
|
|
1853
1999
|
*/
|
|
1854
2000
|
static bot(botToken, channelId, options = {}) {
|
|
2001
|
+
if (!botToken) {
|
|
2002
|
+
throw new PocketPingSetupError({
|
|
2003
|
+
bridge: "Discord",
|
|
2004
|
+
missing: "botToken",
|
|
2005
|
+
guide: SETUP_GUIDES.discord.botToken
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
if (!channelId) {
|
|
2009
|
+
throw new PocketPingSetupError({
|
|
2010
|
+
bridge: "Discord",
|
|
2011
|
+
missing: "channelId",
|
|
2012
|
+
guide: SETUP_GUIDES.discord.channelId
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
1855
2015
|
return new _DiscordBridge({
|
|
1856
2016
|
mode: "bot",
|
|
1857
2017
|
botToken,
|
|
@@ -2097,6 +2257,9 @@ ${JSON.stringify(event.data, null, 2)}
|
|
|
2097
2257
|
if (identity.email) {
|
|
2098
2258
|
fields.push({ name: "Email", value: identity.email, inline: true });
|
|
2099
2259
|
}
|
|
2260
|
+
if (session.userPhone) {
|
|
2261
|
+
fields.push({ name: "Phone", value: session.userPhone, inline: true });
|
|
2262
|
+
}
|
|
2100
2263
|
const embed = {
|
|
2101
2264
|
title: "User Identified",
|
|
2102
2265
|
color: 5793266,
|
|
@@ -2182,6 +2345,20 @@ var SlackBridge = class _SlackBridge {
|
|
|
2182
2345
|
* Create a Slack bridge using a webhook URL
|
|
2183
2346
|
*/
|
|
2184
2347
|
static webhook(webhookUrl, options = {}) {
|
|
2348
|
+
if (!webhookUrl) {
|
|
2349
|
+
throw new PocketPingSetupError({
|
|
2350
|
+
bridge: "Slack",
|
|
2351
|
+
missing: "webhookUrl",
|
|
2352
|
+
guide: SETUP_GUIDES.slack.webhookUrl
|
|
2353
|
+
});
|
|
2354
|
+
}
|
|
2355
|
+
if (!webhookUrl.startsWith("https://hooks.slack.com/")) {
|
|
2356
|
+
throw new PocketPingSetupError({
|
|
2357
|
+
bridge: "Slack",
|
|
2358
|
+
missing: "valid webhookUrl",
|
|
2359
|
+
guide: "Webhook URL must start with https://hooks.slack.com/\n\n" + SETUP_GUIDES.slack.webhookUrl
|
|
2360
|
+
});
|
|
2361
|
+
}
|
|
2185
2362
|
return new _SlackBridge({
|
|
2186
2363
|
mode: "webhook",
|
|
2187
2364
|
webhookUrl,
|
|
@@ -2194,6 +2371,27 @@ var SlackBridge = class _SlackBridge {
|
|
|
2194
2371
|
* Create a Slack bridge using a bot token
|
|
2195
2372
|
*/
|
|
2196
2373
|
static bot(botToken, channelId, options = {}) {
|
|
2374
|
+
if (!botToken) {
|
|
2375
|
+
throw new PocketPingSetupError({
|
|
2376
|
+
bridge: "Slack",
|
|
2377
|
+
missing: "botToken",
|
|
2378
|
+
guide: SETUP_GUIDES.slack.botToken
|
|
2379
|
+
});
|
|
2380
|
+
}
|
|
2381
|
+
if (!botToken.startsWith("xoxb-")) {
|
|
2382
|
+
throw new PocketPingSetupError({
|
|
2383
|
+
bridge: "Slack",
|
|
2384
|
+
missing: "valid botToken",
|
|
2385
|
+
guide: "Bot token must start with xoxb-\n\n" + SETUP_GUIDES.slack.botToken
|
|
2386
|
+
});
|
|
2387
|
+
}
|
|
2388
|
+
if (!channelId) {
|
|
2389
|
+
throw new PocketPingSetupError({
|
|
2390
|
+
bridge: "Slack",
|
|
2391
|
+
missing: "channelId",
|
|
2392
|
+
guide: SETUP_GUIDES.slack.channelId
|
|
2393
|
+
});
|
|
2394
|
+
}
|
|
2197
2395
|
return new _SlackBridge({
|
|
2198
2396
|
mode: "bot",
|
|
2199
2397
|
botToken,
|
|
@@ -2485,6 +2683,13 @@ ${identity.name}`
|
|
|
2485
2683
|
${identity.email}`
|
|
2486
2684
|
});
|
|
2487
2685
|
}
|
|
2686
|
+
if (session.userPhone) {
|
|
2687
|
+
fields.push({
|
|
2688
|
+
type: "mrkdwn",
|
|
2689
|
+
text: `*Phone:*
|
|
2690
|
+
${session.userPhone}`
|
|
2691
|
+
});
|
|
2692
|
+
}
|
|
2488
2693
|
const blocks = [
|
|
2489
2694
|
{
|
|
2490
2695
|
type: "header",
|