How to use Wazo programmable application

Hello,

People ask on Mattermost how to use programmable application with Wazo. So first, the concept for using application on Wazo is very simple. The goal for developpers is to receiving a call from a sip trunk, from a sip phone or webrtc phone and realize a program about what you want. Example IVR, routing etc …
By default an application do nothing, except to receive a message to indicate when a call is entered in the application.

So how to use it? First step you need to create your application in your tenant:

When your application is created you have the choice to link it to an incall:

The event you will received will be : application_call_entered
To alert your application, you have the choice to use a webhook or to use websocket. The payload is the same.

From the user perspective:

The event will be : application_user_outgoing_call_created

When you have finished to configure this simple routing, you are now done. The next step is to take your preferred editor and make code.

Show me the code:

#!/usr/bin/python3

from wazo_websocketd_client import Client as Websocket
from wazo_auth_client import Client as Auth
from wazo_calld_client import Client as Calld

username = ''
password = ''
wazo_domain = ''
client_id = 'my-application'

def notify(handler, msg):
    print("{}: {}".format(handler, msg))
    # call calld API or what you want

def application_call_entered(handler):
    message = "Incoming call is entered"
    notify(handler, message)

def application_user_outgoing_call_created(handler):
    message = "Outgoing call from user has been created"
    notify(handler, message)

def get_refresh_token():
    token_data = auth.token.new('wazo_user', access_type='offline', client_id=client_id)
    refresh_token = token_data['refresh_token']
    return token_data['refresh_token']

def get_token():
    token_data = auth.token.new('wazo_user', expiration=3600, refresh_token=refresh_token, client_id=client_id)
    return token_data['token']

def session_expired(data):
    token_data = auth.token.new('wazo_user', expiration=3600, refresh_token=refresh_token, client_id=client_id)
    token = token_data['token']
    ws.update_token(token)
    calld.update_token(token)

auth = Auth(wazo_domain, username=username, password=password, verify_certificate=False)
refresh_token = get_refresh_token()
ws = Websocket(wazo_domain, token=get_token(), verify_certificate=False, debug=False)
calld = Calld(wazo_domain, token=get_token(), verify_certificate=False)

ws.on('application_call_entered', application_call_entered)
ws.on('application_user_outgoing_call_created', application_user_outgoing_call_created)
ws.on('auth_session_expire_soon', session_expired)

ws.run()

If you want, you have the possibility to use node-red with the wazo-platform plugin. This example show you an incoming call, you answered it, launch moh and after 3 seconds you hangup the call.

Hope this mini tutorial help you to play with the application and Wazo.
Sylvain

3 Likes

Thank you so much @quintana ! Now it’s 100% crystal clear! :+1:

1 Like

@quintana Apologies for the newbie questions here but I am just digging into node-red.
Three questions:

  1. What “extension” do I use when I add the Incall?
    I see you used 01234… ; I want it to apply for all incalls so I used _.*
    But I do not know if I am doing this right
  2. If I setup a node-red flow, does it stop working when the certificate expires?
    If so, how do I setup a node-red flow that will keep running (forever)
    or is that what the refresh-token function handles?
  3. The wazo-domain, username and password:
    Is the wazo-domain my hostname?
    Is the username/password the API account username/password?

Thanks for your help in getting me (and others) into this

@quintana Well, I answered one question; I should NOT put _.* as the Incall extension.

When I do that, it actually prevented any outgoing calls from going out.

So the question remains what SHOULD go there?

And of course, the other 2 questions …

:slight_smile:

@Ramblin

Node-red plugin is using Wazo’s core APIs in the background. You may look at the https://wazo-platform.org/documentation/ for each API that you wanna try in node-red to see the requirements and have a better understanding of what you are doing.

For example you can set an expiration time and also refresh your token with an API:
https://wazo-platform.org/documentation/api/authentication.html#tag/token

This not an exact answer that you are looking for, but it gives you an idea of what is happening and how you may address different things better.

Thank you @Miker @quintana

I have managed to get a username/password for an API account and I have assigned the all-access acls to this (will remove later)

I think I know but wanted to check: is the wazo_domain shown in the post example the hostname of the server on which wazo is running?

Also, what is the appropriate entry to use to the right of the Context field when I create (say) an Incall routing? In the example shown above it shows 01234… but I am not sure what that is supposed to be referring to.

  • This is your extension coming from your trunk sip for example. _.* doesn’t exist, it’s _X. to catch all number.
  • Nope i’m using the refresh_token concept, so token is renewed automatically.
  • wazo_domain is your wazo url/ip/dns. You need to create an api account on your wazo-platform with the good acl.

Not one of my smarter moves; thanks for the catch

Other items dealt with in searate post

Thanks @quintana