|
| 1 | +Go ESL |
| 2 | +==== |
| 3 | + |
| 4 | +###Introduction |
| 5 | + |
| 6 | +[GoESL](https://github.com/0x19/goesl) is a very simple and straight forward [Go](http://golang.org/) package designed to interact with FreeSWITCH [ESL](https://freeswitch.org/confluence/display/FREESWITCH/Event+Socket+Library). GoESL supports both client and server. Server is used to bind and listen for incoming FreeSWITCH messages where client is used for sending commands. GoESL package contains few helpers which can be found in helpers.go so you can easily answer, hangup or send api events. |
| 7 | + |
| 8 | + |
| 9 | +###Installation |
| 10 | + |
| 11 | +[GoESL](https://github.com/0x19/goesl) is a package as-is. Standard go get will get you going :) Make sure to have go properly setup based on your operating system. |
| 12 | + |
| 13 | +If you're unsure how to do it [Go Getting Started](http://golang.org/doc/install) will help you out. |
| 14 | + |
| 15 | +```go |
| 16 | +go get github.com/0x19/goesl |
| 17 | +``` |
| 18 | + |
| 19 | + |
| 20 | +###How To / Examples |
| 21 | + |
| 22 | +Following code is the only thing you need to do in order to import GoESL |
| 23 | + |
| 24 | +```go |
| 25 | +import ( |
| 26 | + . "github.com/0x19/goesl" |
| 27 | +) |
| 28 | +``` |
| 29 | + |
| 30 | +All available examples can be found at [GoESL Examples](https://github.com/0x19/goesl/tree/master/examples) |
| 31 | + |
| 32 | + |
| 33 | +####Client Example |
| 34 | + |
| 35 | +Following example will connect to FreeSWITCH event socket interface and send originate api command |
| 36 | + |
| 37 | +```go |
| 38 | +package examples |
| 39 | + |
| 40 | +import ( |
| 41 | + "flag" |
| 42 | + "fmt" |
| 43 | + . "github.com/0x19/goesl" |
| 44 | + "runtime" |
| 45 | + "strings" |
| 46 | +) |
| 47 | + |
| 48 | +var ( |
| 49 | + fshost = flag.String("fshost", "localhost", "Freeswitch hostname. Default: localhost") |
| 50 | + fsport = flag.Uint("fsport", 8021, "Freeswitch port. Default: 8021") |
| 51 | + password = flag.String("pass", "ClueCon", "Freeswitch password. Default: ClueCon") |
| 52 | + timeout = flag.Int("timeout", 10, "Freeswitch conneciton timeout in seconds. Default: 10") |
| 53 | +) |
| 54 | + |
| 55 | +func main() { |
| 56 | + |
| 57 | + // Boost it as much as it can go ... |
| 58 | + runtime.GOMAXPROCS(runtime.NumCPU()) |
| 59 | + |
| 60 | + client, err := NewClient(*fshost, *fsport, *password, *timeout) |
| 61 | + |
| 62 | + if err != nil { |
| 63 | + Error("Error while creating new client: %s", err) |
| 64 | + return |
| 65 | + } |
| 66 | + |
| 67 | + // Apparently all is good... Let us now handle connection :) |
| 68 | + // We don't want this to be inside of new connection as who knows where it my lead us. |
| 69 | + // Remember that this is crutial part in handling incoming messages. This is a must! |
| 70 | + go client.Handle() |
| 71 | + |
| 72 | + client.Send("events json ALL") |
| 73 | + |
| 74 | + client. BgApi(fmt. Sprintf( "originate %s %s", "sofia/internal/[email protected]", "&socket(192.168.1.2:8084 async full)")) |
| 75 | + |
| 76 | + for { |
| 77 | + msg, err := client.ReadMessage() |
| 78 | + |
| 79 | + if err != nil { |
| 80 | + |
| 81 | + // If it contains EOF, we really dont care... |
| 82 | + if !strings.Contains(err.Error(), "EOF") && err.Error() != "unexpected end of JSON input" { |
| 83 | + Error("Error while reading Freeswitch message: %s", err) |
| 84 | + } |
| 85 | + |
| 86 | + break |
| 87 | + } |
| 88 | + |
| 89 | + Debug("Got new message: %s", msg) |
| 90 | + } |
| 91 | +} |
| 92 | + |
| 93 | +``` |
| 94 | + |
| 95 | +You can run this code by saving it as client.go and than running |
| 96 | + |
| 97 | +```bash |
| 98 | +go build client.go && ./client |
| 99 | +``` |
| 100 | + |
| 101 | +#### Server Example (TTS) |
| 102 | + |
| 103 | +Following example will start server and listen for incoming messages. Once received speak (TTS) will be initiated to the originator. |
| 104 | + |
| 105 | +```go |
| 106 | +package examples |
| 107 | + |
| 108 | +import ( |
| 109 | + . "github.com/0x19/goesl" |
| 110 | + "runtime" |
| 111 | + "strings" |
| 112 | +) |
| 113 | + |
| 114 | +var ( |
| 115 | + goeslMessage = "Hello from GoESL. Open source FreeSWITCH event socket wrapper written in Go!" |
| 116 | +) |
| 117 | + |
| 118 | +func main() { |
| 119 | + |
| 120 | + defer func() { |
| 121 | + if r := recover(); r != nil { |
| 122 | + Error("Recovered in: ", r) |
| 123 | + } |
| 124 | + }() |
| 125 | + |
| 126 | + // Boost it as much as it can go ... |
| 127 | + runtime.GOMAXPROCS(runtime.NumCPU()) |
| 128 | + |
| 129 | + if s, err := NewOutboundServer(":8084"); err != nil { |
| 130 | + Error("Got error while starting FreeSWITCH outbound server: %s", err) |
| 131 | + } else { |
| 132 | + go handle(s) |
| 133 | + s.Start() |
| 134 | + } |
| 135 | + |
| 136 | +} |
| 137 | + |
| 138 | +// handle - Running under goroutine here to explain how to run tts outbound server |
| 139 | +func handle(s *OutboundServer) { |
| 140 | + |
| 141 | + for { |
| 142 | + |
| 143 | + select { |
| 144 | + |
| 145 | + case conn := <-s.Conns: |
| 146 | + Notice("New incomming connection: %v", conn) |
| 147 | + |
| 148 | + if err := conn.Connect(); err != nil { |
| 149 | + Error("Got error while accepting connection: %s", err) |
| 150 | + break |
| 151 | + } |
| 152 | + |
| 153 | + answer, err := conn.ExecuteAnswer("", false) |
| 154 | + |
| 155 | + if err != nil { |
| 156 | + Error("Got error while executing answer: %s", err) |
| 157 | + break |
| 158 | + } |
| 159 | + |
| 160 | + Debug("Answer Message: %s", answer) |
| 161 | + Debug("Caller UUID: %s", answer.GetHeader("Caller-Unique-Id")) |
| 162 | + |
| 163 | + cUUID := answer.GetCallUUID() |
| 164 | + |
| 165 | + if te, err := conn.ExecuteSet("tts_engine", "flite", false); err != nil { |
| 166 | + Error("Got error while attempting to set tts_engine: %s", err) |
| 167 | + } else { |
| 168 | + Debug("TTS Engine Msg: %s", te) |
| 169 | + } |
| 170 | + |
| 171 | + if tv, err := conn.ExecuteSet("tts_voice", "slt", false); err != nil { |
| 172 | + Error("Got error while attempting to set tts_voice: %s", err) |
| 173 | + } else { |
| 174 | + Debug("TTS Voice Msg: %s", tv) |
| 175 | + } |
| 176 | + |
| 177 | + if sm, err := conn.Execute("speak", goeslMessage, true); err != nil { |
| 178 | + Error("Got error while executing speak: %s", err) |
| 179 | + break |
| 180 | + } else { |
| 181 | + Debug("Speak Message: %s", sm) |
| 182 | + } |
| 183 | + |
| 184 | + if hm, err := conn.ExecuteHangup(cUUID, "", false); err != nil { |
| 185 | + Error("Got error while executing hangup: %s", err) |
| 186 | + break |
| 187 | + } else { |
| 188 | + Debug("Hangup Message: %s", hm) |
| 189 | + } |
| 190 | + |
| 191 | + go func() { |
| 192 | + for { |
| 193 | + msg, err := conn.ReadMessage() |
| 194 | + |
| 195 | + if err != nil { |
| 196 | + |
| 197 | + // If it contains EOF, we really dont care... |
| 198 | + if !strings.Contains(err.Error(), "EOF") { |
| 199 | + Error("Error while reading Freeswitch message: %s", err) |
| 200 | + } |
| 201 | + break |
| 202 | + } |
| 203 | + |
| 204 | + Debug("Got message: %s", msg) |
| 205 | + } |
| 206 | + }() |
| 207 | + |
| 208 | + default: |
| 209 | + } |
| 210 | + } |
| 211 | + |
| 212 | +} |
| 213 | +``` |
| 214 | + |
| 215 | +You can run this code by saving it as tts_server.go and than running |
| 216 | + |
| 217 | +```bash |
| 218 | +go build tts_server.go && ./tts_server |
| 219 | +``` |
| 220 | + |
| 221 | + |
| 222 | + |
| 223 | + |
| 224 | + |
| 225 | + |
| 226 | + |
| 227 | + |
| 228 | + |
| 229 | + |
0 commit comments