# Fitur "Publish to Telegram/X"

## Ringkasan

Fitur ini memungkinkan admin untuk mempublikasikan video ke Telegram dan X (Twitter) dengan title dan thumbnail yang dapat dikustomisasi, **tanpa mengubah data video original di database**.

## Fitur Utama

✅ **Tidak mengubah data original** - Video original tetap aman di database
✅ **Telegram & X support** - Publish ke kedua platform dengan satu interface
✅ **Custom title** - Ubah title untuk setiap publish tanpa mengubah original
✅ **Custom thumbnail** - Upload file baru, paste URL, atau gunakan original
✅ **Real-time preview** - Preview thumbnail saat memilih
✅ **Publish history** - Catat semua attempt publish dengan status dan error
✅ **Retry failed** - Ulang publish yang gagal
✅ **Queue job** - Publish diproses secara async via queue

## Struktur Database

### Table: `publish_logs`

```sql
CREATE TABLE publish_logs (
    id BIGINT PRIMARY KEY,
    video_id BIGINT NOT NULL,
    publish_title VARCHAR(255) NOT NULL,
    publish_thumbnail TEXT,
    platform ENUM('telegram', 'x') NOT NULL,
    platform_message_id VARCHAR(255),
    metadata JSON,
    status ENUM('pending', 'published', 'failed') DEFAULT 'pending',
    error_message TEXT,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);
```

**Field Explanation:**
- `video_id`: Reference ke video original
- `publish_title`: Title yang digunakan untuk publish (bisa berbeda dengan title original)
- `publish_thumbnail`: URL/path thumbnail yang digunakan untuk publish
- `platform`: 'telegram' atau 'x'
- `platform_message_id`: ID dari message/tweet di platform
- `metadata`: JSON data tambahan (chat_id untuk Telegram, tweet_id untuk X, dll)
- `status`: pending/published/failed
- `error_message`: Error message jika publish gagal

## Konfigurasi

### 1. Environment Variables (.env)

Tambahkan ke file `.env` Anda:

```env
# Telegram
TELEGRAM_BOT_TOKEN=123456:ABCdefGHIjklmnoPQRstuvWXYZ

# X (Twitter) - Gunakan API v2 Bearer Token
X_BEARER_TOKEN=AAAAAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional: Jika menggunakan API v1.1
X_API_KEY=xxxxxxxxxxxxx
X_API_SECRET=xxxxxxxxxxxxx
X_ACCESS_TOKEN=xxxxxxxxxxxxx
X_ACCESS_TOKEN_SECRET=xxxxxxxxxxxxx
```

### 2. Setup Telegram Bot

1. **Create Bot**: Talk to [@BotFather](https://t.me/BotFather) on Telegram
2. **Get Token**: Copy the bot token (format: `123456:ABCdefGHIjklmnoPQRstuvWXYZ`)
3. **Get Chat ID**: 
   - Untuk user pribadi: Talk to [@userinfobot](https://t.me/userinfobot)
   - Untuk grup: Add bot ke grup dan lihat message detail

### 3. Setup X (Twitter) API

1. **Apply for Access**: Go to [developer.twitter.com](https://developer.twitter.com)
2. **Create App**: Create a new application
3. **Get Credentials**:
   - For API v2: Get Bearer Token from "Keys and tokens" tab
   - For API v1.1: Get API Key, Secret, Access Token, and Secret

## File Structure

```
app/
├── Http/Controllers/Admin/PublishController.php    # Controller
├── Jobs/
│   ├── TelegramPublishJob.php                      # Queue job untuk Telegram
│   └── XPublishJob.php                             # Queue job untuk X
├── Models/
│   └── PublishLog.php                              # Model untuk publish history
├── Services/
│   ├── PublishService.php                          # Business logic
│   ├── TelegramBotService.php                      # Telegram API wrapper
│   └── XPublishService.php                         # X API wrapper
database/
├── migrations/
│   └── 2026_06_10_create_publish_logs_table.php    # Migration
resources/views/admin/videos/
├── publish-form.blade.php                          # Form untuk publish
└── publish-history.blade.php                       # History publish
config/
└── services.php                                    # Configuration
routes/
└── web.php                                         # Routes
```

## Routes

```
GET    /admin/videos/{video}/publish              - Show publish form
POST   /admin/videos/{video}/publish              - Process publish
GET    /admin/videos/{video}/publish-history      - Show history
POST   /admin/publish-logs/{log}/retry            - Retry failed publish
GET    /admin/publish-logs/{log}/status           - Get publish status (for polling)
```

## Usage

### 1. Migrate Database

Jalankan migration untuk membuat table `publish_logs`:

```bash
php artisan migrate
```

### 2. Access Publish Page

1. Go to Admin → Videos
2. Click "📢 Publish" button pada video yang ingin dipublikasikan
3. Atau langsung ke: `/admin/videos/{video_id}/publish`

### 3. Fill Publish Form

**Platform**: Pilih Telegram atau X

**Telegram-specific**:
- Masukkan Chat ID (user ID atau group ID)

**Publish Title**:
- Default terisi dari title original
- Bisa diubah untuk posting
- Max 500 chars (X akan truncate ke 280)

**Publish Thumbnail**:
- **Use Original**: Gunakan thumbnail video original
- **Upload File**: Upload image baru (max 5MB)
- **Paste URL**: Paste URL gambar dari internet

**Preview**:
- Real-time preview saat pilih thumbnail
- Menunjukkan gambar yang akan digunakan

### 4. Submit

Click "Publish" button. Publish akan di-queue untuk diproses async.

### 5. Monitor Status

- Lihat status di publish form page (auto-update)
- Atau go to Publish History: `/admin/videos/{video_id}/publish-history`
- Retry failed publish dari history page

## API Details

### TelegramBotService

```php
// Send photo ke Telegram
$telegramService->sendPhoto(
    chatId: 123456789,
    imageUrl: 'https://example.com/image.jpg',
    caption: 'Video Title'
); // Returns: message_id

// Send text message
$telegramService->sendMessage(
    chatId: 123456789,
    text: 'Pesan text'
);

// Verify bot
$telegramService->getMe(); // Returns: bot info
```

### XPublishService

```php
// Upload media
$mediaId = $xService->uploadMedia('https://example.com/image.jpg');

// Post tweet dengan media
$tweetId = $xService->postTweet(
    text: 'Tweet text (max 280 chars)',
    mediaId: $mediaId
);

// Verify credentials
$xService->getMe(); // Returns: user info
```

### PublishService

```php
// Prepare publish data (validate & sanitize)
$preparedData = $publishService->preparePublishData($video, [
    'publish_title' => 'Custom Title',
    'publish_thumbnail' => $uploadedFile, // atau null
    'publish_thumbnail_url' => 'https://...', // atau null
    'platform' => 'telegram',
]);

// Publish ke Telegram
$publishLog = $publishService->publishToTelegram($video, $preparedData, $chatId);

// Publish ke X
$publishLog = $publishService->publishToX($video, $preparedData);

// Get history
$history = $publishService->getPublishHistory($video, 'telegram');

// Get stats
$stats = $publishService->getPublishStats($video);
```

## Queue Setup

Publish dijalankan via queue job (async). Pastikan queue worker running:

```bash
# Development
php artisan queue:work

# Production (dengan supervisor)
# Setup supervisor config untuk queue:work
```

Konfigurasi queue: `config/queue.php`

## Error Handling

Jika publish gagal:
1. Status di PublishLog di-set ke 'failed'
2. Error message disimpan di `error_message` field
3. Email notification (optional)
4. Admin bisa retry dari history page

Contoh error:
- Invalid Telegram token
- Chat ID tidak valid
- X API authentication failed
- Image upload timeout
- Network error

## Logging

Semua activity di-log ke `storage/logs/laravel.log`:

```
[2026-06-10] INFO: Telegram publish successful - publish_log_id: 123, video_id: 45
[2026-06-10] ERROR: Telegram publish failed - error: Invalid chat ID
```

## Development Notes

### Classes Involved:

1. **PublishController** (`Admin/PublishController.php`)
   - Handle HTTP requests
   - Validate form input
   - Dispatch queue jobs

2. **PublishService** (`Services/PublishService.php`)
   - Prepare publish data
   - Validate thumbnail URL
   - Create PublishLog records
   - Get history & stats

3. **TelegramBotService** (`Services/TelegramBotService.php`)
   - Wrap Telegram Bot API
   - Send photo/message
   - Handle Telegram errors

4. **XPublishService** (`Services/XPublishService.php`)
   - Wrap X API v2
   - Upload media
   - Post tweets
   - Handle X errors

5. **TelegramPublishJob** (`Jobs/TelegramPublishJob.php`)
   - Execute Telegram publish
   - Update PublishLog status
   - Handle job failures

6. **XPublishJob** (`Jobs/XPublishJob.php`)
   - Execute X publish
   - Update PublishLog status
   - Handle job failures

7. **PublishLog Model** (`Models/PublishLog.php`)
   - ORM model untuk table `publish_logs`
   - Relationships & scopes

8. **Blade Views**:
   - `publish-form.blade.php` - Publish form dengan preview
   - `publish-history.blade.php` - History list

### Key Design Decisions:

✅ **No modification to Video model data** - All publish data stored in separate `publish_logs` table
✅ **Async processing** - Publish dijalankan via queue job untuk response time cepat
✅ **Flexible thumbnail** - Support upload file, paste URL, atau original
✅ **Real-time preview** - JavaScript untuk preview thumbnail real-time
✅ **History tracking** - Semua publish attempt disimpan untuk audit trail
✅ **Retry mechanism** - Admin bisa retry failed publish
✅ **Status polling** - Frontend poll status publish untuk real-time update

## Testing

### Manual Testing Checklist:

- [ ] Database migration works
- [ ] Can access publish form
- [ ] Preview works with original thumbnail
- [ ] Can upload custom thumbnail and see preview
- [ ] Can paste URL and see preview
- [ ] Can change publish title
- [ ] Telegram publish works
- [ ] X publish works
- [ ] Error handling works (invalid config)
- [ ] Can view publish history
- [ ] Can retry failed publish
- [ ] Video original data unchanged in database

### Test Data:

```php
// In tinker or seeder:
$video = Video::find(1);
$video->update([
    'title' => 'Test Video',
    'thumbnail_path' => 'path/to/thumbnail.jpg',
    'embed_url' => 'https://example.com/video',
]);
```

## Troubleshooting

### Telegram Bot Not Working

**Problem**: `Invalid chat ID` error

**Solution**:
1. Verify Telegram bot token di `.env`
2. Verify chat ID (gunakan @userinfobot)
3. Make sure bot is in group (jika group chat)
4. Test bot manual: `curl -X POST https://api.telegram.org/botXXXX/sendMessage -d "chat_id=123&text=test"`

### X (Twitter) Not Working

**Problem**: `Unauthorized` error

**Solution**:
1. Verify Bearer token di `.env`
2. Check X API access level (harus "Elevated")
3. Check app permissions (bisa write)
4. Test token: `curl -H "Authorization: Bearer XXX" https://api.twitter.com/2/users/me`

### Queue Job Not Processing

**Problem**: Publish stuck at 'pending'

**Solution**:
1. Check queue worker running: `ps aux | grep queue:work`
2. Check queue config: `config/queue.php`
3. Start worker: `php artisan queue:work`
4. Check failed jobs: `php artisan queue:failed`

### Thumbnail Upload Failed

**Problem**: Upload file tidak bisa

**Solution**:
1. Check disk permissions: `storage/app/public`
2. Check max file size: `php.ini` atau `.env`
3. Check disk space
4. Check file permissions: `chmod -R 775 storage`

## Future Enhancements

Possible improvements:
- [ ] Schedule publish (publish at specific time)
- [ ] Bulk publish multiple videos
- [ ] Template untuk publish title/caption
- [ ] Auto-publish on upload
- [ ] Pinterest integration
- [ ] TikTok integration
- [ ] YouTube integration
- [ ] Analytics (view count, engagement)
- [ ] Webhook untuk real-time status
- [ ] Publish to multiple platforms sekaligus

## References

- [Telegram Bot API](https://core.telegram.org/bots/api)
- [X API v2](https://developer.twitter.com/en/docs/twitter-api)
- [Laravel Queue](https://laravel.com/docs/queues)
- [Laravel Storage](https://laravel.com/docs/filesystem)
