> ## Documentation Index
> Fetch the complete documentation index at: https://docs.softr.io/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Enable Peer-to-Peer Chat?

> Creating a peer-to-peer to chat using Softr’s and Airtable’s native functionalities.

Using a peer-to-peer (or one-on-one) chat, you can let your users initiate private chats with other users. One of the options to add such a functionality is integrating third-party tools such as [AtomChat](/integrations/etS18kJqm1fuD58KCsjC3z/atomchat/bTiJ3zbePgQMwcB9SUYY93). But it’s also possible to build a peer-to-peer chat using just Softr and Airtable. Let’s see how.

## Chat functionality overview

We are going to break down [Cole Fortman](https://www.softr.io/softr-expert-profile/cole-fortman/r/recdRQxd3KleHO27i)’s video that showcases an application where each user has access to the list of all the members in the application and can initiate a chat with any of the members. Users also have access to all the past conversations and can continue from where they’ve left.

<iframe src="https://www.youtube.com/embed/YoUxZcv5QCo?rel=0" width="100%" height="500px" title="YouTube video" />

Our chat application contains three users: Bob Ross, Tony Stark, and Bruce Wayne. The recording below shows how we log in with Bob Ross’s account, navigate to **All Members**, and initiate a chat with Tony Stark.

<Frame caption="Initiating a conversation between users">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image1.gif?s=5f0f4fe81a6e68c70db7bc4ca9c65954" alt="Initiating a conversation between users" width="1280" height="720" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image1.gif" />
</Frame>

There’s also a **Conversations** section, where each user can see the list of all the conversations he/she has participated in, open those, and continue chatting.

<Frame caption="Accessing the “Conversations” section">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image2.gif?s=78ba5cc734877a05213d4dd5779f0d9d" alt="Accessing the “Conversations” section" width="2876" height="1412" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image2.gif" />
</Frame>

We are first going to look into the Softr side of the application to see how each page is set up. Then, we will take a closer look into the Airtable base that serves as a [data source](/4230abecf813402aa2926466c313290a?pvs=25) for the app.

## Softr setup

### Home page with user profile

First comes the home page, where we have a [List Details](/building-blocks/vikC2AWEpQGkZd4jGyoVxo/item-details-block-/4bE8XaFbJp45wkAwuWiz8f) block that is connected to the **Users** table on Airtable. A [conditional filter](/user-groups-and-permissions/3oA6AaFzUiePs2sW2TpYrF/conditional-filters/mDnn7jnpPiYmJcT99jpt7m) is applied to show each user his/her own details.

<Frame caption="A details block with a conditional filter applied">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image3.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=0a6bccfba2e73ccf08274fb52ea3cabb" alt="A details block with a conditional filter applied" width="2702" height="1040" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image3.png" />
</Frame>

The block shows such user details as name and email as well as **Total Conversations** and **Total Conversations Started** fields from Airtable, which we’ll explore in greater detail when we proceed to the Airtable setup.

<Frame caption="Details block content mapping">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image4.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=1cb0f74c370f3dbf727c084bcef79a39" alt="Details block content mapping" width="840" height="1176" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image4.png" />
</Frame>

### All Members

Next, we have the **All Members** page, which is a [List block](/building-blocks/vikC2AWEpQGkZd4jGyoVxo/list-block/pQhPYuA28VXr5tLLFBcbCU) that shows the list of all users and has a **View Profile** button that opens the **Member Details** page, which we’ll discuss next.

<Frame caption="All members list linking to Member Details">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image5.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=46701791f7556ebfbc9ae452be692837" alt="All members list linking to Member Details" width="2658" height="1074" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image5.png" />
</Frame>

### Member Details

Similar to the Home page, the **Member Details** page contains a List Details block that shows some user info. But it also has a [Customizable Form](/building-blocks/vikC2AWEpQGkZd4jGyoVxo/advanced-form-features/jCim5VWZePgZuaRsUZBnpG) block that consists of a **Start Conversation** button and sends two hidden field values.

<Frame>
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image6.gif?s=414e8e8a43d390b0bca12275ab255c97" alt="Notion image" width="2876" height="1412" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image6.gif" />
</Frame>

Basically, the form creates a new record in the **Conversations** table on Airtable, passing the [Record ID](https://support.airtable.com/docs/finding-airtable-record-ids) of the logged-in user who is initiating the conversation as well as the the **Recipient user’s Record ID**, which is the ID of the current record (user profile) that’s opened in the **Member Details** page.

When the form is submitted, the user is taken to the **All** **Conversations** page (through “On Form Submit” Action), where he/she can already view and access the newly-created conversation. Now, let’s see how the **All** **Conversations** page is configured.

### All Conversations

The **All Conversations** page contains an [Inbox block](/building-blocks/vikC2AWEpQGkZd4jGyoVxo/layout-inbox/9cbSp8Mvwru9g6L6RM4uJ5) that is connected to the **Conversations** table on Airtable, which contains all the conversations initiated between users.

<Frame caption="All Conversations list">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image7.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=2d33dd0ce7428fd7d0428f3f766dd777" alt="All Conversations list" width="2664" height="1168" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image7.png" />
</Frame>

In order for users to have access to their own conversations only, a [conditional filter](/user-groups-and-permissions/3oA6AaFzUiePs2sW2TpYrF/conditional-filters/mDnn7jnpPiYmJcT99jpt7m) is applied that shows only those conversations where the logged-in user is either a starter or a recipient of the conversation.

<Frame caption="Conditional filter applied on the conversations list">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image8.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=863470dcb95055d43700bf5727b11715" alt="Conditional filter applied on the conversations list" width="854" height="1266" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image8.png" />
</Frame>

Each conversation contains **Recipient User’s Profile Picture**, the **Conversation ID** (displays the names of the starter and recipient users), L**ast Message** (displays time and date of the last message sent within the given conversation), T**otal Conversation Messages** (calculates the total number of messages exchanged within the given conversation), and an **Open Conversation** button that opens the page with the actual conversation (**Conversation Details** page).

<Frame caption="All Conversations block setup">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image9.gif?s=bb98e7998acd82f847b88b118a93f546" alt="All Conversations block setup" width="2876" height="1412" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image9.gif" />
</Frame>

We’ll take a closer look at how these fields are set up in Airtable in a bit. Now, let’s navigate to the **Conversation Details** page to see how it’s configured.

### Conversation Details

The first block is a List Details that’s linked to the **Conversations** table to indicate which conversation the user is currently on.

<Frame caption="The List Details block with conversation ID">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image10.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=a3acc83a6b6766132e8b6e66ac11adcd" alt="The List Details block with conversation ID" width="2668" height="1054" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image10.png" />
</Frame>

The block displays the **Conversation ID** field, which is simply a combination of the conversation starter and recipient names.

<Frame caption="Displaying Conversation ID">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image11.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=ac07377ac3300282f23084ace5b99c2c" alt="Displaying Conversation ID" width="860" height="966" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image11.png" />
</Frame>

Next comes a [Comments](/697c2ac57a3c40a8b5c14cc7bcf8947c) block where the messaging happens. It is connected to the **Messages** table on Airtable.

<Frame caption="Comment block">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image12.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=8576350785b5507fdf0e6c9c7a0d6277" alt="Comment block" width="2666" height="1068" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image12.png" />
</Frame>

As you can see below, the block sends such data as **Commenter ID** (the name of the person initiating the chat), the [record ID](https://support.airtable.com/docs/finding-airtable-record-ids) of the conversation where the messaging happens (**Current record** parameter), the message body text (**Comment field** parameter), as well as the date.

<Frame caption="Comment block mapping">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image13.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=7c9e4d0fff1772562d7c505740f6a73a" alt="Comment block mapping" width="832" height="784" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image13.png" />
</Frame>

That’s it for the Softr-side setup, now let’s navigate to the Airtable base of the project and see how the tables we’ve just been discussing are organized.

## Airtable setup

### Users

First comes the **Users** table, where all the user data is stored. It contains such fields as **Name**, **Profile Picture**, and **Email**. Further on, we have three [linked records](https://www.airtable.com/guides/build/connect-data-with-linked-records):

* **Conversations Started:** links to the **Conversations** table, where each conversation record contains data on the user who has started the conversation. As you might remember, this was collected through a hidden field in the **Start Conversation** form.

* **Conversations Received:** links to the **Conversations** table, where each conversation record contains data on the conversation recipient user). This was collected through a hidden field in the same form as well.

* **Messages:** links to the **Messages** table, showing the record ID of the messages that the given user has sent. As we saw in the Softr setup section, when a message was created by the user through the Comments block, it stored the **Commenter ID** in Airtable.
  <Frame caption="Users table">
    <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image14.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=9ba202cccb515d5b23f9386b6ce73778" alt="Users table" width="2288" height="846" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image14.png" />
  </Frame>

Then, we have the **Total Conversations Started** and **Total Conversations Received** fields, which calculate the number of conversations based on the **Conversations Started** and **Conversations Received** fields that we just reviewed. The last **Total Conversations** field just sums up the value from the two previous fields through a formula.

<Frame caption="Total conversations">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image15.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=139ad232b26c8f28234bcebb17f02be2" alt="Total conversations" width="1614" height="984" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image15.png" />
</Frame>

### Conversations

<Frame caption="Conversations table">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image16.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=985a76d1cb05aa7e1ca9e299ec37b075" alt="Conversations table" width="1974" height="960" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image16.png" />
</Frame>

Here, we have the **Conversation Starter User** and **Recipient User** fields (linked records from the **Users** table) and the **Conversation ID** field, which is a [concatenation](https://support.airtable.com/docs/formula-field-reference#text-operators-and-functions) of these two fields. Also, there’s the **Messages** field, which is a linked record from the **Messages** table (as we’ve already discussed, each message is submitted under a specific conversation and is automatically linked to that conversation).

Then, we have a few fields that [look up](https://support.airtable.com/docs/lookup-field-overview) user data from the Users table.

<Frame caption="User field lookups">
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image17.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=eeea199ecbe1bcffce8555c0b74dbafb" alt="User field lookups" width="2498" height="1120" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image17.png" />
</Frame>

Lastly, there are a few more fields that calculate things like **Total Messages** or **Conversation Age** as well as indicate the **Record ID** of the record through the [RECORD\_ID () formula](https://support.airtable.com/docs/finding-airtable-record-ids).

### Messages

The last table we have in this base is the **Messages** table. Here, we store all the messages linked to their corresponding conversations (**Conversations** field) and senders (the **ID** field).

<Frame>
  <img src="https://mintcdn.com/softr-2b8a27e1/0TOUhZGdnWj5pNUQ/how-to-guides/images/how-to-enable-peer-to-peer-chat/image18.png?fit=max&auto=format&n=0TOUhZGdnWj5pNUQ&q=85&s=7584f70b4242fdf1b7ae4dea0a88b44c" alt="Notion image" width="2466" height="520" data-path="how-to-guides/images/how-to-enable-peer-to-peer-chat/image18.png" />
</Frame>

And there you have it. We hope that we’ve been able to provide sufficient detail to let you recreate this (or a similar) setup on your side. Enjoy!
