aws / amazon-chime-sdk-js

A JavaScript client library for integrating multi-party communications powered by the Amazon Chime service.
Apache License 2.0
710 stars 478 forks source link

How to RealtimeReceiveChannelMessages ? #1367

Closed abhimanusharma closed 3 years ago

abhimanusharma commented 3 years ago

I am trying to find out how can a participant know that they received a message and update the message in the UI of both the sender and the receiver.

I have started a messaging session using message session endpoint for every participant that is joining the meeting.

https://docs.aws.amazon.com/chime/latest/dg/websockets.html

I have found this documentation but unable to figure out a way to setup that for my use case where there is data message sender and receiver (for open chat), then there is a one to one chat where I am adding the sender and receiver in a single channel, there is group chat where I am adding multiple users in a single channel.

There is an api for list all channel messages but I am unable to figure out how to make this in real-time so that every time a user receive a messages the list refresh or update.

I have also found https://aws.github.io/amazon-chime-sdk-android/amazon-chime-sdk/com.amazonaws.services.chime.sdk.meetings.realtime/-default-realtime-controller/index.html But there is no example or use case to set it up (if this can be used)

Getting an example with use case with dummy data will be really helpful for many users to set it up without looking in multiple links.

ltrung commented 3 years ago

@abhimanusharma So we have 2 way to send message for chime SDK. One is realtime send data message which you can example implementation here https://github.com/aws/amazon-chime-sdk-js/blob/master/demos/browser/app/meetingV2/meetingV2.ts#L875. The other is to use chime messaging API. For this all you need to do is to setup a messaging session and subscribe to messagingSessionDidReceiveMessage as shown in this example https://github.com/aws/amazon-chime-sdk-js/blob/master/demos/browser/app/messagingSession/messagingSession.ts. A full messaging example can be found here https://github.com/aws-samples/amazon-chime-sdk/tree/main/apps/chat. Hope that helps.

abhimanusharma commented 3 years ago

@ltrung

Started session on my client app:

startMessegingSession = async() => {

    const meetingInfo = JSON.parse(localStorage.getItem('strike_ls')).meeting.meeting;    

    const meeting = {
      attendeeId: meetingInfo.attendeeResponse.AttendeeId,
      meetingId: meetingInfo.meetingResponse.MeetingId,
      email: meetingInfo.userEmail,
    }

    AWS.config.update({
      accessKeyId: awsConfig.AWS_ACCESS_KEY_ID,
      secretAccessKey: awsConfig.AWS_SECRET_ACCESS_KEY
    });

    this.chime = new Chime({ region: 'us-east-1' });

    const endpoint = await this.chime.getMessagingSessionEndpoint().promise();

    const logger = new ConsoleLogger('SDK', LogLevel.INFO);
    // You will need AWS credentials configured before calling AWS or Amazon Chime APIs.

    const userArn = `${awsConfig.APP_INSTANCE_ARN}/user/${meeting.email}`;/* The userArn */;
    const sessionId = meeting.meetingId; /* The sessionId */;

    try {
        const configuration = new MessagingSessionConfiguration(userArn, sessionId, endpoint.Endpoint.Url, this.chime, AWS);
        const messagingSession = new DefaultMessagingSession(configuration, logger);
        this.messagingSession = messagingSession;
        this.messageSessionObserver();
    } catch (error) {
        console.log("messagingSession",error);
    }

  }

  async messageSessionObserver() {
    const observer = {
      messagingSessionDidStart: () => {
        console.log('Message Session started');
      },
      messagingSessionDidStartConnecting: reconnecting => {
        if (reconnecting) {
          console.log('Start reconnecting - Message Session');
        } else {
          console.log('Start connecting - Message Session');
        }
      },
      messagingSessionDidStop: event => {
        console.log(`Message Session Closed: ${event.code} ${event.reason}`);
      },
      messagingSessionDidReceiveMessage: message => {
        console.log(`Receive message type ${message.type}`);
        console.log("Received message", message);
      }
    };

    this.messagingSession.addObserver(observer);
    this.messagingSession.start();
  }

Here is sending request from my client to my backend app.

startConversation = async (memberObj:any) => {
    const userId = this.props.meetingSession.configuration.credentials.attendeeId;
    const memberId = memberObj.attendeeId;
    const member:any = await this.fetchAttendeeData(memberId);
    const user:any = await this.fetchAttendeeData(userId);
    console.log("member:", member);
    console.log("user:", user);

    const {dispatch} = this.props;
    const createChannelParams = {
      name: memberObj.attendeeId,
      mode: "UNRESTRICTED",
      privacy: "PRIVATE",
      userId: user._doc.Email,
      memberId: member._doc.Email,
    }
    const channelId = await dispatch(createChannel(createChannelParams));
    const membershipParams = {
      channelId,
      memberId: member._doc.Email,
      userId: user._doc.Email,
    }
    await dispatch(createChannelMembership(membershipParams));
    const addSelf = {
      channelId,
      memberId: user._doc.Email,
      userId: user._doc.Email,
    }
    await dispatch(createChannelMembership(membershipParams));
    this.setState({
      activeIndexPanel: 0,
      isGlobalChat: false,
      isGroupChat: true,
      activeChannel: channelId,
    });
  }

  sendChannelMessage = async () => {
    const { dispatch } = this.props;
    const { activeChannel, channelMessageText } = this.state;
    const userId = this.props.meetingSession.configuration.credentials.attendeeId;
    const user:any = await this.fetchAttendeeData(userId);
    const params = {
      userId: user._doc.Email,
      channelId: activeChannel,
      messageContent: channelMessageText
    }
    const messageRes = await dispatch(sendChannelMessage(params));
    console.log(messageRes);

  }

I am not receiving anything in messagingSessionDidReceiveMessage

ltrung commented 3 years ago

Did you receive any error in console.log? Could you verify the userArn exists using DescribeAppInstanceUser (https://docs.aws.amazon.com/chime/latest/APIReference/API_DescribeAppInstanceUser.html)

abhimanusharma commented 3 years ago

I am not receiving any error, I am getting successful message sent in response also my AppInstanceUserArn exists.

Ques: I tried to get the messageSessionEndpoint from my backend to keep the session in sync with fronend and backend app? Changed:

const endpoint = await this.chime.getMessagingSessionEndpoint().promise();

to:

const endpoint = await dispatch(getMessagingSessionEndpoint());

As I am creating messageSession on frontend but all my createChannel and sendMessage calls are executing in backend and receiving the response in frontend. Can you please see the code above and guess what am I doing wrong?

When I am trying to run the demo, I am getting below error when trying to create a channel.

Screenshot from 2021-06-17 07-01-16

Also I was facing issue while running the app in https in my local so I disabled it from webpack.config.js

anuranduttaroy commented 3 years ago

Hey @abhimanusharma

I tried looking up the error "Missing region in config" and found some articles online like this one https://stackoverflow.com/questions/31039948/configuring-region-in-node-js-aws-sdk/39563972

I think you are missing adding the region in the AWS.config. Could you try adding the below line in your code and see if that fixes the issue?

AWS.config.update({region:'us-east-1'});
abhimanusharma commented 3 years ago

@anuranduttaroy Can you tell me in which file of the demo I have to write above code as the AWS is configure in the demo using the config file by default where the region is already set. Refer line #134 of chat demo.

Also my original question left unanswered, In what case the messagingSessionDidReceiveMessage will not receive any logs? I am getting endpoint from my node app and sending request to createChannel and sendMessage to the same node app.

I think it would be real helpful if some could just add a sample example of createChannel or listChannels or anything a single example would suffice in https://github.com/aws/amazon-chime-sdk-js/blob/master/demos/browser/app/messagingSession/messagingSession.ts. so that the understanding of using them both at time would me more understandable.

PS: I tried everything I could to start the demo at my local system.

  1. I set up the aws cli and configure it with correct aws sercret and access keys
  2. I set up my Config.js file completely by filling each keys mentioned below with correct values.
    const appConfig = {
    region: 'us-east-1',
    cognitoUserPoolId: 'us-east-1_12342334',
    cognitoAppClientId: '123asdasd123234sd',
    cognitoIdentityPoolId: 'us-east-1:xxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx',
    appInstanceArn: 'arn:aws:secretsmanager:us-east-1:123451414:secret:cognito/pool-23123qwe',
    accessKeyId: 'XXXXXXXXXXXXXXXX',
    secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxx',
    attachments_s3_bucket_name: '',
    credentialExchangeServiceApiGatewayInvokeUrl:'',
    };
  3. I also tried to set up AWS_SDK_LOAD_CONFIG=1 in a .env file and also tried to add the ~/.bashrc file but no luck so far.
  4. Also tried to set it in MessageService.js and IndentityService.js like
    AWS.config.update({
          region:'us-east-1',
          accessKeyId: 'xxxxxxxxxxxxxxxxxxxx',
          secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxx'
        });

Still getting errors related to config.

Screenshot from 2021-06-19 13-22-58

vidya-mohan commented 3 years ago

@abhimanusharma have you looked at https://github.com/aws-samples/amazon-chime-sdk/tree/main/apps/chat ?

abhimanusharma commented 3 years ago

@vidya-mohan Obviously I did, sorry but If you tried to read previous comments then you would know what I have tried. I have tried everything that mentioned in the doc and as suggested by @ltrung and @anuranduttaroy

Instead of sending the url please read the comment and reply with a solution.

garyzhon commented 3 years ago

Hi @anuranduttaroy

Here is the documentation on providing credentials to AWS SDK. https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html

If you like to set the credentials within your js code, you can provide your credentials like this. You client app would get the session credentials from your web service. For testing and development purpose only, you can hard code your access key id and secret access key. The session token would null.

AWS.config.update({ region: 'us-east-1' });
AWS.config.credentials = new AWS.Credentials(
  'your access key id',
  'your secret access key',
  'your session token'
);
michhyun1 commented 3 years ago

@abhimanusharma We don't see any reply from you, please close this issue if your issue has been resolved. Thanks

abhimanusharma commented 3 years ago

@michhyun1 I replied 14 days ago and have not received any related reply to my question yet. I am unable to run the demo on my local and unable to receive real time channel message using Chime Messaging SDK, I don't see any other article or video tutorial related to that anywhere, I am sorry I can not close this issue until I get any positive reply for at least one of my queries.

michhyun1 commented 3 years ago

@abhimanusharma by looking at your screenshot errors, it seems like you are having issues with configuring your AWS credentials. Have you made any progress with the information that @garyzhon provided you above?

vidya-mohan commented 3 years ago

Resolving on no response