FOP2 has extensibility hooks so you can add your own actions/commands. In this article we will create a custom action button that will let us create pseudo conferences using chanspy barge option (kind of similar to the conference button you have on a phone) without using meetme, confbridge, and without disrupting your active call.
For background, this post implements the feature request made in this forum post. This will only work on recent Asterisk versions that implement the chansphy Barge feature (1.8 or higher).
First, we need to create a custom button in the FOP2 toolbar, to do this we must edit the fop2 index page. Inside the index.html file we have the "custombar" div that is hidden from view by default:
<div id="custombar" style='float:left; display:none;'> <div title='Custom Action' class='myclick' id='custom_test'>clickme</div> </div>
To make it appear, we must set it to display:block and set the contents to be a real and clickable button, like this:
<div id="custombar" style='float:left; display:block;'> <div title='Conference Call' class='actionbutton myclick' id='custom_conferencecall'> <img src="./images/toolbar/conference.png"> </div> </div>
As you see, we are changing the display:none to display:block and we also set a div that will contain our custom button.
You can use this conference.png image I made and copy it over to the /var/www/html/fop2/images/toolbar directory. (from your browser, right click, save image as)
The key parts here are the actionbutton class (for styling), the myclick class (so the button becomes clickable), and the id, prefixed with "custom_" to indicate that this is a custom function. The method that will be called in our javascript callback file is the text after "custom_". In the above example would be "conferencecall"
After creating the custom toolbar element, we can log into fop2 and see our custom button. When clicked, a javascript method will be called. That method must be defined inside the jCustomAction class, inside the file /var/www/html/fop2/js/jcallback.js.
function jCustomAction() { function conferencecall(target) { debug("Custom command conferencecall on target "+target+" my position "+myposition); if(myposition>0) { var boton = $('boton'+myposition); var number_to_dial; // Look for typed number in the dial textbox field if($('dialtext').value.indexOf(lang.dial)>=0) { // Placeholder text, we have to remove it var largo = lang.dial.length; number_to_dial = $('dialtext').value.substr(largo); } else { number_to_dial = $('dialtext').value; } // If the dialbox is empty, check if we have a target selected // and use the target extension number if(number_to_dial=="") { if(target>0) { number_to_dial = botonitos[target]['EXTENSION']; } } if(number_to_dial=="") { debug("We do not have a target number to dial, exit"); return; } debug(number_to_dial); if(boton.hasClassName('busy')) { if($('securitycode').value !== "") { var pass = $('securitycode').value+lastkey; var hash = hex_md5(pass); queuedcommand = "<msg data=\""+myposition+"|customconference|"+number_to_dial+"|"+hash+"\" />"; sendcommand(); } } else { debug("you are not on a call, we only send this command when we are busy"); } } } this.conferencecall = conferencecall; }
The conferencecall method will be called when a user presses our custom button with id custom_conferencecall. You can create several buttons with its own id to fire different javascript functions based on the id name.
Getting back to our example, the conferencecall function does several checks: it checks to see if we have a target selected (a button selected in the fop2 page) and if we have something typed in the dialbox. If we have some number in the dialbox, it will dial out that number and connect it to our active conversation. If the dialbox is empty and there is a target button selected, the number dialed will be the target button extension number instead. It also checks our button state and only perform the action if our own extension is busy/engaged in an active call.
If we are on an active cal, the javascript function will send the customconference command to the fop2 server, so we can intercept it on the server side call back file and convert that to a final and proper AMI action.
So, we need to create the hook inside /usr/local/fop2/FOP2Callbacks.pm. In that file you have to add an elseif block like this one:
} elsif($command eq "customconference") { my $contexto = $parameters[2]; my $mychannel = main::get_btn_config( "$contexto", $parameters[0], 'MAINCHANNEL'); my $extension_to_dial = $parameters[1]; $return = "Action: Originate\r\n"; $return .= "Channel: Local/$extension_to_dial\@from-internal\r\n"; $return .= "Application: ChanSpy\r\n"; $return .= "Data: $mychannel,BEq\r\n"; $return .= "\r\n"; push @allreturn, $return; return @allreturn; }
So, when the customconference command is received, we get our own channel name, the target number to dial so we can construct a proper AMI action.
With all this in place, we have created a button in the fop2 toolbar that can call an extension and bridge that extension to our active call using chanspy barge option. It is not a real asterisk conference like meetme or confbridge, it is a pseudo conference.

Great! But in log:
<= <msg="" data="32|customconference|29|...">
-- PROCESS_FLASH_COMMAND origen 32 accion customconference destino 29 password ...
Received undefined action from flash: customconference
Perhaps you introduced a bug in the FOP2Callbacks.pm file, try running in the command line:
perl /usr/local/fop2/FOP2Callbacks.pm
It should return nothing, if there is a problem you will see a warning/error on screen.
>perl /usr/local/fop2/FOP2Callbacks.pm
returns nothing
(I add new block to sub flashCommand)
After updating FOP2, custom button work, thank You!
Hello,
I updated to Version 2.25 just today. I also created the conferencall button exactly like it is outlined above, but when I click on conference call, I see this in the console output from Chrome, but nothing happens. Any ideas?
Ejecutando Custom Command conferencecall
Custom command conferencecall on target 4 my position 3
116
sendcommands
ws send <msg data="3|customconference|116|ef9e8a81587a7209746265e60d606ec6">
Thanks!
Jon, start fop2 server in debug mode
/usr/local/fop2/fop2_server -X 511
and see if you receive the customconference command there. If there is a syntax error in FOP2Callbacks.pm the action will fail, you should also have to check for that by running
perl /usr/local/fop2/FOP2Callbacks.pm
and see that it does not return anything. If you see an error, fix it. Then restart fop2 and try again.