title: Problems IP-messagin and Twilio
body: <p>I am using Twilio for the IP messaging. I want to create a chat in my mobile hybrid app, and I am trying to get the whatsup style, with delivered and read messages status.
  After the initial excitement for the Twilio library, right now nothing is working :(.  The chat works the 40% of times, the other times I get several errors. Before looking at the errors, I want to explain how I structured the code.</p>
  
  <p>The idea is to ask, once logged, all the channels of that user and store them in <code>self.channels</code>, so I can visualize the last conversations of that user.</p>
  
  <p>1) The very first step is asks a token as soon as a user logs to my app.</p>
  
  <pre><code> setChatToken = function()
  {
   _token = data.token;
   var accessManager = new Twilio.AccessManager(_token);
   _messagingClient = new Twilio.IPMessaging.Client(accessManager);
   _messagingClient.on('channelUpdated', function(channel) 
      {
       for ( c in self.channels)
          {
           if (self.channels[c].sid == channel.sid)
              { self.channels[c] = channels; }
          }
       });
  // return a promise;
  }
  </code></pre>
  
  <p>2) Then I ask all the channels                                 </p>
  
  <pre><code>// init chat system
       setChatToken()  
          .then(function()
                  {       
                   // Listen for new invitations to your Client
                   _messagingClient.on('channelInvited', function(channel) 
                      {
                       // Automatically join channels that you were invited to
                       channel.join().then(function(channel)
                          {
                           handleMessageEvents(channel);
                           channel.attributes['him']  = channel['createdBy'];
                           // I'll separate old, recent and new msgs
                           channel['recent-messages'] = [];
                           channel['new-messages']    = [];                        
                           self.last_channels.push(channel);
                          });
                      }); 
  
                    // asks all the channels
                   getChannels()
                      .then(function()
                              { // chat init ready
                                self.ready = true;
                              });
                  }
               )
          .catch(function(err){console.error(err);});
  </code></pre>
  
  <p>3) this is the code for asking all the channels. I check if there are new messages looking at the <code>channel.lastConsumedMessageIndex</code>. I consider last 7 messages as 'recent', the other as 'old'.</p>
  
  <pre><code>var getChannels = function()
          {   
           // Get Messages for previously created channels
           _messagingClient.getChannels()
              .then(function(channels) 
                { // GET CHANNELS
                 for (i in channels) 
                   {  
                    var channel = channels[i];
                    channel['recent-messages'] = [];  
                    channel['old-messages']    = [];                    
                    channel['new-messages']    = [];  
                    handleMessageEvents(channel);                               
                    self.last_channels.push(channel);
                   }
                 })
              .then(function()
                 {  // GET MEMBERS
                  var promises_update_read_index = [];                   
                  for (i in self.last_channels)
                     {
                      var channel = self.last_channels[i];
                      var promise = 
                          channel.getMembers()
                              .then(function(channelMembers)
                                      {
    // check the last message read from  the other user, to know
    // if there are new messages not read
                                       for(m in channelMembers)
                                         {
                                          var member = channelMembers[m];
                                          if (member.identity != me.id)
                                              { 
                                                channel.attributes['him'] = member.identity;
                                                channel.attributes['hisLastMsgIndex'] = member.lastConsumedMessageIndex;
  
                                                // last message consumed update
                                                member.on('updated', function(updatedMember) 
                                                  {
                                                     //handle the read status information for this member
                                                     updateHisMessageReadStatus(updatedMember.identity, 
                                                                                updatedMember.lastConsumedMessageIndex, 
                                                                                updatedMember.channel.sid);
                                                   });                                                                                        
                                              }
                                          else
                                              { // it's me
                                              }
                                          }
                                      }
                                   );
                        promises_update_read_index.push(promise);
                      }
                     return $q.all(promises_update_read_index);
                  })          
              .then(function()
                  { //GET MESSAGES
                    var promises_update_messages = [];                   
                    for (i in self.last_channels)
                      {
                       var channel = self.last_channels[i];
                       //determine the newest message index
                       var areThereNewMsgs = false;
                       var lastConsumedMessageIndex = channel.lastConsumedMessageIndex;
           // consider the last 7 messages as 'recent', the other as 'old'
                       var promise = 
                           channel.getMessages(7)
                              .then(function(lastChannelMessages)
                                {
                                 for (j in lastChannelMessages)
                                   {
                                    var message = lastChannelMessages[j];
                                    if (
                                        message.author != me.id &amp;&amp;
                                        message.index &gt; lastConsumedMessageIndex
                                        )
                                      { // there are new messages
                                       var hisId = channel.attributes['him'];
                                       channel['new-messages'].push(message);
                                      }
                                     else
                                      { 
                                       if ( channel.attributes['hisLastMsgIndex']
                                                        &lt; channel.lastConsumedMessageIndex 
                                                      )
                                                      { message['msg-read'] = false;}
                                                   else
                                                      { message['msg-read'] = true; }
                                                   channel['old-messages'].push(message); 
                                                  }
                                               if (message.author != me.id)
                                                      { message['msg-read'] = false; } //hide for him                                                                         
                                               }
                                          });
                          promises_update_messages.push(promise);                             
                      }
                   return $q.all(promises_update_messages);
                  })
              .catch(function(err){console.error('getMessages '+JSON.stringify(err));})
              .then(function()
                      {   
                       $rootScope.$broadcast(self.CHANNEL_UPDATE_EVENT);                      
                       deferred.resolve(true); // i'm ready
                      })
              .catch(function(err)
                      {
                       console.error(err);
                       deferred.reject(err);
                      });
           return deferred.promise;
          }
  </code></pre>
  
  <p>One problem is that often, when I create a channel, the other user doesn't automatically join the channel, so I send messages that are never delivered.
  Another problem is </p>
  
  <pre><code> getMembers {"status":403,"description":"Forbidden","body":{"message":"Access forbidden","status":403}}
  </code></pre>
  
  <p>when I invoke getChannels() as defined before.</p>
  
  <p>Is there any tutorial to build a full chat like this? Or, do you have suggestion on what to modify and how to check the problems'</p>
  
  <p>Thank yo</p>