4
votes

I'm using twilio chat javascript SDK and I'm having problems when I try to create a new channel and invite a user. Both users (sender and receiver) receive this error: Error: Access forbidden for identity

But if I go to the dashboard, the channel is created with the 2 members. What am I doing wrong?

PS: I'm creating user tokens as listed on Twilio API, I don't believe token could be a problem because the message is already sent. It seems the problem happen when I join the channel.

My code to create the channel:

this.client.createChannel({
  uniqueName: roomName,
  friendlyName: 'My Channel',
  type: 'private'
}).then(channel => {
  this.channel = channel
  this.channel.join()
});

My invite code is just:

this.channel.invite(user)

and to generate user tokens:

new Fingerprint2().get(fingerprint => {
  this.fingerprint = fingerprint

  let AUTH_TOKEN = $('meta[name=csrf-token]').attr('content')

  fetch('/chat/tokens', {
    method: 'POST',
    body: JSON.stringify({
      fingerprint: fingerprint,
      authenticity_token: AUTH_TOKEN,
      email: email
    }),
    headers: {
      'X-Requested-With': 'XMLHttpRequest',
      'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content'),
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  }).then(result => result.json()).then(data => {
    callback({ token: data.token, username: data.username })
  })
})

and on my API

user = User.find_by_email(params[:email])

account_sid = ENV['TWILIO_ACCOUNT_SID']
api_key = 'SKe9fcdbefe0bdc1f01af4aa50d3548b70'
api_secret = 'oslALMC18tCZrUhBRDPin5KbqPSR9Rr4'

service_sid = ENV['TWILIO_SERVICE_ID']
device_id = params[:fingerprint]
identity = user.username
endpoint_id = "FakeEndPoint:#{identity}:#{device_id}"

grant = Twilio::JWT::AccessToken::IpMessagingGrant.new
grant.service_sid = service_sid
grant.endpoint_id = endpoint_id

token = Twilio::JWT::AccessToken.new(
  account_sid,
  api_key,
  api_secret,
  [grant],
  identity: identity
)

render status: 200, json: { token: token.to_jwt, username: user.username }

a token sample:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImN0eSI6InR3aWxpby1mcGE7dj0xIn0.eyJqdGkiOiJTS2U5ZmNkYmVmZTBiZGMxZjAxYWY0YWE1MGQzNTQ4YjcwLTE1MDExNjA0MjAiLCJncmFudHMiOnsiaWRlbnRpdHkiOiJqb25hdGFzIiwiaXBfbWVzc2FnaW5nIjp7InNlcnZpY2Vfc2lkIjoiSVMwYThiM2NkYTllMTU0YTUyOTg3MjJkOTRjOTI5ZjBhOSIsImVuZHBvaW50X2lkIjoiSGlwRmxvd1NsYWNrRG9ja1JDOmpvbmF0YXM6ZmU2NGZjYTA5NDc4YjYzNjNlYTFiMzA3OGQzOTQwM2MifX0sImlzcyI6IlNLZTlmY2RiZWZlMGJkYzFmMDFhZjRhYTUwZDM1NDhiNzAiLCJuYmYiOjE1MDExNjA0MjAsImV4cCI6MTUwMTE2NDAyMCwic3ViIjoiQUMxN2VmODM5N2JhODJkZWQ2ZDlmZmE0ODFkMWI2YTczMSJ9.UF8XtcEBN8LSCKVvBRscu9CmYdgMVobTd84RowF5KaU
1
Can you share the code you are using to generate the channel and invite the users? Also, it might be helpful if you can share an example access token too. - philnash
I just updated my answer @philnash. - jonatasdaniel
Can you include how you are inviting the users too? Also an example access token? - philnash
Edited again @philnash - jonatasdaniel
Thanks. Is it possible that it's a race condition between creating the channel and joining it? When do you get the error? - philnash

1 Answers

6
votes

Twilio developer evangelist here.

When you join a channel (with channel.join()) the promise resolves when the request to join the channel succeeds. This doesn't mean that the channel has been completely joined yet.

Instead, you should listen for the channelJoined event on the chat client. Once that fires you can be certain you are now a member of that channel and can interact with it.

So, if you join a channel, you should listen for the event like this:

this.client.on('channelJoined', function(channel) {
  console.log('Joined channel ' + channel.friendlyName) 
})

this.client.createChannel({
  uniqueName: roomName,
  friendlyName: 'My Channel',
  type: 'private'
}).then(channel => {
  this.channel = channel
  this.channel.join()
});