eslgo

package module
v1.4.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2023 License: MPL-2.0 Imports: 17 Imported by: 0

README

eslgo

PkgGoDev GitHub Workflow Status Go Report Card Total alerts GitHub license

eslgo is a FreeSWITCH™ ESL library for GoLang. eslgo was written from the ground up in idiomatic Go for use in our production products tested handling thousands of calls per second.

Install

go get github.com/percipia/eslgo
github.com/percipia/eslgo v1.4.1

Overview

  • Inbound ESL Connection
  • Outbound ESL Server
  • Event listeners by UUID or All events
    • Unique-Id
    • Application-UUID
    • Job-UUID
  • Context support for canceling requests
  • All command types abstracted out
    • You can also send custom data by implementing the Command interface
      • BuildMessage() string
  • Basic Helpers for common tasks
    • DTMF
    • Call origination
    • Call answer/hangup
    • Audio playback

Examples

There are some buildable examples under the example directory as well

Outbound ESL Server
package main

import (
	"context"
	"fmt"
	"github.com/percipia/eslgo"
	"log"
)

func main() {
	// Start listening, this is a blocking function
	log.Fatalln(eslgo.ListenAndServe(":8084", handleConnection))
}

func handleConnection(ctx context.Context, conn *eslgo.Conn, response *eslgo.RawResponse) {
	fmt.Printf("Got connection! %#v\n", response)

	// Place the call in the foreground(api) to user 100 and playback an audio file as the bLeg and no exported variables
	response, err := conn.OriginateCall(ctx, false, eslgo.Leg{CallURL: "user/100"}, eslgo.Leg{CallURL: "&playback(misc/ivr-to_hear_screaming_monkeys.wav)"}, map[string]string{})
	fmt.Println("Call Originated: ", response, err)
}

Inbound ESL Client

package main

import (
	"context"
	"fmt"
	"github.com/percipia/eslgo"
	"time"
)

func main() {
	// Connect to FreeSWITCH
	conn, err := eslgo.Dial("127.0.0.1:8021", "ClueCon", func() {
		fmt.Println("Inbound Connection Disconnected")
	})
	if err != nil {
		fmt.Println("Error connecting", err)
		return
	}

	// Create a basic context
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
	defer cancel()

	// Place the call in the background(bgapi) to user 100 and playback an audio file as the bLeg and no exported variables
	response, err := conn.OriginateCall(ctx, true, eslgo.Leg{CallURL: "user/100"}, eslgo.Leg{CallURL: "&playback(misc/ivr-to_hear_screaming_monkeys.wav)"}, map[string]string{})
	fmt.Println("Call Originated: ", response, err)

	// Close the connection after sleeping for a bit
	time.Sleep(60 * time.Second)
	conn.ExitAndClose()
}

Documentation

Overview

* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * Contributor(s): * Andrew Querol <aquerol@percipia.com>

* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * Contributor(s): * Andrew Querol <aquerol@percipia.com>

* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * Contributor(s): * Andrew Querol <aquerol@percipia.com>

* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * Contributor(s): * Andrew Querol <aquerol@percipia.com>

* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * Contributor(s): * Andrew Querol <aquerol@percipia.com>

* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * Contributor(s): * Andrew Querol <aquerol@percipia.com>

* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * Contributor(s): * Andrew Querol <aquerol@percipia.com>

* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * Contributor(s): * Andrew Querol <aquerol@percipia.com>

Index

Constants

View Source
const (
	TypeEventPlain  = `text/event-plain`
	TypeEventJSON   = `text/event-json`
	TypeEventXML    = `text/event-xml`
	TypeReply       = `command/reply`
	TypeAPIResponse = `api/response`
	TypeAuthRequest = `auth/request`
	TypeDisconnect  = `text/disconnect-notice`
)
View Source
const EndOfMessage = "\r\n\r\n"
View Source
const (
	EventListenAll = "ALL"
)

Variables

View Source
var DefaultInboundOptions = InboundOptions{
	Options:     DefaultOptions,
	Network:     "tcp",
	Password:    "ClueCon",
	AuthTimeout: 5 * time.Second,
}

DefaultOutboundOptions - The default options used for creating the inbound connection

View Source
var DefaultOptions = Options{
	Context:     context.Background(),
	Logger:      NormalLogger{},
	ExitTimeout: 5 * time.Second,
}

DefaultOptions - The default options used for creating the connection

View Source
var DefaultOutboundOptions = OutboundOptions{
	Options:         DefaultOptions,
	Network:         "tcp",
	ConnectTimeout:  5 * time.Second,
	ConnectionDelay: 25 * time.Millisecond,
}

DefaultOutboundOptions - The default options used for creating the outbound connection

Functions

func BuildVars

func BuildVars(format string, vars map[string]string) string

BuildVars - A helper that builds channel variable strings to be included in various commands to FreeSWITCH

func ListenAndServe

func ListenAndServe(address string, handler OutboundHandler) error
  • TODO: Review if we should have a rate limiting facility to prevent DoS attacks
  • For our use it should be fine since we only want to listen on localhost

ListenAndServe - Open a new listener for outbound ESL connections from FreeSWITCH on the specified address with the provided connection handler

Types

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

func Dial

func Dial(address, password string, onDisconnect func()) (*Conn, error)

Dial - Connects to FreeSWITCH ESL at the provided address and authenticates with the provided password. onDisconnect is called when the connection is closed either by us, FreeSWITCH, or network error

func (*Conn) AnswerCall

func (c *Conn) AnswerCall(ctx context.Context, uuid string) error

HangupCall - A helper to answer a call synchronously

func (*Conn) Close

func (c *Conn) Close()

Close - Close our connection to FreeSWITCH without sending "exit". Protected by a sync.Once

func (*Conn) DebugEvents

func (c *Conn) DebugEvents(w io.Writer) string

DebugEvents - A helper that will output all events to a logger

func (*Conn) DebugOff

func (c *Conn) DebugOff(id string)

func (*Conn) EnableEvents

func (c *Conn) EnableEvents(ctx context.Context, formats ...string) error

func (*Conn) EnterpriseOriginateCall

func (c *Conn) EnterpriseOriginateCall(ctx context.Context, background bool, vars map[string]string, bLeg Leg, aLegs ...Leg) (*RawResponse, error)

EnterpriseOriginateCall - Calls the originate function in FreeSWITCH using the enterprise method for calling multiple legs ":_:" If you want variables for each leg independently set them in the aLeg and bLeg strings Arguments: ctx context.Context for supporting context cancellation, background bool should we wait for the origination to complete vars map[string]string, channel variables to be passed to originate for both legs, contained in <> bLeg string The bLeg of the call aLegs ...string variadic argument for each aLeg to call

func (*Conn) ExitAndClose

func (c *Conn) ExitAndClose()

ExitAndClose - Attempt to gracefully send FreeSWITCH "exit" over the ESL connection before closing our connection and stopping. Protected by a sync.Once

func (*Conn) HangupCall

func (c *Conn) HangupCall(ctx context.Context, uuid, cause string) error

HangupCall - A helper to hangup a call asynchronously

func (*Conn) OriginateCall

func (c *Conn) OriginateCall(ctx context.Context, background bool, aLeg, bLeg Leg, vars map[string]string) (*RawResponse, error)

OriginateCall - Calls the originate function in FreeSWITCH. If you want variables for each leg independently set them in the aLeg and bLeg Arguments: ctx context.Context for supporting context cancellation, background bool should we wait for the origination to complete aLeg, bLeg Leg The aLeg and bLeg of the call respectively vars map[string]string, channel variables to be passed to originate for both legs, contained in {}

func (*Conn) Phrase

func (c *Conn) Phrase(ctx context.Context, uuid, macro string, times int, wait bool) (*RawResponse, error)

Phrase - Executes the mod_dptools phrase app

func (*Conn) PhraseWithArg

func (c *Conn) PhraseWithArg(ctx context.Context, uuid, macro string, argument interface{}, times int, wait bool) (*RawResponse, error)

PhraseWithArg - Executes the mod_dptools phrase app with arguments

func (*Conn) Playback

func (c *Conn) Playback(ctx context.Context, uuid, audioArgs string, times int, wait bool) (*RawResponse, error)

Playback - Executes the mod_dptools playback app

func (*Conn) RegisterEventListener

func (c *Conn) RegisterEventListener(channelUUID string, listener EventListener) string

RegisterEventListener - Registers a new event listener for the specified channel UUID(or EventListenAll). Returns the registered listener ID used to remove it.

func (*Conn) RemoveEventListener

func (c *Conn) RemoveEventListener(channelUUID string, id string)

RemoveEventListener - Removes the listener for the specified channel UUID with the listener ID returned from RegisterEventListener

func (*Conn) Say

func (c *Conn) Say(ctx context.Context, uuid, audioArgs string, times int, wait bool) (*RawResponse, error)

Say - Executes the mod_dptools say app

func (*Conn) SendCommand

func (c *Conn) SendCommand(ctx context.Context, command command.Command) (*RawResponse, error)

SendCommand - Sends the specified ESL command to FreeSWITCH with the provided context. Returns the response data and any errors encountered.

func (*Conn) Speak

func (c *Conn) Speak(ctx context.Context, uuid, audioArgs string, times int, wait bool) (*RawResponse, error)

Speak - Executes the mod_dptools speak app

func (*Conn) WaitForDTMF

func (c *Conn) WaitForDTMF(ctx context.Context, uuid string) (byte, error)

WaitForDTMF, waits for a DTMF event. Requires events to be enabled!

type Event

type Event struct {
	Headers textproto.MIMEHeader
	Body    []byte
}

func (Event) GetHeader

func (e Event) GetHeader(header string) string

GetHeader Helper function that calls e.Header.Get

func (Event) GetName

func (e Event) GetName() string

GetName Helper function that returns the event name header

func (Event) GoString

func (e Event) GoString() string

GoString Implement the GoStringer interface for pretty printing (%#v)

func (Event) HasHeader

func (e Event) HasHeader(header string) bool

HasHeader Helper to check if the Event has a header

func (Event) String

func (e Event) String() string

String Implement the Stringer interface for pretty printing (%v)

type EventListener

type EventListener func(event *Event)

type InboundOptions

type InboundOptions struct {
	Options                    // Generic common options to both Inbound and Outbound Conn
	Network      string        // The network type to use, should always be tcp, tcp4, tcp6.
	Password     string        // The password used to authenticate with FreeSWITCH. Usually ClueCon
	OnDisconnect func()        // An optional function to be called with the inbound connection gets disconnected
	AuthTimeout  time.Duration // How long to wait for authentication to complete
}

InboundOptions - Used to dial a new inbound ESL connection to FreeSWITCH

func (InboundOptions) Dial

func (opts InboundOptions) Dial(address string) (*Conn, error)

Dial - Connects to FreeSWITCH ESL on the address with the provided options. Returns the connection and any errors encountered

type Leg

type Leg struct {
	CallURL      string
	LegVariables map[string]string
}

Leg This struct is used to specify the individual legs of a call for the originate helpers

func (Leg) String

func (l Leg) String() string

String - Build the Leg string for passing to Bridge/Originate functions

type Logger

type Logger interface {
	Debug(format string, args ...interface{})
	Info(format string, args ...interface{})
	Warn(format string, args ...interface{})
	Error(format string, args ...interface{})
}

type NilLogger

type NilLogger struct{}

func (NilLogger) Debug

func (l NilLogger) Debug(string, ...interface{})

func (NilLogger) Error

func (l NilLogger) Error(string, ...interface{})

func (NilLogger) Info

func (l NilLogger) Info(string, ...interface{})

func (NilLogger) Warn

func (l NilLogger) Warn(string, ...interface{})

type NormalLogger

type NormalLogger struct{}

func (NormalLogger) Debug

func (l NormalLogger) Debug(format string, args ...interface{})

func (NormalLogger) Error

func (l NormalLogger) Error(format string, args ...interface{})

func (NormalLogger) Info

func (l NormalLogger) Info(format string, args ...interface{})

func (NormalLogger) Warn

func (l NormalLogger) Warn(format string, args ...interface{})

type Options

type Options struct {
	Context     context.Context // This specifies the base running context for the connection. If this context expires all connections will be terminated.
	Logger      Logger          // This specifies the logger to be used for any library internal messages. Can be set to nil to suppress everything.
	ExitTimeout time.Duration   // How long should we wait for FreeSWITCH to respond to our "exit" command. 5 seconds is a sane default.
}

Options - Generic options for an ESL connection, either inbound or outbound

type OutboundHandler

type OutboundHandler func(ctx context.Context, conn *Conn, connectResponse *RawResponse)

type OutboundOptions

type OutboundOptions struct {
	Options                       // Generic common options to both Inbound and Outbound Conn
	Network         string        // The network type to listen on, should be tcp, tcp4, or tcp6
	ConnectTimeout  time.Duration // How long should we wait for FreeSWITCH to respond to our "connect" command. 5 seconds is a sane default.
	ConnectionDelay time.Duration // How long should we wait after connection to start sending commands. 25ms is the recommended default otherwise we can close the connection before FreeSWITCH finishes starting it on their end. https://github.com/signalwire/freeswitch/pull/636
}

OutboundOptions - Used to open a new listener for outbound ESL connections from FreeSWITCH

func (OutboundOptions) ListenAndServe

func (opts OutboundOptions) ListenAndServe(address string, handler OutboundHandler) error

ListenAndServe - Open a new listener for outbound ESL connections from FreeSWITCH with provided options and handle them with the specified handler

type RawResponse

type RawResponse struct {
	Headers textproto.MIMEHeader
	Body    []byte
}

RawResponse This struct contains all response data from FreeSWITCH

func (RawResponse) ChannelUUID

func (r RawResponse) ChannelUUID() string

ChannelUUID Helper to get the channel UUID. Calls GetHeader internally

func (RawResponse) GetHeader

func (r RawResponse) GetHeader(header string) string

GetHeader Helper function that calls RawResponse.Headers.Get. Result gets passed through url.PathUnescape

func (RawResponse) GetReply

func (r RawResponse) GetReply() string

GetReply Helper to get the Reply text from FreeSWITCH, uses the Reply-Text header primarily. Also will use the body if the Reply-Text header does not exist, this can be the case for TypeAPIResponse

func (RawResponse) GetVariable

func (r RawResponse) GetVariable(variable string) string

GetVariable Helper function to get "Variable_" headers. Calls GetHeader internally

func (RawResponse) GoString

func (r RawResponse) GoString() string

GoString Implement the GoStringer interface for pretty printing (%#v)

func (RawResponse) HasHeader

func (r RawResponse) HasHeader(header string) bool

HasHeader Helper to check if the RawResponse has a header

func (RawResponse) IsOk

func (r RawResponse) IsOk() bool

IsOk Helper to check response status, uses the Reply-Text header primarily. Calls GetReply internally

func (RawResponse) String

func (r RawResponse) String() string

String Implement the Stringer interface for pretty printing

Directories

Path Synopsis
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
call
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
example
events
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
inbound
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
outbound
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.
* Copyright (c) 2020 Percipia * * This Source Code Form is subject to the terms of the Mozilla Public * License, v.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL