{"id":13400408,"url":"https://github.com/CyCoreSystems/ari","last_synced_at":"2025-03-14T06:31:39.974Z","repository":{"id":23959938,"uuid":"27342110","full_name":"CyCoreSystems/ari","owner":"CyCoreSystems","description":"Golang Asterisk REST Interface (ARI) library","archived":false,"fork":false,"pushed_at":"2025-02-27T15:53:16.000Z","size":5749,"stargazers_count":207,"open_issues_count":33,"forks_count":79,"subscribers_count":24,"default_branch":"main","last_synced_at":"2025-03-07T03:56:22.345Z","etag":null,"topics":["ari","asterisk","golang","nats"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CyCoreSystems.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-30T16:28:10.000Z","updated_at":"2025-03-02T18:34:32.000Z","dependencies_parsed_at":"2024-06-18T14:00:21.487Z","dependency_job_id":"6941039b-ab9f-498c-bb50-311c6ad213c5","html_url":"https://github.com/CyCoreSystems/ari","commit_stats":{"total_commits":657,"total_committers":20,"mean_commits":32.85,"dds":0.482496194824962,"last_synced_commit":"0e2dabc3bcb1fc70dad8f4ae5f72bba262e67c26"},"previous_names":[],"tags_count":76,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyCoreSystems%2Fari","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyCoreSystems%2Fari/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyCoreSystems%2Fari/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyCoreSystems%2Fari/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CyCoreSystems","download_url":"https://codeload.github.com/CyCoreSystems/ari/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242634187,"owners_count":20161281,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ari","asterisk","golang","nats"],"created_at":"2024-07-30T19:00:51.703Z","updated_at":"2025-03-14T06:31:39.956Z","avatar_url":"https://github.com/CyCoreSystems.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# ari - Golang Asterisk Rest Interface (ARI) library\n[![Build Status](https://travis-ci.org/CyCoreSystems/ari.png)](https://travis-ci.org/CyCoreSystems/ari) [![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go\u0026logoColor=white\u0026style=flat-square)](https://pkg.go.dev/github.com/CyCoreSystems/ari/v6) \n\nThis 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.  \n\nThis 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.  \n\n**NOTE** This version of `ari` requires Asterisk version 14 or later.  If\nsupport is needed for version 13, please use v5 of `ari`.\n\n# Getting started\n\nThis library maintains semver, and APIs between major releases **do** change.\nWe use `GO111MODULE`, so Go version 1.11 or later is required.\n\nVersion `5.x.x` is the current version.\n\nThere is also a NATS-based `ari-proxy` which is designed to work with this\nclient library.  It can be found at\n[CyCoreSystems/ari-proxy](https://github.com/CyCoreSystems/ari-proxy).\n\nInstall with: \n```sh \ngo get github.com/CyCoreSystems/ari/v6\n```\n\n# Features\n\n## Cloud-ready\n\nAll configuration options for the client can be sourced by environment\nvariable, making it easy to build applications without configuration files.\nThe default connection to Asterisk is set to `localhost` on port 8088,\nwhich should run on Kubernetes deployments without configuration.\n\nThe available environment variables (and defaults) are:\n\n  - `ARI_APPLICATION` (*randomly-generated ID*)\n  - `ARI_URL` (`http://localhost:8088/ari`)\n  - `ARI_WSURL` (`ws://localhost:8088/ari/events`)\n  - `ARI_WSORIGIN` (`http://localhost/`)\n  - `ARI_USERNAME` (*none*)\n  - `ARI_PASSWORD` (*none*)\n\nIf using `ari-proxy`, the process is even easier.\n\n## Resource Keys\n\nIn order to facilitate the construction of ARI systems across many Asterisk\ninstances, in version 4, we introduce the concept of Resource Keys.  Previous\nversions expected a simple ID (string) field for the identification of a\nresource to ARI.  This reflects how ARI itself operates.  However, for systems\nwith multiple Asterisk instances, more metadata is necessary in order to\nproperly address a resource.  Specifically, we need to know the Asterisk node.\nThere is also the concept of a Dialog, which offers an orthogonal logical\ngrouping of events which transcends nodes and applications.  This is not\nmeaningful in the native client, but other transports, such as the ARI proxy,\nmay make use of this for alternative routing of events. This Key includes all of these data.\n\n```go\npackage ari\n\n// Key identifies a unique resource in the system\ntype Key struct {\n   // Kind indicates the type of resource the Key points to.  e.g., \"channel\",\n   // \"bridge\", etc.\n   Kind string   `json:\"kind\"`\n\n   // ID indicates the unique identifier of the resource\n   ID string `json:\"id\"`\n\n   // Node indicates the unique identifier of the Asterisk node on which the\n   // resource exists or will be created\n   Node string `json:\"node,omitempty\"`\n\n   // Dialog indicates a named scope of the resource, for receiving events\n   Dialog string `json:\"dialog,omitempty\"`\n}\n```\nAt a basic level, when the specific Asterisk ID is not needed, a key can consist\nof a simple ID string:\n\n```go\n  key := ari.NewKey(ari.ChannelKey, \"myID\")\n```\n\nFor more interesting systems, however, we can declare the Node ID:\n\n```go\n  key := ari.NewKey(ari.BridgeKey, \"myID\", ari.WithNode(\"00:01:02:30:40:50\"))\n```\n\nWe can also bind a dialog:\n\n```go\n  key := ari.NewKey(ari.ChannelKey, \"myID\",\n   ari.WithNode(\"00:01:02:30:40:50\"),\n   ari.WithDialog(\"privateConversation\"))\n```\n\nWe can also create a new key from an existing key.  This allows us to easily\ncopy the location information from the original key to a new key of a different\nresource.  The location information is everything (including the Dialog) except\nfor the key Kind and ID.\n\n```go\n  brKey := key.New(ari.BridgeKey, \"myBridgeID\")\n\n```\n\nAll ARI operations which accepted an ID for an operator now expect an `*ari.Key`\ninstead.  In many cases, this can be easily back-ported by wrapping IDs with\n`ari.NewKey(\"channel\", id)`.\n\n## Handles\n\nHandles for all of the major entity types are available, which bundle in the\ntracking of resources with their manipulations.  Every handle, at a minimum,\ninternally tracks the resource's cluster-unique Key and the ARI client\nconnection through which the entity is being interacted.  Using a handle\ngenerally results in less and more readable code.\n\nFor instance, instead of calling:\n\n```go\nariClient.Channel().Hangup(channelKey, \"normal\")\n```\n\nyou could just call `Hangup()` on the handle:\n\n```go\nh.Hangup()\n```\n\nWhile the lower level direct calls have maintained fairly strict semantics to\nmatch the formal ARI APIs, the handles frequently provide higher-level, simpler\noperations.  Moreover, most of the extensions (see below) make use of handles.\n\nIn general, when operating on longer lifetime entities (such as channels and\nbridges), it is easier to use handles wherever you can rather than tracking Keys\nand clients discretely.\n\nObtaining a Handle from a Key is very simple; just call the `Get()` operation on\nthe resource interface appropriate to the key.  The `Get()` operation is a\nlocal-only operation which does not interact with the Asterisk or ARI proxy at\nall, and it is thus quite efficient.\n\n```go\nh := ariClient.Channel().Get(channelKey)\n```\n\n## Staging resources\n\nA common issue for ARI resources is making sure a subscription exists before\nevents for that resource are sent.  Otherwise, important events which occur too\nquickly can become lost.  This results in a chicken-and-egg problem for\nsubscriptions.\n\nIn order to address this common issue, resource handles creation operations now\noffer a `StageXXXX` variant, which returns the handle for the resource without\nactually creating the resource.  Once all of the subscriptions are bound to this\nhandle, the caller may call `resource.Exec()` in order to create the resource in\nAsterisk.\n\n```go\n   h := NewChannelHandle(key, c, nil)\n\n   // Stage a playback\n   pb, err := h.StagePlay(\"myPlaybackID\", \"sound:tt-monkeys\")\n   if err != nil {\n      return err\n   }\n   \n   // Add a subscription to the staged playback\n   startSub := pb.Subscribe(EventTypes.PlaybackStarted)\n   defer startSub.Cancel()\n\n   // Execute the staged playback\n   pb.Exec()\n\n   // Wait for something to happen\n   select {\n      case \u003c-time.After(time.Second):\n        fmt.Println(\"timeout waiting for playback to start\")\n        return errors.New(\"timeout\")\n      case \u003c-startSub.Events():\n        fmt.Println(\"playback started\")\n   }\n```\n\n## Extensions\n\nThere are a number of extensions which wrap the lower-level operations in\nhigher-level ones, making it easier to perform many common tasks.\n\n\n### AudioURI [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](http://godoc.org/github.com/CyCoreSystems/ari/ext/audiouri)\n\nConstructing Asterisk audio playback URIs can be a bit tedious, particularly for handling\ncertain edge cases in digits and for constructing dates.\n\nThe `audiouri` package provides a number of routines to make the construction of\nthese URIs simpler.\n\n### Bridgemon [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](http://godoc.org/github.com/CyCoreSystems/ari/ext/bridgemon)\n\nMonitoring a bridge for events and data updates is not difficult, but it\ninvolves a lot of code and often makes several wasteful calls to obtain bridge\ndata, particularly when accessing it on large bridges.\n\nBridgemon provides a cache and proxy for the bridge data and bridge events so\nthat a user can simply `Watch()` for changes in the bridge state and efficiently\nretrieve the updated data without multiple requests.\n\nIt also shuts itself down automatically when the bridge it is monitoring is\ndestroyed.\n\n### Play [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](http://godoc.org/github.com/CyCoreSystems/ari/ext/play)\n\nPlayback of media and waiting for (DTMF) responses therefrom is an incredibly\ncommon task in telephony.  ARI provides many tools to perform these types of\nactions, but the asynchronous nature of the interface makes it fairly tedious to\nbuild these kinds of things.\n\nIn `ext/play`, there resides a tool for executing many common tasks surrounding\nmedia playback and response sequences.  The core function, `play.Play()`\nplays, in sequence, a series of audio media URIs.  It can be extended to expect\nand (optionally) wait for a DTMF response by supplying it with a Match function.\nThere is a small convenience wrapper `play.Prompt()` which sets some common\ndefaults for playbacks which expect a response.\n\nThe execution of a `Play` is configured by any number of option functions, which\nsupply structured modifiers for the behaviour of the playback.  You can even\nsupply your own Match function for highly-customized matching.\n\n### Record [![](https://godoc.org/github.com/CyCoreSystems/ari?status.svg)](http://godoc.org/github.com/CyCoreSystems/ari/ext/record)\n\nMaking recordings is another complicated but common task for ARI applications.\nThe `ext/record`, we provide a simple wrapper which facilitates many common\nrecording-related operations inside a single recording Session wrapper.\n\nFeatures include:\n\n  - record with or without a beep at the start\n  - listen for various termination types: hangup, dtmf, silence, timeout\n  - review, scrap, and save recordings upon completion\n  - retrieve the playback URI for the recording\n\n# Documentation and Examples\n\nGo documentation is available at https://godoc.org/github.com/CyCoreSystems/ari\n\nExamples 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:\n\n```sh\ncd /_examples/helloworld\ngo run ./main.go\n```\n\nOther examples:\n\n - `stasisStart` demonstrates a simple click-to-call announcer system\n - `stasisStart-nats` demonstrates the same click-to-call using the NATS-based\n   ARI proxy\n - `bridge` demonstrates a simple conference bridge\n - `play` demonstrates the use of the `ext/play` extension\n - `record` demonstrates the use of the `ext/record` extension\n\nThe files in `_ext/infra` demonstrates the minimum necessary changes to the\nAsterisk configuration to enable the operation of ARI.\n\n\n# Tests\n\nRun `go test` to verify \n\n# Contributing\n\nContributions welcomed. Changes with tests and descriptive commit messages will get priority handling.  \n\n# License\n\nLicensed under the Apache License, Version 2.0 \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCyCoreSystems%2Fari","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCyCoreSystems%2Fari","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCyCoreSystems%2Fari/lists"}