In this 10 minute tutorial, you will a small command line application, and learn how to use pycall in a production environment. The application we are going to build will be an 'annoy' program which places a number of calls to a given phone number, using a random caller ID to annoy that person. This is similar to what many of the prank call websites do (call someone and play a funny music file).
assumptions
For the purposes of this tutorial, we will assume that a SIP trunk is defined on the Asterisk server, and that the trunk name is 'flowroute'. If you do NOT have a SIP trunk to test with, I suggest using Flowroute, as they are a cheap and reliable VoIP provider (who even give free trial accounts which are perfect for testing stuff like this).
We will also assume that on your server, Asterisk is configured to run as the user 'asterisk'. This is critical, as whatever user account Asterisk runs as must own all call files, otherwise the Asterisk spooler will be unable to read and process the call files generated by pycall.
pyannoy - an annoying prank call program
The goal of pyannoy will be to create a simple command line application, that when ran, allows the user to annoy a friend. The program should take in three arguments:
- the phone number of the person to annoy,
- the amount of times to annoy the person, and (optionally)
- the sound file to play to the person if they pick up the call
step 1 - skeleton
The first thing we're going to do is write a skeleton program which does everything except make the actual calls. This skeleton program will:
- validate the command line parameters,
- generate a random caller ID for each call,
- place each call exactly 1 minute after the previous call (we don't want to make a bunch of calls at once, only 1 will get through, and that wouldn't be very annoying!),
- and print some information to the screen so that the user knows what is going on
This program should look something like:
As you can see in the code above, we really aren't doing that much. We check the arguments to make sure they are valid, then we loop the required amount of times (specified by the user), and increment the time by 1 minute each iteration of the loop.
The reason we add 1 minute to the time variable each loop iteration is because when we implement the actual call file creation, we want to place one call every minute. This will achieve a maximum level of annoyance. If we were to place all of the calls at once, it wouldn't be very fun, as the end user would simply pick up one of the calls, and not get the rest. By spacing out the calls, we guarantee that the user will get each call (assuming they pick up). By adding in the time handling now, we can easily schedule calls once we implement our pycall code.
step 2 - output
When ran, the output of the skeleton program should look something like this:
The output of the skeleton program is really simple, and descriptive. We see the number of the person we're going to annoy, we see the fake caller ID we will use when we call them, and we also see the time at which we will place the call. Now that we have our skeleton written, it is time to add pycall into our program.
step 3 - using pycall
pycall provides a class, CallFile, which is used to create new CallFile objects. Each CallFile object contains a unique set of attributes that pycall uses to generate actual call files on the system. The CallFile class provides all abstraction necessary to hide details about file generation, and only uses the attributes specified. The fields we are going to use in order to create a CallFile for pyannoy are:
trunk_type - the type of trunk we are using (SIP / Local / etc.)
trunk_name - name of the trunk (flowroute, voipms, etc.)
callerid_num - the caller ID number (18882223333, etc.)
number - the number to call
application - the Asterisk dialplan command to run when the call is answered
data - the parameters to pass to the application
user - the user on the system to schedule the call file as
After the CallFile object has been created, we can instruct pycall to actually schedule the call file at any time using the run method provided by the CallFile class. This method will generate the actual call file, and schedule it with Asterisk.
CallFile.run([time])
Optionally, you can specify a time to the run method, which will set the file access time accordingly before the call file is handed off the the Asterisk spooler. If the time is set in the future, the call file will be placed at that time; if the time is set in the past, the call file will be placed instantly.
Below is our original program, modified to include call file creation. Note how simple it is to create the CallFile object, and how we can re-use the same CallFile object for each of our calls, and modify only the run time of the call.
Let's quickly discuss the code changes. After reading in and validating all command line parameters in main(), we create a CallFile object, cf. This object contains all of the necessary parameters to place our call.
In the loop at the bottom of main(), we insert the code to generate the actual call files on the system. To do this, all we need to add is the code to set a new caller ID for each call: cf.callerid_num = cid, and the code to actually create the call file and hand it off to Asterisk to run at the specified time: cf.run(time).
step 4 - examining more output
Now, let's examine the output of this program to get a better idea of exactly what is happening:
As you can see, the program displays the same output as it did before. The output simply shows the user running the program what we are doing. After the script has been ran, the ls -la command shows the call files created, as well as their attributes (look at the modification time). The modification times for these calls are all 1 minute apart, which means that Asterisk will run the call file tmpe5YUMR.call first (as it has a modification time of 02:09, then the call file tmpe_Nan2.call (as it was created 1 minute afterwards), etc. This demonstrates pycall's ability to schedule calls in the future.
Lastly, take a look at the call files actually created. Using the simple CallFile object we constructed in our program, we generated a perfect Asterisk call file which shows what is actually happening behind the scenes. As you can tell, the call files are being generated according to all Asterisk call file requirements.
pyannoy - conclusion
This basic example should have taught you how to build a simple application to use pycall, and how simple it is to both generate call files, and schedule calls in the future. You should now be able to create programs using pycall.
The next step is to check out our documentation page to see all the features that pycall has, and read the detailed API inforamtion for more advanced usage. If you would like to see more examples of programs using pycall, check out the examples page.
pycall