Code Monkey home page Code Monkey logo

twilio-conversations-demo-react's Introduction

Conversations Demo Web Application Overview

SDK version of this demo app:

The latest available SDK version of this demo app:

Getting Started

Welcome to the Conversations Demo Web application. This application demonstrates a basic Conversations client application with the ability to create and join conversations, add other participants into the conversations and exchange messages.

You can try out one of our 1-click deploys to test the app out prior to jumping to Next Steps:

Deploy

Test out on Github Codespaces

Open in GitHub Codespaces

Note: This deployment requires a token service url.

Deploy to Vercel

Automatically clone this repo and deploy it through Vercel.

Note: This deployment requires a token service url. Vercel will ask for the REACT_APP_ACCESS_TOKEN_SERVICE_URL env variable.

Deploy with Vercel

Next Steps

What you'll need to get started:

Generating Access Tokens

Client apps need access tokens to authenticate and connect to the Conversations service as a user. These tokens should be generated by your backend server using your private Twilio API Keys. If you already have a service that does this, skip to setting the token service URL.

For testing purposes, you can quickly set up a Twilio Serverless Functions to generate access tokens. Note that this is not a production ready implementation.

Generating Access Tokens with Twilio Functions

  1. Create a Twilio Functions Service from the console and add a new function using the Add+ button.
  2. Set the function path name to /token-service
  3. Set the function visibility to Public.
  4. Insert the following code:
// If you do not want to pay for other people using your Twilio service for their benefit,
// generate a username and password pair different from what is presented below.

//The 1st value [user00] acts as your Username for the Demo app Login. The 2nd value within double qoutes will act as your Password for the login.
//This method is not advised to be used in production. This is ONLY for testing. In production, please utilize your own server side application to handle your users. 

let users = {
    user00: "", !!! SET NON-EMPTY PASSWORD AND REMOVE THIS NOTE, THIS GENERATOR WILL NOT WORK WITH EMPTY PASSWORD !!!
    user01: ""  !!! SET NON-EMPTY PASSWORD AND REMOVE THIS NOTE, THIS GENERATOR WILL NOT WORK WITH EMPTY PASSWORD !!!
};

let response = new Twilio.Response();
let headers = {
    'Access-Control-Allow-Origin': '*',
  };

exports.handler = function(context, event, callback) {
    response.setHeaders(headers);
    if (!event.identity || !event.password) {
        response.setStatusCode(401);
        response.setBody("No credentials");
        callback(null, response);
        return;
    }

    if (users[event.identity] != event.password) {
        response.setStatusCode(401);
        response.setBody("Wrong credentials");
        callback(null, response);
        return;
    }
    
    let AccessToken = Twilio.jwt.AccessToken;
    let token = new AccessToken(
      context.ACCOUNT_SID,
      context.TWILIO_API_KEY_SID,
      context.TWILIO_API_KEY_SECRET, {
        identity: event.identity,
        ttl: 3600
      });

    let grant = new AccessToken.ChatGrant({ serviceSid: context.SERVICE_SID });
    if(context.PUSH_CREDENTIAL_SID) {
      // Optional: without it, no push notifications will be sent
      grant.pushCredentialSid = context.PUSH_CREDENTIAL_SID; 
    }
    token.addGrant(grant);
    response.setStatusCode(200);
    response.setBody(token.toJwt());

    callback(null, response);
};
  1. Save the function.
  2. Open the Environment Variables tab from the Settings section and:
    • Check the "Add my Twilio Credentials (ACCOUNT_SID) and (AUTH_TOKEN) to ENV" box, so that you get ACCOUNT_SID automatically.
    • Add SERVICE_SID
      • Open Conversations Services
      • Copy the SID for Default Conversations Service, or the service you want to set up.
    • Add TWILIO_API_KEY_SID and TWILIO_API_KEY_SECRET. Create API Keys in the console.
    • Optionally add PUSH_CREDENTIAL_SID, for more info see Setting up Push Notifications
  3. Copy URL from the "kebab" three dot menu next to it and and use it as REACT_APP_ACCESS_TOKEN_SERVICE_URL .env variable below.
  4. Click Deploy All.

Set the Token Service URL

If you don't have your own .env, rename this repo's .env.example file to .env. Set the value of REACT_APP_ACCESS_TOKEN_SERVICE_URL to point to a valid Access Token server. If you used Twilio Functions for generating tokens, get the value from Copy URL in step 7 above.

REACT_APP_ACCESS_TOKEN_SERVICE_URL=http://example.com/token-service/

NOTE: No need for quotes around the URL, they will be added automatically.

This demo app expects your access token server to provide a valid token for valid credentials by URL:

$REACT_APP_ACCESS_TOKEN_SERVICE_URL?identity=<USER_PROVIDED_USERNAME>&password=<USER_PROVIDED_PASSWORD>

And return HTTP 401 in case of invalid credentials.

Setting up Push Notifications

This demo app uses Firebase for processing notifications. This setup is optional. Note: Support may be limited for some browsers.

Set up Firebase

  1. Create a Firebase project
  2. Go to the Project Settings
  3. Got to the Cloud Messaging and enable Cloud Messaging API (Legacy) through the "kebab" menu besides it.
  4. Note or copy the Server Key token for creating push credentials.

Create Push Credential

Create a push credential to add a push grant to our access token.

  1. Go to the Credentials section of the console.
  2. Create a new FCM Push Credential and set the Firebase Cloud Message Server Key Token as the FCM Secret.
  3. Note or copy the CREDENTIAL SID to set as PUSH_CREDENTIAL_SID env variable in your token creation Function.

Create Firebase App set config

From the Firebase Project Settings General tab, add a web app to get the firebaseConfig, it should look like this:

var firebaseConfig = {
  apiKey: "sample__key12345678901234567890",
  authDomain: "convo-demo-app-internal.firebaseapp.com",
  projectId: "convo-demo-app-internal",
  storageBucket: "convo-demo-app-internal.appspot.com",
  messagingSenderId: "1234567890",
  appId: "1:1234567890:web:1234abcd",
  measurementId: "EXAMPLE_ID"
};

Note: Firebase API Keys aren't like Twilio API keys and don't need to be kept secret.

Replace this project's firebase-config.example in the public folder with a firebase-config.js containing your specific config.

Enable Push Notification in Conversations Service

Select your conversations service, navigate to the Push Notifications section, and check the Push notifications enabled boxes for the push notifications you want.

Build & Run

Deploy on Github Codespaces

  • Click Open in GitHub Codespaces
  • Wait for the pop-up message to let you know that the port forwarding is done. Then, click "Open in Browser".
  • If the pop-up message isn't displayed, you can always open "PORTS" tab and click on "Open in Browser" button manually.

Run Application Locally

  • Run yarn to fetch project dependencies.
  • Run yarn build to fetch Twilio SDK files and build the application.
  • Run yarn start to run the application locally.

Run Application Inside Docker

  • Run docker compose up --build to build and locally run the application inside a Docker container.

License

MIT

twilio-conversations-demo-react's People

Contributors

baugistoms avatar berkus avatar dependabot[bot] avatar dooley1001 avatar gray-wind avatar infiniterain avatar ipletnjov-tw avatar jconama avatar josethepm avatar krahal avatar lesquive avatar lfrestrepog avatar malinovskiy-alex avatar nicolas-camacho avatar nipel-crumple avatar omalinovkyi avatar pavel-cherentsov avatar ricardonunoalmeida avatar rusmonster avatar rziehl-twilio avatar sahibbajaj avatar snyk-bot avatar sveta-leonovets-twi avatar turgutbasar avatar twilio-product-security avatar yafuquen avatar yunuscanemre avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

twilio-conversations-demo-react's Issues

TypeError: undefined is not an object (evaluating 'this._conversationsPromise.then')

We get a lot of errors that this._conversationsPromise is undefined when trying to call getSubscribedConversations on a channel. Let's take a look at getSubscribedConversations:

async getSubscribedConversations() {
    await this._ensureReady;
    return this._conversationsPromise.then((conversations) => conversations.getConversations());
}

Let's look how _ensureReady is defined in client.js of @twilio/conversations

this._ensureReady = new Promise((resolve, reject) => {
    this._resolveEnsureReady = resolve;
    this._rejectEnsureReady = reject;
 }).catch(() => void 0); // @todo How to process unhandled rejection here?

Well, it seems that there is a bug here and await this._ensureReady will never throw because you swallowed the error. Since you swallowed the error we get to the next line return this._conversationsPromise.... But we can't be sure that _conversationsPromise was set.

You should remove that catch on _ensureReady in Client constructor. At least users or your library would get the original error.

TypeError: Cannot read properties of undefined (reading 'updateToken')

We're following the example, where on tokenAboutToExpire we fetch a new token and call client.updateToken, but we're seeing a lot of these errors:

TypeError: Cannot read properties of undefined (reading 'updateToken')
  at call(node_modules/@twilio/conversations/builds/browser.js:9351:49)
  at tryCatch(node_modules/@twilio/conversations/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
  at _invoke(node_modules/@twilio/conversations/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
  at key(node_modules/@twilio/conversations/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
  at asyncGeneratorStep(node_modules/@twilio/conversations/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:20)
  at _next(node_modules/@twilio/conversations/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:9)

We are thinking of try/catching client.updateToken so it doesn't die, but from reading the conversations js internals, it looks like internally Client._fpaToken won't get set due to the error. Would there be any bad side effects?

We're on @twilio/conversations 2.4.1.

Getting Error on Chat Participant add

Hello, i cloned the repo and setup the dependencies and everything on twilio console.
I'm getting an error when I try to add a Chat Participant to a conversation.
I dunno what I m doing wrong.
I've logged the error to the console.

if (chatParticipant && name.length > 0) {
    try {
      const result = await convo.add(name);
      successNotification({
        message: PARTICIPANT_MESSAGES.ADDED,
        addNotifications,
      });
      return result;
    } catch (e) {
      console.log(e);
      return Promise.reject(e);
    }
  }}

Here is the picture:
Twilio

app setup issues

Hey there!

After cloning when i am installing node modules, it keep saying this to me:

Module not found: Error: Can't resolve '@twilio-paste/icons/esm/ProductSwitcherIcon' in 'D:\csdev\codesymphony\twilio-conversations-demo-react\node_modules\@twilio-paste\product-switcher\dist'

However, somehow I fixed this issue myself but after that I am not able to "create a conversation" as the modal keep saying that
Cannot read properties of undefined (reading 'then')

Image has been attached for reference.

tilio-github-1

Thank you for you help

FCM notification priority

I am using Twilio Conversations Javascript SDK for a React Native App.
And I am using "react-native-firebase/messaging" package for messaging.

However, the library I am using requires the messages coming from Twilio to have 'high' priority.
Currently message priority is default. Is there any way to configure this in twilio?

"Something went wrong. Please try again." when trying to create conversation

I followed the readme to setup this demo app using the Twilio function. I did not use Firebase.

I am able to login successfully, however when I try to create a conversation, a toast appears saying "Something went wrong. Please try again."

Had a wee look to see if I can find out what's going wrong, and found that we are getting the following error in the addConversation method in api.ts

TypeError: Cannot read properties of undefined (reading 'then')
    at _class._callee8$ (client.ts:1070:1)
    at tryCatch (regeneratorRuntime.js:86:1)
    at Generator._invoke (regeneratorRuntime.js:66:1)
    at Generator.next (regeneratorRuntime.js:117:1)
    at asyncGeneratorStep (asyncToGenerator.js:3:1)
    at _next (asyncToGenerator.js:25:1)

This seems to be thrown by the following call:

const conversation = await client.createConversation({
  friendlyName: name,
});

https://gyazo.com/dff0fb9b4a41a3768ce6d0c0d5b96f5c

Perhaps I'm missing something obvious here?

Get conversations in the order they were last updated?

Thank you for creating this repo and sample app! It's helpful to see a new one built around Conversations 2.0.0.

In an existing application we're trying to get a list of a user's conversations and then display the most recent ones along with each conversation's most recent message. A problem we're running into is scaling this as a user belongs to 100+ conversations. We have to get that entire list, sort by the time it was last updated, then get the last message for each one of those conversations . It looks like you're doing something similar in convoReducer.js with case ActionType.LIST_CONVERSATIONS:.

We could delete a ton of client code, reduce app complexity, and (we believe) dramatically speed things up if we could have an orderBy parameter when fetching a list of a user's conversations. That way we could have them pre-sorted by date, then fetch the most recent message for the first 20 that we need to display.

Does this exist or will it exist? The docs for the Conversations API are a bit vague on what arguments Client.getSubscribedConversations accepts.

getSubscribedConversations(args?: any): Promise<Paginator<Conversation>>
Get the current list of all the subscribed conversations.

Parameters
Optional args: any

Property 'conversationTitle' does not exist on type 'PushNotificationData'

Unable to build the app due to a Typescript error. It looks like this issue was introduced in the latest merge: https://github.com/twilio/twilio-conversations-demo-react/pull/16/files

Property 'conversationTitle' does not exist on type 'PushNotificationData'. Did you mean 'conversationSid'?ts(2551)
[lib.d.ts(1430, 5): ]()'conversationSid' is declared here.

Digging into lib.d.ts, conversationTitle property seems to be missing from the PushNotificationData type:

/**
 * Additional data for a given push notification.
 */
interface PushNotificationData {
    /**
     * SID of the conversation.
     */
    conversationSid?: string;
    /**
     * Index of the message in the conversation.
     */
    messageIndex?: number;
    /**
     * SID of the message in the conversation.
     */
    messageSid?: string;
}

how to still use public channel features ?

we still want to use public channels and let others see these public channels and be able to join them. we already have this feature set up with Twilio chat. Now we are trying to migrate into Twilio conversations and we are not sure how to still provide this feature to end-users.

conversationAdded event never hit?

Hi, I'm implementing a chat application based on the code here and its going great mostly but I have an annoying little bug where it seems conversationAdded will sometimes not get hit (for any conversations) and I have no idea why. Is there any commonly known reason that could be causing this?

I'm initializing the twilio client in a singleton service

async initialize(myCarmmunityUserId: string): Promise<Client> {
    return new Promise(async (resolve, reject) => {
      if (this.client) {
        return resolve(this.client);
      }
      const token = await this.getToken();
      this.client = new Client(token);
      this.client.on('stateChanged', state => {
        if (state === 'initialized') {
          this.listenToEvents(this.client);
          return resolve(this.client);
        } else if (state === 'failed') {
          return reject('Failed to initialize Twilio client');
        }
      });
    });
  }

And then in listenToEvents:

listenToEvents(client: Client) {
    client.on('conversationAdded', async (conversation: Conversation) => {
        // intermittently this will not get hit happens maybe once every 4 times
    }
}

@twilio/conversations postinstall script fails to run

while installing @twilio/conversations@^2.0.0, I get this error during the postinstall step with yarn 3 on Ubuntu:

➤ YN0009: │ @twilio/conversations@npm:2.0.0 couldn't be built successfully (exit code 127, logs can be found here: /tmp/xfs-a48fafed/build.log)

that file contains the following:

# This file contains the result of Yarn building a package (@twilio/conversations@npm:2.0.0)
# Script name: postinstall

command not found: if
command not found: then
command not found: fi

a comment here seemed to imply that a fix would be coming, but AFAICT there have been no releases of @twilio/conversations since the original 2.0.0 a few months ago.

are there any workarounds I can try in the meantime?

thanks!

Create Conversation Chat_Service_SID Specific

how to create a conversation to a specific chat service id using client SDK ?

This one is API BASED

client.conversations.v1.services('ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
.conversations('CHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
.messages
.create()
.then(message => console.log(message.sid));

I want to do this in the client SDK itself . Is it possible or do I have to do that using API?

Destroy client at logout

How to destroy the client at logout.
when log in again then it creates a duplicate of the message while adding

this listener runs two times
client.on("messageAdded", (event) => {
console.log("messageAdded")})

Hide/Add UI components based on Role/Permission

It would be great to show how to modify the UI using the Role or the Permissions assigned to that Role. For example hide the "Manage Participants" button if the Role doesn't have addParticipant or removeParticipant permissions.

React Native

We have a project in React Native, can we use the JS REACT SDK, or do I need to create bridges for Swift and Java?

setLastReadIndex and consumed messages

I'm having trouble displaying unread messages correctly.

For example, if the user is not inside the web demo and a new conversation is created, when said user enters the web demo he does not see the notifications (those that appear on the left), correctly.

Maybe it's related to firebase notifications that I have them turned off?

Thank you

Couldn't initialize firebase app

I have followed carefully the instructions for setting up firebase push notification but still can't get it work. The image below shows the error in the console.

Screenshot 2023-11-15 at 3 54 46 PM

older messages are append bottom instead of top

while open the conversation details with messages, default load the 30 recent messages, while scroll up older messages came, but these older messages append to bottom instead of top. can you please help, thank you.

If the user is not connected to the web initially, he will not receive the messages the first time

I am experiencing some strange behavior:
If I send a message to a new conversation, where there is a person who is not logged in in this demo... when that person enters the page they will not see any of the sent messages.

Only when either of the two people send a new message will it work normally.

I think it may be because there is some kind of listener or behavior that is not initialized correctly.

Have you ever been to a similar situation? How can I solve that?

Thank you

Cannot create a new conversation

I was trying to test the demo out, after having done the initial steps and setting up the serverless functions. I can log in and build the app successfully. However, I cannot create a new conversation.

Error: Cannot read properties of undefined (reading 'then')

  "react": "17.0.2",
  "@twilio/conversations": "2.4.1",

It's this function

  async createConversation(options) {    
        await this._ensureReady;
        options = options || {};
        return this._conversationsPromise.then((conversationsEntity) => conversationsEntity.addConversation(options));
    }

Note: I am using the serverless functions for the backend.

Node: v18

Use the steps here to set up the service.

Screenshot 2023-12-06 at 10 51 07 AM

I have gone through the other issues, not that helpful. Anyone who's been able to get throught this, I'd appreciate the support.

Redux make this demo hard to read

Just saying.

I don't think using an over-engineering tool like Redux is a good idea for "demo" apps,
I noticed that I been battling with navigating between Redux reducers and actions just to get to know how basic things work in this SDK

Convo List does not handling a long list very well

I have more than a hundred conversations and this app is not user-friendly with such a long list.
Below is the list of the issues I noticed:

  • It will take to finish loading the last in the list to show the conversations list. So if you have a 500 in the record, it will take several seconds for the list to show up.
  • After loading the list, the messages in the conversation will load, and it will take another seconds for us to use the app properly.
  • If you click a conversation while loading, it will return an error "Cannot read properties of undefined (reading 'length')"

Message List can handle a long list of messages in a conversation very well. I hope Infinite Scroll can be implemented in Conversations List. In most cases, we will only need the most recent messages not more than 50.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.