How do I get Asterisk to forward incoming calls based on matching the incoming call number with a number to forward to? Both numbers are stored in a MySQL database.
This article should do the trick. It's about 3 lines of code and some simple queries to add and remove forwarding rules.
Sorry for the long code sample, but more than half of it is debugging code to help you get it set up.
I'm assuming your server already has a modern version of PHP (at /usr/bin/php
) with the PDO library, and that you have a database table named fwd_table
with columns caller_id
and destination
.
In /var/lib/asterisk/agi-bin get a copy of the PHP AGI library. Then create a file named something like forward_by_callerid.agi
that contains:
#!/usr/bin/php
<?php
ini_set('display_errors','false'); //Supress errors getting sent to the Asterisk process
require('phpagi.php');
$agi = new AGI();
try {
$pdo = new PDO('mysql:host='.$db_hostname.';dbname='.$db_database.';charset=UTF-8', $db_user, $db_pass);
} catch (PDOException $e) {
$agi->conlog("FAIL: Error connecting to the database! " . $e->getMessage());
die();
}
$find_fwd_by_callerid = $pdo->prepare('SELECT destination FROM fwd_table WHERE caller_id=? ');
$caller_id = $agi->request['agi_callerid'];
if($callerid=="unknown" or $callerid=="private" or $callerid==""){
$agi->conlog("Call came in without caller id, I give up");
exit;
}else{
$agi->conlog("Call came in with caller id number $caller_id.");
}
if($find_fwd_by_callerid->execute(array($caller_id)) === false){
$agi->conlog("Database problem searching for forward destination (find_fwd_by_callerid), croaking");
exit;
}
$found_fwds = $find_fwd_by_callerid->fetchAll();
if(count($found_fwds) > 0){
$destination = $found_contacts[0]['destination'];
$agi->set_variable('FWD_TO', $destination);
$agi->conlog("Caller ID matched, setting FWD_TO variable to ''");
}
?>
Then from the dial plan you can call it like this:
AGI(forward_by_callerid.agi)
And if your database has a match, it will set the variable FWD_TO
with goodness. Please edit your question if you need more help getting this integrated into your dial plan.
The solution I was looking for ended up looking like this:
[default]
exten => _X.,1,Set(ARRAY(${EXTEN}_phone)=${DTC_ICF(phone_number,${EXTEN})})
exten => _X.,n(callphone),Dial(SIP/metaswitch/${${EXTEN}_phone},26)
exten => _X.,n(end),Hangup()