Packages

A SMS adapter for Hedwig

Current section

Files

Jump to
hedwig_sms lib hedwig_sms.ex
Raw

lib/hedwig_sms.ex

defmodule Hedwig.Adapters.SMS do
@moduledoc """
Hedwig adapter that communicates via SMS using the Twilio API.
"""
use Hedwig.Adapter
require Logger
@doc false
def init({robot, opts}) do
HTTPoison.start
Hedwig.Robot.register(robot, opts[:name])
state = %{
account_sid: opts[:account_sid],
account_token: opts[:auth_token],
account_number: opts[:account_number],
robot: robot
}
{ :ok, state }
end
@doc false
def handle_cast({:emote, msg}, state) do
send_message(msg.user, msg.text, state)
{:noreply, state}
end
@doc false
def handle_cast({:reply, msg}, state) do
send_message(msg.user, msg.text, state)
{:noreply, state}
end
@doc false
def handle_cast({:send, msg}, state) do
send_message(msg.user, msg.text, state)
{:noreply, state}
end
defp send_message(phone_number, body, state) do
Logger.info "sending #{body} to #{phone_number}"
case build_request(phone_number, body, state) do
{:ok, %HTTPoison.Response{status_code: status_code} = response } when status_code in 200..299 ->
Logger.info("#{inspect response}")
{:ok, %HTTPoison.Response{status_code: status_code} = response } when status_code in 400..599 ->
Logger.error("#{inspect response}")
{:error, %HTTPoison.Error{reason: reason}} ->
Logger.error("#{inspect reason}")
end
end
defp build_request(phone_number, body, state) do
endpoint = "https://#{state.account_sid}:#{state.account_token}@api.twilio.com/2010-04-01/Accounts/#{state.account_sid}/Messages.json"
body = URI.encode("To=#{phone_number}&From=#{state.account_number}&Body=#{body}")
headers = [{"Content-Type", "application/x-www-form-urlencoded" }]
HTTPoison.post(endpoint, body, headers)
end
@doc """
Sends the Twilio request body from the callback to the robot
with the specified `name`. `req_body` is assumed to be the post
body string or a map with keys `"From"` and `"Body"`.
Use this function if you are defining your on receive callback
from Twilio
"""
@spec handle_message(String.t, String.t | Map.t) :: {:error, :not_found} | :ok
def handle_message(name, req_body) do
case Hedwig.whereis(name) do
:undefined ->
Logger.error("Robot named #{name} not found")
{ :error, :not_found }
robot ->
msg = build_message(req_body)
Hedwig.Robot.handle_message(robot, msg)
:ok
end
end
defp build_message(body) when is_binary(body) do
build_message URI.decode_query(body)
end
defp build_message(%{ "From" => user, "Body" => text }) do
%Hedwig.Message{
ref: make_ref(),
text: text,
type: "chat",
user: user
}
end
end