---
# System prepended metadata

title: Chat socket

---

# Chat socket

Client example code
```javascript
const io = require('socket.io-client');
const jwt = require('jsonwebtoken');

const user1 = '406525501113368576';
const user2 = '408503898509148160';

function createConnection(socketServer, chatToken) {
  const socket = io(socketServer, {
    transports: ['websocket'],
    query: { token: chatToken },
  });

  // client-side
  socket.on('connect_error', (err) => {
    console.log(err.message); // prints the message associated with the error
  });

  socket.on('connect', () => {
    console.log(`create connection to ${socketServer} successfully`)

    socket.emit('createMessage', {
      channel_id: `${user1}-${user2}`,
      image_urls: ['http://cdn.piktina.com/123.jpg'],
      message: 'description for images hahah',
      type: 'image',
      client_gen_id: Date.now(),
    }, (err, data) => console.log(err, data));

    // socket.emit('updateMessage', {
    //   channel_id: `${user1}-${user2}`,
    //   created_at: 1630057791871,
    //   type: 'text',
    //   message: 'Hello world', // new message
    // }, (err, data) => console.log(err, data));

    socket.emit('getOnlineStatus', {
      user_ids: [user1, user2],
    }, (err, data) => console.log(err, data));

    socket.emit('isTyping', {
      channel_id: `${user1}-${user2}`,
      to_user_ids: [user1, user2],
    }, (err, data) => console.log(err, data));

    socket.emit('read', {
      channel_id: `${user1}-${user2}`,
      to_user_ids: [user1, user2],
    }, (err, data) => console.log(err, data));
  });

  const events = ['error', 'disconnect', 'createMessage', 'isTyping', 'read'];
  events.forEach((event) => {
    socket.on(event, (data) => console.log('received event: ', event, data));
  });
}

const socketServer = process.env.SOCKET_SERVER_URL || 'https://chat-socket.default:1337/';
const jwtSecret = process.env.JWT_SECRET || 'secret';
const chatToken = jwt.sign({ sub: user1, iss: 'chat' }, jwtSecret);
createConnection(socketServer, chatToken);
```


# Events (launch version 0.1)

When client emit an event to server, if there is any error, server will return error in callback function by calling `callback(err, data)`, format of error is 
```json
{
    "error": "Type of error", // Iternal Server Error, Bad Request
    "message": "Error message show to user"
}
```

### Example code on client and server
```javascript
// client code
socket.emit('eventName', data, (err, response) => {
    if(err) console.log(err.message)
})


// server code
socket.on('eventName', (data, callback) => {
    //check data is valid
    
    if(!isValid(data)){
        if(callback) callback({error: 'Bad Request', message: 'Empty Data'}, null)
        return
    }
    
    
    // processing data
    let {response, err} = processing(data)
    if(err){
        if(callback) callback(err, null)
        return
    }
    callback(null, response)
})


```



## send a message
- Client emit event / Server on event: `createMessage`
- Payload (client -> server)
    - send text message
        ```json
        {
            "channel_id": "ch1",
            "type": "text",
            "message": "Hello",
            "client_gen_id": 2763648234,
            "metadata": {"field": "value"}
        }
        ```
    - send images
        ```json
        {
            "channel_id": "ch1",
            "image_urls":["http://cdn.chotot.com/123.jpg"],
            "message": "description for images",
            "type": "image",
            "client_gen_id": 2763648234,
            "metadata": {"field": "value"}
        }
        ```
     - send attachment
        ```json
        {
            "channel_id": "channel1",
            "message": "hello world",
            "image_urls": [],
            "type": "attachment",
            "attachment": {
                "id": "123",
                "type": "minicv",
                "data": {
                    "key": "value"
                    // flexible fields
                }
            }
            "client_gen_id": 2763648234,
            "metadata": {"field": "value"}
        }
        ```
- Callback response
    - Success Response
        ```json
        {
            "channel_id": "ch1",
            "type": "text",
            "message": "Hello",
            "client_gen_id": 2763648234,
            "sender_id": "user1",
            "created_at": 2763649234
        }
        ```
    - Error
        ```json
        {
            "error": "Bad Request",
            "message": "Missing message type"
        }
        ```
- Server emit event/Client on event: `createMessage`
- Payload(server -> client)
    ```json
    {
        "channel_id": "ch1",
        "type": "text",
        "message": "Hello",
        "client_gen_id": 2763648234,
        "sender_id": "user1",
        "created_at": 2763649234
    }
    ```




## get online status
- Client emit event / Server on event: `getOnlineStatus`
- Payload (client -> server)
```json
{
   "user_ids": ["user1", "user2", "user3"]
}
```
- Callback response
    - Success Response
    ```json
    [
        {"user_id": "user1", "is_online": true, "last_online_at": 2763649234},
        {"user_id": "user2", "is_online": false, "last_online_at": 2763649234},
        {"user_id": "user3", "is_online": false, "last_online_at": 0}
    ]
    ```
    - Error
    ```json
    {
        "error": "Bad Request",
        "message": "user_ids is not an array"
    }
    ```


## typing
- Client emit event / Server on event: `isTyping`
- Payload (client -> server)
    ```json
    {
        "channel_id": "ch1",
        "to_user_ids": ["user2", "user3"]
    }
    ```
- Callback response
    - Error
    ```json
    {
        "error": "Bad Request"
        "message": "channel_id is not valid"
    }
    ```
- Server emit event/Client on event: `isTyping`
- Payload(server -> client)
    ```json
    {
        "channel_id": "ch1",
        "user_id": "user1"
    }
    ```
    
    
## read
- Client emit event / Server on event: `read`
- Payload (client -> server)
    ```json
    {
        "channel_id": "ch1",
        "to_user_ids": ["user2", "user3"]
    }
    ```
- Callback response
    - Success
    ```json
    {
       "unread_count": 11
    }
    ```
    - Error
    ```json
    {
        "error": "Bad Request"
        "message": "channel_id is not valid"
    }
    ```
- Server emit event/Client on event: `read`
- Payload(server -> client)
    ```json
    {
        "channel_id": "ch1",
        "user_id": "user1",
        "last_read_at": 2763649234,
    }
    ```
    
## watchOnlineStatus
- Client emit event / Server on event: `watchOnlineStatus`
- Payload (client -> server)
    ```json
    {
        "channel_ids": ["channel_id_1", "channel_id_2", "channel_id_3"],
    }
    ```
- Server emit event/Client on event: `refreshOnlineStatus`
- Payload(server -> client)
    ```json
    {
        "online_channels": ["channel_id_1", "channel_id_2"]
        
    }
    ```

## update a message
- Client emit event / Server on event: `updateMessage`
- Payload (client -> server)
    ```json
    {
        "channel_id": "ch1",
        "message_created_at": 2763649234,
        "message": "Hello world" // new message
    }
    ```
- Callback response
    - Error
    ```json
    {
        "error": "Not found",
        "message": "Message not found"
    }
    ```
- Server emit event/Client on event: `updateMessage`
- Payload(server -> client)
    ```json
    {
        "channel_id": "ch1",
        "type": "text",
        "message": "Hello",
        "client_gen_id": 2763648234,
        "sender_id": "user1",
        "message_created_at": 2763649234
    }
    ```


## delete a message
- Client emit event / Server on event: `deleteMessage`
- Payload (client -> server)
    ```json
    {
        "channel_id": "ch1",
        "message_created_at": 2763649234,
    }
    ```
- Callback response
    - Error
    ```json
    {
        "error": "Not found",
        "message": "Message not found"
    }
    ```
- Server emit event/Client on event: `deleteMessage`
- Payload(server -> client)
    ```json
    {
        "channel_id": "ch1",
        "sender_id": "user1",
        "message_created_at": 2763649234
    }
    ```

## create channel
 - Client emit event: `createChannel`
 - Emit payload:
    ```json
    {
      "to_user_id": "userId",
      "message": "I can pay $500", // optional
      "message_type": "text", // optional
      "channel_type": "direct" 
    }
    ```
 - Callback response:
    ```json
    {
        "channel_id": "channel1"
    }
    ```

## list channels

  - Client emit event: `listChannels`
  - Emit payload:
      ```json
      {
          "params": {
              "before_ts": "1656749676347", // default now (milliseconds)
              "order": "desc" // default desc
              "limit": 10,
          }
      }
      ```
  - Callback repsonse:
      ```json
      [
        {
            "channel_id": "channel_1",
            "unread_count": 12,
            "last_message": "hello",
            "last_message_type": "buyer",
            "last_message_created_at": 1610693806662,
            "channel_name": "user2", // display as name for channel
            "channel_avatar": "https://cdn.chotot.com/user2.jpg", // display as avatar for channel
            "is_muted": false,
        },
        ...
      ]
      ```
      
## get channel detail
  - Client emit event: getChannel
  - Emit payload:
    ```json
    {
        "channel_id": "channel_id1"
    }
    ```
  - Callback response:
    ```json
    {
      "channel": {
        "channel_id": "channel_1",
        "channel_name": "name of this chat room, this can be ad title",
        "channel_avatar": "http://cdn.chotot.com/useravatar.jpg",
        "unread_count": 12,
        "last_message": "hello",
        "last_message_type": "buyer",
        "last_message_created_at": 1610693806662,
        // status of :channel_id for :user_id
        "status": "blocked", // banned, others_banned,...
        "status_text": "you are blocked by user2",
        "is_muted": false, // to show toggle button mute/unmute
      },
      "users": [
        {
          "full_name": "abc",
          "avatar": "https://cdn.piktina.com/user1.jpg",
          "metadata": {"phone":"0123","email":"xyz@gmail.com"},
          "user_id": "user1",
          "last_received_at": 1610693806662, // not yet available
          "last_read_at": 1610693806665,
          "joined_at": 1610693806662,
          "role": "seller"
        },
        {
          "full_name": "abcd",
          "avatar": "https://cdn.piktina.com/user2.jpg",
          "metadata": {"phone":"0123","email":"xyz@gmail.com"},
          "user_id": "user2",
          "last_received_at": 1610693806662, // not yet available
          "last_read_at": 1610693806665,
          "joined_at": 1610693806662,
          "role": "seller"
        }
      ] 
    }
    ```
    
<!-- ## update total unread count
 - Server emit event: `updateTotalUnreadCount`
 - When:
     - on success socket connection.
     - on read event
     - on new message.

 - Emit payload:
    ```json
    {
      "unread_count": 10
    }
    ``` -->