twilio / twilio-ruby

A Ruby gem for communicating with the Twilio API and generating TwiML
MIT License
1.35k stars 463 forks source link

Twilio::JWT::AccessToken not working for API KEYS outside US1 #628

Open ppascualv opened 1 year ago

ppascualv commented 1 year ago

Issue Summary

Twilio::JWT::AccessToken only works when api keys are generated on US1 region.

Steps to Reproduce

  1. Use a IE1 API KEY and cannot be used to do an outbound call.

Code Snippet

   def initialize(account_sid, application_sid, user)
      @account_sid = account_sid
      @application_sid = application_sid
      @user = user
    end

  def generate_capability
      token = access_token(voice_grant)
      token.to_jwt
    end

    private

    def voice_grant
      voice_grant = Twilio::JWT::AccessToken::VoiceGrant.new
      voice_grant.outgoing_application_sid = DEVELOPMENT_TWIML
      voice_grant.incoming_allow = true

      voice_grant
    end

    def access_token(voice_grant)
      Twilio::JWT::AccessToken.new(
        Rails.application.credentials.twilio.account_sid,
        API_KEY, 
        API_SECRET,
        [voice_grant],
        identity: user.twilio_identity,
        ttl: 3600,
        region: 'ie1'
      )

Exception/Log

Client side error:
Received an error from the gateway: ConnectionError: ConnectionError (31005): Error sent from gateway in HANGUP

Technical details:

isha689 commented 1 year ago

Hi @ppascualv,

Thank you for posting this, we are currently looking into this issue.

isha689 commented 1 year ago

Hey @ppascualv, I am not able to reproduce this issue. Can you please provide more insights into what you are trying to achieve? (debugging information or full code)

This is what I have tested:

Note: you have to specify the edge as well while initialising the client.


require 'twilio-ruby'

account_sid = ENV['TWILIO_ACCOUNT_SID']
auth_token = ENV['TWILIO_AUTH_TOKEN']

api_key = ENV['API_KEY']
api_secret = ENV['API_SECRET']

api_key_ie1 = ENV['API_KEY_IE1']
api_secret_ie1 = ENV['API_SECRET_IE1']

outgoing_application_sid = 'APxxxxxxxxxxxx'
identity = 'userName'

grant = Twilio::JWT::AccessToken::VoiceGrant.new
grant.outgoing_application_sid = outgoing_application_sid
grant.incoming_allow = true

def access_token(grant)
  token = Twilio::JWT::AccessToken.new(
    ENV['TWILIO_ACCOUNT_SID'],
    ENV['API_KEY_IE1'],
    ENV['API_SECRET_IE1'],
    [grant],
    identity: 'userName',
    region: 'ie1'
  )
  token
end

token = access_token(grant)
token.to_jwt

@client = Twilio::REST::Client.new(account_sid, auth_token)
@client.region = 'ie1'
@client.edge = 'dublin'

call = @client.calls.create(
                       twiml: '<Response><Say>Ahoy, World!</Say></Response>',
                       to: 'your_phone_number',
                       from: 'twilio_purchased_phone_number'
                     )

puts call.sid
ppascualv commented 1 year ago

The JWT is correctly generated but when you try to call using this JWT with a frontend app, the JWT is not working properly. Does the javascript client have a different configuration in order to use the Dublin edge?

isha689 commented 1 year ago

For setting an edge location for javascript client, refer this.

ppascualv commented 1 year ago

Still not working, the token is generated but the call is not working

isha689 commented 1 year ago

Can you please share the code you have written to make the call, and the associated error logs ?

ppascualv commented 1 year ago

I'm getting this error

Twilio outgoing call: connecting
log.js?44b0:73 signalingState is "have-local-offer"
log.js?44b0:73 dtlsTransportState is "new"
log.js?44b0:73 pc.iceGatheringState is "gathering"
log.js?44b0:73 ICE Candidate: {"candidate":"candidate:649925946 1 udp 2122260223 192.168.1.185 54049 typ host generation 0 ufrag Ts+H network-id 1 network-cost 10","sdpMid":"0","sdpMLineIndex":0}
log.js?44b0:73 ICE Candidate: {"candidate":"candidate:3625435566 1 tcp 1518280447 192.168.1.185 9 typ host tcptype active generation 0 ufrag Ts+H network-id 1 network-cost 10","sdpMid":"0","sdpMLineIndex":0}
log.js?44b0:73 Received HANGUP from gateway
next-dev.js?3515:32 Received an error from the gateway: ConnectionError: ConnectionError (31005): Error sent from gateway in HANGUP
    at ConnectionError.TwilioError [as constructor] (twilioError.js?cc64:25:1)
    at new ConnectionError (generated.js?2802:159:1)
    at Call._this._onHangup (call.js?181d:299:1)
    at PStream.emit (events.js?b914:153:1)
    at PStream._handleTransportMessage (pstream.js?2afb:179:1)
    at WSTransport.emit (events.js?b914:153:1)
    at WSTransport._this._onSocketMessage (wstransport.js?34d2:173:1)
window.console.error @ next-dev.js?3515:32
Log.error @ log.js?44b0:54
Call._this._onHangup @ call.js?181d:300
emit @ events.js?b914:153
PStream._handleTransportMessage @ pstream.js?2afb:179
emit @ events.js?b914:153
WSTransport._this._onSocketMessage @ wstransport.js?34d2:173
Twilio.tsx?c826:297 Twilio outgoing call: error ConnectionError (31005): Error sent from gateway in HANGUP
eval @ Twilio.tsx?c826:297
emit @ events.js?b914:158
Call._this._onHangup @ call.js?181d:301
emit @ events.js?b914:153
PStream._handleTransportMessage @ pstream.js?2afb:179
emit @ events.js?b914:153
WSTransport._this._onSocketMessage @ wstransport.js?34d2:173
log.js?44b0:73 Disconnecting...
log.js?44b0:73 dtlsTransportState is "closed"
Twilio.tsx?c826:273 Twilio outgoing call: hang up

I'm doing the call from the frontend

const device = new Device(mutation.data.currentUser.twilioToken, {
      allowIncomingWhileBusy: false,
      logLevel: process.env.NEXT_PUBLIC_ENVIRONMENT === "development" ? 0 : 4,
      edge: "dublin"
    })

const params = { UserId: userId, ContactId: contactId, ...extraParams }
    if (!device.current && setMessage) return setMessage({ message: t("twilioDeviceNotReady"), severity: "error" })
    const newConnection = await device.current.connect({
      params
    })
manisha1997 commented 1 month ago

Are you still facing problem with the JWT token based on region?