- language:ruby - sdk:compatibility - product:voice repo: https://github.com/signalwire/guides/tree/main/Voice/Answering%20Machine%20Detection%20with%20Ruby This guide utilizes the Answering Machine Detection feature to determine whether a human or voicemail machine has answered the call. This allows your program to determine whether to dial a number to connect someone to the human or leave a message for the voicemail box. When a call is initiated with machine_detection set to DetectMessageEnd, there is a parameter posted to the webhook called AnsweredBy. The potential options here are machine_end_other, machine_end_beep, machine_end_silence, and human. If the parameter returned is anything other than human, this example will take a short pause to wait for the beep and then play a message for the intended recipient. If the parameter returned is human, it will dial a number to connect the human to another person. What do I need to run this code? -- View the full code on our Github [here](https://github.com/signalwire/guides/tree/main/Voice/Answering%20Machine%20Detection%20with%20Ruby)! You will need the [Ruby SignalWire SDK](/compatibility-api/sdks) and the [Sinatra](http://sinatrarb.com/) framework. You will need a SignalWire phone number as well as your API Credentials (**API Token**, **Space URL**, and **Project ID**) which can all be found in an easily copyable format within the **API** tab of your SignalWire portal. How to Run Application - ### Build and run on Docker Copy env.example to .env and edit the file, adding the necessary SignalWire credentials and other phone numbers you will need. Build the image with docker build . -t rubyamd, then run the script using docker run -it --rm -p 8080:8080 --name rubyamd --env-file .env rubyamd. ### Build and run natively You may need to use an SSH tunnel for testing this code if running on your local machine. – we recommend [ngrok](https://ngrok.com/). You can learn more about how to use ngrok [here](/platform/basics/guides/technical-troubleshooting/how-to-test-webhooks-with-ngrok). Step by Step Code Walkthrough -- Within the Github repository you will find 5 files: - Dockerfile - Gemfile - Gemfile.lock - README.md - app.rb - .env We will start with the .env file that contains our environment variables, go through the app.rb file next, and finish off by showing a few different ways to trigger an outbound call in this scenario with answering machine detection enabled. ### Setup your .env file We will start by filling out our .env file so that this file contains all that we need for authentication as well as the to/from numbers and the app domain (your ngrok tunnel or server URL). text SIGNALWIRE_PROJECT_KEY=YOURKEY SIGNALWIRE_TOKEN=YOURTOKEN SIGNALWIRE_SPACE=YOURSPACENAME.signalwire.com FROM_NUMBER=+15556677888 AGENT_NUMBER=+12027621401 APP_DOMAIN=https://YOURTUNNEL.ngrok.io ### Walk through app.rb We start by creating a route for Sinatra and initializing response as a VoiceResponse object, which is required in order to use Say, Dial, Hangup, and Pause. ruby post /start do response = Signalwire::Sdk::VoiceResponse.new Now we use a switch statement to designate that we will take different actions depending on the value of [:AnsweredBy]. You can see below that if anything other than human is returned, this code will output Its a machine, take a brief pause to allow the voicemail system time to reach the recording beep, leave a voicemail for the intended recipient, and hang up. If the value returned is human, this code will output We got ourselves a live human here! and then dial the number of your agent (or the next part of your standard call flow). In the dial, you have the option to either hard code the number you would like to dial or use environment variables. ruby case params[:AnsweredBy] when machine_end_other, machine_end_silence, machine_end_beep puts Its a machine! # put in a little pause to allow the recording to start on the other end response.pause(length: 1) # replace messsage with whatever voicemail you want to leave response.say(message: Hello! This is the County Medical Center. We are calling you to confirm your doctor appointment. Please call us back as soon as possible.) response.hangup when human puts We got ourselves a live human here! response.dial do |dial| # defaulting to calling a time voice announcement number as an example dial.number(ENV.fetch(AGENT_NUMBER, +12027621401)) end end When [:AnsweredBy] returns any value other than human, the XML code is a simple