Code Monkey home page Code Monkey logo

stream-chat-js's Introduction

Official JavaScript SDK for Stream Chat

NPM

Official JavaScript API client for Stream Chat, a service for building chat applications.
Explore the docs Β»

Report Bug Β· Request Feature

πŸ“ About Stream

You can sign up for a Stream account at our Get Started page.

This library can be used by both frontend and backend applications. For frontend, we have frameworks that are based on this library such as the Flutter, React and Angular SDKs. For more information, check out our docs.

βš™οΈ Installation

NPM

npm install stream-chat

Yarn

yarn add stream-chat

JS deliver

<script src="https://cdn.jsdelivr.net/npm/stream-chat"></script>

✨ Getting started

The StreamChat client is setup to allow extension of the base types through use of generics when instantiated. The default instantiation has all generics set to Record<string, unknown>.

import { StreamChat } from 'stream-chat';
// Or if you are on commonjs
const StreamChat = require('stream-chat').StreamChat;

const client = StreamChat.getInstance('YOUR_API_KEY', 'API_KEY_SECRET');

const channel = client.channel('messaging', 'TestChannel');
await channel.create();

Or you can customize the generics:

type ChatChannel = { image: string; category?: string };
type ChatUser1 = { nickname: string; age: number; admin?: boolean };
type ChatUser2 = { nickname: string; avatar?: string };
type UserMessage = { country?: string };
type AdminMessage = { priorityLevel: number };
type ChatAttachment = { originalURL?: string };
type CustomReaction = { size?: number };
type ChatEvent = { quitChannel?: boolean };
type CustomCommands = 'giphy';

type StreamType = {
  attachmentType: ChatAttachment;
  channelType: ChatChannel;
  commandType: CustomCommands;
  eventType: ChatEvent;
  messageType: UserMessage | AdminMessage;
  reactionType: CustomReaction;
  userType: ChatUser1 | ChatUser2;
};

const client = StreamChat.getInstance<StreamType>('YOUR_API_KEY', 'API_KEY_SECRET');

// Create channel
const channel = client.channel('messaging', 'TestChannel');
await channel.create();

// Create user
await client.upsertUser({
  id: 'vishal-1',
  name: 'Vishal',
});

// Send message
const { message } = await channel.sendMessage({ text: `Test message` });

// Send reaction
await channel.sendReaction(message.id, { type: 'love', user: { id: 'vishal-1' } });

Custom types provided when initializing the client will carry through to all client returns and provide intellisense to queries.

πŸ”— (Optional) Development Setup in Combination with our SDKs

Run in the root of this repo

yarn link

Run in the root of one of the example apps (SampleApp/TypeScriptMessaging) in the stream-chat-react-native repo

yarn link stream-chat
yarn start

Open metro.config.js file and set value for watchFolders as

module.exports = {
  ...
  watchFolders: [projectRoot].concat(alternateRoots).concat(['{{CHANGE_TO_THE_PATH_TO_YOUR_PROJECT}}/stream-chat-js'])
};

Make sure to replace {{CHANGE_TO_THE_PATH_TO_YOUR_PROJECT}} with the correct path for stream-chat-js folder as per your directory structure Run in the root of this repo

yarn start

πŸ“š More code examples

Head over to docs/typescript.md for more examples.

✍️ Contributing

We welcome code changes that improve this library or fix a problem, please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on Github. We are very happy to merge your code in the official repository. Make sure to sign our Contributor License Agreement (CLA) first. See our license file for more details.

Head over to CONTRIBUTING.md for some development tips.

πŸ§‘β€πŸ’» We are hiring!

We've recently closed a $38 million Series B funding round and we keep actively growing. Our APIs are used by more than a billion end-users, and you'll have a chance to make a huge impact on the product within a team of the strongest engineers all over the world.

Check out our current openings and apply via Stream's website.

stream-chat-js's People

Contributors

anatolyrugalev avatar arnautov-anton avatar bdandy avatar bogdan-d avatar bogdan-getstream avatar dependabot[bot] avatar ferhatelmas avatar ffenix113 avatar github-actions[bot] avatar gumuz avatar jeltef avatar khushal87 avatar link512 avatar mahboubii avatar martincupela avatar miagilepner avatar myandrienko avatar nhannah avatar peterdeme avatar ruggi avatar ruudniew avatar shaljam avatar szuperaz avatar tbarbugli avatar thesyncim avatar tschellenbach avatar vangalilea avatar vishalnarkhede avatar yaziine avatar zerozez 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stream-chat-js's Issues

user information does not update even if client.updateUser() executed successfully in client side

Hi i am facing a problem in getstram api (chat). when I update user information, i see client.updateUser() executed successfully. but we do not get update user information in client.user. It remain previous old information. right now i am trying to update image url. It remains the old info until we reload the whole application (cmd+R in ios, RR android simulator). but channel update work when we update channel information.

Could you please tell me what is the reason for this ?

Do you have any plans to support locale?

My service provides Korean, Taiwanese, Japanese, Chinese, etc. However, we cannot provide locale support only in stream-chat. I hope locale support is available as soon as possible.

Do you have any plans to support locale?

Update Avatar for User in Chat

Hi Team,
Trying to update the Chat Avatar (As per below given snapshot) for the User once he will select to upload a new image from the Upload button we have in our application.
To achieve this I have tried some in built functions (client.setUser & client.partialUpdateUser) given in the GetStream documentation to update the image for that particular user but it didn’t updated.
Please suggest what is the best way to achieve this.

image

countUnread strange behaviour

Hello, i'm having an issue the situation is the next, i have a frontend chat using react and a backend server to handle the list of channels and their unread messages per client, the problem what i'm facing its the next:

1 - I go to my chat i click on the channel's box then i send using the client something like:

const selectedChannel = client.channel("messaging", channel.id);
selectedChannel.markRead();

2 - I get a list from my backend of my channels using this code on nodejs (i'm using the client server-side):

const channels = await streamChatClient.queryChannels(
     {},
     { last_message_at: -1, created_at: -1 },
     {}
   );

   channels.map(channel => {
 
     console.log(channel.state.read);

     chanListResponse.push({
       id: channel.data.id,
       cid: 'messaging:'+channel.data.id,
       name: channel.data.chanName,
       type: channel.data.chanType,
       created_by: channel.data.created_by.name,
       unread: channel.countUnread(),
     });
   });

3 - The first time i do markRead from the frontend and then i do a channel list from the backend and get all the channels data, i get 0 from countUnread and the channel.state.read seems to be filled with the right information.

Now the problem is once i restart my node server, this information seems to get lost and the state.read's object comes empty from the endpoint when i do the list channels's call, so i've to do a markRead again from the frontend and then the state.read's object gets filled with the right information, and the countUnread value is set to 0, any clue about this behaviour ? I also tried using markRead server side and the result is the same.

It seems each time the StreamChat's object gets instantiated it lost the reference to the last read's object, i don't know if its a normal or a flaw, but the thing is i can't automatically read all the messages for the user at startup time, the user should be able to know which ones were read and which ones weren't, and should be able to markRead some channels and some channels not, and i can't rely only in 1 instance because the server may get restarted and then i should mark read all them again. I hope the problem is clear, otherwise it pushes me to do some extra work in my side, grabbing all the channels and keep updating their latest messages into a local db with an unread counter.

Thanks in advance.

Issue with time taken to execute a "reconnect"?

Hi there,

I am currently trialing Stream Chat at work and have a working implementation using the stream-chat-js directly within our React Native project. I have a query surrounding when/how the SDK decides to perform the _reconnect action. Understanding this will help us avoid "dropping" messages when a user backgrounds the mobile app (i.e. the user can't see the app) but the backing web-socket connection is still available.

The problem flow goes a bit like this;

  1. User 1 and User 2 are chatting as normal in a conversation
  2. User 2 switches app/backgrounds their app/exits their app
  3. User 1 soon (<10 seconds) after User 2 has backgrounded their app writes User 2 a new message
  4. User 2 does not receive this message by way of a push notification.
  5. Greater than 10 seconds later after the last activity in the channel User 1 writes another message and sends it
  6. Since User 2's client has now "initiated the reconnect" and they receive a push message informing them of the ongoing conversation. However, they have missed a message in the middle.

It appears there maybe issues with the channel stopWatching API call. I can see User 1's client issue a stopWatching API call only for typing.start & typing.stop messages to continue to be received.

This reconnect() function appears to fix things but I'm not sure if this is a side-effect. Here are some annotated logs from User 1's device to assist. Lines i've added start with a >>;

>> Start

>> User 1 is viewing their inbox of messages here:

08-14 17:59:00.533  6564  6851 I ReactNativeJS: 'info', 'client: post - Request - https://chat-us-east-1.stream-io-api.com/channels/messaging/classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351/query'
08-14 17:59:00.681  6564  6851 I ReactNativeJS: 'info', 'client:post - Response - url: https://chat-us-east-1.stream-io-api.com/channels/messaging/classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351/query > status 201'


>> User 1 and User 2 start chatting here:

08-14 17:59:00.748  6564  6851 I ReactNativeJS: 'info', 'channel:watch() - started watching channel messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:00.750  6564  6851 I ReactNativeJS: 'info', 'client: post - Request - https://chat-us-east-1.stream-io-api.com/channels/messaging/classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351/message'
08-14 17:59:00.836  6564  6851 I ReactNativeJS: 'info', 'client: post - Request - https://chat-us-east-1.stream-io-api.com/channels/messaging/classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351/event'
08-14 17:59:00.869  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.new }'
08-14 17:59:00.869  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.new } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:01.286  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.new }'
08-14 17:59:01.286  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.new } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:01.290  6564  6851 I ReactNativeJS: 'info', 'client:post - Response - url: https://chat-us-east-1.stream-io-api.com/channels/messaging/classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351/message > status 201'
08-14 17:59:01.293  6564  6851 I ReactNativeJS: 'info', 'client: get - Request - https://chat-us-east-1.stream-io-api.com/channels'
08-14 17:59:01.297  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.new }'
08-14 17:59:01.297  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.new } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:01.659  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.new }'
08-14 17:59:01.659  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.new } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:01.826  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.stop }'
08-14 17:59:01.827  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.stop } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:01.829  6564  6851 I ReactNativeJS: 'info', 'client:post - Response - url: https://chat-us-east-1.stream-io-api.com/channels/messaging/classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351/event > status 201'
08-14 17:59:01.831  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.stop }'
08-14 17:59:01.831  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.stop } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:01.831  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.stop }'
08-14 17:59:01.831  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.stop } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:01.832  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.stop }'
08-14 17:59:01.832  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.stop } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:01.843  6564  6851 I ReactNativeJS: 'info', 'client:get - Response - url: https://chat-us-east-1.stream-io-api.com/channels > status 200'
08-14 17:59:03.637  6564  6851 I ReactNativeJS: 'info', 'client: post - Request - https://chat-us-east-1.stream-io-api.com/channels/messaging/classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351/stop-watching'
08-14 17:59:03.781  6564  6851 I ReactNativeJS: 'info', 'client:post - Response - url: https://chat-us-east-1.stream-io-api.com/channels/messaging/classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351/stop-watching > status 201'


>> User 1 backgrounds their app here:

08-14 17:59:03.782  6564  6851 I ReactNativeJS: 'info', 'channel:watch() - stopped watching channel messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'


>> User 2 starts their response to User 1 here:

08-14 17:59:08.955  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.start }'
08-14 17:59:08.956  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.start } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:08.988  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.start }'
08-14 17:59:08.988  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.start } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:09.109  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.start }'
08-14 17:59:09.110  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.start } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:09.772  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:09.773  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:09.807  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:09.807  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:09.811  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:09.811  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.028  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.stop }'
08-14 17:59:12.028  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.stop } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.134  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { user.watching.start }'
08-14 17:59:12.134  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { user.watching.start } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.135  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.stop }'
08-14 17:59:12.135  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.stop } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.136  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { user.watching.start }'
08-14 17:59:12.136  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { user.watching.start } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.136  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { typing.stop }'
08-14 17:59:12.137  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { typing.stop } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.184  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { user.watching.start }'
08-14 17:59:12.184  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { user.watching.start } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'


>> User 1 gets a notification.message_new event here but the app is backgrounded so our app process does not respond:

08-14 17:59:12.186  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { notification.message_new }'
08-14 17:59:12.243  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { notification.message_new } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.244  6564  6851 I ReactNativeJS: 'info', 'client: get - Request - https://chat-us-east-1.stream-io-api.com/channels'
08-14 17:59:12.251  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { notification.message_new }'
08-14 17:59:12.252  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.new }'
08-14 17:59:12.252  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.new } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.256  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.new }'
08-14 17:59:12.256  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.new } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.562  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.new }'
08-14 17:59:12.562  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.new } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:12.733  6564  6851 I ReactNativeJS: 'info', 'client:get - Response - url: https://chat-us-east-1.stream-io-api.com/channels > status 200'
08-14 17:59:19.704  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:19.704  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:19.707  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:19.708  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:19.710  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:19.710  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:26.055  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:26.056  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:26.059  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:26.059  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:26.063  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:26.063  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:32.301  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:32.301  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:32.304  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:32.305  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'
08-14 17:59:32.307  6564  6851 I ReactNativeJS: 'info', 'client:_handleClientEvent - Received event of type { message.read }'
08-14 17:59:32.308  6564  6851 I ReactNativeJS: 'info', 'channel:_handleChannelEvent - Received event of type { message.read } on messaging:classifieds__41909b8e_805d_4920_bb4d_0b57ef70f2ce__4063__5351'


>> User 1's client issues a "reconnect" command here meaning that subsequent messages from User 2 will be delivered via Push:

08-14 17:59:34.567  6564  6851 I ReactNativeJS: 'info', 'connection:_reconnect() - Initiating the reconnect'
08-14 17:59:34.602  6564  6851 I ReactNativeJS: 'info', 'connection:_reconnect() - Initiating the reconnect'

Question about public channels

I'm having an issue, i'm creating public channels without adding members in it, then i log using other user's token and i can't see them, is it a normal behaviour? I remember i used to see them no matter what user i was using, since those channels all public, i don't think its needed to add members into it.

Thanks

Add support for Keep-Alive (Node)

Keep-Alive and connection pooling are both very useful (TLS handshake is expensive)

We should create an instance of axios and make sure it has decent keep-alive settings. Users of the library should be able to pass an http and https agent so that they can tweak things as they please (ie. connection pool settings, keep-alive TTL)

Note: last time I checked, Node.js would default to unlimited connection pools and without setting a fixed limit keep-alive was totally useless. Because TLS handshake is so slow, it should be very simple to validate that keep-alive and connection pooling is working.

See: axios/axios#1846

Trivial TS issue with StreamChat Constructor

constructor(key: string, secretOrOptions?: string, options?: StreamChatOptions);

I believe that line should instead read:

- constructor(key: string, secretOrOptions?: string, options?: StreamChatOptions);
+ constructor(key: string, secretOrOptions?: string | StreamChatOptions);
+ constructor(key: string, secretOrOptions?: string, options?: StreamChatOptions);

I haven't tested it in that format (method overloads), but I'd be equally happy with:

constructor(key: string, secretOrOptions?: string | StreamChatOptions, options?: StreamChatOptions);

This is simpler, and engineers should be able to figure out that they're not supposed to pass the options twice, but I guess it's not as explicit.

Server-side ban action not working

Following on from #112 we've been testing how the "ban"/"unban" functionality is meant to operate. Unfortunately, we've encountered more issues with the server-side node approach or the (stream-cli)[https://github.com/GetStream/stream-cli/blob/master/docs/chat.md#stream-chatuserban] stream:chat:ban approach yielding errors. Here is a short gif of the actions I'm taking resulting in the below noted exception;

stream-ban-user

Error: StreamChat error code 4: Ban failed with error: "either user or user_id must be provided when using server side auth."
    at StreamChat.errorFromResponse (/usr/local/lib/node_modules/getstream-cli/node_modules/stream-chat/dist/index.js:4124:15)
    at StreamChat.handleResponse (/usr/local/lib/node_modules/getstream-cli/node_modules/stream-chat/dist/index.js:4138:20)
    at StreamChat._callee8$ (/usr/local/lib/node_modules/getstream-cli/node_modules/stream-chat/dist/index.js:3923:56)
    at tryCatch (/usr/local/lib/node_modules/getstream-cli/node_modules/regenerator-runtime/runtime.js:45:40)

We're a little perturbed as to what is going on for everything not to be working. I understand the stream-chat-js client has only just reached 1.0.0. We are running stream-cli at getstream-cli/0.0.12 darwin-x64 node-v12.8.0 and stream-chat-js at 1.0.1.

We are going to upgrade to 1.0.4 and retry but both this ticket and #112 don't appear to be client issues.

Improved TS types for event handlers

Currently, the event registration and deregistration methods (on and off respectively) aren't correctly typed for registration of the "catch all" event handler case, i.e. it's not possible to do the following and have TypeScript be happy with you:

client.on(() => {
  console.log('got an event');
});

This can be pretty easily fixed by changing the type definitions to support the overloaded forms of the methods. For example the type definitions on the client would look something like:

on(eventName: string, eventHandler: any): { unsubscribe(): void };
on(eventHandler: any): { unsubscribe(): void };
off(eventName: string, eventHandler: any): void;
off(eventHandler: any): void;

You could actually go pretty hardcore on this typing if you ever feel so inclined, with strong definitions for specific type definitions for each of the different event and details with regards to the data that is sent through from event calls. e.g.

type EventRegistrationResult = { unsubscribe: () => void };
type MessageNewHandler = (evt: MessageNewEvent) => void;
type HealthCheckHandler = (evt: HealthCheckEvent) => void;

on(eventName: 'message.new', eventHandler: MessageNewHandler): EventRegistrationResult;
on(eventName: 'health.check', eventHandler: HealthCheckHandler): EventRegistrationResult;
...
on(eventHandler: GlobalEventHandler): EventRegistrationResult;

That's pretty extreme, but I'm sure all of us using TypeScript would be over the moon if we ended up there one day :)

More than happy to raise a PR to take care of the simple case of handling the global event handler if that's helpful.

License warning

package.json: License should be a valid SPDX license expression

Is it something we should consider to silence?

Following patch gets rid of the warning:

--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
     "./dist/index.js": "./dist/browser.js"
   },
   "jsdelivr": "./dist/browser.full-bundle.min.js",
-  "license": "Other/Commercial",
+  "license": "SEE LICENSE IN LICENSE",
   "keywords": [
     "chat",
     "messaging",
@@ -31,7 +31,8 @@
   "files": [
     "/dist",
     "/types/stream-chat/index.d.ts",
-    "readme.md"
+    "readme.md",
+    "license"
   ],
   "dependencies": {
     "@babel/runtime": "^7.3.1",

Unmute action doesn't send "notification.mutes_updated" event

We have been trying out some of the chat moderation controls whilst assessing the suitability of Stream Chat for our application and encountered an issue with the mute/unmute action.

To replicate

  1. Mute a user in a chat
  2. Receive notification.mutes_updated event
  3. Unmute the same user in a chat

Expected result

  • We receive a notification.mutes_updated event

Actual result

  • No event is received

Is this expected? If so how do we go about listening for unmute changes without leveraging the mutes_updated event?

Thank you in advance.

Incorrect and incomplete typings

One of the examples of incorrect typings in index.d.ts

Right now:

export class Channel {
  ...
  addMembers(members: User[]): Promise<APIResponse>;
  addModerators(members: User[]): Promise<APIResponse>;

Should be:

export class Channel {
  ...
  addMembers(members: string[]): Promise<APIResponse>;
  addModerators(members: string[]): Promise<APIResponse>;

There are many other cases when typings are different from runtime types.

And overall types are very limited and incomplete, frequent usage of [propName: string]: any; and any makes typings useless. Integrating Stream chat into Typescript codebase is very difficult.

The userId argument is missing from the removeDevice method in types/stream-chat/index.d.ts.

Hi. I'm developing using Typescript.

I use addDevice and removeDevice methods for push notification, but I can't put userId in removeDevice method.
The userId argument is missing from the removeDevice method in types/stream-chat/index.d.ts.

The current code is shown below.
removeDevice(deviceId: string): Promise<APIResponse>;
(types/stream-chat/index.d.ts, line 214)

I think it should change as follows.
removeDevice(deviceId: string, userId: string | undefined): Promise<APIResponse>;

please check this code.

Issues when Caching Client Object (Server Side) - Converting circular structure to JSON

Hello people, i'm having an issue maybe its fixeable maybe not, the situation is the next, to avoid unnesesary calls to the getstream's api every time i need to instantiate a client from the sdk (server-side) i'm caching the object that results from new StreamChat and then setUser from the client (the fully connected client), the problem what i'm dealing with is the circular references inside the main client object, so i can cache it on my backend's memory but when i'm dealing with many clusters and doing process communications, i'm not able to send that object among them because it tries to stringify the json and the Converting circular structure to JSON error is thrown, is there any fix to this? I think replacing the circular references by my side wouldn't be the right way because i can screw up the whole library doing this, but maybe there's some patch by design to deal with this, because i want to avoid the latency gap everytime that the client connects to my backend and i make an instance for him to use in subsecuents requests, hence its more performant for me cache that object per client once and avoiding calling it multiple times, but it seems to work only with a in memory flat cache due to the nature of the error.

Remember i'm dealing with it backend side.

I know this issue might be a bit outside of the scope of the library but given the need to cache it to avoid latency from backend side and also avoid hitting many times getstream's servers, maybe there's some workaround that brings light to my problem.

I hope the problem is understood.

Thanks again.

When stream api send a notification?

Hi Team,

I implemented APNs and FCM for push notification for my react native app. It works fine and gets notifications in the foreground/background/when the app is closed. I tested it with APNs notification send utility and stream CLI push:test.

But, in the case of iOS, It seems the push notification is sent when the app is closed. When I test with stream CLI, it gets a push notification when the app is in the background too. I guess stream API starts sending a notification when a channel member seems offline or something.

How can I make my app getting a notification from stream API even though my app is in foreground or background? Any method or API to trigger to send a notification?

gz#10622

Messages with type 'channel.event' is not created when user accept invite

I found in React-Native component undocumented (in official docs) pretty cool feature - that we have special type of messages for member.add and member.removed events

 else if (message.type === 'channel.event') {
        const EventIndicator =
          this.props.eventIndicator || this.props.EventIndicator;
        return <EventIndicator event={message.event} />;

I wonder, is it possible to created the same messages for accept/reject events?

Filter last message by user

Is there any way from the sdk to filter (using queryChannels's method or query's method) the last message using a specific user id that created that message?

I mean i want to get the last message according to the user that's making the reques,t but the sdk is retrieving the last message no matter what user is making the request, that makes sense, but i would like to filter by a specific user id or using the inverse condition those messages whose don't belong to the user who's making the request, is there any way to accomplish this?

I couldn't see any examples in the test suite or the doc page using this use case.
Thanks

couple of TS issues

  • activeChannels does not exist in the typings file, but exists on the ChatContextValue's client.
  • users does not exist in the typings file, but exists on the ChatContextValue's client.state. Here are the properties on a user:
export interface IClientStateUser {
  readonly banned: boolean;
  readonly created_at: string;
  readonly id: string;
  readonly image: string;
  readonly last_active: string;
  readonly name: string;
  readonly online: boolean;
  readonly role: string;
  readonly updated_at: string;
}

You may want to account for the functions on the user, as well as indicating that more properties can be added (or at least add instructions for how => extending from the Stream User, e.g. interface ICustomUser extends IStreamUser).

  • setActiveChannel on ChatContextValue expects an event: React.SyntheticEvent<Element, Event> as its second parameter, but it works as expected without it. Should probably make this a optional (?) param.

Incorrect unread number in user object

I'm trying to display unread channels number on TabBar, but it turns out to be tricky

First, I try to get the number from client.user object. Which is

created_at: "2019-09-11T15:05:17.713231Z"
devices: (3) [{…}, {…}, {…}]
id: "fc64d57b-8f34-466f-b408-fc0daf80426b"
image: "https://stream-cloud-uploads.imgix.net/images/59012/2f1bf76f-bcb1-4096-885c-2ebfaec6a807.27815B66-5C1C-4C58-A13B-161DB5127D94.jpg?ro=0&s=0a46ded3b5e7b4919e7692d3ecf477ed"
invisible: false
last_active: "2019-10-10T09:10:01.843663549Z"
mutes: []
name: "frederikke olsen"
online: true
role: "user"
total_unread_count: 0
unread_channels: 0
unread_count: 0
updated_at: "2019-10-10T08:10:47.450972Z"
__proto__: Object

Which is not correct from my perspective. Bcs the following code:

const filters = {
    type: 'messaging',
    $or: [
      {
        invite: 'pending',
      },
      {
        invite: 'accepted',
      },
      {
        ownerId: chatClient.user.id,
      },
    ],
  };
  const user = useUser(chatClient.user);
  useEffect(() => {
    const check = async () => {
      let channels = await chatClient.queryChannels(
        filters,
        {},
        {
          limit: 100,
        },
      );
      const unread = channels.reduce(
        (prev, current) => prev + (current.countUnread() > 0 ? 1 : 0),
        0,
      );
      setTabBadge(componentId, unread);
    };
    check();
  });

gives 12 unread channels

Problem with sendFile method

Hello i'm having an issue when i try to upload a pdf, the size of the file is 10MB

this is the code:
async function sendFile() {
try {
const response = await channel.sendFile(fs.createReadStream('file.pdf'),'file.pdf');
console.log(response);
} catch(e) {
console.log(e)
}
}

The process is returning the following
{ FetchError: invalid json response body at https://chat-us-east-1.stream-io-api.com/channels/messaging/XXXXXXX/file?api_key=XXXXXX reason: Unexpected token E in JSON at position 0
at /Users/user/Desktop/react-stream-chat-nodejs/node_modules/node-fetch/lib/index.js:272:32
at process._tickCallback (internal/process/next_tick.js:68:7)
message:
'invalid json response body at https://chat-us-east-1.stream-io-api.com/channels/messaging/XXXXXX/file?api_key=XXXXXX reason: Unexpected token E in JSON at position 0',
type: 'invalid-json' }

It seems its returning a 400 Bad request according with some tests i did, but i don't know why its happening.
My node version is 10.16.0
Any idea?

Thanks

Invalid type "bool" set as the return type for function

hide(userId?: string, clearHistory?: bool): Promise<APIResponse>;

The line above is causing my code not to compile. It expects boolean as type and not bool. I see there's a mix of using boolean and bool type in this file.

Also making reference the links below.

  1. https://github.com/pmbanugo/angular-conversational-ui-tutorial/blob/1fac384de42373035101a6acf5151f286a6ac585/src/app/app.component.ts#L66

  2. https://github.com/pmbanugo/angular-conversational-ui-tutorial/blob/1fac384de42373035101a6acf5151f286a6ac585/src/app/app.component.ts#L68

The first one is an optional object but the way it is Typescript expects me to pass a third argument for chatClient.channel("commerce", "conversational-ui");.

The second one in the docs doesn't say that it requires parameters but typescript wants me to put a value for that. I can pass empty objects to make them work but the main blocker for me is the bool type used in the fyour type script definition

Reduce response type of setUser

Right now, it's a wrapper over Event which is quite unnecessary.

I also do not think it makes sense to say setUser returns a Event object; we should create a new response type ad-hoc (Event has way too many optional fields)

#211 (review)

Canβ€˜t find variable:Buffer

I'm using expo. For some reason the Buffer polyfill wasn't included in the build. I was able to fix it by installing buffer and adding the following line to node_modules/stream-chat/dist/browser.js
global.Buffer = global.Buffer || require('buffer').Buffer

Can't resolve isomorphic-ws

Apologies if this is not the right place, but I'm trying to understand why I'm getting this error when running tests (via karma/puppeteer/chromium)

ERROR in ./node_modules/stream-chat/dist/browser.es.js
--
153 | Module not found: Error: Can't resolve 'isomorphic-ws' in 'node_modules/stream-chat/dist'

The code simply import stream-chat.

import { StreamChat } from 'stream-chat';

This works fine when running in the browser on local dev, i.e. webpack-dev-server.

Adding isomorphic-ws explicitly to my package.json seems to fix the issue. But I fail to understand why I need to add it, since it's already included because it's specified in stream-chat-js dependencies (package.json and yarn.lock)

Is it because it's defined as an externalPackage in rollup? and since the browser version is basically not using the dist/compiled, it builds everything and that resolves isomorphic-ws just fine?

That's the only reasonable explanation I have, that something is wrong in the built version of stream-chat

I tried using this with heroku and one way or the other `ws` module is not found

I checked your pkg.json and ws was in there as a dependency, I don't know why it can't resolve itself when hosted with Heroku. But doing npm i ws fixed it.

FYI: this worked locally without having to install npm i ws.

log

Error: Cannot find module 'ws'
2019-06-20T07:45:36.010066+00:00 app[web.1]:     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
2019-06-20T07:45:36.010068+00:00 app[web.1]:     at Function.Module._load (internal/modules/cjs/loader.js:562:25)
2019-06-20T07:45:36.010074+00:00 app[web.1]:     at Module.require (internal/modules/cjs/loader.js:690:17)
2019-06-20T07:45:36.010076+00:00 app[web.1]:     at require (internal/modules/cjs/helpers.js:25:18)
2019-06-20T07:45:36.010078+00:00 app[web.1]:     at Object.<anonymous> (/app/node_modules/isomorphic-ws/node.js:3:18)
2019-06-20T07:45:36.010080+00:00 app[web.1]:     at Module._compile (internal/modules/cjs/loader.js:776:30)
2019-06-20T07:45:36.010082+00:00 app[web.1]:     at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
2019-06-20T07:45:36.010084+00:00 app[web.1]:     at Module.load (internal/modules/cjs/loader.js:653:32)
2019-06-20T07:45:36.010086+00:00 app[web.1]:     at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
2019-06-20T07:45:36.010087+00:00 app[web.1]:     at Function.Module._load (internal/modules/cjs/loader.js:585:3)

I checked the log, it's pointing to isomorphic which requires Node and ws installed https://github.com/heineiuo/isomorphic-ws#readme

Maybe update your readme to show we need ws to make this sdk work

updateUser does not update client.user

I update user profile picture using the following snippet, but the updated info does not reflect in client.user

export async function updateUser(user) {
  // if (chatClient.user)
  const res = await chatClient.updateUser({
    id: user.uid,
    name: user.displayName,
    image: user.photoURL,
  })
}

Typescript typing is broken in version 1.0.0

Following errors are generated when trying to compile a Typescript project after importing stream-chat:

ERROR in node_modules/stream-chat/types/stream-chat/index.d.ts(45,18): error TS2430: Interface 'MessageResponse' incorrectly extends interface 'Message'.
  Types of property 'mentioned_users' are incompatible.
    Type 'string[]' is not assignable to type 'User[]'.
      Type 'string' is not assignable to type 'User'.
node_modules/stream-chat/types/stream-chat/index.d.ts(98,8): error TS2304: Cannot find name 'OwnUser'.
node_modules/stream-chat/types/stream-chat/index.d.ts(105,3): error TS2300: Duplicate identifier 'type'.
node_modules/stream-chat/types/stream-chat/index.d.ts(109,3): error TS2300: Duplicate identifier 'type'.
node_modules/stream-chat/types/stream-chat/index.d.ts(303,41): error TS2304: Cannot find name 'Immutable'.
node_modules/stream-chat/types/stream-chat/index.d.ts(315,29): error TS2314: Generic type 'Promise<T>' requires 1 type argument(s).

I'm using Typescript 3.2

Direct Message: how to display the message receiver's name as channel name

I am currently creating the direct messaging feature using GetStream's One to One conversation. Right now I can only set a single name for the direct message channel. For example, A sent a message to B and the created channel between A and B is initially named to B. If, when A and B both enter the channel, I want A to see the channel name as B and B sees the channel name as A, how can I implement this?

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.