I had this working for the beta version of Twilio Video but now that version 1 is officially released, they’ve changed how things work a little bit. Any idea how I would adapt this if I wanted to create a room with a server-side post request to Twilio as outlined here: https://www.twilio.com/docs/api/video/rooms-resource#post-list-resource
Here’s what I’ve got so far, which works, but I need to create a token containing the room name. Any help greatly appreciated!
def create_room(name) do
api_key = Application.get_env(:myapp, :TWILIO_API_KEY)
api_secret = Application.get_env(:myapp, :TWILIO_API_SECRET)
encoded = Base.encode64("#{api_key}:#{api_secret}")
body = {:form, [UniqueName: name, Type: "peer-to-peer", EnableTurn: "true", StatusCallback: "https://myapp.com/video/callback"]}
HTTPoison.post("https://video.twilio.com/v1/Rooms", body, ["Authorization": "Basic #{encoded}", "Accept": "Application/json; Charset=utf-8"])
end
Edit:
I’ve got a working solution with Twilio Video version 1 now:
# myapp/web/twilio_token.ex
defmodule MyApp.TwilioToken do
# Generates token for Twilio Programmable video
# Assumes Joken is in Mix.exs deps and Twilio creds are in app config
defp tokenize(username, room) do
sid = Application.get_env(:myapp, :TWILIO_ACCOUNT_SID)
api_key = Application.get_env(:myapp, :TWILIO_API_KEY)
api_secret = Application.get_env(:myapp, :TWILIO_API_SECRET)
now = epoch_ts()
exp = now + 3600
payload = %{
"jti" => "#{api_key}-#{now}",
"iss" => api_key,
"sub" => sid,
"exp" => exp,
"grants" => %{
"identity" => username,
"video": %{
"room": room
}
}
}
payload
|> Joken.token()
|> Joken.with_header_arg("cty", "twilio-fpa;v=1")
|> Joken.with_signer(Joken.hs256(api_secret))
|> Joken.sign()
|> Joken.get_compact()
end
defp epoch_ts() do
epoch = {{1970, 1, 1}, {0, 0, 0}}
epoch_i = :calendar.datetime_to_gregorian_seconds(epoch)
now_i = :calendar.datetime_to_gregorian_seconds(:calendar.universal_time)
now_i - epoch_i
end
def create_room(room, username) do
api_key = Application.get_env(:myapp, :TWILIO_API_KEY)
api_secret = Application.get_env(:myapp, :TWILIO_API_SECRET)
encoded = Base.encode64("#{api_key}:#{api_secret}")
headers = ["Authorization": "Basic #{encoded}"]
{:ok, response} = HTTPoison.get("https://video.twilio.com/v1/Rooms/#{room}", headers)
#does this room already exist? If not, create it
if response.status_code == 404 do
body = {:form, [UniqueName: room, Type: "peer-to-peer", MaxParticipants: 2, EnableTurn: "true", StatusCallback: "https://myapp.com/callback-url"]}
{:ok, post_response} = HTTPoison.post("https://video.twilio.com/v1/Rooms", body, headers)
end
tokenize(username, room)
end
def config, do: Application.get_env(:myapp, __MODULE__)
end
Note: this only does some very basic checking to see if the room exists and creates one if it doesn’t and only really handles the happy path. You’ll want to add some logic to handle various failure scenarios.