# Webhook

## Webhook Integration

### Overview

When using the **UserID & Webhook** campaign type, game results are not displayed on an in-game leaderboard. Instead, the results are sent directly to your server via a webhook POST request.

This allows you to collect game data in real time and integrate it with your own system — whether that's a database, CRM, analytics platform, or even a simple Google Sheet.

***

### How It Works

1. Your website embeds the game with a `userid` parameter
2. The user plays the game
3. Upon completion, our system sends the game result to your **Webhook URL** via POST
4. Your server processes the data and returns a status code

```
Your Website                          Branded Mini-Games
    |                                        |
    |-- userid (via URL parameter) --------->|
    |                                        |  User plays the game
    |<-- Webhook POST (game result) ---------|
    |                                        |
    |-- Return "S" (success) --------------->|
```

<figure><img src="https://970521601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXF5Q8drxdQOBisGrmGGu%2Fuploads%2F6JYxFKhcqQUUurAgI9JC%2FScreenshot%202024-09-10%20at%2011.30.33.png?alt=media&#x26;token=95080d19-255d-47d6-9b6a-be9097049096" alt=""><figcaption></figcaption></figure>

***

### URL Parameter

Append the `userid` as a GET parameter when embedding the game:

```
https://branded.mini-games.io/?php=landing@game&campaign_no=YOUR_CAMPAIGN_NO&userid=T4g4fLTa
```

> For details on generating and managing user IDs, see the User ID Setup Guide.

***

### Webhook Data

The following parameters are sent to your Webhook URL via **POST**:

| Parameter  | Required | Description                                 | Example               |
| ---------- | -------- | ------------------------------------------- | --------------------- |
| `userid`   | Yes      | Unique user identifier sent by your system  | `T4g4fLTa`            |
| `tx_id`    | Yes      | Unique transaction ID for each game play    | `234234`              |
| `time`     | Yes      | Date and time when the user played the game | `2025-04-10 06:39:23` |
| `score`    | Yes      | Score the user achieved                     | `3500`                |
| `playtime` | Yes      | Play duration in seconds                    | `20`                  |

#### Data Format

You can choose the data format in the Studio settings:

* **default** — standard form POST (`application/x-www-form-urlencoded`)
* **json** — JSON format (`application/json`)

***

### Return Code

Your webhook endpoint **must** return a status code to confirm receipt:

| Code | Description                                                    |
| ---- | -------------------------------------------------------------- |
| `S`  | Successfully received and processed                            |
| `F`  | Failed. You may include a reason, e.g., `F: Score is missing.` |

***

### Server-Side Example (Node.js)

```javascript
app.post('/webhook', (req, res) => {
  const { userid, tx_id, time, score, playtime } = req.body;

  // Validate required fields
  if (!userid || !tx_id || !score) {
    return res.send('F: Missing required fields.');
  }

  // Store the data in your database
  db.insert({ userid, tx_id, time, score, playtime });

  return res.send('S');
});
```

***

### Google Sheets Integration (No Server Required)

If you don't have a backend server, you can use **Google Apps Script** to receive webhook data directly into a Google Sheet. This is ideal for promotions, contests, or quick setups.

#### Step 1: Create a Google Sheet

1. Go to [Google Sheets](https://sheets.google.com) and create a new spreadsheet
2. In the first row, add headers:

| A            | B          | C          | D        | E         | F            |
| ------------ | ---------- | ---------- | -------- | --------- | ------------ |
| **Received** | **userid** | **tx\_id** | **time** | **score** | **playtime** |

#### Step 2: Open Apps Script

1. In your Google Sheet, go to **Extensions > Apps Script**
2. Delete any existing code and paste the following:

```javascript
function doPost(e) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = JSON.parse(e.postData.contents);

  sheet.appendRow([
    new Date(),
    data.userid,
    data.tx_id,
    data.time,
    data.score,
    data.playtime
  ]);

  return ContentService.createTextOutput('S');
}
```

3. Click **Save** (Ctrl+S / Cmd+S)

#### Step 3: Deploy as Web App

1. Click **Deploy > New deployment**
2. Click the gear icon and select **Web app**
3. Configure the settings:

| Setting        | Value                        |
| -------------- | ---------------------------- |
| Description    | Webhook receiver             |
| Execute as     | **Me** (your Google account) |
| Who has access | **Anyone**                   |

4. Click **Deploy**
5. Authorize the app when prompted (review permissions and allow)
6. Copy the **Web app URL** — this is your Webhook URL

> The URL looks like: `https://script.google.com/macros/s/AKfycb.../exec`

<figure><img src="https://970521601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FXF5Q8drxdQOBisGrmGGu%2Fuploads%2FWEdr2gBaPQMkLgjaGcnf%2FScreenshot%202024-09-23%20at%2016.21.04.png?alt=media&#x26;token=1f33e612-c57b-4956-aa5a-839486f81c18" alt=""><figcaption></figcaption></figure>

#### Step 4: Set the Webhook URL in Studio

1. Go to your campaign's **UserID & Webhook** settings
2. Paste the Web app URL into the **Webhook URL** field
3. Set **Result data format** to **json**
4. Click **Update the URL information**

#### Important Notes

* **Result data format must be set to `json`** — Google Apps Script's `JSON.parse(e.postData.contents)` expects JSON format. If set to `default`, the data will not be parsed correctly.
* **Re-deploy after code changes** — Every time you edit the Apps Script code, you must create a **New deployment** (not just save). The URL changes with each new deployment, so update the Webhook URL in Studio accordingly.
* **Google account permissions** — The script runs under your Google account. The first deployment requires authorization to access your Google Sheets.
* **Rate limits** — Google Apps Script has a daily quota (approximately 20,000 requests/day for free accounts). For high-traffic campaigns, consider a dedicated server instead.
* **Response time** — Apps Script may have a slight delay (1-3 seconds). This does not affect the game experience, as the webhook is sent asynchronously after the game ends.
* **Data privacy** — Game result data is stored in your Google Sheet. Ensure your spreadsheet sharing settings are appropriate for your data privacy requirements.

***

### Testing Your Webhook

You can test your webhook endpoint using curl:

```bash
curl -X POST https://your-webhook-url \
  -H "Content-Type: application/json" \
  -d '{"userid":"testuser","tx_id":"123456","time":"2025-04-10 06:39:23","score":"3500","playtime":"20"}'
```

Expected response: `S`

***

### Building a Leaderboard with Webhook Data

The webhook data you receive can be used to build your own leaderboard. Below are no-code and low-code options that receive scores and display rankings on your website.

***

#### Option 1: Zapier + KeepTheScore (Recommended)

Use [Zapier](https://zapier.com/) to receive the webhook and push scores to [KeepTheScore](https://keepthescore.com/), which provides a hosted leaderboard with real-time updates.

```
Game End → Webhook POST → Zapier (receive) → KeepTheScore API (push score)
                                                      ↓
                                        Embed leaderboard on your website
```

**Step 1: Create a Zap**

1. Go to [Zapier](https://zapier.com/) and create a new Zap
2. **Trigger**: Choose "Webhooks by Zapier" → "Catch Hook"
3. Copy the webhook URL provided by Zapier
4. Paste this URL into your campaign's **Webhook URL** field in Studio
5. Set **Result data format** to `json`

**Step 2: Create a KeepTheScore Board**

1. Go to [keepthescore.com](https://keepthescore.com/) and create a new leaderboard
2. Note your board ID from the URL (e.g., `https://keepthescore.com/board/xxxxxx/`)
3. Get your API key from the board settings

**Step 3: Connect Zapier to KeepTheScore**

1. **Action**: Choose "Webhooks by Zapier" → "POST"
2. URL: `https://keepthescore.com/api/xxxxxx/score/`
3. Payload Type: `json`
4. Data: Map `userid` → player name, `score` → score value

**Step 4: Embed on Your Website**

```html
<iframe src="https://keepthescore.com/board/xxxxxx/leaderboard/"
        width="100%" height="600" frameborder="0"></iframe>
```

| Feature           | Details                                                                               |
| ----------------- | ------------------------------------------------------------------------------------- |
| Real-time updates | Scores appear automatically                                                           |
| Filters           | All-time, daily, weekly, monthly                                                      |
| Pricing           | Basic free, premium features paid                                                     |
| WordPress         | [WP plugin](https://wordpress.com/plugins/keep-the-score) available (shortcode embed) |

***

#### Option 2: Airtable (Webhook + Data Management + Embed)

[Airtable](https://airtable.com/) can receive webhooks directly, store data, and embed a sorted view as a leaderboard.

**Step 1: Create a Base**

Create an Airtable base with these fields:

| Field    | Type             |
| -------- | ---------------- |
| userid   | Single line text |
| score    | Number           |
| tx\_id   | Single line text |
| time     | Date             |
| playtime | Number           |

**Step 2: Set Up Webhook Automation**

1. Go to **Automations** → Create automation
2. Trigger: **When webhook received**
3. Copy the webhook URL and paste it into Studio's Webhook URL field
4. Action: **Create record** — map the webhook fields to your table columns

**Step 3: Create a Leaderboard View**

1. Create a new **Grid view** named "Leaderboard"
2. Sort by `score` descending
3. Hide unnecessary columns (tx\_id, playtime, etc.)

**Step 4: Embed on Your Website**

1. Click **Share and sync** → **Embed this view**
2. Copy the iframe code

| Feature         | Details                                   |
| --------------- | ----------------------------------------- |
| Webhook         | Built-in, no middleware needed            |
| Data management | Filter, search, export                    |
| Pricing         | Free (1,000 records), Team $20/user/month |
| Limitation      | Embed uses Airtable's default styling     |

***

#### Option 3: Google Sheets + Common Ninja Widget

Combine the Google Sheets integration above with [Common Ninja's Leaderboard Widget](https://www.commoninja.com/widgets/leaderboard) for a visual leaderboard.

**Step 1:** Set up Google Sheets webhook receiver (see above)

**Step 2:** Create a Common Ninja leaderboard widget

1. Go to [commoninja.com/widgets/leaderboard](https://www.commoninja.com/widgets/leaderboard)
2. Create a new widget and configure the [API Integration](https://help.commoninja.com/hc/en-us/articles/17188672146205-How-to-Set-Up-API-Integration) to read from your Google Sheet
3. Customize the design (colors, layout, number of entries)

**Step 3:** Embed the widget on your website

```html
<!-- Common Ninja embed code (from widget settings) -->
<div class="commoninja_component" comp-type="leaderboard" comp-id="YOUR_WIDGET_ID"></div>
<script src="https://cdn.commoninja.com/sdk/latest/commonninja.js"></script>
```

| Feature     | Details                                                                         |
| ----------- | ------------------------------------------------------------------------------- |
| Design      | Highly customizable                                                             |
| Data source | Google Sheets, Airtable, or API                                                 |
| WordPress   | [WP plugin](https://www.commoninja.com/widgets/leaderboard/wordpress) available |
| Pricing     | Free tier available                                                             |

***

#### Option 4: Leaderboarded

[Leaderboarded.com](https://leaderboarded.com/) — dedicated leaderboard SaaS with API and WordPress support.

| Feature   | Details                                                            |
| --------- | ------------------------------------------------------------------ |
| API       | [REST API](https://leaderboarded.com/docs/api/) for pushing scores |
| Themes    | 40+ leaderboard themes                                             |
| Embed     | iframe, real-time updates                                          |
| WordPress | [WP shortcode embed](https://leaderboarded.com/docs/wordpress/)    |
| Pricing   | Free tier, embed requires Business plan                            |

***

#### Which Option Should I Choose?

|                          | Zapier + KeepTheScore | Airtable           | Sheets + Common Ninja | Leaderboarded     |
| ------------------------ | --------------------- | ------------------ | --------------------- | ----------------- |
| **Easiest setup**        | Good                  | Best               | Moderate              | Good              |
| **Leaderboard design**   | Good (themes)         | Basic              | Best (customizable)   | Good (40+ themes) |
| **Data management**      | Limited               | Best               | Good (Sheets)         | Limited           |
| **No middleware needed** | No (Zapier)           | Yes                | No (Apps Script)      | No (Zapier/Make)  |
| **WordPress plugin**     | Yes                   | No                 | Yes                   | Yes               |
| **Best for**             | Quick leaderboard     | Data + leaderboard | Custom design         | Themed boards     |
