npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

whitebox-pro-sms-mobica

v0.2.0

Published

Mobica (gate.mobica.bg) provider for whitebox-pro-server-plugin-sms — HTTP send with a short client-defined id, DLR delivery-status parsing. Send-only (no inbound). No SDK.

Downloads

273

Readme

whitebox-pro-sms-mobica

Mobica provider for whitebox-pro-server-plugin-sms. Lives in its own repo; the SMS plugin stays provider-agnostic and composes this in like any other integration. Mobica is a plain HTTP SMS gateway popular for Bulgaria (+359) — typically used as a per-prefix route alongside an international default like Twilio.

import { sms } from 'whitebox-pro-server-plugin-sms'
import { twilio } from 'whitebox-pro-sms-twilio'
import { mobica } from 'whitebox-pro-sms-mobica'

sms({
  provider: twilio({ /* … international default … */ }),
  routes: {
    '+359': mobica({
      user: process.env.WB_MOBICA_USER,
      pass: process.env.WB_MOBICA_PASS,
      from: 'WhiteBox',                              // alphanumeric sender id
      // instanceId: process.env.WB_INSTANCE_ID,        // per-instance idd prefix; required for DLR fan-out (see below)
      // gate:      'https://gate.mobica.bg/send.php',  // override the gateway URL
      // iddLength: 10,                                 // message-id length (Mobica's `idd` limit)
      // dlrSecret: process.env.WB_MOBICA_DLR_SECRET,   // require ?secret= on the DLR callback
    }),
  },
  defaultCountry: 'BG',
  auth: { secret: process.env.WB_SMS_TOKEN },
})

Send-only (no inbound)

Mobica is a one-way gateway: it sends and reports delivery, but does not deliver inbound replies (MO). So this provider implements send + parseStatus but not parseInbound — the plugin's inbound webhook returns 501 for mobica. There is consequently no inbound STOP/START path through Mobica; manage Bulgarian opt-outs via the suppression API or route a reply-capable number through another provider.

Client-defined message id

Mobica's idd field (the id the DLR references) is short and won't hold a UUID. This provider generates a compact 10-char base62 id per send, passes it as idd, and returns it as messageId — so the plugin's outbox matches DLRs on that id. Tune the length with iddLength if your Mobica account differs.

Multi-instance DLR fan-out (instanceId)

Mobica allows one DLR callback URL per account, set via Mobica support — there's no per-message callback parameter (confirmed against the v2 API docs) and no subaccounts. If several WhiteBox instances (dev/staging/prod, or multiple tenants) share one Mobica account, that single URL has to reach the instance that actually sent each message.

Since the idd is the only handle a DLR carries back, the approach is: make the idd globally unique by namespacing it per instance, then fan the one callback URL out to every instance (e.g. with nginx). Each instance matches the DLR against its own outbox — the owner advances the row, everyone else silently no-ops.

1. Give each instance a distinct instanceId (a short base62 prefix). The id becomes instanceId + random, capped at iddLength:

mobica({ user, pass, from: 'WhiteBox', instanceId: process.env.WB_INSTANCE_ID })  // e.g. 'a1' → idd "a1Xk9..." (10 chars total)

A 2-char prefix supports 3,844 instances and still leaves 62⁸ ≈ 2×10¹⁴ ids each. With no instanceId (single-instance), ids are pure random — today's behavior.

2. Fan the single Mobica URL out to all instances. Point Mobica's callback at a front door that broadcasts the DLR (query string intact, incl. any ?secret=) to each instance's /sms/webhooks/mobica/status:

# The one URL configured with Mobica support → mirror to every instance.
location = /sms/webhooks/mobica/status {
    mirror /_dlr_b;            # instance B (and add more mirror dirs per instance)
    proxy_pass http://instance_a/sms/webhooks/mobica/status$is_args$args;   # instance A handles the response to Mobica
}
location = /_dlr_b { internal; proxy_pass http://instance_b/sms/webhooks/mobica/status$is_args$args; }

Each instance returns 200 OK even for an idd it didn't mint, so Mobica always sees success. Only the instance whose instanceId prefixed the idd finds a matching outbox row — it advances the status, notifies, and (on undelivered/failed/blacklisted) blocklists. The others match nothing and do nothing, so a failure for one instance's recipient never suppresses another's.

What it implements

| method | Mobica specifics | |---|---| | send({ to, from, body }) → { messageId } | POST to the gate with user/pass/from/phone (E.164 minus +)/message/idd; returns the generated idd | | verifySignature(req, kind) | checks ?secret= (or x-dlr-secret) against dlrSecret; if no secret is configured, doesn't verify (secure the callback by IP allowlist instead) | | parseStatus(req) | maps Mobica's numeric DLR code → canonical status; flags blacklisted | | classifyError(err) | 4xx / invalid / blacklisted / barred ⇒ blocklist instead of retry |

DLR setup

Point your Mobica account's delivery-report callback at:

GET https://YOUR_HOST/sms/webhooks/mobica/status?status=<code>&id=<idd>&phone=<e164-no-+>

(The SMS plugin accepts the status webhook over GET specifically for Mobica's DLR style.) Code mapping:

| Mobica DLR code | canonical | effect in WhiteBox | |---|---|---| | 1000, 1001 | delivered | outbox → delivered | | 1003, 1203 | sent | → sent (accepted / pending) | | 1204, 1205 | undelivered | → undelivered (+ invalid list) | | 1004, 1206–1207, 1005–1117 | failed | → failed (+ invalid list) | | 1209 | failed | → failed + blacklisted |

If you set dlrSecret, configure the same ?secret= value in the Mobica panel so unsigned callbacks are rejected.

Credentials

user + pass from your Mobica account. Keep them in the environment (WB_MOBICA_USER, WB_MOBICA_PASS) — never commit them.