@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 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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pocketping/sdk-node",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "description": "Node.js SDK for implementing PocketPing protocol",
6
6
  "main": "dist/index.cjs",