Webhook Fact Event
Publish a Discord webhook when a Typewriter fact changes
Publishes a Discord webhook whenever a Typewriter fact changes. The watcher uses Typewriter's player-facing fact tracker. This means a grouped fact is read through the same group implementation as the rest of the engine instead of reading storage directly, and the entry remains compatible with custom fact implementations.
Fields
| Field | Type | Default | Description | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
enabled | Boolean | true | Keep this event disabled without removing the manifest entry | ||||||||||||||||||||||||||||||||||||
fact | Ref<ReadableFactEntry> | — | Readable Typewriter fact to observe | ||||||||||||||||||||||||||||||||||||
destination | Ref<WebhookDefinitionEntry> | — | Reusable Discord destination receiving the event | ||||||||||||||||||||||||||||||||||||
scope | FactWebhookScope | PLAYER | How often the event is published: once per player, group or fact globallyValues:PLAYERGROUPGLOBAL | ||||||||||||||||||||||||||||||||||||
audience | Ref<out AudienceEntry> | — | Optional Typewriter audience. Empty means every player observing the fact | ||||||||||||||||||||||||||||||||||||
previousValue | List<FactValueCondition> | empty | Previous value must satisfy all configured conditions
|
| Field | Type | Default | Description |
|---|---|---|---|
operator | FactValueOperator | ANY | Comparison applied to the value before or after the fact updateValues:ANYEQUALSNOT_EQUALSGREATER_THANGREATER_THAN_OR_EQUALSLESS_THANLESS_THAN_OR_EQUALS |
value | Int | 0 | Value used by the comparison |
newValueList<FactValueCondition>emptyFactValueCondition (2)
| Field | Type | Default | Description |
|---|---|---|---|
operator | FactValueOperator | ANY | Comparison applied to the value before or after the fact updateValues:ANYEQUALSNOT_EQUALSGREATER_THANGREATER_THAN_OR_EQUALSLESS_THANLESS_THAN_OR_EQUALS |
value | Int | 0 | Value used by the comparison |
contentTemplateString{player} updated {fact}: {previous_value} → {new_value}threadNameTemplateStringembedFactWebhookEmbedFactWebhookEmbed (5)
| Field | Type | Default | Description | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
enabled | Boolean | true | Send an embed in addition to the message content | ||||||||||||
titleTemplate | String | {fact} | Embed title templatePlaceholdersMulti-line | ||||||||||||
descriptionTemplate | String | {player} changed the fact from {previous_value} to {new_value}. | Embed description templatePlaceholdersMulti-line | ||||||||||||
color | String | #5865F2 | Hex color, for example #5865F2 | ||||||||||||
fields | List<FactWebhookField> | — | Fields added to the embed
|
| Field | Type | Default | Description |
|---|---|---|---|
value | String | {fact}: {new_value} | Field value. Supports the fact event placeholdersPlaceholdersMulti-line |
inline | Boolean | true | Display this field inline when possible |
pingRoleIdsList<String>emptytriggerCooldownSecondsInt1Common TypeWriter fields (triggers)
| Field | Type | Default | Description |
|---|---|---|---|
triggers | List<Ref<TriggerableEntry>> | empty | — |
How to use it
Pick the fact to watch and the destination. A message is posted each time the fact changes for a player.
scope:PLAYERposts for every player,GROUPonce per TypeWriter group,GLOBALonce for the fact.audiencelimits the event to players in a TypeWriter audience. Empty means every player.previousValueandnewValueare conditions (EQUALS,GREATER_THAN, and so on) that must all be true to post, for example a new value of at least10.- Templates accept
{player},{player_uuid},{fact},{fact_name},{previous_value},{new_value},{change},{scope},{group},{players}and{timestamp}. threadNameTemplateis for forum channels only.pingRoleIdsadds role mentions.triggersrun for the player whose fact change was published, each time a webhook is published. With aGROUPorGLOBALscope the event is published once, so they run once, for the first player who observed the change. They run only when a message was actually handed to Discord: a template set that renders nothing publishes nothing and triggers nothing. They do not wait for Discord to accept the message, so a rejected webhook still runs them.triggerCooldownSeconds(default1) is a loop guard fortriggers: the minimum number of seconds between two firings for the same player and the same event. Without it, a chained action that rewrites the watched fact would fire this event again forever.0disables the guard. The webhook itself is still published at every change; only the firing oftriggersis spaced, so a change inside the cooldown posts its message but runs notriggers.