Search code examples
javascripttwiliotwilio-programmable-chat

Twilio chat don't work when refresh the page


I have followed the twilio documentation to implement the chat on the website, But I am having the problem is that when ever I refresh the page or turn my Internet off and then on, then I am unavailable to join the chat, the error I got is that "the Channel with provided unique name already exists." What is the thing I am doing wrong here? Any help would be appreciated as I am stuck on this for quiet long now.

  $(function () {
          // Get handle to the chat div
          var $chatWindow = $("#messages");
          // Our interface to the Chat service
          var chatClient, generalChannel, username, client_token;
          // Helper function to print info messages to the chat window
          function print(infoMessage, asHtml) {
            var $msg = $('<div class="info">');
            if (asHtml) {
              $msg.html(infoMessage);
            } else {
              $msg.text(infoMessage);
            }
            $chatWindow.append($msg);
          }
          // Helper function to print chat message to the chat window
          function printMessage(fromUser, message) {
            var $userImage = $(
              '<div class="user-icon"><img class="w-100 client-image" src="' +
                data.advisor_info.advisor_image_url +
                '"alt=""/></div>'
            );
        
            var $user = $('<span class="user-message-time">').text("4:53PM");
            var $message = $('<span class="user-message">').text(message);
            var $container = $("<li>");
            if (fromUser === username) {
              $container.addClass("user-message-wrapper");
              $userImage = $(
                '<div class="user-icon"><img class="w-100 client-image" src="' +
                  data.user_info.user_image_url +
                  '"alt=""/></div>'
              );
            }
            $container.append($message).append($userImage).append($user);
            $chatWindow.append($container);
            $chatWindow.scrollTop($chatWindow[0].scrollHeight);
          }
          // Alert the user they have been assigned a random username
          // print("Logging in...");
          // Get an access token for the current user
          $.post("https://psychicdev7345.woptim.com/wp-content/themes/hello-theme-child-master/twiliochatapp/webroot/token.php", { identity: "user_1236" }, function (data) {
            console.log(data);
            // Alert the user they have been assigned a random username
            username = data.identity;
            client_token = data.token;
          
            // Initialize the Chat client
            Twilio.Chat.Client.create(data.token)
              .then((client) => {
                console.log("Created chat client", client);
                chatClient = client;
                chatClient.channels.on("channelAdded", (channel) => {
                  console.log("new channelAdded", channel);
                  generalChannel = channel;
                  // channel.on("messageAdded", function (message) {
                  //   printMessage(message.author, message.body);
                  // });
                });
            
                chatClient.getSubscribedChannels().then(createOrJoinGeneralChannel);
                // when the access token is about to expire, refresh it
                chatClient.on("tokenAboutToExpire", function () {
                  refreshToken(username);
                });
                // if the access token already expired, refresh it
                chatClient.on("tokenExpired", function () {
                  refreshToken(username);
                });
                print();
                // "You have been assigned a random username of: " +
                //   '<span class="me">' +
                //   username +
                //   "</span>",
                // true
              })
              .catch((error) => {
                console.error(error);
                print(
                  "There was an error creating the chat client:<br/>" + error,
                  true
                );
                print("Please check your .env file.", false);
              });
          });
          function refreshToken(identity) {
            console.log("Token about to expire");
            // Make a secure request to your backend to retrieve a refreshed access token.
            // Use an authentication mechanism to prevent token exposure to 3rd parties.
            $.getJSON("https://psychicdev7345.woptim.com/wp-content/themes/hello-theme-child-master/twiliochatapp/webroot/token.php", { identity, identity }, function (data) {
              console.log("updated token for chat client");
              chatClient.updateToken(data.token);
            });
          }
          function createMember() {
            $.post("https://psychicdev7345.woptim.com/wp-content/themes/hello-theme-child-master/twiliochatapp/webroot/member.php", {
              identity: "agent_1236",
              channel: generalChannel.channelState.uniqueName,
            }).then((data) => {
              console.log("createMember.success", ...arguments);
              
            });
          }
          function createOrJoinGeneralChannel() {
            var unique_channel_name =  chatid2+"_"+customer_id;
            console.log("createOrJoinGeneralChannel", ...arguments);
            chatClient
              .createChannel({
                uniqueName: unique_channel_name,
                friendlyName: "General Chat Channel",
                isPrivate: true,
              })
              .then(function (channel) {
                   document.getElementsByClassName("loader")[0].style.display = "none";
                               document.getElementById("chat-input").style.display = "block";
    
                console.log("Created general channel:", channel);
                generalChannel = channel;
                setupChannel();
                createMember();
              })
              .catch(function (err) {
                console.log("Channel could not be created:", err);
              });
          }
          // Set up channel after it has been found
          function setupChannel() {
            generalChannel.on("memberJoined", function (member) {
              console.log("new member added", member);
             
            });
            generalChannel.on("typingStarted", function (member) {
          //   console.log(data.sid);
          document.getElementById("typing-indicator").style.display = "block";
          console.log("hiiiiiiiiiii");
          //process the member to show typing
          //     updateTypingIndicator(member, true);
        });
        //set  the listener for the typing ended Channel event
        generalChannel.on("typingEnded", function (member) {
          console.log("byeeeeeeeee");
          document.getElementById("typing-indicator").style.display = "none";
          //process the member to stop showing typing
          //  updateTypingIndicator(member, false);
        });
            // Join the general channel
            generalChannel.join().then(function (channel) {
              print();
              // "Joined channel as " + '<span class="me">' + username + "</span>.",
              // true
            });
            // Listen for new messages sent to the channel
            generalChannel.on("messageAdded", function (message) {
              printMessage(message.author, message.body);
            });
          }
          // Creating our own channel
          function createChannel() {
            print("Create channel executed");
            chatClient
              .createChannel({
                uniqueName: chatid2+"_"+customer_id,
                friendlyName: "General Chat Channel",
                isPrivate: true,
              })
              .then(function (channel) {
                console.log("Created general channel:");
                console.log(channel);
                generalChannel = channel;
                setupChannel();
              })
              .catch(function (channel) {
                console.log("Channel could not be created:");
                console.log(channel);
              });
          }

Solution

  • Twilio developer evangelist here.

    The issue is that every time you successfully create a Twilio Chat client you then call createOrJoinGeneralChannel. That function then tries to create a new private channel (not the general channel) with the unique name chatid2+"_"+customer_id. I can't see where chatid2 is set, but I am guessing that it doesn't change.

    Rather than try to create the same channel each time and get that error, you should try to fetch the channel and only create it if it doesn't already exist.

    I would likely change the function name createOrJoinGeneralChannel so it is more descriptive. Like this:

              function fetchOrCreatePrivateChannel() {
                var unique_channel_name =  chatid2+"_"+customer_id;
                console.log("createOrJoinGeneralChannel", ...arguments);
                chatClient
                  .getChannelByUniqueName(unique_channel_name)
                  .then(() => {
                    // Got existing channel, set it up now
                  })
                  .catch(() => { 
                    // Channel didn't exist, we should create it
                    chatClient
                      .createChannel({
                        uniqueName: unique_channel_name,
                        friendlyName: "General Chat Channel",
                        isPrivate: true,
                      })
                      .then(function (channel) {
                        // Channel created, set up the channel now
                      }) 
                      .catch(function (err) {
                        console.log("Channel could not be created:", err);
                      });
                  })
              }