Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ast_route-0.9.2.tar.gz (130.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ast_route-0.9.2-py3-none-any.whl (134.6 kB view details)

Uploaded Python 3

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

Hashes for ast_route-0.9.2.tar.gz
Algorithm Hash digest
SHA256 544ddd2314b3f0389a3fba698bb399191ad9f732a3016425d160ca14d631a87f
MD5 a3be150340fdc3f5721d479a8a608585
BLAKE2b-256 c420b277ae5cd68c66a7c366e300fa67561295ec025a91d224f38b562198281d

See more details on using hashes here.

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

Hashes for ast_route-0.9.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c97908950398d6be3314e31203920f77f6426075984ba1229358b44b81c781a3
MD5 4750a2003bdd9115db380d28751e674e
BLAKE2b-256 bd356b7899b86246d45a43985b289ac2227de80ebb39a893e7c60041422ff670

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page