---
source_url: https://www.pubnub.com/docs/chat/unreal-chat-sdk/build/features/messages/moderation
title: Report offensive messages
updated_at: 2026-06-19T11:35:27.841Z
---

> 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


# Report offensive messages

:::note Message Persistence
Enable Message Persistence in the [Admin Portal](https://admin.pubnub.com/).
:::

Users can report offensive messages directly from your app. Reported messages publish to `PUBNUB_INTERNAL_ADMIN_CHANNEL` and emit [report events](https://www.pubnub.com/docs/chat/unreal-chat-sdk/build/features/custom-events#chat-events).

Add custom logic using [emitted events](#stream-message-report-events) to handle reported messages (e.g., [delete them](https://www.pubnub.com/docs/chat/unreal-chat-sdk/build/features/messages/delete)).

##### Usage in Blueprints and C++

You can use PubNub's functionality via Blueprints or directly in C++ code.

* In Blueprints, you can access PubNub from any Widget or Actor. Start by [initializing chat](https://www.pubnub.com/docs/chat/unreal-chat-sdk/build/configuration#initialize-pubnub-chat) using `InitChat` on `UPubnubChatSubsystem`. Afterwards, you can use the returned `UPubnubChat` object reference to call all Chat SDK functions.

:::warning Blueprint functions
The Blueprints provided in the documentation show how you can structure your application and may contain utility methods and elements like buttons that are not part of the Unreal Chat SDK and are meant to serve as guidance.
:::

* In C++, you can use UPubnubChatSubsystem as any other Game Instance Subsystem. #include "Kismet/GameplayStatics.h" #include "Engine/GameInstance.h" #include "PubnubChatSubsystem.h" // ACTION REQUIRED: Replace ASample_ChatSubsystem with name of your Actor class void ASample_ChatSubsystem::InitChatSample() { // Get PubnubChatSubsystem from GameInstance UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(this); UPubnubChatSubsystem* PubnubChatSubsystem = GameInstance->GetSubsystem<UPubnubChatSubsystem>(); // Initialize Chat - InitChat may fail under some conditions so make sure to check the Result for errors before using the Chat FPubnubChatInitChatResult InitChatResult = PubnubChatSubsystem->InitChat(TEXT("demo"), TEXT("demo"), TEXT("Player_001")); UPubnubChat* PubnubChat = InitChatResult.Chat; } Chat now allows you to call all Chat SDK functions, for example, Chat->GetChannel("my_channel").

:::note Asynchronous and synchronous method execution
Most PubNub Unreal SDK methods are available in both asynchronous and synchronous variants.
* Asynchronous methods (Async suffix) return void and take an optional delegate parameter that fires when the operation completes. 1Message->ReportAsync(OnReportResponseDelegate, Reason); You can also use native callbacks that accept lambdas instead of dynamic delegates. Native callback types have the Native suffix (for example, FOnPubnubChatOperationResponseNative).
* Synchronous methods (no suffix) block the main game thread until the operation completes and return a result struct directly. 1FPubnubChatOperationResult Result = Message->Report(Reason);
:::

## Flag/Report messages

`Report()` flags a message for admin review.

### Method signature

#### Blueprint

#### C++ / Input parameters

```cpp
Message->Report(FString Reason = "");
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| Reason | FString | Optional | `""` | Reason for reporting/flagging a given message. |

#### Output

| Type | Description |
| --- | --- |
| `FPubnubChatOperationResult` | Result of the operation. Check `Error` and `ErrorMessage` for failure. |

### Sample code

:::tip Reference code
This example is a self-contained code snippet ready to be run. Set up your Unreal project and follow the instructions in the lines marked with `ACTION REQUIRED` before running the code. Use it as a reference when working with other examples in this document.
:::

Report a message asynchronously.

###### C++

###### Actor.h

```cpp
// blueprint.z3rdh_21
UFUNCTION(BlueprintCallable, Category = "PubnubChat|Samples|ChatMessage")
void ReportMessageSample();
```

###### Actor.cpp

```cpp
// ACTION REQUIRED: Replace ASample_ChatMessage with name of your Actor class
void ASample_ChatMessage::ReportMessageSample()
{
	// snippet.hide
	UPubnubChatMessage* Message = nullptr;
	// snippet.show

	// Assumes Message is a valid UPubnubChatMessage

	// Reason or context for reporting this message
	FString Reason = TEXT("Inappropriate content");

	// Report this message to the moderation stream
	Message->ReportAsync(nullptr, Reason);
}
```

###### Blueprint

## Stream message report events

`StreamMessageReports()` subscribes to real-time report events on a channel. Bind the channel's `OnMessageReported` delegate before calling this method to receive report events.

:::note
Use this method for channels where you want live monitoring of reported messages, such as an admin moderation dashboard.
:::

### Method signature

```cpp
Channel->StreamMessageReports();
```

Bind the channel's `OnMessageReported` delegate before calling `StreamMessageReports()` to receive report events.

#### Output

| Type | Description |
| --- | --- |
| `FPubnubChatOperationResult` | Result of the operation. Check `Error` for failure. |

### Sample code

Stream report events on the `support` channel.

```cpp
// ACTION REQUIRED: Replace ASample_ChatChannel with name of your Actor class
void ASample_ChatChannel::StreamMessageReportsSample()
{
	// snippet.hide
	UPubnubChatChannel* Channel = nullptr;
	// snippet.show

	// Assumes Channel is a valid UPubnubChatChannel (e.g. from GetChannel)

	// Bind to receive message report events (moderation stream)
	Channel->OnMessageReportedNative.AddUObject(this, &ASample_ChatChannel::OnMessageReportReceived);

	// Start streaming message reports
	Channel->StreamMessageReportsAsync(nullptr);

	// When report events are no longer needed, stop streaming
	Channel->StopStreamingMessageReportsAsync(nullptr);
}

// ACTION REQUIRED: Replace ASample_ChatChannel with name of your Actor class
void ASample_ChatChannel::OnMessageReportReceived(const FPubnubChatReportEvent& ReportEvent)
{
	/* e.g. handle moderation events (report payload, user, etc.) */
}
```

### Other examples

Stop streaming report events.

###### Actor.h

```cpp
UFUNCTION(BlueprintCallable, Category = "PubnubChat|Samples|ChatChannel")
void StreamMessageReportsSample();

void OnMessageReportReceived(const FPubnubChatReportEvent& ReportEvent);
```

###### Actor.cpp

```cpp
// ACTION REQUIRED: Replace ASample_ChatChannel with name of your Actor class
void ASample_ChatChannel::StreamMessageReportsSample()
{
	// snippet.hide
	UPubnubChatChannel* Channel = nullptr;
	// snippet.show

	// Assumes Channel is a valid UPubnubChatChannel (e.g. from GetChannel)

	// Bind to receive message report events (moderation stream)
	Channel->OnMessageReportedNative.AddUObject(this, &ASample_ChatChannel::OnMessageReportReceived);

	// Start streaming message reports
	Channel->StreamMessageReportsAsync(nullptr);

	// When report events are no longer needed, stop streaming
	Channel->StopStreamingMessageReportsAsync(nullptr);
}

// ACTION REQUIRED: Replace ASample_ChatChannel with name of your Actor class
void ASample_ChatChannel::OnMessageReportReceived(const FPubnubChatReportEvent& ReportEvent)
{
	/* e.g. handle moderation events (report payload, user, etc.) */
}
```

## Get message reports history

`GetMessageReportsHistory()` retrieves historical report events from a channel, similar to [GetHistory()](https://www.pubnub.com/docs/chat/unreal-chat-sdk/build/features/messages/history) for messages. Use this to audit past message reports.

### Method signature

```cpp
Channel->GetMessageReportsHistory(
    FString StartTimetoken,
    FString EndTimetoken,
    int Count = 100
);
```

| Parameter | Description |
| --- | --- |
| `StartTimetoken`Type: `FString`Default: n/a | [Timetoken](https://www.pubnub.com/docs/sdks/javascript/api-reference/misc#time) delimiting the start of a time slice (exclusive) to pull report events from. |
| `EndTimetoken`Type: `FString`Default: n/a | Timetoken delimiting the end of a time slice (inclusive) to pull report events from. |
| `Count`Type: `int`Default: `100` | Number of historical report events to return for the channel in a single call. Maximum: 100. |

#### Output

| Parameter | Description |
| --- | --- |
| `FPubnubChatEventsResult`Type: `struct` | Returned object containing `Result`, `Events`, and `IsMore`. |
| → `Result`Type: `FPubnubChatOperationResult` | Operation result with `Error` (bool), `ErrorMessage` (FString), and `StepResults`. |
| → `Events`Type: `TArray<FPubnubChatEvent>` | Array of historical report event objects. |
| → `IsMore`Type: `bool` | Indicates whether there are more historical events to pull. |

### Sample code

Fetch the last 10 report events from the `support` channel.

```cpp
// ACTION REQUIRED: Replace ASample_ChatChannel with name of your Actor class
void ASample_ChatChannel::GetMessageReportsHistorySample()
{
	// snippet.hide
	UPubnubChatChannel* Channel = nullptr;
	// snippet.show

	// Assumes Channel is a valid UPubnubChatChannel (e.g. from GetChannel)

	// Start timetoken (inclusive); must be higher (newer) than EndTimetoken (17-digit PubNub timetoken)
	FString StartTimetoken = TEXT("17800000000000000");
	// End timetoken (inclusive); must be lower (older) than StartTimetoken
	FString EndTimetoken = TEXT("17200000000000000");

	// Callback for when the operation completes (returns report events)
	FOnPubnubChatEventsResponseNative Callback;
	// ACTION REQUIRED: Replace ASample_ChatChannel with name of your Actor class
	Callback.BindUObject(this, &ASample_ChatChannel::OnGetMessageReportsHistoryResponse);
	Channel->GetMessageReportsHistoryAsync(StartTimetoken, EndTimetoken, Callback);
}

// ACTION REQUIRED: Replace ASample_ChatChannel with name of your Actor class
void ASample_ChatChannel::OnGetMessageReportsHistoryResponse(const FPubnubChatEventsResult& Result)
{
	if (Result.Result.Error) { return; }
	TArray<FPubnubChatEvent> Events = Result.Events;
}
```