The Asterisk Interconnect for Roblox. Connecting Roblox to the real world using Voice Over IP (VoIP).
  • JavaScript 70.3%
  • Lua 29.7%
Find a file
exoworo a7c855f519 Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control
Adds a Node.js bridge server using Asterisk ARI for call origination,
DTMF relay, and hangup control. Includes a WebSocket gateway for
pushing live call events to Roblox, a REST API secured with API key
+ JWT session tokens, a Roblox Lua client module, an example door
button script, and Asterisk ari.conf/extensions.conf templates.
2026-06-25 16:03:19 -05:00
asterisk Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control 2026-06-25 16:03:19 -05:00
roblox Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control 2026-06-25 16:03:19 -05:00
src Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control 2026-06-25 16:03:19 -05:00
.env.example Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control 2026-06-25 16:03:19 -05:00
.gitignore Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control 2026-06-25 16:03:19 -05:00
LICENSE Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control 2026-06-25 16:03:19 -05:00
package.json Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control 2026-06-25 16:03:19 -05:00
README.md Initial commit: SIPBlox, an Asterisk-Roblox bridge for VoIP and in-game device control 2026-06-25 16:03:19 -05:00

SIPBlox

SIPBlox connects an Asterisk PBX to Roblox so that real telephony and in-game logic can drive each other. A player presses a button in-game, Asterisk places a real call through a SIP trunk, and a relay on the other end opens a door. A call comes in on a real line, and Roblox can react to it live. It's the glue between a PBX and a game server.

Built for door relays, intercoms, in-game payphones, and anything else where "press a button in Roblox, something happens on a real phone line" is the goal.

Why SIPBlox exists

Roblox has no SIP or RTP stack, so it can never speak directly to a PBX. SIPBlox sits in between: Asterisk handles all the actual telephony over ARI (the Asterisk REST Interface), and Roblox talks to SIPBlox over plain HTTPS and WebSockets, which HttpService already supports. Roblox never needs to know anything about SIP, trunks, or codecs. It just calls an API.

How it fits together

Roblox game server  --HTTPS-->  SIPBlox API  --ARI-->  Asterisk  --SIP trunk-->  PSTN / relay hardware
                     <--WS------ live events  <--------
  1. Roblox authenticates with SIPBlox using a shared API key and gets back a short-lived session token.
  2. Roblox calls /api/call/originate to place a call through Asterisk, for example dialing into a door relay extension.
  3. SIPBlox uses ARI to originate the channel, answer it, and track it for the lifetime of the call.
  4. Roblox can send DTMF tones, trigger a dedicated door relay shortcut, or hang up, all over plain HTTP.
  5. Every call event Asterisk fires (answered, DTMF received, hung up) gets pushed straight back to Roblox over a WebSocket, so the game can react in real time instead of polling.

What's in this repo

Path What it is
src/server.js Entry point. Boots the HTTP server, connects to Asterisk over ARI, attaches the WebSocket gateway.
src/ari.js All Asterisk call control: originate, send DTMF, hang up, the door relay shortcut, channel tracking.
src/routes.js The REST API Roblox talks to.
src/auth.js API key validation for Roblox and JWT session tokens for everything after that.
src/wsGateway.js WebSocket endpoint that streams live call events to connected Roblox servers.
roblox/SIPBlox.lua Drop-in ModuleScript for Roblox. Handles auth and wraps every API call.
roblox/DoorButtonExample.server.lua Working example wiring a ClickDetector to originate a call and trigger a door relay.
asterisk/ari.conf.example ARI user config for Asterisk.
asterisk/extensions.conf.example Dialplan routing calls into the Stasis app SIPBlox listens on.
.env.example Every environment variable SIPBlox needs, with safe placeholder values.

Requirements

  • Asterisk 18 or newer with ARI enabled
  • Node.js 18 or newer
  • A SIP trunk or PJSIP endpoint wired up to whatever relay or intercom hardware you're controlling
  • A Roblox experience with HttpService enabled and outbound HTTP requests allowed in game settings

Getting it running

1. Install dependencies

npm install

2. Configure environment variables

Copy .env.example to .env and fill it in with your own values — Asterisk ARI credentials, a Roblox API key you generate yourself, and a JWT secret.

cp .env.example .env

3. Wire up Asterisk

Drop the example configs into your Asterisk install, adjusting extensions, trunk names, and credentials to match your setup:

  • asterisk/ari.conf.example/etc/asterisk/ari.conf
  • asterisk/extensions.conf.example → merge into /etc/asterisk/extensions.conf

Then reload:

asterisk -rx "core reload"

4. Start SIPBlox

npm start

By default it listens on the port set in .env and immediately connects to Asterisk over ARI.

Wiring up Roblox

Place roblox/SIPBlox.lua in ReplicatedStorage as a ModuleScript named SIPBlox. Update BASE_URL and ROBLOX_KEY inside it to match your deployment.

local SIPBlox = require(game.ReplicatedStorage.SIPBlox)

local client = SIPBlox.new(tostring(player.UserId), tostring(game.PlaceId))
local result = client:originateCall("PJSIP/door_relay", "9001", "from-internal", player.Name)

client:openDoor(result.channelId)
task.wait(3)
client:hangup(result.channelId)

See roblox/DoorButtonExample.server.lua for a complete, working version of this wired to a ClickDetector.

API reference

Method Path What it does
POST /api/session Exchange a Roblox API key for a short-lived session token
POST /api/call/originate Place a call out through Asterisk
POST /api/call/:channelId/dtmf Send DTMF digits on an active call
POST /api/call/:channelId/hangup Hang up an active call
POST /api/door/:channelId/open Send the configured door relay DTMF tone
GET /api/calls List currently active channel IDs
WS /ws Live event feed: call started, call ended, DTMF received

All endpoints except /api/session require a Bearer session token in the Authorization header.

Configuration reference

Every variable lives in .env.example. The ones worth knowing about:

  • ARI_URL, ARI_USERNAME, ARI_PASSWORD, ARI_APP — how SIPBlox connects to Asterisk's REST interface
  • ROBLOX_API_KEY — the shared secret Roblox uses to request a session token
  • JWT_SECRET — signs the session tokens issued after that
  • DOOR_EXTENSION_CONTEXT — the dialplan context calls get originated into
  • DOOR_RELAY_DTMF — the digit sent when /api/door/:channelId/open is hit
  • DEFAULT_TRUNK — your default outbound trunk name

Security notes

  • Never commit .env. It's already in .gitignore.
  • Run SIPBlox behind TLS in production — Roblox HttpService will refuse plain HTTP.
  • Scope the dialplan context SIPBlox originates into so it can only reach the extensions and trunks it actually needs.
  • Rotate ROBLOX_API_KEY and JWT_SECRET if either ever leaks.

License

SIPBlox is licensed under the GNU General Public License v3.0. See LICENSE for the full text.