Custom Chat Integration
Verité normally filters messages automatically. However, some chat plugins intercept Minecraft's normal chat event and handle message delivery themselves.
If your plugin does this, Verité may never receive the original message to filter. In that case, you should pass the message through Verité before your plugin sends it.
You only need this guide if your plugin handles or replaces normal Minecraft chat. Servers using standard chat do not need any additional setup.
Java Integration
Verité provides a small public API specifically for integrations like custom chat systems.
1. Add Verité as a soft dependency
Add Verité to your plugin.yml:
softdepend:
- VeriteUsing a soft dependency ensures Verité loads before your integration when installed, without making it mandatory for your plugin to start.
2. Check whether the API is available
If Verité is optional, check for the API before using it:
private static final boolean VERITE_AVAILABLE;
static {
boolean available;
try {
Class.forName("teacommontea.api.VeriteFilter");
available = true;
} catch (ClassNotFoundException ignored) {
available = false;
}
VERITE_AVAILABLE = available;
}Your integration can then simply do nothing when Verité isn't installed.
3. Filter the message
Before your custom chat system sends a message, pass it to VeriteFilter:
if (VERITE_AVAILABLE) {
FilterResult result = VeriteFilter.check(
player.getUniqueId(),
message
);
if (result.blocks()) {
player.sendMessage(VeriteFilter.blockMessage());
return;
}
}That's all that is required for a basic integration.
check() runs the message through Verité's filter and records the flag against the player. If .blocks() returns true, your chat system should prevent the message from being sent.
Using the filter category
Sometimes you'll want to know why Verité caught a message:
FilterResult result = VeriteFilter.check(
player.getUniqueId(),
message
);
switch (result) {
case CLEAN -> {
// Send normally
}
case SELF_HARM, ABUSE -> {
// Handle appropriately
}
default -> {
// Ordinary blocked content
}
}The possible results are:
CLEANBLOCKPROFANITYSELF_HARMABUSE
Anything except CLEAN returns true from .blocks().
Important:
SELF_HARMandABUSEexist so these messages can be handled differently from ordinary rule violations. We recommend against automatically treating them as punishable chat offenses.
Detecting repeated messages
If your chat system needs to distinguish filtered content from repeat-message detection, use the repeat-aware overload:
FilterOutcome outcome = VeriteFilter.check(
player.getUniqueId(),
message,
true
);
if (outcome.blocks()) {
if (outcome.repeat()) {
player.sendMessage(VeriteFilter.repeatMessage());
} else {
player.sendMessage(VeriteFilter.blockMessage());
}
return;
}outcome.category() provides the normal filter category, while outcome.repeat() tells you whether the message was blocked because it was repeated.
Filtering Other User Content
The API isn't limited to chat.
If your plugin accepts user-written content such as nicknames, prefixes, team tags, or similar fields, you can run those through the same filter:
if (VeriteFilter.check(player.getUniqueId(), nickname).blocks()) {
// Reject the nickname
}For text that doesn't belong to a particular player, use VeriteFilter.ANONYMOUS:
FilterResult result = VeriteFilter.check(
VeriteFilter.ANONYMOUS,
text
);Anonymous checks still return the appropriate filter category, but do not add a flag to any player's record.
Using Verité with Skript
If your custom chat system is written in Skript, you don't need to interact with the Java API.
With Verité and Skript installed, Verité's filtering syntax is available automatically.
Filtering Custom Chat
If your script already handles sending chat messages itself, check the message before sending it:
if {_msg} is blocked for player:
send block message to player
stopIncluding for player tells Verité who sent the message and records the flag against that player.
Without a player:
if {_text} is blocked:
# Reject the textVerité performs a pure filter check without recording a flag. This is useful for things such as names, tags, signs, or other text that shouldn't count against a specific player.
Checking Why a Message Was Blocked
For more control, retrieve the filter result:
set {_result} to filter result of {_msg} for player
if {_result} is "self_harm":
# Handle separately
stop
if {_result} is "abuse":
# Handle separately
stop
if {_result} is not "clean":
send block message to player
stopThe result will be one of:
clean, block, profanity, self_harm, or abuse
Important: Consider handling
self_harmandabuseseparately from ordinary moderation violations rather than automatically punishing the player.
Checking a Player's Flag Count
You can also retrieve the number of messages Verité has flagged for a player:
set {_flags} to message flags of playerThis can be used by your own moderation system if you want different behaviour for repeated violations.
Skript Syntax Reference
%string% is blocked [for %-player%]
%string% is not blocked [for %-player%]
filter result of %string% [for %-player%]
block message
message flags of %player%The optional player matters:
With a player: the filter result is recorded against that player.
Without a player: Verité only checks the text and does not record a flag.
API Reference
The public API is located under:
teacommontea.apiThe primary class for chat integrations is:
VeriteFilterUseful methods include:
VeriteFilter.check(UUID player, String message)
VeriteFilter.check(UUID player, String message, boolean repeatAware)
VeriteFilter.count(UUID player)
VeriteFilter.blockMessage()
VeriteFilter.repeatMessage()
VeriteFilter.selfHarmMessage()
VeriteFilter.blockNotice(FilterResult result, String message)VeriteFilter.ANONYMOUS can be used when filtering text that isn't associated with a player.
Verité also exposes its normalization utilities for integrations that need them, including accent folding, entity stripping, repeated-character reduction, fingerprinting, and edge trimming. These functions are thread-safe and generally do not need to be called manually before using check().
For most custom chat integrations, all you need is:
if (VeriteFilter.check(player.getUniqueId(), message).blocks()) {
// Don't send the message
}Verité handles the rest.