---
source_url: https://www.pubnub.com/docs/general/messages/type
title: Message Types
updated_at: 2026-06-04T11:10:18.987Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Message Types

In many use cases, you define descriptive, predefined categories of messages. This helps your app grow without being limited by basic messaging structures. You can also apply conditional processing to messages of the same type, for example:

* Text messaging.
* Text messaging with language translations embedded in the message.
* Hosted image/file messages, where the file is static and the URL is referenced.
* Video files that contain thumbnails and loading icons.
* Polling and questionnaire messages where you also supply predefined answers.
* Invitations to new channels for private or group chat.
* Action messages for the app to do something for this user.
* Session data linked to a third-party such as video service or streaming event.

## Custom vs. internal message type

A message can include two type fields:

* Integer `messageType` refers to the internal PubNub type of the message.
* String `custom_message_type` refers to a business-specific label or category to messages, signals, and files.

### Server response

Every message sent through PubNub has its internal integer message type returned as `type` in the subscribe payload. On the contrary, a custom message type string (returned as `cmt`) is only returned when it has been explicitly set beforehand. The `cmt` value in the returned server response is the same as the value of `custom_message_type` (name may vary across SDKs) used during a publish.

| Internal message type | Description |
| --- | --- |
| `0` | Regular message |
| `2` | App Context event |
| `3` | Message Actions event |
| `4` | File message |

When working with historical messages, you can choose to return the type and the custom message type in the response by enabling the `include_custom_message_type` flag (name varies across SDKs). For more information on fetching historical messages and how those parameters are returned, refer to [Retrieve messages](https://www.pubnub.com/docs/general/storage#retrieve-messages).

###### Use internal types to distinguish delivery modes

The integer `messageType` differentiates what PubNub delivered. Type `0` is a regular message, type `4` is a [file message](https://www.pubnub.com/docs/general/files) with associated file metadata. When retrieving messages from [Message Persistence](https://www.pubnub.com/docs/general/storage#retrieve-messages), use this field to route each entry to the appropriate display logic in your app.

:::note Custom message type not present in payload
If you don't set the `custom_message_type` parameter during a publish, it is not present in the subscribe or history payloads.
:::

## Descriptive message types

Consider these three messages:

* `{payload: “Hello I am a Message"}`
* `{payload: "https://cdn.app/your/image/here.png"}`
* `{payload: "https://cdn.app/your/video/here.mp4"}`

Because of the way these messages are constructed, you may run into a number of problems while trying to interpret their payloads in your app. Should you just scan for text? Should you check if every message starts with `https`? Should you look for `.fileType` at the end of each message?

You can make your app easier to expand upon by including message types in the publish call. Making types more descriptive also makes it easier to interpret these messages later on.

| Generic payload | Descriptive payload |
| --- | --- |
| `{payload: “Hello, I am a message"}` | `{message:"Hello, I am a Message"}` with `custom_message_type` set to `text` |
| `{payload: "https://cdn.app/your/image/here.png"}` | `{full:"https://cdn.app/your/image/here.png", thumbnail:" https://cdn.app/your/image/here_thumbnail.png"}` with `custom_message_type` set to `image` |
| `{payload: "https://cdn.app/your/video/here.mp4"}` | `{url:"https://cdn.app/your/video/here.mp4", thumbnail:"https://cdn.app/your/video/here_thumbnail.png"}` with `custom_message_type` set to `video` |

When your app receives these kinds of messages, it can process them differently displaying text, images and videos according to their respective types.

:::tip Future-proof message types
You can add fail-safe measures into your app. If you introduce new message types, older versions of your app can prompt users to upgrade to unlock the features the new message types provide.
:::

Check out these examples of publishing a **Hello World!** message with the `custom_message_type` parameter set to `text-message`:

###### Java

```java
pubnub.publish()
    .message("Hello World!")
    .channel("my_channel")
    .customMessageType("text-message")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

###### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {"Hello World!"},
    custom_message_type: "text-message"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

###### Kotlin

```kotlin
pubnub.publish(
    message="Hello World!",
    channel = "my_channel",
    custom_message_type = "text-message"
).async { result, status ->
    if (!status.error) {
        println("Publish timetoken ${result!!.timetoken}")
    }
    println("Status code ${status.statusCode}")
}
```

###### Objective-C

```objectivec
self.client.publish()
    .message(@"Hello World!")
    .channel(@"my_channel")
    .customMessageType(@"text-message")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

###### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message("Hello World!")
                ->customMessageType("text-message")
                ->meta(["name" => "Alex"])
                ->sync();
```

###### Python

```python
def publish_callback(result, status):
  if status.isError:
    print status.statusCode
  elif
    print result.timetoken

pubnub.publish()\
  .channel("my_channel")\
  .message({"Hello World!"})\
  .custom_message_type("text-message")\
  .pn_async(publish_callback)
```

###### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: ["Hello World!"],
  customMessageType: "text-message"
){ result in
  switch result {
    case let .success(response):
      print("succeeded: \(response)")

    case let .failure(error):
      print("failed: \(error.localizedDescription)")
  }
}
```

## Custom message type

Like we showed before, the optional string parameter `custom_message_type` (name may vary across SDKs) in the Publish and Files APIs allows you to add business-specific label or category to messages, signals, and files.

You can use this parameter to easily filter, group or apply conditional logic based on the value of the `custom_message_type` parameter. Refer to [Publish with type in payload](https://www.pubnub.com/docs/general/channels/subscribe-filters#publish-with-type-in-payload) and [Publish with type in metadata](https://www.pubnub.com/docs/general/channels/subscribe-filters#publish-with-type-in-metadata) for more information on filtering by custom message type.

###### Add server-side filtering to message types

Custom message types work with [subscribe filters](https://www.pubnub.com/docs/general/channels/subscribe-filters#message-type-filtering) to control which messages reach each subscriber. By assigning descriptive types when you publish, subscribers can filter at the server level rather than discarding messages client-side.

Refer to [Sending Messages](https://www.pubnub.com/docs/general/messages/publish#send-messages), [Sending Signals](https://www.pubnub.com/docs/general/messages/publish#send-signals), and [Sending Files](https://www.pubnub.com/docs/general/files#send-files) for more information on messages.

The value or the `custom_message_type` parameter must be a case-sensitive, alphanumeric string from 3 to 50 characters (dashes and underscores are allowed). The value can't start with special characters or the `pn_` or `pn-` string.

:::note SDKs supporting custom_message_type
For more info on `custom_message_type`, go to the following SDKs that already support this parameter: [Objective-C](https://www.pubnub.com/docs/sdks/objective-c/api-reference/publish-and-subscribe#methods), [Swift](https://www.pubnub.com/docs/sdks/swift/api-reference/publish-and-subscribe#methods), [Java](https://www.pubnub.com/docs/sdks/java/api-reference/publish-and-subscribe#methods), [JavaScript](https://www.pubnub.com/docs/sdks/javascript/api-reference/publish-and-subscribe#methods), [Python](https://www.pubnub.com/docs/sdks/python/api-reference/publish-and-subscribe#methods), [PHP](https://www.pubnub.com/docs/sdks/php/api-reference/publish-and-subscribe#methods), and [Kotlin](https://www.pubnub.com/docs/sdks/kotlin/api-reference/publish-and-subscribe#methods).
:::

###### Track message types with analytics

Custom message types feed directly into PubNub analytics. [Insights](https://www.pubnub.com/docs/pubnub-insights/dashboards/messages) automatically charts your top message types when you follow the recommended type conventions. [Illuminate](https://www.pubnub.com/docs/illuminate/business-objects/basics) can use message type values as dimensions in Business Objects, letting you segment metrics and trigger decisions based on message categories.

## Recommendations

Message payloads and their types should be easy to read and extendable. As your app grows, you want to ensure that future releases don't break old versions.

Below is a list of payload structures and message types that might be helpful to you:

### Text

#### Java

```java
pubnub.publish()
    .message(new JSONObject()
        .put("content", new JSONObject()
            .put("message", "This is a message"))
        .put("sender", "Mathew.Jenkinson"))
    .channel("my_channel")
    .customMessageType("text-message")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {
        "content": {
            "message": "This is a message"
        },
        "sender": "Mathew.Jenkinson"
    },
    customMessageType: "text-message"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

#### Kotlin

```kotlin
pubnub.publish(
    mapOf("content" to mapOf(
      "message" to "This is message"),
      "sender" to "Mathew.Jenkinson")),
    channel = "my_channel",
    custom_message_type = "text-message"
).async { result, status ->
    if (!status.error) {
        println("Publish timetoken ${result!!.timetoken}")
    }
    println("Status code ${status.statusCode}")
}
```

#### Objective-C

```objectivec
self.client.publish()
    .message(@{
        @"content": @{
            @"message": @"This is a message"
        },
        @"sender": @"Mathew.Jenkinson"
    })
    .channel(@"my_channel")
    .customMessageType(@"text-message")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

#### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "message" => "This is a message"
                    ],
                    "sender" => "Mathew.Jenkinson"
                ])
                ->customMessageType("text-message")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
  if status.isError:
    print status.statusCode
  elif
    print result.timetoken

pubnub.publish()\
  .channel("my_channel")\
  .message({
      "content": {
          "message": "This is a message"
      },
      "sender": "Mathew.Jenkinson"
  })\
  .custom_message_type("text-message")\
  .pn_async(publish_callback)
```

#### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: [
    "content": [
      "message": "This is a message"
    ],
    "sender": "Mathew.Jenkinson"
  ] as [String: AnyJSON],
  customMessageType: "text-message"
) { result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```

### Multi-language text

#### Java

```java
JSONObject data = new JSONObject()
    .put("content", new JSONObject()
        .put("message", new JSONObject()
            .put("en", "This is a message")
            .put("es", "Este es un mensaje")
            .put("de", "Dies ist eine Nachricht")
            .put("nl", "Dit is een bericht")))
    .put("sender", "Mathew.Jenkinson");

pubnub.publish()
    .message(data)
    .channel("my_channel")
    .customMessageType("multi-language-text")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {
        "content": {
            "message": {
                "en": "This is a message",
                "es": "Este es un mensaje",
                "de": "Dies ist eine Nachricht",
                "nl": "Dit is een bericht"
            }
        },
        "sender": "Mathew.Jenkinson"
    },
    customMessageType: "multi-language-text"
  },
Change
of 45
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

#### Kotlin

```kotlin
val data = mapOf(
            "content" to mapOf(
                "message" to mapOf(
                    "en" to "This is a message",
                    "es" to "Este es un mensaje",
                    "de" to "Dies ist eine Nachricht",
                    "nl" to "Dit is een bericht"
                )
            ), "sender" to "Mathew.Jenkinson"
        )

pubnub.publish()
    .message(data)
    .channel("my_channel")
    .customMessageType("multi-language-text")
    .async { result, status ->
        if (!status.error) {
            println("Publish timetoken ${result!!.timetoken}")
        }
        println("Status code ${status.statusCode}")
    }
```

#### Objective-C

```objectivec
self.client.publish()
    .message(@{
        @"content": @{
            @"message": @{
                @"en": @"This is a message",
                @"es": @"Este es un mensaje",
                @"de": @"Dies ist eine Nachricht",
                @"nl": @"Dit is een bericht"
            }
        },
        @"sender": @"Mathew.Jenkinson"
    })
    .channel(@"my_channel")
    .customMessageType(@"multi-language-text")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

#### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "message" => [
                            "en" => "This is a message",
                            "es" => "Este es un mensaje",
                            "de" => "Dies ist eine Nachricht",
                            "nl" => "Dit is een bericht"
                        ]
                    ],
                    "sender" => "Mathew.Jenkinson"
                ])
                ->customMessageType("multi-language-text")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
    if status.is_error():
        print("Status code: {}".format(status.error_data.information))
    else:
        print("Publish timetoken: {}".format(result.timetoken))

pubnub.publish() \
    .channel("my_channel") \
    .message({
        "content": {
            "message": {
              "en": "This is a message",
              "es": "Este es un mensaje",
              "de": "Dies ist eine Nachricht",
              "nl": "Dit is een bericht"
            }
        },
        "sender": "Mathew.Jenkinson"
    }) \
    .custom_message_type("multi-language-text") \
    .async(publish_callback)
```

#### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: [
    "content": [
      "message": [
        "en": "This is a message",
        "es": "Este es un mensaje",
        "de": "Dies ist eine Nachricht",
        "nl": "Dit is een bericht"
      ]
    ],
    "sender": "Mathew.Jenkinson"
  ] as [String: AnyJSON],
  customMessageType: "multi-language-text"
) { result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```

### Text with image

#### Java

```java
pubnub.publish()
    .message(new JSONObject()
        .put("content", new JSONObject()
            .put("text", "The weather is gorgeous today. Who's available to meet up for lunch at Bob’s Diner? 🌞")
            .put("attachments", new JSONArray()
                .put(new JSONObject()
                    .put("image", new JSONObject()
                        .put("source", "https://www.pubnub.com/pubnub_logo.svg")
                    )
                )
            )
            .put("sender", "Mathew.Jenkinson"))
    .channel("my_channel")
    .customMessageType("text-with-image")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {
        "content": {
            "text": "The weather is gorgeous today. Who's available to meet up for lunch at Bob’s Diner? 🌞",
            "attachments": [
              {
                "image": {
                  "source": "https://www.pubnub.com/pubnub_logo.svg"
                }
              }
            ],
            "sender": "Mathew.Jenkinson"
        }
    },
    customMessageType: "text-with-image"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

#### Kotlin

```kotlin
pubnub.publish(
  channel: "my_channel",
  message: mapOf(
            "content" to mapOf(
                "text" to "The weather is gorgeous today. Who's available to meet up for lunch at Bob's Diner? 🌞",
                "attachments" to listOf(
                    mapOf(
                        "image" to mapOf(
                            "source" to "https://www.pubnub.com/pubnub_logo.svg"
                        )
                    )
                ),
                "sender" to "Mathew.Jenkinson"
            )
        ),
  customMessageType: "text-with-image"
){ result in
  switch result {
    case let .success(response):
      print("succeeded: \(response)")

    case let .failure(error):
      print("failed: \(error.localizedDescription)")
  }
}
```

#### Objective-C

```objectivec
self.client.publish()
    .message(@{
        @"content": @{
            @"text": @"The weather is gorgeous today. Who's available to meet up for lunch at Bob’s Diner? 🌞",
            @"attachments": @[
                @{
                    @"image": @{
                        @"source": @"https://www.pubnub.com/pubnub_logo.svg"
                    }
                }
            ],
            @"sender": @"Mathew.Jenkinson"
        }
    })
    .channel(@"my_channel")
    .customMessageType(@"text-with-image")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

#### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "text" => "The weather is gorgeous today. Who's available to meet up for lunch at Bob’s Diner? 🌞",
                        "attachments" => [
                            [
                                "image" => [
                                    "source" => "https://www.pubnub.com/pubnub_logo.svg"
                                ]
                            ]
                        ],
                        "sender" => "Mathew.Jenkinson"
                    ]
                ])
                ->customMessageType("text-with-image")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
  if status.isError:
    print status.statusCode
  else:
    print result.timetoken

pubnub.publish()\
  .channel("my_channel")\
  .message({
      "content": {
          "text": "The weather is gorgeous today. Who's available to meet up for lunch at Bob’s Diner? 🌞",
          "attachments": [
            {
              "image": {
                "source": "https://www.pubnub.com/pubnub_logo.svg"
              }
            }
          ],
          "sender": "Mathew.Jenkinson"
      }
  })\
  .custom_message_type("text-with-image")\
  .pn_async(publish_callback)
```

#### Swift

```swift
struct TextWithImage: JSONCodable {
  let text: String
  let attachments: [[String: AnyJSON]]
  let sender: String
}

pubnub.publish(
  channel: "my_channel",
  message: TextWithImage(
    text: "The weather is gorgeous today. Who's available to meet up for lunch at Bob's Diner? 🌞",
    attachments: [
      [
        "image": [
          "source": "https://www.pubnub.com/pubnub_logo.svg"
        ]
      ]
    ],
    sender: "Mathew.Jenkinson"
  ),
  customMessageType: "text-with-image"
) { result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```

### Document

#### Java

```java
pubnub.publish()
    .message(new JSONObject()
        .put("content", new JSONObject()
            .put("link", "https://my/full/document.pdf")
            .put("thumbnail", "https://my/thumbnail/image.png"))
        .put("sender", "Mathew.Jenkinson"))
    .channel("my_channel")
    .customMessageType("document")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {
        "content": {
            "link": "https://my/full/document.pdf",
            "thumbnail": "https://my/thumbnail/image.png"
        },
        "sender": "Mathew.Jenkinson"
    },
    customMessageType: "document"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

#### Kotlin

```kotlin
pubnub.publish(
    message = mapOf(
            "content" to mapOf(
                "link" to "https://my/full/document.pdf",
                "thumbnail" to "https://my/thumbnail/image.png"
            ),
            "sender" to "Mathew.Jenkinson"
        ),
    channel = "my_channel",
    customMessageType = "document"
).async { result, status ->
    if (!status.error) {
        println("Publish timetoken ${result!!.timetoken}")
    }
    println("Status code ${status.statusCode}")
}
```

#### Objective-C

```objectivec
self.client.publish()
    .message(@{
        @"content": @{
            @"content": @{
                @"link": @"https://my/full/document.pdf",
                @"thumbnail": @"https://my/thumbnail/image.png"
            },
            @"sender": @"Mathew.Jenkinson"
        },
    })
    .channel(@"my_channel")
    .customMessageType(@"document")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
            NSLog(@"Publish timetoken %@", status.data.timetoken);
        } else {
            NSLog(@"Status code %ld", (long)status.statusCode);
        }
    });
```

#### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "link" => "https://my/full/document.pdf",
                        "thumbnail" => "https://my/thumbnail/image.png"
                    ],
                    "sender" => "Mathew.Jenkinson"
                ])
                ->customMessageType("document")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
    if status.isError:
        print(status.statusCode)
    else:
        print(result.timetoken)

pubnub.publish()\
    .channel("my_channel")\
    .message({
        "content": {
            "content": {
                "link": "https://my/full/document.pdf",
                "thumbnail": "https://my/thumbnail/image.png"
            },
            "sender": "Mathew.Jenkinson"
        }
    })\
    .custom_message_type("document")\
    .pn_async(publish_callback)
```

#### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: [
    "content": [
      "content": [
        "link": "https://my/full/document.pdf",
        "thumbnail": "https://my/thumbnail/image.png"
      ],
      "sender": "Mathew.Jenkinson"
    ]
  ] as [String: AnyJSON],
  customMessageType: "document"
) { result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```

### Video

#### Java

```java
pubnub.publish()
    .message(new JSONObject()
        .put("content", new JSONObject()
            .put("url", "https://my/video/file.png")
            .put("thumbnail", "https://my/video/image.png"))
        .put("sender", "Mathew.Jenkinson"))
    .channel("my_channel")
    .customMessageType("video")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {
        "content": {
            "url": "https://my/video/file.png",
            "thumbnail": "https://my/video/image.png"
        },
        "sender": "Mathew.Jenkinson"
    },
    customMessageType: "video"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

#### Kotlin

```kotlin
pubnub.publish(
    message = mapOf(
            "content" to mapOf(
                "content" to mapOf(
                    "url" to "https://my/video/file.png",
                    "thumbnail" to "https://my/video/image.png"
                )
            ),
            "sender" to "Mathew.Jenkinson"
        ),
    channel = "my_channel",
    customMessageType = "video"
).async { result, status ->
    if (!status.error) {
        println("Publish timetoken ${result!!.timetoken}")
    }
    println("Status code ${status.statusCode}")
}
```

#### Objective-C

```objectivec
self.client.publish()
    .message(@{
        @"content": @{
            @"content": @{
                @"url": @"https://my/video/file.png",
                @"thumbnail": @"https://my/video/image.png"
            },
            @"sender": @"Mathew.Jenkinson"
        }
    })
    .channel(@"my_channel")
    .customMessageType(@"video")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

#### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "url" => "https://my/video/file.png",
                        "thumbnail" => "https://my/video/image.png"
                    ],
                    "sender" => "Mathew.Jenkinson"
                ])
                ->customMessageType("video")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
  if status.isError:
    print status.statusCode
  elif
    print result.timetoken

pubnub.publish()\
  .channel("my_channel")\
  .message({
      "content": {
          "url": "https://my/video/file.png",
          "thumbnail": "https://my/video/image.png"
      },
      "sender": "Mathew.Jenkinson"
  })\
  .custom_message_type("video")\
  .pn_async(publish_callback)
```

#### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: [
    "content": [
      "url": "https://my/video/file.png",
      "thumbnail": "https://my/video/image.png"
    ],
    "sender": "Mathew.Jenkinson"
  ] as [String: AnyJSON],
  customMessageType: "video"
) { result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```

### Typing indicator

#### Java

```java
pubnub.signal()
    .message(new JSONObject()
        .put("content", new JSONObject()
            .put("event", "typing"))
        .put("sender", "Mathew.Jenkinson"))
    .channel("my_channel")
    .customMessageType("typing-indicator")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.signal(
  {
    channel: "my_channel",
    message: {
        "content": {
            "event": "typing"
        },
        "sender": "Mathew.Jenkinson"
    },
    customMessageType: "typing-indicator"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

#### Kotlin

```kotlin
pubnub.signal(
    message = mapOf(
            "content" to mapOf(
                "message" to mapOf(
                    "content" to mapOf(
                        "event" to "typing"
                    )
                ),
                "sender" to "Mathew.Jenkinson"
            )
        ),
    channel = "my_channel",
    customMessageType = "typing-indicator"
).async { result, status ->
    if (!status.error) {
        println("Publish timetoken ${result!!.timetoken}")
    }
    println("Status code ${status.statusCode}")
}
```

#### Objective-C

```objectivec
self.client.signal()
    .message(@{
        @"content": @{
            @"message": @{
                @"content": @{
                    @"event": @"typing"
                },
                @"sender": @"Mathew.Jenkinson"
            }
        }
    })
    .channel(@"my_channel")
    .customMessageType(@"typing-indicator")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

#### PHP

```php
$result = $pubnub->signal()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "content" => [
                            "event" => "typing"
                        ],
                        "sender" => "Mathew.Jenkinson"
                    ]
                ])
                ->customMessageType("typing-indicator")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
  if status.isError:
    print status.statusCode
  else:
    print result.timetoken

pubnub.signal()\
  .channel("my_channel")\
  .message({
      "content": {
          "event": "typing"
      },
      "sender": "Mathew.Jenkinson"
  })\
  .custom_message_type("typing-indicator")\
  .pn_async(publish_callback)
```

#### Swift

```swift
pubnub.signal(
  channel: "my_channel",
  message: [
    "content": [
      "content": [
        "event": "typing"
      ],
      "sender": "Mathew.Jenkinson"
    ]
  ] as [String: AnyJSON],
  customMessageType: "typing-indicator"
) { result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```

### Chat invitation

#### Java

```java
JSONObject message = new JSONObject()
        .put("content", new JSONObject()
            .put("channel", "this is the channel you are being invited to")
            .put("message", "Hi Craig, welcome to the team!"))
        .put("sender", "Mathew.Jenkinson");

pubnub.publish()
    .message(message)
    .channel("my_channel")
    .customMessageType("chat-invitation")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {
        "content": {
            "channel": "this is the channel you are being invited to",
            "message":"Hi Craig, welcome to the team!"
        },
        "sender": "Mathew.Jenkinson"
    },
    customMessageType: "chat-invitation"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

#### Kotlin

```kotlin
pubnub.publish(
    message = mapOf(
            "content" to mapOf(
                "channel" to "this is the channel you are being invited to",
                "message" to "Hi Craig, welcome to the team!"
            ),
            "sender" to "Mathew.Jenkinson"
        ),
    channel = "my_channel",
    customMessageType = "chat-invitation"
).async { result, status ->
    if (!status.error) {
        println("Publish timetoken ${result!!.timetoken}")
    }
    println("Status code ${status.statusCode}")
}
```

#### Objective-C

```objectivec
self.client.publish()
    .message(@{
        @"content": @{
            @"channel": @"this is the channel you are being invited to",
            @"message": @"Hi Craig, welcome to the team!"
        },
        @"sender": @"Mathew.Jenkinson"
    })
    .channel(@"my_channel")
    .customMessageType(@"chat-invitation")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

#### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "channel" => "this is the channel you are being invited to",
                        "message" => "Hi Craig, welcome to the team!"
                    ],
                    "sender" => "Mathew.Jenkinson"
                ])
                ->customMessageType("chat-invitation")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
  if status.isError:
    print status.statusCode
  else:
    print result.timetoken

pubnub.publish()\
  .channel("my_channel")\
  .message({
      "content": {
          "channel": "this is the channel you are being invited to",
          "message":"Hi Craig, welcome to the team!"
      },
      "sender": "Mathew.Jenkinson"
  })\
  .custom_message_type("chat-invitation")\
  .pn_async(publish_callback)
```

#### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: [
    "content": [
      "channel": "this is the channel you are being invited to",
      "message": "Hi Craig, welcome to the team!"
    ],
    "sender": "Mathew.Jenkinson"
  ] as [String: AnyJSON],
  customMessageType: "chat-invitation"
){ result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```

### Video invitation

#### Java

```java
JSONObject data = new JSONObject()
        .put("content", new JSONObject()
            .put("session", "your-token-here"))
        .put("sender", "Mathew.Jenkinson");

pubnub.publish()
    .message(data)
    .channel("my_channel")
    .customMessageType("video-invitation")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {
        "content": {
            "session": "your-token-here"
        },
        "sender": "Mathew.Jenkinson"
    },
    customMessageType: "video-invitation"
  },
  function(status, response) {
    console.log(status);
    console.log(response);
  }
);
```

#### Kotlin

```kotlin
pubnub.publish(
    message = mapOf("content" to mapOf("session" to "your-token-here"), "sender" to "Mathew.Jenkinson",
    channel = "my_channel",
    customMessageType = "video-invitation"
    ).async { result, status ->
        if (!status.error) {
            println("Publish timetoken ${result!!.timetoken}")
        }
        println("Status code ${status.statusCode}")
    }
)
```

#### Objective-C

```objectivec
self.client.publish()
    .message(@{
        @"content": @{
            @"session": @"your-token-here"
        },
        @"sender": @"Mathew.Jenkinson"
    })
    .channel(@"my_channel")
    .customMessageType(@"video-invitation")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

#### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "session" => "your-token-here"
                    ],
                    "sender" => "Mathew.Jenkinson"
                ])
                ->customMessageType("video-invitation")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
  if status.isError:
    print status.statusCode
  else:
    print result.timetoken

pubnub.publish()\
  .channel("my_channel")\
  .message({
      "content": {
          "session": "your-token-here"
      },
      "sender": "Mathew.Jenkinson"
  })\
  .custom_message_type("video-invitation")\
  .pn_async(publish_callback)
```

#### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: [
    "content": [
      "session": "your-token-here"
    ],
    "sender": "Mathew.Jenkinson"
  ] as [String: AnyJSON],
  customMessageType: "video-invitation"
) { result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```

### Poll

#### Java

```java
pubnub.publish()
    .message(new JSONObject()
        .put("content", new JSONObject()
            .put("question", "What do people want for lunch?")
            .put("answers", new JSONObject()
                .put("pizza", 0)
                .put("pierogi", 6)
                .put("sushi", 0)))
        .put("sender", "Mathew.Jenkinson"))
    .channel("my_channel")
    .customMessageType("poll")
    .async(new PNCallback<PNPublishResult>() {
        @Override
        public void onResponse(PNPublishResult result, PNStatus status) {
            if(!status.isError()) {
                System.out.println("pub timetoken: " + result.getTimetoken());
            }
            System.out.println("pub status code: " + status.getStatusCode());
        }
    });
```

#### JavaScript

```javascript
pubnub.publish(
  {
    channel: "my_channel",
    message: {
        "content": {
            "question": "What do people want for lunch?",
            "answers": {
                "pizza": 0,
                "pierogi": 6,
                "sushi": 0
            }
        },
        "sender": "Mathew.Jenkinson"
    },
    customMessageType: "poll"
  },
  function(status, response) {
    if (!status.error) {
      console.log("timetoken: " + response.timetoken);
    } else {
      console.log("pub status code: " + status.statusCode);
    }
  }
);
```

#### Kotlin

```kotlin
pubnub.publish(
    message = mapOf ("content" to mapOf(
            "question" to "What do people want for lunch?",
            "answers" to mapOf("pizza" to 0, "pierogi" to 6, "sushi" to 0)
        ), "sender" to "Mathew.Jenkinson"),
    channel = "my_channel",
    customMessageType = "poll"
).async { result, status ->
    if (!status.error) {
        println("Publish timetoken ${result!!.timetoken}")
    }
    println("Status code ${status.statusCode}")
}
```

#### Objective-C

```objectivec
self.client.publish()
    .message(@{
        @"content": @{
            @"question": @"What do people want for lunch?",
            @"answers": @{
                @"pizza": @0,
                @"pierogi": @6,
                @"sushi": @0
            }
        },
        @"sender": @"Mathew.Jenkinson"
    })
    .channel(@"my_channel")
    .customMessageType(@"poll")
    .performWithCompletion(^(PNPublishStatus *status) {
        if (!status.isError) {
        } else {
        }
});
```

#### PHP

```php
$result = $pubnub->publish()
                ->channel("my_channel")
                ->message([
                    "content" => [
                        "question" => "What do people want for lunch?",
                        "answers" => [
                            "pizza" => 0,
                            "pierogi" => 6,
                            "sushi" => 0
                        ]
                    ],
                    "sender" => "Mathew.Jenkinson"
                ])
                ->customMessageType("poll")
                ->meta(["name" => "Alex"])
                ->sync();
```

#### Python

```python
def publish_callback(result, status):
  if status.isError:
    print status.statusCode
  elif
    print result.timetoken

pubnub.publish()\
  .channel("my_channel")\
  .message({
      "content": {
          "question": "What do people want for lunch?",
          "answers": {
              "pizza": 0,
              "pierogi": 6,
              "sushi": 0
          }
      },
      "sender": "Mathew.Jenkinson"
  })\
  .custom_message_type("poll")\
  .pn_async(publish_callback)
```

#### Swift

```swift
pubnub.publish(
  channel: "my_channel",
  message: [
    "content": [
      "question": "What do people want for lunch?",
      "answers": [
        "pizza": 0,
        "pierogi": 6,
        "sushi": 0
      ]
    ],
    "sender": "Mathew.Jenkinson"
  ] as [String: AnyJSON],
  customMessageType: "poll"
) { result in
  switch result {
  case let .success(response):
    print("succeeded: \(response)")
  case let .failure(error):
    print("failed: \(error.localizedDescription)")
  }
}
```