github.com/CyCoreSystems/ari@v4.8.4+incompatible/README.md (about)

     1  # ari - Golang Asterisk Rest Interface (ARI) library
     2  [![Build Status](https://travis-ci.org/CyCoreSystems/ari.png)](https://travis-ci.org/CyCoreSystems/ari) [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](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 [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](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 [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](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 [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](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 [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](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