logicmason

logicmason

Has anyone worked with Twilio’s video product successfully in a Phoenix project? They support several backend languages but Elixir isn’t one of them. As far as I can tell all their docs use their own helper libraries as opposed to offering a general API.

ExTwilio looks interesting but is for their phone API. Anybody know how to get started? I’m psyched to play around with video + some Phoenix channels in an app!

(could not tag this post twilio)

Showing Posts 1 to 6

bobbypriambodo

bobbypriambodo

I saw @alchemist_in_training (was that you?) asked this twice too on Slack with no response, I’m hoping that someone with more experience can answer but since there isn’t any I’ll give it a shot :smile:

I’ve looked around their docs and here’s what I got:

Since the Twilio Video API is in public beta and the API is still subject to change (as per their JavaScript client docs), I don’t think you’ll get that much unless you dig down their SDKs’ source code.

And I’m not sure what you mean by several backend languages; the getting started guide lists only Java, Objective-C, Swift, and JS, so I think they only provide client SDKs for Android, iOS, and browser.

That said, there’s one mention of video and webRTC in the ExTwillio issues. I think you can start from there.

logicmason

logicmason OP

Thanks for the response! Yeah, to me four is several languages :smiley:

I did dig into the source code but found it a bit of a rabbit hole with the helper libraries farming out work to sub-helper libraries. The only thing the server does in their example apps is create the json web token, so by “general API”, I meant just a spec of what they required in the JWT payload since that’s more straight forward to work from than reverse engineering their bundle of helper libs.

E.g. if an api were documented in RAML or Swagger, what would it say to send?

logicmason

logicmason OP

That comment from @stavro does look like a good starting point!

bobbypriambodo

bobbypriambodo

Ah, that is of course :smile: I meant to contrast between “backend” and “client”, not the number of languages.

True, I was also looking for a more straightforward HTTP API docs but can’t seem to find it, hence my suggestion to dig the code ^^ Perhaps they’ll make one after they got out of beta? (not sure though, public beta seems to be the perfect time to have a public API spec if they really wanted to open it.)

carterbryden

carterbryden

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.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews