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.1.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.1-py3-none-any.whl (134.6 kB view details)

Uploaded Python 3

File details

Details for the file ast_route-0.9.1.tar.gz.

File metadata

  • Download URL: ast_route-0.9.1.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.1.tar.gz
Algorithm Hash digest
SHA256 c8ac27bd6c70665ada169f7171cb4b9232e29ef99d98be273e6c96dcf59a1d2a
MD5 32c0c867fe56b8ccc0d5b8d494204935
BLAKE2b-256 be613170fc255d770ab7b60e528f5f64f08ca25b5ffc6ab11dddec66f784b417

See more details on using hashes here.

File details

Details for the file ast_route-0.9.1-py3-none-any.whl.

File metadata

  • Download URL: ast_route-0.9.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 eb2d839936262ee981b49cf7fa73eeda94391fefeb9e09b3a56930195249487d
MD5 bedd6d27ad51a5b51eba60df97ef1638
BLAKE2b-256 02659ded8f3d50654dbdeb38dd67334c3e3968a1835756f4db27b8b1332bd9b1

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