adora-tech / ARIty

ARIty is a library that provides an async API to run voice applications, using the Asterisk ARI protocol

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ARIty Framework

ARIty is a library that gives you services to run voice applications, using the Asterisk ARI protocol.

Arity exposes the ARI API using a set of asynchronous operations, using java [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html) and fluent API concepts.

Sample Voice Application

public class Application extends CallController {

	// Application class extends CallController, which includes an abstract method 'run()', and therefore need to implements
	// it

	@Override
	public CompletableFuture<Void> run() {
			return CompletableFuture.completedFuture(null);
	}

	public static void main(String[] args) throws ConnectionFailedException, URISyntaxException {

		// Connect to ARI and register a stasis application
		ARIty arity = null;
		try {
			arity = new ARIty("http://127.0.0.1:8088/", "myStasisApp", "user", "pass");

		} catch (Throwable e1) {
			logger.info("Error When creating the ARIty: " + e1.getMessage());
		}

		// main application flow
	     arity.registerVoiceApp(call -> {
			call.answer().run()
			.thenCompose(v -> call.play("hello-world").loop(2).run())
			.thenCompose(pb -> {
				logger.info("finished playback! id: " + pb.getPlayback().getId());
				return call.hangup().run();
			}).handle(call::endCall).exceptionally(t -> {
				logger.severe(t.toString());
				return null;
			});
		});

        // after registering, just stay running to get and handle calls
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				System.out.println("Thread is not sleeping");
			}
		}
	}

}

Installation

In your pom.xml file, add the repository for ARIty (we are currently not hosted in the public Maven repository) as an element under <project>:

<repositories>
  <repository>
    <id>cloudonix-dist</id>
    <url>https://cloudonix-dist.s3.amazonaws.com/maven2/releases</url>
  </repository>
</repositories>

Then add ARIty as a dependency:

<dependency>
	<groupId>io.cloudonix</groupId>
	<artifactId>arity</artifactId>
	<version>[0,)</version>
</dependency>

Usage

To use ARIty, we start by creating a connection to Asterisk's ARI URL and registering our Stasis application. ARIty will trigger the application entry point for each incoming call providing a CallController API using which the application can manipulate the call state and perform channel-specific operation, such as playback and record.

Connecting

String url = "http://asterisk:8088/";
ARIty ari = new ARIty(url, "myStasisApp", "user", "pass");

Registering to receive incoming calls

The registerVoiceApp() method receives a "callable" value (functional interface) that accepts a CallController object and executes the implementation for each call sent to the Stasis application by Asterisk.

Please note that currently only one voice application may be registered.

In order to register your voice application, you have the following options:

Give a lambda during registration:


public static void main(String[] args) throws ConnectionFailedException, URISyntaxException {

	...
		arity.registerVoiceApp(call -> {
				// handle call
				call.dial("SIP/app2").run().handle(call::endCall)
				.exceptionally(t -> {
					logger.severe(t.toString());
					return null;
				});

		});

Give a Supplier of CallController:

	public void voiceApp(CallController call) {
		// handle call
		...
	}

	public static void main(String[] args) throws ConnectionFailedException, URISyntaxException {
	    Application app = new Application();
	...
		ari.registerVoiceApp(app::voiceApp);
	...
	}

Give an instance of your class (for example: Application.class):

	@Override
	public void run() {
		// handle call
		...
	}

	public static void main(String[] args) throws ConnectionFailedException, URISyntaxException {
	...
		arity.registerVoiceApp(Application.class);
	...

	}

Handling a call

To handle a call scenario, create a method that takes a CallController argument. When the method is called, use the CallController API to execute operations on the channel connected to the application. Each API call creates an Operation instance that will start the specified operation when it's run() method is called. run() returns a CompletableFuture that will be completed when the ARI operation completes. Multiple operation can be scheduled in order, using CompletableFuture's completion methods, such as thenCompose(), thenAccept(), etc.

	public void voiceApp(CallController call) {

		call.answer().run()
		.thenCompose(ans -> call.play("hello-world").loop(2).run())
		.thenCompose(play -> {
			logger.info("finished playback! id: " + play.getPlayback().getId());
			return call.hangup().run();
		}).thenAccept(h -> {
			logger.info("hanged up call");
		}).exceptionally(t -> {
			logger.severe("Unexpected error happened", t);
			return null;
		});
	}

Features

endCall feature

In order to end the voice application, you can use the endCall method that will guarantee that the call will be hanged up (you can see an example in "Sample Voice Application" section above). This method hang up the call anyway, even if an error occurred during the execution. Therefore, you can use the endCall method to hang up the call and/or use call.hangup().run(); like in the "Handling call" example.

About

ARIty is a library that provides an async API to run voice applications, using the Asterisk ARI protocol

License:GNU Lesser General Public License v3.0


Languages

Language:Java 99.3%Language:Makefile 0.7%