# Receiving inbound messages The app integration can receive inbound messages from an user, which will be sent to the bot to be processed asynchronously. The bot will process the user messages and create a response. Note: The response will be provided to the `messaging.performSend` operation from which you can send it back to the user using the external messaging service APIs. See [Sending](/docs/chatlayer/messaging/sending). The method `messaging.performReceive` will be called with 2 arguments. The first argument is the [sdk](/docs/chatlayer/actions/sdk-object) object and the second argument is the [bundle](/docs/chatlayer/actions/bundle-object) object. ```javascript const performReceive = (sdk, bundle) => { return [evt1, evt2] } ``` The `bundle.request` field contains the webhook request sent from the external messaging service. It contains the following fields: | Field | Description | | --- | --- | | `request.content` | The body of the request. If the content type of the request was set to `application/json` it will be transformed into an object; otherwise it will be a plain string. | | `request.method` | The HTTP method of the request. | | `request.query` | The parsed query string of the request. | | `request.headers` | The parsed headers of the request. | Your app's logic must process this request and return an array of messages or actions to be handled by the bot. The returned array can be empty if no processing is needed by the bot. ## Return format The follow section details the format that needs to be followed when returning a messages array to Chatlayer: ### Schema | Field | Description | Type | Required | | --- | --- | --- | --- | | `user` | Define user properties | [User Properties](#user-properties) | Yes | | `actor` | Define from who the message is coming [User Properties](#actor-properties) | Yes | | | `type` | Type of the message payload | message/action | Yes | | `message` | Message data. **Only required when type is message** | [Messages](#messages-schema) | No | | `action` | Action data. **Only required when type is action** | [Actions](#actions-schema) | No | | `timestamp` | Timestamp the message was generated in number of milliseconds elapsed since January 1, 1970 00:00:00 UTC. If not provided, the time at which the message was received will be used | number | Yes | #### User properties | Field | Description | Type | Required | | --- | --- | --- | --- | | `id` | User id used to differentiate from other conversations | string | Yes | | `firstName` | First name of the user | string | No | | `lastName` | Last name of the user | string | No | | `preferredLanguage` | Preferred language for the conversation | string | No | #### Actor properties | Field | Description | Type | Required | | --- | --- | --- | --- | | `type` | Type of entity the message is coming from | "user" | Yes | ### Example ```javascript // a text message const message = { user: { id: "user_id", firstName: "John", lastName: "Doe", preferedLanguage: "en" }, actor: { type: "user" }, type: "message", message: { messageType: "text", text: "Hi from user", }, timestamp: 1646415058102 } return [message] ``` ## Messages schema Note: In the following schemas we will only describe the actual message format and omit the user data, actor, timestamp, and other fields. ### Text | Field | Description | Type | Required | | --- | --- | --- | --- | | `messageType` | Type of the message | "text" | Yes | | `text` | Text contained in the message | string | Yes | ```json { "message": { "messageType": "text", "text": "Hey bot, how are you doing?" } } ``` ### Postback Postback is used when a user clicks on a button or some other response trigger. The payload provided is usually base64 encoded data. ```json { "message": { "messageType": "postback_v2", "payload": "jkhasiopwqnm12ikonhbio", "title": "Button title" } } ``` ### Upload Upload can be used when the user sends an uploaded file in the bot. ```json { "message": { "messageType": "upload", "url": [ "https://upload.com/image1", "https://upload.com/image2" ] } } ``` ## Actions schema Besides the messaging capabilities, we can also trigger certain actions by returning an action object. ### Handover to bot/user The value of `action.data.handover.to` can be `bot` or `agent`: | Value | Description | | --- | --- | | `bot` | Onload the conversation to the bot again. | | `agent` | Offload the conversation to the agent (the bot will not reply anymore after this). | ```json { "type": "action", "action": { "type": "conversation_handover", "data": { "handover": { "to": "bot" } } }, "timestamp": 1646415058102, "actor": { "type": "user" }, "user": { "id": "user_id" } } ``` ## Altering the session Each conversation has session data that can be read in the bot. You can add session data to the conversation by specifying a session object. The names you give to your object keys are only for your organization and do not matter to Chatlayer. ```javascript const message = { user: { id: "user_id", }, actor: { type: "user" }, type: "message", message: { messageType: "text", text: "Hi from user", }, session: { myKey: { foo: "bar" } }, timestamp: 1646415058102 } ```