github.com/CyCoreSystems/ari@v4.8.4+incompatible/README.md (about) 1 # ari - Golang Asterisk Rest Interface (ARI) library 2 [](https://travis-ci.org/CyCoreSystems/ari) [](http://godoc.org/github.com/CyCoreSystems/ari) 3 4 This library allows you to easily access ARI in go applications. The Asterisk Rest Interface (https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=29395573) is an asynchronous API which allows you to access basic Asterisk objects for custom communications applications. 5 6 This project also includes some convenience wrappers for various tasks, found in /ext. These include go-idiomatic utilities for playing audio, IVRs, recordings, and other tasks which are tricky to coordinate nicely in ARI alone. 7 8 # Getting started 9 10 This library maintains semver, and APIs between major releases **do** change. 11 Therefore, always use a vendoring tool which supports semver, such as [dep](https://github.com/golang/dep). 12 13 Version `4.x.x` is the current version. It offers a number of 14 new features focused on facilitating ARI across large clusters and simplifies 15 the API. 16 17 There is also a NATS-based `ari-proxy` which is designed to work with this 18 client library. It can be found at 19 [CyCoreSystems/ari-proxy](https://github.com/CyCoreSystems/ari-proxy). 20 21 Install with: 22 ```sh 23 go get github.com/CyCoreSystems/ari 24 ``` 25 26 # Features 27 28 ## Cloud-ready 29 30 All configuration options for the client can be sourced by environment 31 variable, making it easy to build applications without configuration files. 32 The default connection to Asterisk is set to `localhost` on port 8088, 33 which should run on Kubernetes deployments without configuration. 34 35 The available environment variables (and defaults) are: 36 37 - `ARI_APPLICATION` (*randomly-generated ID*) 38 - `ARI_URL` (`http://localhost:8088/ari`) 39 - `ARI_WSURL` (`ws://localhost:8088/ari/events`) 40 - `ARI_WSORIGIN` (`http://localhost/`) 41 - `ARI_USERNAME` (*none*) 42 - `ARI_PASSWORD` (*none*) 43 44 If using `ari-proxy`, the process is even easier. 45 46 ## Resource Keys 47 48 In order to facilitate the construction of ARI systems across many Asterisk 49 instances, in version 4, we introduce the concept of Resource Keys. Previous 50 versions expected a simple ID (string) field for the identification of a 51 resource to ARI. This reflects how ARI itself operates. However, for systems 52 with multiple Asterisk instances, more metadata is necessary in order to 53 properly address a resource. Specifically, we need to know the Asterisk node. 54 There is also the concept of a Dialog, which offers an orthogonal logical 55 grouping of events which transcends nodes and applications. This is not 56 meaningful in the native client, but other transports, such as the ARI proxy, 57 may make use of this for alternative routing of events. This Key includes all of these data. 58 59 ```go 60 package ari 61 62 // Key identifies a unique resource in the system 63 type Key struct { 64 // Kind indicates the type of resource the Key points to. e.g., "channel", 65 // "bridge", etc. 66 Kind string `json:"kind"` 67 68 // ID indicates the unique identifier of the resource 69 ID string `json:"id"` 70 71 // Node indicates the unique identifier of the Asterisk node on which the 72 // resource exists or will be created 73 Node string `json:"node,omitempty"` 74 75 // Dialog indicates a named scope of the resource, for receiving events 76 Dialog string `json:"dialog,omitempty"` 77 } 78 ``` 79 At a basic level, when the specific Asterisk ID is not needed, a key can consist 80 of a simple ID string: 81 82 ```go 83 key := ari.NewKey(ari.ChannelKey, "myID") 84 ``` 85 86 For more interesting systems, however, we can declare the Node ID: 87 88 ```go 89 key := ari.NewKey(ari.BridgeKey, "myID", ari.WithNode("00:01:02:30:40:50")) 90 ``` 91 92 We can also bind a dialog: 93 94 ```go 95 key := ari.NewKey(ari.ChannelKey, "myID", 96 ari.WithNode("00:01:02:30:40:50"), 97 ari.WithDialog("privateConversation")) 98 ``` 99 100 We can also create a new key from an existing key. This allows us to easily 101 copy the location information from the original key to a new key of a different 102 resource. The location information is everything (including the Dialog) except 103 for the key Kind and ID. 104 105 ```go 106 brKey := key.New(ari.BridgeKey, "myBridgeID") 107 108 ``` 109 110 All ARI operations which accepted an ID for an operator now expect an `*ari.Key` 111 instead. In many cases, this can be easily back-ported by wrapping IDs with 112 `ari.NewKey("channel", id)`. 113 114 ## Handles 115 116 Handles for all of the major entity types are available, which bundle in the 117 tracking of resources with their manipulations. Every handle, at a minimum, 118 internally tracks the resource's cluster-unique Key and the ARI client 119 connection through which the entity is being interacted. Using a handle 120 generally results in less and more readable code. 121 122 For instance, instead of calling: 123 124 ```go 125 ariClient.Channel().Hangup(channelKey, "normal") 126 ``` 127 128 you could just call `Hangup()` on the handle: 129 130 ```go 131 h.Hangup() 132 ``` 133 134 While the lower level direct calls have maintained fairly strict semantics to 135 match the formal ARI APIs, the handles frequently provide higher-level, simpler 136 operations. Moreover, most of the extensions (see below) make use of handles. 137 138 In general, when operating on longer lifetime entities (such as channels and 139 bridges), it is easier to use handles wherever you can rather than tracking Keys 140 and clients discretely. 141 142 Obtaining a Handle from a Key is very simple; just call the `Get()` operation on 143 the resource interface appropriate to the key. The `Get()` operation is a 144 local-only operation which does not interact with the Asterisk or ARI proxy at 145 all, and it is thus quite efficient. 146 147 ```go 148 h := ariClient.Channel().Get(channelKey) 149 ``` 150 151 ## Staging resources 152 153 A common issue for ARI resources is making sure a subscription exists before 154 events for that resource are sent. Otherwise, important events which occur too 155 quickly can become lost. This results in a chicken-and-egg problem for 156 subscriptions. 157 158 In order to address this common issue, resource handles creation operations now 159 offer a `StageXXXX` variant, which returns the handle for the resource without 160 actually creating the resource. Once all of the subscriptions are bound to this 161 handle, the caller may call `resource.Exec()` in order to create the resource in 162 Asterisk. 163 164 ```go 165 h := NewChannelHandle(key, c, nil) 166 167 // Stage a playback 168 pb, err := h.StagePlay("myPlaybackID", "sound:tt-monkeys") 169 if err != nil { 170 return err 171 } 172 173 // Add a subscription to the staged playback 174 startSub := pb.Subscribe(EventTypes.PlaybackStarted) 175 defer startSub.Cancel() 176 177 // Execute the staged playback 178 pb.Exec() 179 180 // Wait for something to happen 181 select { 182 case <-time.After(time.Second): 183 fmt.Println("timeout waiting for playback to start") 184 return errors.New("timeout") 185 case <-startSub.Events(): 186 fmt.Println("playback started") 187 } 188 ``` 189 190 ## Extensions 191 192 There are a number of extensions which wrap the lower-level operations in 193 higher-level ones, making it easier to perform many common tasks. 194 195 196 ### AudioURI [](http://godoc.org/github.com/CyCoreSystems/ari/ext/audiouri) 197 198 Constructing Asterisk audio playback URIs can be a bit tedious, particularly for handling 199 certain edge cases in digits and for constructing dates. 200 201 The `audiouri` package provides a number of routines to make the construction of 202 these URIs simpler. 203 204 ### Bridgemon [](http://godoc.org/github.com/CyCoreSystems/ari/ext/bridgemon) 205 206 Monitoring a bridge for events and data updates is not difficult, but it 207 involves a lot of code and often makes several wasteful calls to obtain bridge 208 data, particularly when accessing it on large bridges. 209 210 Bridgemon provides a cache and proxy for the bridge data and bridge events so 211 that a user can simply `Watch()` for changes in the bridge state and efficiently 212 retrieve the updated data without multiple requests. 213 214 It also shuts itself down automatically when the bridge it is monitoring is 215 destroyed. 216 217 ### Play [](http://godoc.org/github.com/CyCoreSystems/ari/ext/play) 218 219 Playback of media and waiting for (DTMF) responses therefrom is an incredibly 220 common task in telephony. ARI provides many tools to perform these types of 221 actions, but the asynchronous nature of the interface makes it fairly tedious to 222 build these kinds of things. 223 224 In `ext/play`, there resides a tool for executing many common tasks surrounding 225 media playback and response sequences. The core function, `play.Play()` 226 plays, in sequence, a series of audio media URIs. It can be extended to expect 227 and (optionally) wait for a DTMF response by supplying it with a Match function. 228 There is a small convenience wrapper `play.Prompt()` which sets some common 229 defaults for playbacks which expect a response. 230 231 The execution of a `Play` is configured by any number of option functions, which 232 supply structured modifiers for the behaviour of the playback. You can even 233 supply your own Match function for highly-customized matching. 234 235 ### Record [](http://godoc.org/github.com/CyCoreSystems/ari/ext/record) 236 237 Making recordings is another complicated but common task for ARI applications. 238 The `ext/record`, we provide a simple wrapper which facilitates many common 239 recording-related operations inside a single recording Session wrapper. 240 241 Features include: 242 243 - record with or without a beep at the start 244 - listen for various termination types: hangup, dtmf, silence, timeout 245 - review, scrap, and save recordings upon completion 246 - retrieve the playback URI for the recording 247 248 # Documentation and Examples 249 250 Go documentation is available at https://godoc.org/github.com/CyCoreSystems/ari 251 252 Examples for helloworld, play, script, bridge, and record are available. Set your environment variables as described above (at minimum, `ARI_USERNAME` and `ARI_PASSWORD`) and run: 253 254 ```sh 255 cd /_examples/helloworld 256 go run ./main.go 257 ``` 258 259 Other examples: 260 261 - `stasisStart` demonstrates a simple click-to-call announcer system 262 - `stasisStart-nats` demonstrates the same click-to-call using the NATS-based 263 ARI proxy 264 - `bridge` demonstrates a simple conference bridge 265 - `play` demonstrates the use of the `ext/play` extension 266 - `record` demonstrates the use of the `ext/record` extension 267 268 The files in `_ext/infra` demonstrates the minimum necessary changes to the 269 Asterisk configuration to enable the operation of ARI. 270 271 272 # Tests 273 274 Run `go test` to verify 275 276 # Contributing 277 278 Contributions welcomed. Changes with tests and descriptive commit messages will get priority handling. 279 280 # License 281 282 Licensed under the Apache License, Version 2.0