### Install goami AMI client via go get command Source: https://github.com/heltonmarx/goami/blob/master/README.md Installs the goami package using Go's package manager. Requires Go environment to be configured and internet access to download from GitHub. This command fetches the latest version of the AMI client library and its dependencies. ```shell go get -u github.com/heltonmarx/goami/ami ``` -------------------------------- ### Initialize AMI Connection and Event Loop Source: https://context7.com/heltonmarx/goami/llms.txt Demonstrates how to establish a connection to the Asterisk Manager Interface using GoAMI, including authentication and event loop setup. Requires context, socket handling, and proper error management. The connection supports real-time event monitoring and periodic status checks. ```go package main import ( "context" "flag" "log" "os" "os/signal" "sync" "syscall" "time" "github.com/heltonmarx/goami/ami" ) var ( host = flag.String("host", "127.0.0.1:5038", "AMI host:port") username = flag.String("user", "admin", "AMI username") password = flag.String("pass", "admin", "AMI password") ) type AsteriskManager struct { socket *ami.Socket uuid string events chan ami.Response stop chan struct{} wg sync.WaitGroup } func NewAsteriskManager(ctx context.Context, host, user, pass string) (*AsteriskManager, error) { socket, err := ami.NewSocket(ctx, host) if err != nil { return nil, err } if _, err := ami.Connect(ctx, socket); err != nil { socket.Close(ctx) return nil, err } uuid, err := ami.GetUUID() if err != nil { socket.Close(ctx) return nil, err } err = ami.Login(ctx, socket, user, pass, "system,call,all", uuid) if err != nil { socket.Close(ctx) return nil, err } mgr := &AsteriskManager{ socket: socket, uuid: uuid, events: make(chan ami.Response, 100), stop: make(chan struct{}), } mgr.wg.Add(1) go mgr.eventLoop(ctx) return mgr, nil } func (m *AsteriskManager) eventLoop(ctx context.Context) { defer m.wg.Done() for { select { case <-m.stop: return case <-ctx.Done(): return default: event, err := ami.Events(ctx, m.socket) if err != nil { log.Printf("Event error: %v", err) return } m.events <- event } } } func (m *AsteriskManager) Close(ctx context.Context) error { close(m.stop) m.wg.Wait() if err := ami.Logoff(ctx, m.socket, m.uuid); err != nil { return err } return m.socket.Close(ctx) } func main() { flag.Parse() ctx, cancel := context.WithCancel(context.Background()) defer cancel() mgr, err := NewAsteriskManager(ctx, *host, *username, *password) if err != nil { log.Fatalf("Failed to connect: %v", err) } defer mgr.Close(ctx) log.Println("Connected to Asterisk Manager Interface") // Handle shutdown signals sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // Periodic status check ticker := time.NewTicker(10 * time.Second) defer ticker.Stop() for { select { case <-sigChan: log.Println("Shutting down...") return case <-ticker.C: // Get channel count channels, err := ami.CoreShowChannels(ctx, mgr.socket, mgr.uuid) if err != nil { log.Printf("Error getting channels: %v", err) continue } log.Printf("Active channels: %d", len(channels)) case event := <-mgr.events: eventType := event.Get("Event") log.Printf("Event received: %s", eventType) } } } ``` -------------------------------- ### Manage Asterisk SIP Peers with GoAMI Source: https://context7.com/heltonmarx/goami/llms.txt Shows how to list all SIP peers, retrieve detailed information for a specific peer, qualify peer connectivity, and get the status of SIP peers. Requires an active AMI connection. ```go package main import ( "context" "log" "github.com/heltonmarx/goami/ami" ) func manageSIPPeers(ctx context.Context, socket *ami.Socket, actionID string) { // List all SIP peers peers, err := ami.SIPPeers(ctx, socket, actionID) if err != nil { log.Fatalf("SIPPeers failed: %v", err) } log.Printf("Found %d SIP peers", len(peers)) for _, peer := range peers { log.Printf("Peer: %s, IP: %s, Status: %s", peer.Get("ObjectName"), peer.Get("IPaddress"), peer.Get("Status")) } // Show detailed peer information if len(peers) > 0 { peerName := peers[0].Get("ObjectName") peerDetail, err := ami.SIPShowPeer(ctx, socket, actionID, peerName) if err != nil { log.Fatalf("SIPShowPeer failed: %v", err) } log.Printf("Peer Details:") log.Printf(" Name: %s", peerDetail.Get("ObjectName")) log.Printf(" Status: %s", peerDetail.Get("Status")) log.Printf(" IP: %s", peerDetail.Get("IPaddress")) log.Printf(" Port: %s", peerDetail.Get("IPport")) log.Printf(" Codecs: %s", peerDetail.Get("Codecs")) } // Qualify peer (send OPTIONS to check connectivity) qualifyResp, err := ami.SIPQualifyPeer(ctx, socket, actionID, "1001") if err != nil { log.Fatalf("SIPQualifyPeer failed: %v", err) } log.Printf("Qualify response: %s", qualifyResp.Get("Response")) // Get peer status for all or specific peer peerStatuses, err := ami.SIPPeerStatus(ctx, socket, actionID, "") if err != nil { log.Fatalf("SIPPeerStatus failed: %v", err) } for _, status := range peerStatuses { log.Printf("Peer %s status: %s, Time: %s ms", status.Get("Peer"), status.Get("PeerStatus"), status.Get("Time")) } } ``` -------------------------------- ### Configure Asterisk manager.conf for goami client Source: https://github.com/heltonmarx/goami/blob/master/README.md Configures Asterisk's manager.conf file to enable AMI interface and define admin credentials. Requires Asterisk server installation and file system access to modify configuration. Sets up access control and permissions for the goami client to connect via localhost on port 5038. ```ini [general] enabled = yes port = 5038 bindaddr = 127.0.0.1 [admin] secret = admin deny = 0.0.0.0/0.0.0.0 permit = 127.0.0.1/255.255.255.255 read = all,system,call,log,verbose,command,agent,user,config write = all,system,call,log,verbose,command,agent,user,config ``` -------------------------------- ### Manage Asterisk Channels: List, Status, Variables (Go) Source: https://context7.com/heltonmarx/goami/llms.txt This Go function demonstrates how to list active Asterisk channels, retrieve the status of a specific channel, set a channel variable, and get the value of a channel variable using the goami library. It requires a context, an AMI socket connection, and an action ID. ```go package main import ( "context" "log" "github.com/heltonmarx/goami/ami" ) func manageChannels(ctx context.Context, socket *ami.Socket, actionID string) { // List all active channels channels, err := ami.CoreShowChannels(ctx, socket, actionID) if err != nil { log.Fatalf("failed to list channels: %v", err) } log.Printf("Found %d active channels", len(channels)) for _, ch := range channels { log.Printf("Channel: %s, State: %s, Context: %s@%s:%s", ch.Get("Channel"), ch.Get("ChannelStateDesc"), ch.Get("Context"), ch.Get("Extension"), ch.Get("Priority")) } // Get specific channel status if len(channels) > 0 { channelName := channels[0].Get("Channel") status, err := ami.Status(ctx, socket, actionID, channelName, "CHANNEL,EXTEN,CONTEXT") if err != nil { log.Fatalf("status query failed: %v", err) } log.Printf("Channel status: %s", status.Get("ChannelStateDesc")) } // Set channel variable err = ami.Setvar(ctx, socket, actionID, "SIP/1001-00000001", "MY_VAR", "test_value") if err != nil { log.Printf("failed to set variable: %v", err) } // Get channel variable varResp, err := ami.Getvar(ctx, socket, actionID, "SIP/1001-00000001", "MY_VAR") if err != nil { log.Fatalf("failed to get variable: %v", err) } log.Printf("Variable value: %s", varResp.Get("Value")) } ``` -------------------------------- ### Demonstrate AMI Login and Logoff operations in Go Source: https://github.com/heltonmarx/goami/blob/master/README.md Shows how to establish a connection to an Asterisk server using the goami library, perform login authentication, and execute logoff. Requires a running Asterisk instance with AMI properly configured. Accepts username, secret, and host address via command-line flags, and demonstrates error handling and context management. ```go package main import ( "flag" "fmt" "log" "github.com/heltonmarx/goami/ami" ) var ( username = flag.String("username", "admin", "AMI username") secret = flag.String("secret", "admin", "AMI secret") host = flag.String("host", "127.0.0.1:5038", "AMI host address") ) func main() { flag.Parse() ctx, cancel := context.WithCancel(context.Background()) defer cancel() socket, err := ami.NewSocket(ctx, *host) if err != nil { log.Fatalf("socket error: %v\n", err) } if _, err := ami.Connect(ctx, socket); err != nil { log.Fatalf("connect error: %v\n", err) } //Login uuid, _ := ami.GetUUID() if err := ami.Login(ctx, socket, *username, *secret, "Off", uuid); err != nil { log.Fatalf("login error: %v\n", err) } fmt.Printf("login ok!\n") //Logoff fmt.Printf("logoff\n") if err := ami.Logoff(ctx, socket, uuid); err != nil { log.Fatalf("logoff error: (%v)\n", err) } fmt.Printf("goodbye !\n") } ``` -------------------------------- ### Execute Asterisk Commands and Manage Configuration in Go Source: https://context7.com/heltonmarx/goami/llms.txt Shows various operations with Asterisk AMI including executing CLI commands, retrieving core settings, checking module status, and managing configurations. Requires github.com/heltonmarx/goami/ami package. Handles errors with log.Fatalf. ```go package main import ( "context" "log" "github.com/heltonmarx/goami/ami" ) func executeCommands(ctx context.Context, socket *ami.Socket, actionID string) { // Execute CLI command cmdResp, err := ami.Command(ctx, socket, actionID, "core show version") if err != nil { log.Fatalf("Command failed: %v", err) } log.Printf("Command output:\n%s", cmdResp.Get("Output")) // Get core settings settings, err := ami.CoreSettings(ctx, socket, actionID) if err != nil { log.Fatalf("CoreSettings failed: %v", err) } log.Printf("Asterisk Version: %s", settings.Get("AsteriskVersion")) log.Printf("System Name: %s", settings.Get("SystemName")) // Get core status status, err := ami.CoreStatus(ctx, socket, actionID) if err != nil { log.Fatalf("CoreStatus failed: %v", err) } log.Printf("Startup: %s, Reload: %s, Calls: %s", status.Get("CoreStartupDate"), status.Get("CoreReloadDate"), status.Get("CoreCurrentCalls")) // Get configuration file config, err := ami.GetConfig(ctx, socket, actionID, "sip.conf", "", "") if err != nil { log.Fatalf("GetConfig failed: %v", err) } log.Printf("Config Response: %s", config.Get("Response")) // Reload module reloadResp, err := ami.Reload(ctx, socket, actionID, "chan_sip.so") if err != nil { log.Fatalf("Reload failed: %v", err) } log.Printf("Reload: %s - %s", reloadResp.Get("Response"), reloadResp.Get("Message")) // Module check modCheck, err := ami.ModuleCheck(ctx, socket, actionID, "chan_pjsip.so") if err != nil { log.Fatalf("ModuleCheck failed: %v", err) } log.Printf("Module loaded: %s, Version: %s", modCheck.Get("Response"), modCheck.Get("Version")) } ``` -------------------------------- ### GoAMI Originate Calls with Custom Parameters Source: https://context7.com/heltonmarx/goami/llms.txt Shows how to originate outbound calls through Asterisk using GoAMI library. Supports originating calls to extensions with configurable context/priority or to applications with custom data. Includes caller ID customization, timeout settings, channel variables, and async execution. Early media and asynchronous options allow for advanced call handling scenarios. Returns response data for success/failure tracking. ```go package main import ( "context" "log" "github.com/heltonmarx/goami/ami" ) func originateCall(ctx context.Context, socket *ami.Socket, actionID string) { // Originate call to extension originateData := ami.OriginateData{ Channel: "SIP/1001", Exten: "5000", Context: "default", Priority: 1, CallerID: "GoAMI <1001>", Timeout: 30000, // milliseconds Variable: []string{"CUSTOM_VAR=value1", "SECOND_VAR=value2"}, Async: "true", EarlyMedia: "true", } resp, err := ami.Originate(ctx, socket, actionID, originateData) if err != nil { log.Fatalf("originate failed: %v", err) } if resp.Get("Response") == "Success" { log.Printf("Call originated: %s", resp.Get("Message")) } else { log.Printf("Originate failed: %s", resp.Get("Message")) } // Originate call to application appOriginateData := ami.OriginateData{ Channel: "SIP/1002", Application: "Playback", Data: "hello-world", CallerID: "System <9999>", Timeout: 20000, Async: "true", } appResp, err := ami.Originate(ctx, socket, actionID, appOriginateData) if err != nil { log.Fatalf("application originate failed: %v", err) } log.Printf("Application call response: %s", appResp.Get("Response")) } ``` -------------------------------- ### GoAMI Connect and Authenticate with Asterisk Source: https://context7.com/heltonmarx/goami/llms.txt Demonstrates establishing TCP connection to Asterisk Manager Interface and authenticating with username/password. Includes connection verification, UUID generation for action tracking, and optional event filtering. Supports login with event categories like 'system', 'call', 'all' or 'user'. Requires valid AMI credentials and network access to Asterisk server on port 5038. ```go package main import ( "context" "log" "time" "github.com/heltonmarx/goami/ami" ) func main() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Create socket connection to AMI socket, err := ami.NewSocket(ctx, "127.0.0.1:5038") if err != nil { log.Fatalf("socket connection failed: %v", err) } defer socket.Close(ctx) // Verify connection connected, err := ami.Connect(ctx, socket) if err != nil || !connected { log.Fatalf("AMI connect failed: %v", err) } log.Println("Successfully connected to Asterisk Manager Interface") } ``` ```go package main import ( "context" "log" "github.com/heltonmarx/goami/ami" ) func main() { ctx := context.Background() socket, err := ami.NewSocket(ctx, "127.0.0.1:5038") if err != nil { log.Fatalf("connection error: %v", err) } defer socket.Close(ctx) if _, err := ami.Connect(ctx, socket); err != nil { log.Fatalf("connect error: %v", err) } // Generate unique action ID for tracking uuid, err := ami.GetUUID() if err != nil { log.Fatalf("UUID generation failed: %v", err) } // Login with event filtering: "Off", "system", "call", "all", or "user" err = ami.Login(ctx, socket, "admin", "admin", "system,call,all", uuid) if err != nil { log.Fatalf("login failed: %v", err) } log.Println("Logged in successfully") // Logoff when done if err := ami.Logoff(ctx, socket, uuid); err != nil { log.Fatalf("logoff error: %v", err) } } ``` -------------------------------- ### List and Manage PJSIP Endpoints using GoAMI Source: https://context7.com/heltonmarx/goami/llms.txt Demonstrates how to retrieve all PJSIP endpoints, display their details, list contacts, and qualify a specific endpoint using the goami library. Requires a connected ami.Socket and an action ID; logs results and handles errors. Useful for administrators needing comprehensive endpoint insight. ```go package main\n\nimport (\n \"context\"\n \"log\"\n\n \"github.com/heltonmarx/goami/ami\"\n)\n\nfunc managePJSIPEndpoints(ctx context.Context, socket *ami.Socket, actionID string) {\n // List all PJSIP endpoints\n endpoints, err := ami.PJSIPShowEndpoints(ctx, socket, actionID)\n if err != nil {\n log.Fatalf(\"PJSIPShowEndpoints failed: %v\", err)\n }\n\n log.Printf(\"Found %d PJSIP endpoints\", len(endpoints))\n for _, ep := range endpoints {\n log.Printf(\"Endpoint: %s, State: %s, Contacts: %s\",\n ep.Get(\"ObjectName\"),\n ep.Get(\"DeviceState\"),\n ep.Get(\"Contacts\"))\n }\n\n // Show detailed endpoint information\n if len(endpoints) > 0 {\n endpointName := endpoints[0].Get(\"ObjectName\")\n details, err := ami.PJSIPShowEndpoint(ctx, socket, actionID, endpointName)\n if err != nil {\n log.Fatalf(\"PJSIPShowEndpoint failed: %v\", err)\n }\n\n for _, detail := range details {\n eventType := detail.Get(\"Event\")\n log.Printf(\"%s details:\", eventType)\n switch eventType {\n case \"EndpointDetail\":\n log.Printf(\" Auth: %s, Transport: %s\",\n detail.Get(\"Auth\"),\n detail.Get(\"Transport\"))\n case \"ContactStatusDetail\":\n log.Printf(\" URI: %s, Status: %s, RTT: %s\",\n detail.Get(\"URI\"),\n detail.Get(\"Status\"),\n detail.Get(\"RoundtripUsec\"))\n }\n }\n }\n\n // List all contacts\n contacts, err := ami.PJSIPShowContacts(ctx, socket, actionID)\n if err != nil {\n log.Fatalf(\"PJSIPShowContacts failed: %v\", err)\n }\n\n for _, contact := range contacts {\n log.Printf(\"Contact: %s, Status: %s, Expires: %s\",\n contact.Get(\"URI\"),\n contact.Get(\"Status\"),\n contact.Get(\"ExpirationTime\"))\n }\n\n // Qualify PJSIP endpoint\n qualifyResp, err := ami.PJSIPQualify(ctx, socket, actionID, \"2001\")\n if err != nil {\n log.Fatalf(\"PJSIPQualify failed: %v\", err)\n }\n log.Printf(\"Qualify result: %s\", qualifyResp.Get(\"Response\"))\n}\n ``` -------------------------------- ### Format Multi-Stack Trace in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `String()` method on `Multi` provides a consolidated, human-readable, multi-line string representation of all the stacked traces it contains. This is useful for logging or displaying comprehensive error origins. ```go func (m *Multi) String() string ``` -------------------------------- ### Manage Asterisk Channel Bridging and Transfers (Go) Source: https://context7.com/heltonmarx/goami/llms.txt This Go function shows how to bridge two Asterisk channels together, perform a blind transfer of a channel to an extension, and execute an attended transfer (redirect) to a specified destination. It requires context, an AMI socket, an action ID, and channel details. ```go package main import ( "context" "log" "github.com/heltonmarx/goami/ami" ) func bridgeChannels(ctx context.Context, socket *ami.Socket, actionID string) { // Bridge two channels together bridgeResp, err := ami.Bridge(ctx, socket, actionID, "SIP/1001-00000001", "SIP/1002-00000002", "yes") // tone: "yes" or "no" if err != nil { log.Fatalf("bridge failed: %v", err) } log.Printf("Bridge response: %s - %s", bridgeResp.Get("Response"), bridgeResp.Get("Message")) // Blind transfer transferResp, err := ami.BlindTransfer(ctx, socket, actionID, "SIP/1001-00000001", "default", "5000") if err != nil { log.Fatalf("blind transfer failed: %v", err) } log.Printf("Transfer response: %s", transferResp.Get("Response")) // Redirect (attended transfer) callData := ami.CallData{ Channel: "SIP/1001-00000001", Exten: "6000", Context: "default", Priority: "1", } redirectResp, err := ami.Redirect(ctx, socket, actionID, callData) if err != nil { log.Fatalf("redirect failed: %v", err) } log.Printf("Redirect: %s", redirectResp.Get("Response")) } ``` -------------------------------- ### Format a Stack of Frames in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `String()` method on the `Stack` type generates a multi-line, human-readable representation of the entire call stack. This is invaluable for understanding the sequence of events leading to a specific point in the code. ```go func (s Stack) String() string ``` -------------------------------- ### Format a Single Stack Frame in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `String()` method on the `Frame` type provides a human-readable representation of a stack frame, typically in a 'file:line' format. This aids in debugging by presenting frame information clearly. ```go func (f Frame) String() string ``` -------------------------------- ### Subscribe and Process Real-time AMI Events in Go Source: https://context7.com/heltonmarx/goami/llms.txt Shows how to enable AMI event flow and continuously monitor events such as Newchannel, Hangup, Queue join, and Peer status using goami. Runs a goroutine that reads events until the context is cancelled, logging relevant information. Suitable for real-time call monitoring and system notifications. ```go package main\n\nimport (\n \"context\"\n \"log\"\n \"time\"\n\n \"github.com/heltonmarx/goami/ami\"\n)\n\nfunc monitorEvents(ctx context.Context, socket *ami.Socket, actionID string) {\n // Enable event flow\n eventResp, err := ami.EventFlow(ctx, socket, actionID, \"on\")\n if err != nil {\n log.Fatalf(\"EventFlow failed: %v\", err)\n }\n log.Printf(\"Event flow: %s\", eventResp.Get(\"Response\"))\n\n // Monitor events in a goroutine\n go func() {\n for {\n select {\n case <-ctx.Done():\n log.Println(\"Event monitoring stopped\")\n return\n default:\n event, err := ami.Events(ctx, socket)\n if err != nil {\n log.Printf(\"Event error: %v\", err)\n return\n }\n\n eventType := event.Get(\"Event\")\n switch eventType {\n case \"Newchannel\":\n log.Printf(\"New channel: %s, State: %s\",\n event.Get(\"Channel\"),\n event.Get(\"ChannelStateDesc\"))\n\n case \"Hangup\":\n log.Printf(\"Hangup: %s, Cause: %s (%s)\",\n event.Get(\"Channel\"),\n event.Get(\"Cause\"),\n event.Get(\"Cause-txt\"))\n\n case \"Join\":\n log.Printf(\"Queue join: %s joined queue %s, Position: %s\",\n event.Get(\"CallerIDNum\"),\n event.Get(\"Queue\"),\n event.Get(\"Position\"))\n\n case \"QueueMemberStatus\":\n log.Printf(\"Queue member %s status: %s, Paused: %s\",\n event.Get(\"MemberName\"),\n event.Get(\"Status\"),\n event.Get(\"Paused\"))\n\n case \"PeerStatus\":\n log.Printf(\"Peer %s status changed to: %s\",\n event.Get(\"Peer\"),\n event.Get(\"PeerStatus\"))\n\n default:\n log.Printf(\"Event: %s\", eventType)\n }\n }\n }\n }()\n\n // Let events run for some time\n time.Sleep(30 * time.Second)\n}\n ``` -------------------------------- ### Manage Asterisk Call Queues with GoAMI Source: https://context7.com/heltonmarx/goami/llms.txt Demonstrates adding, pausing, removing, and retrieving status for members in an Asterisk call queue. Requires an active AMI connection and proper queue configuration. ```go package main import ( "context" "log" "github.com/heltonmarx/goami/ami" ) func manageQueues(ctx context.Context, socket *ami.Socket, actionID string) { // Add member to queue queueData := ami.QueueData{ Queue: "support", Interface: "SIP/1001", Penalty: "0", Paused: "false", MemberName: "Agent 1001", StateInterface: "SIP/1001", } addResp, err := ami.QueueAdd(ctx, socket, actionID, queueData) if err != nil { log.Fatalf("queue add failed: %v", err) } log.Printf("Queue add response: %s", addResp.Get("Response")) // Pause queue member pauseData := ami.QueueData{ Queue: "support", Interface: "SIP/1001", Paused: "true", Reason: "Break time", } pauseResp, err := ami.QueuePause(ctx, socket, actionID, pauseData) if err != nil { log.Fatalf("queue pause failed: %v", err) } log.Printf("Queue pause: %s", pauseResp.Get("Response")) // Get queue status with all members and calls statuses, err := ami.QueueStatuses(ctx, socket, actionID, "support") if err != nil { log.Fatalf("queue status failed: %v", err) } for _, status := range statuses { if status.Get("Event") == "QueueMember" { log.Printf("Member: %s, Status: %s, Calls: %s", status.Get("Name"), status.Get("Status"), status.Get("CallsTaken")) } } // Remove member from queue removeData := ami.QueueData{ Queue: "support", Interface: "SIP/1001", } removeResp, err := ami.QueueRemove(ctx, socket, actionID, removeData) if err != nil { log.Fatalf("queue remove failed: %v", err) } log.Printf("Queue remove: %s", removeResp.Get("Response")) } ``` -------------------------------- ### Add a Stack to a Multi-Stack in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `Add` method on `Multi` allows manually adding a `Stack` to the collection. This enables programmatic construction of multi-stack traces for complex scenarios. ```go func (m *Multi) Add(s Stack) ``` -------------------------------- ### Manage Asterisk Channel Hangup and Timeouts (Go) Source: https://context7.com/heltonmarx/goami/llms.txt This Go function illustrates how to terminate Asterisk channels using hangup commands with optional cause codes and how to set an absolute timeout for a channel, after which it will be automatically hung up. It requires a context, an AMI socket, and an action ID. ```go package main import ( "context" "log" "github.com/heltonmarx/goami/ami" ) func hangupChannel(ctx context.Context, socket *ami.Socket, actionID string) { // Hangup channel with cause code // Cause codes: "16" = Normal, "17" = Busy, "21" = Rejected resp, err := ami.Hangup(ctx, socket, actionID, "SIP/1001-00000001", "16") if err != nil { log.Fatalf("hangup failed: %v", err) } if resp.Get("Response") == "Success" { log.Println("Channel hung up successfully") } else { log.Printf("Hangup failed: %s", resp.Get("Message")) } // Set absolute timeout (channel will hangup after timeout) timeoutResp, err := ami.AbsoluteTimeout(ctx, socket, actionID, "SIP/1002-00000002", 60) if err != nil { log.Fatalf("timeout setting failed: %v", err) } log.Printf("Timeout set: %s", timeoutResp.Get("Response")) } ``` -------------------------------- ### Capture Multiple Stacks in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `CallersMulti` function captures a `Multi` type, which can hold multiple `Stack` traces. This is particularly useful for tracking errors across goroutines, allowing for a comprehensive view of the execution path. ```go func CallersMulti(skip int) *Multi ``` -------------------------------- ### Retrieve Stacks from Multi-Stack in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `Stacks` method on `Multi` returns a slice of all tracked `Stack` traces. This allows iteration and processing of the individual stacks within the `Multi` object. ```go func (m *Multi) Stacks() []Stack ``` -------------------------------- ### Capture a Single Stack Frame in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `Caller` function captures a single stack frame for the caller. It takes an integer `skip` argument to specify how many stack frames to ascend. This is useful for precise error origin tracking. ```go func Caller(skip int) Frame ``` -------------------------------- ### Capture a Stack of Frames in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `Callers` function captures a stack of `Frame` objects representing the call stack. The `skip` argument controls the number of frames to ascend from the caller. This provides a detailed history of function calls. ```go func Callers(skip int) Stack ``` -------------------------------- ### Add Current Callers to Multi-Stack in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `AddCallers` method on `Multi` automatically captures the current call stack and adds it to the `Multi` object. The `skip` parameter adjusts the frame ascension. This simplifies capturing stacks from different points in execution. ```go func (m *Multi) AddCallers(skip int) ``` -------------------------------- ### Strip Package Name from Function Name in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `StripPackage` function removes the package name prefix from a function name string. This cleans up function names for more concise display, as the package is often implied by the file path. ```go func StripPackage(n string) string ``` -------------------------------- ### Strip GOPATH from File Path in Go Source: https://github.com/heltonmarx/goami/blob/master/vendor/github.com/facebookgo/stack/readme.md The `StripGOPATH` function removes the GOPATH prefix from a given file path. It supports using the environment variable during development and can be configured for production builds using ldflags to embed the GOPATH. ```go func StripGOPATH(f string) string ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.