Events
Asterisk makes a large set of events available via the Manager API. In turn Adhearsion has a rich and very useful events subsystem which allows you to define custom handlers for callbacks exposed by either Adhearsion itself or by an Adhearsion component you're using. When these callbacks are asynchronously triggered, they will utilize a Thread pool so that, ideally, the occasional long-running task won't lock up the throughput of events too much.
events.rb
When you create a new Adhearsion application, you will notice there is a file in the root directory of the app called "events.rb". This file is yours to freely modify by registering callbacks with the namespaces you may have available. For example
A namespace could be something such as...
- /asterisk/before_call
- /shutdown
- /xmpp/my_username/incoming_message
When one part of the framework must notify another part of the framework of something, it should go through this events subsystem. The /xmpp/my_username/incoming_message example above shows how a hypothetical XMPP component might allow you to receive incoming messages asynchronously.
A sample callback definition in events.rb looks like this:
events.asterisk.before_call.each do |call| extension = call.variables[:extension] ahn_log "New call with extension #{extension}" end
Notice how, for this namespace (the /asterisk/before_call namespace), a Call object is passed in case your callback may want to use its behavior or state somehow.
Dealing with all Events
You may process each event as it comes into the events.rb file and then evaluate the events as follows:
events.each do |event| case event.name.downcase when "hangup" ahn_log "Hung up @ #{Time.now}" when "newchannel" #do something end end
Events Available in Asterisk
May be found here.
Using Events Outside of Adhearsion
If you are using Adhearsion's ManagerInterface in a separate script, you may want enable events and handle them without using Theatre. To do this, simply subclass ManagerInterface and override the event_message_received() method. The method takes one argument which will receive an instance of ManagerInterfaceEvent each time one comes in.
class MyManagerInterface < Adhearsion::VoIP::Asterisk::Manager::ManagerInterface
def event_message_received(event)
if event.name.downcase == "newstate"
puts "Got a newstate event! #{event.inspect}"
end
end
end
MyManagerInterface.connect ......
Custom Events with AGI command UserEvent
It is possible to use the AGI command UserEvent to send custom events to be processed by the Adhearsion events subsystem. Although, you must follow a particular format or you risk corrupting the event parsing which would then stop Adhearsion from processing any further events for that session (see ticket #58).
To send a UserEvent you must follow this format:
exten => _X.,1,UserEvent(MYEVENT|key1:value|key2:value)
INFO event_logger: Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceEvent:
#<Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceEvent:0x177611c
@headers={"Privilege"=>"user,all", "key1"=>"value", "key2"=>"value", "UserEvent"=>"MYEVENT"},
@name="UserEvent">