Sending SMS Text from a Ruby App
Tags: ruby, twilio, rails
Published: 2021-01-15 19:34:30

### Beginner’s guide to Setting up the Twilio API in Ruby and using ENV files to secure your credentials. Time to actually say Hello World to the world!

---

As a beginner in Ruby working primarily in a text editor, Terminal, and interacting with an app through CLI, it’s natural to itch for something “bigger” and to want to give your basic app a greater reach. It’s exciting to see “Hello World” pop up on your screen for the first time, but after the 100th (or even 3rd) time it loses a little magic. What if we could instead send that message out to the users in the world via a text message? Or, in more advanced cases, what if you wanted to incorporate Two-factor Authorization for user logins to your web app? Or, if you wanted to send push notification and event reminders? Turns out you can with not too much effort thanks to Twilio’s API.

![Image for post](https://miro.medium.com/max/1400/1*ZajKA3EXMPKhfKjdb5CcZQ.png)

## Twilio

[Twilio](https://www.twilio.com/) is a service that provides virtual phone numbers that can be used to send or receives Voice, SMS, and MMS depending on various needs and integrations. It is free to sign up, and a free trial comes with a $15 credit that can be used to rent a virtual phone number and pay for calls/texts sent or received. For beginners looking to try out Twilio and what it can do for your app, please know than this complimentary $15 is way more than enough to get going, but more on that later. In order to send messages from your Ruby app, you need to connect to Twilio’s API.

## Twilio API

---

[APIs (Application Programming Interfaces)](https://www.howtogeek.com/343877/what-is-an-api/) can be complex, but essentially they are a set of commands/protocols presented to the public by a service. These commands allow outside programs, websites, or applications to interact with the service in some way such as receiving data from or submitting data to the service. In this case, the Twilio API allows apps to connect and utilize the virtual phone numbers that Twilio hosts. It is by connecting to this API and utilizing the commands it provides that we can send SMS from an APP.

---

## Getting Connected
### Step 1: Make a Twilio Account & Rent a Phone Number

Go to the Twilio website and make a free trial account. After confirming your contact information and answering some questions about your app such as programming language and desired functions, you will be taken to the main console where you will be able to rent your a trial phone number.
A phone numbers can be rented for $1.00 per month, so as long as you “release” the number when you are done with your app, the free trial credit will last you for many projects.

### Step 2: Install the Twilio gem into your app

Add gem 'twilio-ruby' to your Gemfile and run bundle install from your terminal. This will install the helper library needed to integrate your app with Twilio.

### Step 3: Copy the code snippet from the Twilio CodeExchange 

On the code exchange there are snippets for different functionalities that you can incorporate. Copy the snippets that pertain to your app. The snippet for sending an SMS that we will be using is shown below.

{% gist
https://gist.github.com/dsasse07/6933ab99a4b7eee4244daba37dc92f5d %}

Copy the snippet into a new file, in my case I made a file called `twilio.rb`. Let’s break down the code above:

`require 'twilio-ruby'`

- This provides access to the needed Twilio methods from the `'twilio-ruby'` gem.

`account_sid = 'ACcd207c4be71151a3f50ef05c79e865d5'`
`auth_token = 'yyyyyyyyyyyyyyyyyyyyyyyyy'`

These two lines will connect your app to your Twilio account. They can be thought of as your username and password. The strings following the variable names will eventually be replaced with your own credentials but you do not want to type them directly into this string since it will allow anyone who can see the code to gain access your Twilio account and you can end up financially responsible for their actions. We will go over how to secure these credentials later.

```ruby 
from '+15551234567' # Your Twilio number
to = '+15555555555' # Your mobile phone number
```

These two lines define the phone numbers to be used in the text message: from should be replaced here with the Twilio phone number that you rented, and can be found on your Twilio console. The to phone number will be the phone number that the SMS is sent two, and will likely be defined in your app by a user and then passed into the send_sms message.

```ruby
client.messages.create(
from: from,
to: to,
body: "Hey friend!"
) 
```

This is the method from the Twilio gem that ultimately creates the text message by sending phone numbers and message body to Twilio via its API. In order to pass in different phone numbers and message content to this method, we will want to put this into a method of our own.

### Step 4: Incorporating the snippet into your app

Depending on your needs, the code snippet can be incorporated directly into a method with the desired class, but if this functionality will be needed in other places, you will likely want to build this into a `Module` to be included in other classes. More information on abstraction using modules can be found in my previous post [here](https://dsasse07.medium.com/abstracting-refactoring-in-ruby-with-send-97e6ef1a4661).

{% gist 
https://gist.github.com/dsasse07/84e165ccc8400e2ad69ccb23de8c223a
%}

Here, I made a `send_sms` method that accepts a phone number and a message string as an argument that can then be passed to the Twilio method for sending the text message. Since this method is in my `TwilioControls` module, it can be called from any class as long as the class inherits the module. The other new change that can be seen above, is the addition of `require 'dotenv/load'` and the replacement of the `@@account_sid` and `@@auth_token` strings with a call to the `ENV` variable which will store the authentication information without making it publicly available.

### Step 5: Securing your credentials with dotenv

`dotenv` is another ruby gem that can be used to add information to the environment variable ENV such as API keys and credentials from a separate file. Since this information will be stored in a separate `.env` file, it can be included in your `.gitignore` file so that it is not uploaded to GitHub with the rest of your code. Documentation for `dotenv` can be found in its [Readme](https://github.com/bkeepers/dotenv).

- Add `gem 'dotenv'` to your Gemfile and run bundle install.
- Create a new file in your app directory called `.env` if you do not already have one.
- Into this `.env` add your Twilio API credentials

{% gist https://gist.github.com/dsasse07/50a621c12faf8b8307ce66dc65b6d7ed %}

- With this file in place, when a file has `require 'dotenv/load'` it will load the data from the `.env` file into the ENV hash variable. This data can then be accessed using the hash’s key as shown below

{% gist
https://gist.github.com/dsasse07/84e165ccc8400e2ad69ccb23de8c223a %}

- __Prevent your keys from being uploaded to GitHub.__ This is done by creating a `.gitignore` file and typing `.env` into it. Files listed in `.gitignore` will not be tracked or added to GitHub when you commit and push your code.

### Step 6: Send your Message!

With everything set up, call the send_sms message from your app after providing a receiving phone number and a message string. With a trial account, you will only be able to send your message to phone numbers verified on your Twilio account. This means the only recipients can be you or your teammates until you upgrade your account, but it will not prevent you from testing your functionality. (Note: sending and receiving SMS messages each cost $ 0.0075 per message and will be charged against your complimentary account balance.)

In the app I developed, I wanted to be able to send a text message with a reminder of a password to a user, so I implemented the send_sms method from the `TwilioControls` module like this:

{% gist https://gist.github.com/dsasse07/83181fedb2d21ba5a2d17acd085d4403 %}

![Text Message Received](https://miro.medium.com/max/1400/1*qbfiMyl28JvQkK3Q7RGZ0g.jpeg)