# X (Twitter) Giveaway Winner Picker - Random Reply Picker (`jan.jiran/twitter-giveaway-picker`) Actor

Pick a random winner from Twitter comments on any tweet. Free, fair giveaway/contest winner picker: set the number of winners, require tagging a friend or a hashtag, and export the results. Works for AI assistants too.

- **URL**: https://apify.com/jan.jiran/twitter-giveaway-picker.md
- **Developed by:** [Jan Jiran](https://apify.com/jan.jiran) (community)
- **Categories:** AI, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.20 / actor start

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Twitter Giveaway Winner Picker 🎉 - Free & Fair Random Comment Picker

**Pick a random winner from your Twitter comments in seconds.** This Twitter
giveaway picker (a.k.a. random comment winner generator) reads the comments on any
Twitter **video**, applies the giveaway rules you choose, and randomly draws one or
more winners for you - no manual scrolling, copy‑pasting, or screenshots required.

Perfect for **Twitter giveaways, contests, raffles, and prize draws** run by
creators, small businesses, shops, and marketing teams who want a fast, transparent,
and fair way to choose a winner.

> 💡 **Not a developer?** You don't need to be. Just paste your video link, choose how
> many winners you want, and click **Start**. Results appear in a clean table you can
> download as Excel, CSV, or JSON.

---

### What you can use it for

- 🎁 **Twitter giveaway winner picker** - draw a fair winner from comments.
- 🏆 **Contest & raffle draws** - pick multiple winners at once.
- 🤝 **"Tag a friend" promotions** - only count comments that tag someone.
- #️⃣ **Hashtag / keyword campaigns** - only count comments containing your keyword.
- 📊 **Comment exports** - get a clean list of everyone who commented.

### How to pick a winner in 3 steps

1. **Paste your Twitter link.** Add one or more video URLs (e.g.
   `https://x.com/apify/status/1234567890`).
2. **Choose your rules.** Set how many winners you want and, optionally, require
   tagging a friend or a specific keyword/hashtag.
3. **Click Start.** In under a minute you get your randomly drawn winner(s), ready to
   announce. Download them as Excel/CSV/JSON or copy them straight from the table.

That's it - no login to your Twitter account needed.

### Settings explained (in plain English)

| Setting | What it does |
| --- | --- |
| **Twitter video URLs** | The video(s) you're running the giveaway on. You can add several and the comments are combined into one pool. |
| **Number of winners** | How many winners to randomly draw. |
| **Max comments per video** | How many comments to read per video. Higher = more thorough (and slightly more credits). |
| **Unique users only** | On by default - the same person can't win twice, even if they commented many times. |
| **Must mention/tag someone** | Only count comments that tag a friend (e.g. `@bestie`). Great for "tag a friend" rules. |
| **Required keyword / hashtag** | Only count comments that include your word or hashtag (e.g. `#giveaway`). |

#### Example settings

```json
{
    "postUrls": ["https://x.com/apify/status/1234567890"],
    "numberOfWinners": 3,
    "maxCommentsPerPost": 200,
    "uniqueUsers": true,
    "requireMention": true,
    "requiredKeyword": "#giveaway"
}
````

### What you get (results)

- A **Winners** table with each winner's username, their comment, the video link, and
  when they commented - exportable to **Excel, CSV, JSON, or HTML**.
- A summary record (`OUTPUT`) with the winners plus useful stats: total comments read,
  how many were eligible after your rules, and the settings used - handy proof that the
  draw was fair.
- A **🎬 winner reveal link** (in the run's Output tab) that opens an animated, shareable
  draw on [giveaways-picker.com](https://giveaways-picker.com) using your real results -
  perfect for recording the moment you pick the winner for your audience.

#### 🎬 Interactive winner reveal

Every successful run produces a `reveal` link in the Output tab (also `revealUrl` in the
`OUTPUT` record). Opening it plays a suspenseful, animated draw that shuffles through the
real eligible commenters and lands on your actual winner(s) - ideal for going live or
recording the reveal.

### 🤖 Use it with AI assistants (ChatGPT, Claude & others)

This Actor is built to be **AI‑agent friendly**, so assistants like **ChatGPT, Claude,
and other LLM tools** can run your giveaway for you when asked something like
*"pick a random winner from the comments on this Twitter video."*

Apify exposes every Actor as a tool through the **[Apify MCP server](https://mcp.apify.com)**
([docs](https://docs.apify.com/platform/integrations/mcp)). Once connected, an AI
assistant can discover this Twitter giveaway picker and call it directly.

### Frequently asked questions

**Is this a fair / random Twitter comment picker?**
Yes. Eligible comments are shuffled with a uniform random draw, so every qualifying
comment has an equal chance. The result includes the comment count and rules used, so
you can show your audience the draw was unbiased.

**Can I pick more than one winner?**
Yes - set **Number of winners** to any amount. You can also keep it fair by leaving
**Unique users only** on, so one person can't take multiple prizes.

**Do I need to log in to Twitter?**
No. You only provide the public video link.

**Can I require people to tag a friend or use a hashtag?**
Yes - turn on **Must mention/tag someone** and/or set a **Required keyword/hashtag**.

**Is it free?**
The Actor itself is lightweight, but it reads comments via a dedicated Twitter comment
scraper, which uses a small amount of Apify platform credits per run. New Apify accounts
include free monthly usage to get started.

***

### For developers

This is an [Apify Actor](https://apify.com/actors) written in **TypeScript**. It calls a
dedicated Twitter comment scraper Actor (configurable via `COMMENT_SCRAPER_ACTOR_ID` in
`src/main.ts`, default `clappi/x-twitter-comments-scraper`) to collect comments, then
de‑duplicates, filters, and randomly draws winners. The scraper's output fields are
normalised, so it keeps working even if the scraper labels comment fields differently.

#### Input schema

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `postUrls` | `string[]` | ✅ | - | Twitter video URLs. Comments are pooled across all of them. |
| `numberOfWinners` | `integer` | ✅ | `1` | How many winners to randomly pick. |
| `maxCommentsPerPost` | `integer` | - | `100` | Max comments scraped per video (1–1000). |
| `uniqueUsers` | `boolean` | - | `true` | Each username can win at most once (first comment per user is kept). |
| `requireMention` | `boolean` | - | `false` | Only comments tagging another account (`@someone`) are eligible. |
| `requiredKeyword` | `string` | - | - | Only comments containing this keyword/hashtag (case‑insensitive) are eligible. |

#### Output

- **Default dataset** - one record per winner (`winnerRank`, `ownerUsername`, `text`,
  `postUrl`, `timestamp`, …).
- **Key‑value store `OUTPUT`** - summary: `winners`, `totalComments`, `eligibleCount`,
  the applied `filters`, the input `postUrls`, and the `revealUrl`.

#### Run locally

```bash
npm install
## A token is required because the Actor calls a paid Apify Actor:
export APIFY_TOKEN=your_apify_api_token
## Put your input in storage/key_value_stores/default/INPUT.json, then:
npm start
```

Build the production JavaScript with `npm run build`. Deploy with
[`apify push`](https://docs.apify.com/cli).

### Limitations & disclaimer

The underlying comment scraper sees publicly available comments, so results can differ
slightly from what you see while logged in to Twitter. This tool is not affiliated with or
endorsed by X or X Corp. Always follow Twitter's promotion guidelines when running
giveaways.

# Actor input Schema

## `postUrls` (type: `array`):

One or more Twitter post URLs to collect comments from. Comments are pooled across all posts before the draw.

## `numberOfWinners` (type: `integer`):

How many winning comments to randomly pick from the eligible pool.

## `maxCommentsPerPost` (type: `integer`):

Maximum number of comments to scrape per post. Higher values are more thorough but cost slightly more.

## `uniqueUsers` (type: `boolean`):

If enabled, each Twitter user can win at most once even if they commented multiple times. The first comment per user is kept.

## `requireMention` (type: `boolean`):

If enabled, only comments that tag at least one other account (e.g. @friend) are eligible. Common giveaway rule.

## `requiredKeyword` (type: `string`):

If set, only comments containing this keyword or hashtag (case-insensitive) are eligible.

## Actor input object example

```json
{
  "postUrls": [
    "https://x.com/apify/status/1234567890"
  ],
  "numberOfWinners": 1,
  "maxCommentsPerPost": 1000,
  "uniqueUsers": true,
  "requireMention": false
}
```

# Actor output Schema

## `reveal` (type: `string`):

An animated, shareable winner reveal — perfect for recording the live draw for your audience.

## `winners` (type: `string`):

The randomly selected winning comments, ready to announce.

## `summary` (type: `string`):

Winners plus stats: total comments read, how many were eligible, and the filters applied — proof the draw was fair.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "postUrls": [
        "https://x.com/username/status/1234567890"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jan.jiran/twitter-giveaway-picker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "postUrls": ["https://x.com/username/status/1234567890"] }

# Run the Actor and wait for it to finish
run = client.actor("jan.jiran/twitter-giveaway-picker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "postUrls": [
    "https://x.com/username/status/1234567890"
  ]
}' |
apify call jan.jiran/twitter-giveaway-picker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=jan.jiran/twitter-giveaway-picker",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "X (Twitter) Giveaway Winner Picker - Random Reply Picker",
        "description": "Pick a random winner from Twitter comments on any tweet. Free, fair giveaway/contest winner picker: set the number of winners, require tagging a friend or a hashtag, and export the results. Works for AI assistants too.",
        "version": "0.1",
        "x-build-id": "izwaJIiygeqfXfnnE"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/jan.jiran~twitter-giveaway-picker/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-jan.jiran-twitter-giveaway-picker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/jan.jiran~twitter-giveaway-picker/runs": {
            "post": {
                "operationId": "runs-sync-jan.jiran-twitter-giveaway-picker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/jan.jiran~twitter-giveaway-picker/run-sync": {
            "post": {
                "operationId": "run-sync-jan.jiran-twitter-giveaway-picker",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "postUrls",
                    "numberOfWinners"
                ],
                "properties": {
                    "postUrls": {
                        "title": "Twitter post URLs",
                        "type": "array",
                        "description": "One or more Twitter post URLs to collect comments from. Comments are pooled across all posts before the draw.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "numberOfWinners": {
                        "title": "Number of winners",
                        "minimum": 1,
                        "type": "integer",
                        "description": "How many winning comments to randomly pick from the eligible pool.",
                        "default": 1
                    },
                    "maxCommentsPerPost": {
                        "title": "Max comments per post",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of comments to scrape per post. Higher values are more thorough but cost slightly more.",
                        "default": 1000
                    },
                    "uniqueUsers": {
                        "title": "Unique users only",
                        "type": "boolean",
                        "description": "If enabled, each Twitter user can win at most once even if they commented multiple times. The first comment per user is kept.",
                        "default": true
                    },
                    "requireMention": {
                        "title": "Must mention/tag someone",
                        "type": "boolean",
                        "description": "If enabled, only comments that tag at least one other account (e.g. @friend) are eligible. Common giveaway rule.",
                        "default": false
                    },
                    "requiredKeyword": {
                        "title": "Required keyword / hashtag",
                        "type": "string",
                        "description": "If set, only comments containing this keyword or hashtag (case-insensitive) are eligible."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
