package asterisk import ( "errors" "fmt" "regexp" "strings" "time" "github.com/CyCoreSystems/ari/v5" ) var dialedRoute = regexp.MustCompile(`^[a-zA-Z0-9]+$`) // approvedOriginateRequest binds an already-approved Agent instruction to one // native ARI channel. The Dispatcher, not the Agent, selected the trunk, // caller and complete dialed number (including any trunk-specific prefix). func approvedOriginateRequest(executionID, trunkID, dialedCallee, callerID string, answerTimeout time.Duration) (ari.OriginateRequest, error) { if !trunkName.MatchString(executionID) || !trunkName.MatchString(trunkID) || !dialedRoute.MatchString(dialedCallee) || strings.TrimSpace(callerID) == "" || strings.ContainsAny(callerID, "\r\n") { return ari.OriginateRequest{}, errors.New("approved ARI channel identity or route is incomplete") } seconds := int(answerTimeout / time.Second) if seconds < 1 { return ari.OriginateRequest{}, fmt.Errorf("approved ARI answer window is shorter than one second: %s", answerTimeout) } return ari.OriginateRequest{ ChannelID: executionID, Endpoint: "PJSIP/" + dialedCallee + "@" + trunkID, CallerID: callerID, App: "go-sip-agent", Timeout: seconds, }, nil }