How to make a TalkJS chat inbox with filterable topics


Tags: chat, api, javascript, webdev
Published: 2021-04-30 13:45:13

We will be creating a chat inbox with the [TalkJS Chat API](https://talkjs.com/), that will allow you to programmatically filter by different topics, giving you complete control over which chat conversations get shown to a user. In TalkJS these filters are known as feed filters.


### What is a TalkJS chat inbox?

The TalkJS Inbox is our most full-featured user interface component. It shows all the conversations you're part of on the left and the selected conversation on the right. You can create an Inbox through [Session.createInbox](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Session.html#Session.createInbox) and then call [mount](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Inbox.html#Inbox.mount) to show it. It's designed to act as the messaging center of your app, and it usually lives on its own page. 


### What are feed filters?

The left part of the Inbox is called the Feed. You can filter which conversations are shown based on multiple properties. For example, you can filter the list of conversations to only show conversations that are unread, conversations that the user can write in, or filter conversations by a custom parameter such as a category or topic.

See [ConversationPredicate](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Other_interfaces.html#ConversationPredicate) for all available filtering options.

#### Feed filter object structure

For our example, want to use the feed filter in conjunction with our custom attribute. The rules for using the optional custom property with `setFeedFilter` are as follows:

- Only select conversations that have particular custom fields set to particular values.
- Every key must correspond to a key in the custom conversation data that you set (by passing `custom` to [ConversationBuilder.setAttributes](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/ConversationBuilder.html#ConversationBuilder.setAttributes)).
- It is not necessary for all conversations to have these keys.
- Each value must be one of the following:
  - A string, equal to `"exists"` or `"!exists"`
  - A 2-element array of `[operator, operand]` structure. The operand must be either a string or an array of strings (for the oneOf operators). Valid operators are: `"=="`, `"!="`, `"oneOf"`, and `"!oneOf"`.

For example, assuming you have set a category custom field on your conversations:


```javascript
// only show conversations that have no category set:
{ custom: { category: "!exists" } }

// only show conversations of category "shoes"
{ custom: { category: ["==", "shoes"] } }

// only show conversations either category "shoes" or "sandals"
{ custom: { category: ["oneOf", ["shoes", "sandals"] ] } }

// only show conversations about shoes that are marked visible. 
// this assumes you also have a custom field called visibility 
{ custom: { category: ["==", "shoes"], visibility: ["==", "visible" ] } }
```

#### Examples of using feed filters

You can set the feed filter of an inbox by using the method [inbox.setFeedFilter](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Inbox.html#Inbox.setFeedFilter). Alternatively, you can pass in a feedFilter when creating the inbox. 

For example, to hide read conversations, use:

`inbox.setFeedFilter({ hasUnreadMessages: true })`.

To show everything (ie. to disable the filter), use an empty object:

`inbox.setFeedFilter({})`.

To show only the conversations that have a custom attribute called `category`, where `category` is equal to `shoes`:

`inbox.setFeedFilter({ custom: { category: ["==", "shoes"] } })`

You can also use `setFeedFilter` in an event handler, or in response to when an input value is changed. This allows `setFeedFilter` to be used dynamically, in direct response to the user’s actions. For example:

```javascript
const button = document.getElementById("filter-btn"):
	button.addEventListener("click", function() {
	inbox.setFeedFilter({custom: {category: ["==", "shoes"]}});
});
```

With this information regarding feed filters on hand, let us now create our inbox that can filter based on custom attributes.


### Adding TalkJS to your app and Starting a Conversation

To demonstrate the use of feed filters we will be creating two different conversations. 

The first conversation will take place between Alice and John and will be a generic question about a random product. 

The second conversation will take place between Alice and Paul, where the conversation will be about shoes, a popular product at our imaginary store.

Use our comprehensive [Getting Started guide](https://talkjs.com/docs/Getting_Started/index.html) to create your users and conversation data. Our scenario requires two additional steps that are not included in the Getting Started guide:

1. We need to create an additional user. You can copy and paste an existing user and simply change the `id` value
2. We will need to tweak the conversation data shown here to include our custom attribute, which will be used to filter our inbox.


```javascript
const conversation = session.getOrCreateConversation(Talk.oneOnOneId(me, otherGeneric));
conversation.setAttributes({subject: "Generic Question"});
conversation.setParticipant(me);
conversation.setParticipant(otherGeneric);

const shoeConversation = session.getOrCreateConversation(Talk.oneOnOneId(me, otherShoes));
shoeConversation.setAttributes({subject: "Shoes Question"});
shoeConversation.setAttributes({custom:{ category: "shoes" } });
shoeConversation.setParticipant(me);
shoeConversation.setParticipant(otherShoes);
```

For this example, I have our imaginary user Alice set to `me`, John set to `otherGeneric`, and Paul set to `otherShoes`.

Note the use of the method, [setAttributes](https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/ConversationBuilder.html#ConversationBuilder.setAttributes), which we use to tag the `shoesConversation` with the key `category: shoes`. This is how we can set the topic of different conversations. 

Now that we have our conversations set up along with the attribute that will be used in conjunction with our feed filter, we can move onto the next step.


### Creating our Inbox that uses Feed Filters

Add the following code to your project, continuing on from our previous example.

```javascript
const inbox = session.createInbox({selected: conversation});
inbox.mount(document.getElementById("talkjs-container"));
```

We have not introduced our feed filter yet. First, we will populate both conversations with some text. 

The use of `selected: conversation` will launch our inbox with our first conversation selected, the conversation between `me` and `otherGeneric` (Alice and John). If we did not do this, we would be shown a message saying we have not started any conversations yet.

After adding the code above, run your program! 

You should have the ability to add a message:

![First conversation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6b3dv0gab78ychhulowj.png)

After adding a message to this conversation, go back to your code. 

Replace `const inbox = session.createInbox({selected: conversation});` 

with `const inbox = session.createInbox({selected: shoeConversation});`

Run your program again! As before you should be presented with a conversation, this time with Paul. As before, add some text to this conversation.

![Second conversation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qeq0r6g14ewilqrwbj46.png)

We now have two separate ongoing conversations. To see this in action, go back to your code and replace `const inbox = session.createInbox({selected: shoeConversation});` with `const inbox = session.createInbox();`. You should now see both conversations with the option to switch between them.

![Both conversations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x86l8jwf3m4unt16ojnr.png)

We have now created our inbox and populated it with some conversations. Time to create our filter that will allow us to filter between our categories. Remember for this example we created the category of shoes and added it to our second conversation. With our custom attribute already set up, we can simply add the following line of code:


```javascript
inbox.setFeedFilter({ custom: { category: ["==", "shoes"] } });
```

This makes our final code look like the following:

```javascript
const inbox = session.createInbox();
inbox.setFeedFilter({ custom: { category: ["==", "shoes"] } });
inbox.mount(document.getElementById("talkjs-container"));
```

Our inbox will now only show conversations that have category of "shoes".

There you have it! The application of our filter was successful, we can now filter which conversations are shown in our inbox based on a specific topic or category.