Python phone router and support code
Project description
This Python package performs external routing for Asterisk.
While Asterisk has an event-based interface (and a REST-based interface), it lacks a simple straightforward way to forward phone calls from A to B. Also, mangling phone numbers is rather awkward in Asterisk’s AEL.
This package is useful if you want to write your phone number mangling and rewriting in Python.
Installation
Install Asterisk and this module.
Create an appropriate configuration file.
Add this to extensions.ael:
// Your SIP calls arrive here. Add one of these for each SIP peer.
context in_foo {
includes { default; };
_[+0-9]. => &aroute(foo,${EXTEN});
}
context default {
h => Hangup();
i => Hangup();
}
macro aroute(src,ext) {
Verbose(0,CALL: ${src}:${CALLERID(NUM)}:${ext});
Set(curl=http://localhost:50080/route/${src}:${CALLERID(NUM)}:${ext});
Verbose(0, = ${CURL(${curl})});
Set(dispatch=${CURL(${curl})});
&get(hangup); Set(hangup=${res});
if("${hangup}" = "") {
&get(chan); Set(chan=${res});
if("${chan}" = "Local") {
&get(dest); Set(dest=${res});
Set(dest=Local/${STRREPLACE(dest,+,@in_${src}&Local/)}@in_${src})
Dial(${chan}/${dest});
} else {
&get(a_nr); Set(a_nr=${res});
&get(b_nr); Set(b_nr=${res});
&get(p_nr); Set(p_nr=${res});
&get(end); Set(end=${res});
Set(CALLERID(num)=${a_nr});
Dial(${chan}/${b_nr}@${end});
}
} else {
// error
PJSIPHangup(${hangup});
}
Hangup();
return;
}
macro get(name) {
// extract a field from the CURL result.
//
// dispatch="foo=bar:baz=quux"
// get(foo) -> bar
//
Set(disp=${dispatch});
while("${disp}"!="") {
Set(assign=${CUT(disp,:,1)});
Set(disp=${CUT(disp,:,2-99)});
Set(var=${CUT(assign,=,1)});
Set(res=${CUT(assign,=,2)});
if("${var}"=="${name}") {
return;
}
}
Set(res=);
return;
}
Variables
This dialplan accepts these parameters:
a_nr number part of the caller id. This might need to be our SIP ID.
p_nr The real a_nr (SIP: P-Preferred-Identity)
b_nr Number to dial. This may need to be the destination SIP ID.
chan Channel. You probably want PJSIP. To divert to a local channel use “Local”.
dest Destination endpoint. This is the dialplan context when diverting to a local channel.
or
hangup PJSIP cause code.
For diverting a call to a local context, set chan=Local dest=context_name b_nr=extension.
Configuration
Bugs
hypercorn, which we use as an HTTP server, has an annoying bug in releases up to and including 0.17.3: it ignores a Connection: close header. This causes problems with clients like Icinga.
Zoom Phone integration
Get an API token from Zoom. It needs to be able to read your user records.
Create a secrets.yaml file:
zoom: # API to them account: "xxxxxxxxxxxxxxxxxxxxxx" client: "xxxxxxxxxxxxxxxxxxxxxx" password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # Sign replies to the callback from them # TODO #token: "xxxxxxxxxxxxxxxxxxxxxx"
Add something like this to your routing.yaml:
route:
- match: "496990009(0|[1-6]{2,3})"
dest: zoom
use: known
- match: "496990009(0|[1-6]{2,3})"
dest: legacy_pbx
legacy_pbx:
fallback: zoom
zoom:
type: zoom
fallback: legacy_pbx
# Interval for updating extensions allocated on Zoom.
# -1: read once (and when refreshing), 0: don't read at all
update: 1200
# Numbers to forward to Zoom, regardless of whether they are known
known:
- "496990009123"
use: known # only forward numbers that have been assigned
route:
- match: "(0|[1-6][0-9]{2,3})"
result: "496990009$1"
dest: legacy_pbx
a_in: false
b_in: true
a_out: null
b_out: true
p_out: false
chan: "PJSIP" # default
# end: "zoom" # endpoint. Default: provider name
zoom:
# auth
auth_url: https://zoom.us/oauth/token
cred:
# API
account: !secret zoom.account
client: !secret zoom.client
secret: !secret zoom.password
# callbacks
#token: !secret zoom.token
The “fallback” causes a call that originates from this provider and gets routed back to the same provider to be routed to the fallback provider instead.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ast_route-0.9.2.tar.gz.
File metadata
- Download URL: ast_route-0.9.2.tar.gz
- Upload date:
- Size: 130.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
544ddd2314b3f0389a3fba698bb399191ad9f732a3016425d160ca14d631a87f
|
|
| MD5 |
a3be150340fdc3f5721d479a8a608585
|
|
| BLAKE2b-256 |
c420b277ae5cd68c66a7c366e300fa67561295ec025a91d224f38b562198281d
|
File details
Details for the file ast_route-0.9.2-py3-none-any.whl.
File metadata
- Download URL: ast_route-0.9.2-py3-none-any.whl
- Upload date:
- Size: 134.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c97908950398d6be3314e31203920f77f6426075984ba1229358b44b81c781a3
|
|
| MD5 |
4750a2003bdd9115db380d28751e674e
|
|
| BLAKE2b-256 |
bd356b7899b86246d45a43985b289ac2227de80ebb39a893e7c60041422ff670
|