ivahaev / amigo Goto Github PK
View Code? Open in Web Editor NEWAsterisk AMI connector in golang
License: MIT License
Asterisk AMI connector in golang
License: MIT License
Hi,
I'd like to use this library, but the infinite loop when calling Connect() is causing me problems. Would it be possible to either : (1) implement a conditional flag to turn off this looping
or
(2) expose the Amigo struct attributes, so that its methods can be used with a custom Adapter
Thanks!
Hello. Im trying follow the example that is here but it not connect on my AMI. I use asterisk 11.
It dont show error or something just not connect. Could you help me?
Hi @ivahaev, excelent lib, thanks. This is a feature request. It would be great if an amigo.Disconnect() function exists. I have a pool of connections and I need to connect and disconnect on demand.
I encountered a case where the events comes out of order, even though I use SetEventChannel.
I think it is because of this code amigo.go:168
if a.defaultChannel != nil {
go func(e map[string]string) {
a.defaultChannel <- e
}(e)
}
A goroutine is fired to send the event, but the code does not check the goroutine is running.
When there are many events, later event's goroutine may execute first.
A possible fix is
if a.defaultChannel != nil {
running := make(chan bool)
go func(e map[string]string) {
running <- true
a.defaultChannel <- e
}(e)
<-running
}
I think other handlers may also have this problem.
If, for example, a messages contains the non-ASCII characters ö
, that character will be replaced by the replacement character � .
One way to handle this is to repack the read bytes as rune
s in readMessage(...). I'm happy to create a PR for this.
go version go1.7.3 windows/amd64
Взял код с гитхаба, при компиляции выдает ошибку
cannot use DeviceStateChangeHandler (type func(amigo.M)) as type amigo.handlerFunc in argument to a.RegisterHandler
ami.go:13
var actionTimeout = time.Second * 3
Hello,
Trying to use this library but a.Connect doesn't work for me.
This is the code I'm trying to use:
fmt.Println("Init Amigo")
settings := &amigo.Settings{Username: "admin", Password: "admin123", Host: "127.0.0.1:5038"}
a := amigo.New(settings)
a.Connect()
// Listen for connection events
a.On("connect", func(message string) {
fmt.Println("Connected", message)
})
a.On("error", func(message string) {
fmt.Println("Connection error:", message)
})
// Registering default handler function for all events.
a.RegisterDefaultHandler(DefaultHandler)
But, I'm getting only "Init Amigo" and the application is exiting with status code 0. Also, I noticed that the same happens when application is not able to connect to the server, while I expected to get an error message. In doc is saying that if the application cannot reach the server - it will try again on every second, which is not happening in my case. Basically I need to connect to the server and listen for all events coming from there, could you please tell me what I'm doing wrong?
Go ver: go version go1.16.4
Module version: github.com/ivahaev/amigo v0.1.11-0.20210303101006-9e0ec2c34445
I have tested generate INVITE call from SIPP with rate 200 tps, after sometime i found error "events chan is full" show in log. How to fix this error?
I use you library, it's good library. I have the task of connecting to several asterisk, it's work this code
for _, s := range conf.Asterisk {
settings := &amigo.Settings{Username: s.Login, Password: s.Password, Host: s.IP, Port: s.Port}
a := amigo.New(settings)
a.Connect()
a.On("connect", func(message string) {
fmt.Println("Connected", message)
})
a.On("error", func(message string) {
fmt.Println("Connection error:", message)
})
a.RegisterHandler("DialBegin", DialBeginHandler)
a.RegisterHandler("BridgeEnter", BridgeEnterHandler)
a.RegisterHandler("Newchannel", NewchanneHandler)
}
But when the event handler is work, I can not determine from which PBX the event came, is it possible expand the library to work with several PBXs or can you advise the solution?
I've noticed in the case of a "Bridge" event that amigo will produce extra properties AccountCode
, Channel
, Uniqueid
.
When connecting to the same box using Nami (the NodeJS client) these properties are not on the event object.
Why would the same AMI produce different data?
According to the documentation we should only have the following for a bridge event:
Event: Bridge
Bridgestate: <value>
Bridgetype: <value>
Channel1: <value>
Channel2: <value>
Uniqueid1: <value>
Uniqueid2: <value>
CallerID1: <value>
CallerID2: <value>
NAMI Event:
{ Event: 'Bridge',
Privilege: 'call,all',
Bridgestate: 'Link',
Bridgetype: 'core',
Channel1: 'SIP/1180-000005fd',
Channel2: 'SIP/Flowroute-000005fe',
Uniqueid1: '1485316340.3781',
Uniqueid2: '1485316340.3782',
CallerID1: '15555551170',
CallerID2: '15555551170' }
AMIGO Event:
map[Channel2:SIP/Flowroute-000005fe CallerID2:15555551170 AccountCode: Uniqueid2:1485316340.3782 CallerID1:15555551170 Channel:SIP/Flowroute-000005fe Bridgestate:Link Bridgetype:core Uniqueid1:1485316340.3781 Event:Bridge Privilege:call,all Uniqueid:1485316340.3782 OldAccountCode: Channel1:SIP/1180-000005fd]
I need to issue a Command Action though AMI. Basically I could pass any command string accepted in Asterisk CLI to 'Command:' field.
The problem is response from asterisk is not in a standard 'Field:Value' format. It is something like this:
Action: Command
Command: core show hi
Response: Follows
Privilege: Command
No such command 'core show hi' (type 'core show help core show hin' for other possible commands)
--END COMMAND--
amigo seems does not recognize the response string and it ignores the response body:
res, _ := ami.Action(map[string]string{
"Action": "Command",
"Command": "core show hi",
})
// res == {"Response":"Follows","Privilege":"Command"}
Can we introduce a CommandAction specifically for that? Or offer an option to return the raw response body?
Thanks!
Function readMessage in ami.go takes "ActionID" pair in command's long response as part of this response so result of Action function is Error:Timeout.
Possible solution is to replace ami.go:254 if responseFollows && key != "Privilege" {
to if responseFollows && key != "Privilege" && key != "ActionID" {
Thank you
I found that Amigo works wrong if a value in Event is empty - all followed Events are parsed as one.
It can be reproduced with PJSIPShowEndpoints command:
Action: PJSIPShowEndpoints
Response: Success
EventList: start
Message: A listing of Endpoints follows, presented as EndpointList events
Event: EndpointList
ObjectType: endpoint
ObjectName: XXXXX
Transport: transport-udp
Aor: XXX
Auths:
OutboundAuths:
Contacts: XXXX/sip:XXXX,
DeviceState: Unavailable
ActiveChannels:
I think the problem is in the file ami.go line 191:
if len(value) > 0 {
chanOut <- data
data = make(map[string]string)
}
Thank you!
When an event is received by amigo, looks like the time that the event is received is being set in the "Time" field. However, this overwrites some values that are expected in the event. Specifically, the "Time" value sent in PeerStatus events: https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+ManagerEvent_PeerStatus
Line 396 in dc43221
Hi,
I'm trying to send a command but the response is not complete.
Example:
result, err := amiHandle.Action(map[string]string{"Action": "Command", "Command": "core show taskprocessors"})
The response:
map[#:26 ActionID:e0d5f292-b2c5-4728-ad6a-df8213595f31 Message:Command output follows Output: Response:Success Time:2021-07-13T15:19:31.337807073Z]
If I connect by telnet to AMI, this is an example of the output:
Action: Command
Command: core show taskprocessors
Response: Success
Message: Command output follows
Output:
Output: Processor Processed In Queue Max Depth Low water High water
Output: app_voicemail 0 0 0 450 500
Output: ast_msg_queue 0 0 0 450 500
Output: CCSS_core 0 0 0 450 500
Output: dns_system_resolver_tp 0 0 0 450 500
Output: hep_queue_tp 0 0 0 450 500
Output: pjsip/default-0000000b 29 0 2 450 500
Output: pjsip/default-0000000c 0 0 0 450 500
Output: pjsip/default-0000000d 0 0 0 450 500
Output: pjsip/default-0000000e 0 0 0 450 500
Output: pjsip/default-0000000f 0 0 0 450 500
Output: pjsip/default-00000010 0 0 0 450 500
Output: pjsip/default-00000011 0 0 0 450 500
Output: pjsip/default-00000012 0 0 0 450 500
Output: pjsip/distributor-00000023 369 0 1 450 500
Output: pjsi
.....
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.