# Notifications

THNDR sends your server real-time webhooks every time something meaningful happens in a game. These webhooks exist primarily to keep your wallet in sync, but they carry rich event data that you can also use to trigger timely, personalized engagement campaigns across push notifications, email, SMS, or in-app messaging.

This page explains how.

## The core idea

Every webhook THNDR sends contains a `userId` - your own identifier for the player. That means when you receive a webhook, you already know who the event belongs to. You can immediately look up that user in your own system and trigger any downstream action:

* fire a push notification
* queue an email
* update a CRM record
* log the event for a retargeting campaign.

You are not required to act on these webhooks beyond processing the wallet transaction. But every webhook is also a signal about what a player just did or experienced. Players who just won are in a different mindset to players who just lost. Players waiting for an opponent to finish are in a state of anticipation. These moments are high-intent, and the right message at the right moment drives real engagement.

## What each webhook tells you, and what you can do with it

### **Transaction webhooks**

**Webhook:** `POST {operatorURL}/thndr/transactions`

You already implement these to debit and credit the player's wallet. They also give you a complete picture of player activity.

| Transaction type | What it means                         | Engagement opportunity                                                              |
| ---------------- | ------------------------------------- | ----------------------------------------------------------------------------------- |
| BET              | Player placed a wager                 | Confirm the stake; show streak progress ("3 games played today")                    |
| LOSE             | Player lost a round                   | Offer a re-engagement nudge; consider a time-limited bonus if the player goes quiet |
| DRAW             | Round ended as a draw, stake returned | Prompt the player to try again; low-friction moment since they lost nothing         |
| WIN              | Player won a round                    | Celebrate immediately with a push or in-app message; surface a "play again" prompt  |

**Example: win celebration push notification**

```
Title: You won! 🎉
Body:  You just won $2.00 on Solitaire. Your balance has been updated. Play again?
```

**Example: post-loss re-engagement email (sent if player doesn't return within 24 hours)**

```
Subject: Still got it in you?
Body:    You were close in your last game. Your balance is ready when you are.
```

The `gameId` field lets you personalise by game title. "Your Blackjack win" hits differently than a generic message. The `amount` field lets you reference the actual stake or win value, which makes the message feel real rather than templated.

### **Game event webhooks**

**Webhook:** `POST {operatorURL}/thndr/events`

Game events are entirely optional from a wallet perspective. You do not need to implement them to go live. But they give you the richest real-time signals of any webhook type.

| Event                     | What it means                             | Engagement opportunity                                              |
| ------------------------- | ----------------------------------------- | ------------------------------------------------------------------- |
| OPPONENT\_JOINED          | An opponent has joined your player's room | Push notification to bring the player back if they've left the app. |
| OPPONENT\_ROUND\_FINISHED | The opponent has completed their round    | Drive urgency: "Your opponent just finished. Check out the result.  |

The `opponentNick` field on `OPPONENT_JOINED` and `OPPONENT_ROUND_FINISHED` lets you name the opponent in your message, which makes it feel immediate and personal.

**Example: opponent joined push notification**

```
Title: Your opponent is ready
Body:  SpeedAce just joined your Solitaire match.
```

**Example: opponent finished push notification**

```
Title: SpeedAce just finished their round
Body:  They've locked in their score. Jump back in and show them what you've got.
```

Players who created a room and drifted away are far more likely to return when you tell them their match is live.

## Practical implementation patterns

### **Pattern 1: fire and forget**

The simplest approach. When a webhook arrives and you've processed the transaction, publish an event to an internal queue (e.g. SQS, Pub/Sub, RabbitMQ). A separate consumer reads from the queue and decides whether to send a notification. This keeps your webhook handler fast and decoupled from your messaging infrastructure.

```
Webhook arrives
  → Process wallet transaction (required)
  → Publish event to queue (async)
    → Consumer picks up event
      → Looks up user's notification preferences
        → Sends push / email / SMS if opted in
```

### **Pattern 2: segment and suppress**

Not every event should trigger a message. Too many notifications train players to ignore them. Apply rules before sending:

* Only send the "you won" push if the player is not currently active in the app (check your own session state).
* Only send the post-loss re-engagement email if the player has not returned within a defined window (e.g. 4 hours).
* Only send the "opponent joined" push if the player is not in the foreground.
* Suppress all messages for players who have opted out of marketing communications.

### **Pattern 3: personalise with game and amount**

Every transaction and event carries `gameId`. Use it. "You won at Blackjack" outperforms "You won a game" in open and click rates. Where the amount is available, include it. Real numbers make messages feel real.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.thndr.io/integration/customisation/notifications.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
