# Token Giveaway System

## Overview

The token giveaway system allows admins to run campaigns where the first N new users automatically receive free tokens. This is separate from the existing discount promo system.

## Features

- **Admin Commands**: Start/stop giveaway campaigns with custom token amounts
- **Automatic Grants**: New users receive tokens silently upon first interaction
- **Welcome Message**: `/start` command shows special welcome message for recipients
- **Race Condition Safe**: Uses EXCLUSIVE transaction locks to prevent double-grants
- **Audit Trail**: All grants logged in transactions table with type='giveaway'
- **Campaign Statistics**: Track how many users received tokens

## Admin Commands

### `/giveaway_start <users> [tokens]`

Start a new giveaway campaign.

**Examples:**
```
/giveaway_start 100         # First 100 users get 3 tokens (default)
/giveaway_start 50 5        # First 50 users get 5 tokens
```

**Parameters:**
- `users` (required): Number of slots available
- `tokens` (optional): Tokens per user (defaults to 3)

**Response:**
```
✅ Раздача токенов запущена!

👥 Пользователей: 100
🎁 Токенов каждому: 3
📊 Всего токенов: 300
```

### `/giveaway_stop`

Stop the active giveaway campaign.

**Response:**
```
✅ Раздача токенов остановлена

📊 Статистика:
👥 Пользователей получили: 47
🎁 Токенов роздано: 141
📉 Осталось слотов: 53
```

## User Experience

### New User via `/start`

When a giveaway is active, new users who send `/start` see:

```
🎁 Добро пожаловать!

Вы получили 3 бесплатных генераций!

🎬 VideoBot — AI-видео для карточек Wildberries
...
```

### Other Entry Points

Users who first interact via other entry points (submitting URL, clicking buy, accepting terms) receive tokens **silently** - no special message. If they later use `/start`, they won't see the welcome bonus message (already received).

## Technical Details

### Database Schema

**giveaway_config table:**
```sql
CREATE TABLE giveaway_config (
    key TEXT PRIMARY KEY,
    value TEXT NOT NULL
);
```

Keys:
- `active`: '0' or '1' (is campaign running?)
- `tokens_per_user`: '3' (tokens to grant)
- `remaining_users`: '100' (slots left)
- `started_at`: timestamp (for stats calculation)
- `started_by`: admin user_id

**users table addition:**
```sql
ALTER TABLE users ADD COLUMN giveaway_received INTEGER DEFAULT 0;
```

Prevents double-grants even across multiple campaigns.

### Transaction Types

Giveaway grants create transactions with:
- `type`: 'giveaway'
- `description`: 'Welcome bonus: N free tokens'
- `amount`: positive integer (tokens granted)

### Race Condition Handling

`check_and_grant_giveaway()` uses EXCLUSIVE transaction lock:

```python
conn.execute("BEGIN EXCLUSIVE")
# Check eligibility, grant tokens, decrement counter
conn.commit()
```

This ensures serialization when multiple users sign up simultaneously.

### Integration Points

1. **telegram_bot.py** - `/start` command
   - Checks if user is new
   - Calls `check_and_grant_giveaway(user_id, is_new=True)`
   - Customizes welcome message if tokens granted

2. **telegram_bot.py** - URL handler, product_id handler
   - Silently checks giveaway on user creation

3. **telegram_bot.py** - Terms acceptance
   - Silently checks giveaway when user accepts terms

4. **payment_handlers.py** - `/buy` command
   - Silently checks giveaway when user visits buy page

5. **viewer_bot.py** - Admin commands
   - `/giveaway-start` and `/giveaway-stop`

## Testing

47 total tests, including 8 new giveaway tests:

```bash
cd /home/videobot/dev/scripts
../venv/bin/python test_token_system.py
```

**Giveaway Test Coverage:**
- ✅ Start/stop campaigns
- ✅ Grant to new users
- ✅ Deny to existing users
- ✅ Slot exhaustion
- ✅ Inactive giveaway
- ✅ Double-grant prevention
- ✅ Transaction audit logging
- ✅ Campaign statistics

## Usage Example

```bash
# Admin starts giveaway
/giveaway_start 100 5

# User1 sends /start
→ Receives: "🎁 Добро пожаловать! Вы получили 5 бесплатных генераций!"
→ Balance: 5 tokens

# User2 submits URL without /start
→ Silent grant
→ Balance: 5 tokens

# User2 later sends /start
→ Normal welcome (no bonus message)

# After 100 users
# User101 sends /start
→ Normal welcome (slots exhausted)
→ Balance: 0 tokens

# Admin stops giveaway
/giveaway_stop
→ Shows stats: 100 users received 500 tokens
```

## Differences from Promo System

| Feature | Promo System | Giveaway System |
|---------|--------------|-----------------|
| **Purpose** | Discount pricing on purchases | Free tokens for new users |
| **Trigger** | User makes first purchase | User first interacts with bot |
| **Visibility** | Shown in /buy pricing | Welcome message (only in /start) |
| **Eligibility** | `is_promo_eligible` flag | `giveaway_received` flag |
| **Management** | `/promo <count>` | `/giveaway-start` / `/giveaway-stop` |
| **Transaction Type** | 'purchase' (with promo pricing) | 'giveaway' |
| **Depletion** | Promo counter decrements on purchase | Giveaway counter decrements on grant |

Both systems can run simultaneously - a user could receive giveaway tokens AND later buy at promo pricing.

## Files Modified

- `scripts/database.py` - Schema, giveaway config CRUD
- `scripts/token_manager.py` - `check_and_grant_giveaway()` logic
- `viewer/viewer_bot.py` - Admin commands
- `scripts/telegram_bot.py` - User integration (/start, URL, terms)
- `scripts/payment_handlers.py` - Buy page integration
- `scripts/test_token_system.py` - Test coverage

## Implementation Date

2025-02-02
