---
name: TikTok Trends
description: Fetch top trending TikTok videos for a given country and generate an engagement report with optional video downloads.
version: 3
author: pastilhas
tags:
  - social-media
  - tiktok
  - trends
  - apify
  - content-analysis
tools:
  - apify
dependencies:
  - name: yt-dlp
    description: Required only when download option is enabled. Downloads TikTok videos.
    check_command: yt-dlp --version
    optional: true
inputs:
  - name: country
    description: Country code to fetch trending videos for.
    type: select
    default: PT
    required: false
    options:
      - value: PT
        label: Portugal
      - value: US
        label: United States
      - value: BR
        label: Brazil
      - value: GB
        label: United Kingdom
      - value: ES
        label: Spain
      - value: FR
        label: France
      - value: DE
        label: Germany
      - value: IT
        label: Italy
      - value: NL
        label: Netherlands
      - value: BE
        label: Belgium
      - value: PL
        label: Poland
      - value: RO
        label: Romania
      - value: SE
        label: Sweden
      - value: AT
        label: Austria
      - value: CH
        label: Switzerland
      - value: IE
        label: Ireland
      - value: CA
        label: Canada
      - value: AU
        label: Australia
      - value: MX
        label: Mexico
      - value: AR
        label: Argentina
      - value: CO
        label: Colombia
      - value: CL
        label: Chile
      - value: JP
        label: Japan
      - value: KR
        label: South Korea
      - value: IN
        label: India
      - value: TR
        label: Turkey
      - value: SA
        label: Saudi Arabia
      - value: AE
        label: United Arab Emirates
      - value: ZA
        label: South Africa
      - value: NG
        label: Nigeria
  - name: limit
    description: Number of trending videos to fetch (1-100).
    type: number
    default: 20
    min: 1
    max: 100
    required: false
  - name: download
    description: Download video files using yt-dlp (requires yt-dlp to be installed).
    type: boolean
    default: false
    required: false
outputs:
  - name: engagement_report
    description: Markdown report with trending videos analysis, engagement metrics, top hashtags, sounds, and creators.
    path: tiktok_trends_<country>_<timestamp>/report.md
  - name: raw_data
    description: Raw JSON data from Apify actor containing all video metadata.
    path: tiktok_trends_<country>_<timestamp>/raw.json
  - name: videos
    description: Downloaded video files (only present if download option was enabled).
    path: tiktok_trends_<country>_<timestamp>/videos/
    optional: true
config:
  timeout: 600
  retry_count: 0
---

# TikTok Trends

Fetch top trending TikTok videos for a given country and generate a comprehensive engagement report.

## Important

- Use the `apify` tool to fetch data. Do NOT call the Apify REST API directly via curl or fetch.
- Do NOT explore or list files before starting. Create the output directory, call the tool, process results.
- If `download` is false (default), do NOT attempt to download any videos.
- Large data files (like `raw.json`) exceed the 50KB read limit. Never try to read them directly. Instead, write a Node.js script to process and transform the data, execute it, then delete the script.

## Steps

### 1. Setup output directory

Create a timestamped output directory:
```
$HOME/tiktok-trends/tiktok_trends_<country>_<YYYYMMDD_HHMMSS>/
```

### 2. Fetch trending videos

Call the `apify` tool with `output_path` pointing to `raw.json` in the output directory:
```
apify(
  actor_id: "novi~fast-tiktok-scraper",
  input: { "type": "TREND", "region": "<country>", "maxItems": <limit> },
  output_path: "<output_dir>/raw.json"
)
```

The tool saves the full dataset to `raw.json` and returns a summary (item count). If it returns an error or 0 items, report the error and stop.

### 3. Generate engagement report

**Important:** The raw JSON file is too large to read directly (exceeds the 50KB read limit). Instead, write a Node.js script (e.g. `generate-report.js`) in the output directory that reads `raw.json`, processes the data, and writes `report.md`. Then execute it with `node generate-report.js`. Delete the script after it runs successfully.

The script should read `raw.json`, parse it as a JSON array of video items, and write `report.md` with the following sections:

#### Header
```markdown
# TikTok Trending Report — <COUNTRY> — YYYY-MM-DD

Total videos analyzed: <count>
```

#### Engagement Summary

Build a table from each video's `statistics` object (`play_count`, `digg_count`, `share_count`, `comment_count`):

| Metric | Total | Avg per video |
|--------|------:|-------------:|
| Views | ... | ... |
| Likes | ... | ... |
| Shares | ... | ... |
| Comments | ... | ... |

#### Top Hashtags (up to 20)

Extract hashtags from each video's `text_extra` array (entries where `hashtag_name` is set). If `text_extra` is empty, fall back to parsing `#tags` from the `desc` field. Count occurrences, sort descending.

| Hashtag | Count |
|---------|------:|

#### Top Sounds (up to 10)

From each video's `music` object, format as `title — author`. Count occurrences, sort descending.

| Sound | Count |
|-------|------:|

#### Creators Appearing in Trending (up to 10)

From each video's `author.unique_id`. Count occurrences, sort descending.

| Creator | Videos |
|---------|-------:|

#### Video List

Full table of all videos, sorted by position:

| # | Creator | Description | Views | Likes | URL |
|--:|---------|-------------|------:|------:|-----|

- Creator: `@author.unique_id`
- Description: first 60 chars of `desc`, pipe and newline characters replaced, with `...` if truncated
- URL: `share_url`
- Format numbers with locale separators (e.g. `1,234,567`)

### 4. Download videos (only if `download` is true)

If `download` is false, skip this step entirely.

If `download` is true:
1. Check that `yt-dlp` is installed
2. Create a `videos/` subdirectory in the output directory
3. Write all `share_url` values to a `urls.txt` file
4. Run: `yt-dlp -a urls.txt -o "videos/%(id)s.%(ext)s" --write-info-json --no-overwrites`
5. Report how many videos were downloaded. Partial failures are acceptable — do not fail the task if some downloads fail.

### 5. Report results

Print a summary to the user:
- Country and date
- Number of videos fetched
- Top video: `@creator` — views count — URL
- Top hashtag and count
- Output directory path
- Files created and their sizes

## Data Shape Reference

Each video item from the actor has this structure:
```json
{
  "aweme_id": "string",
  "desc": "video description with #hashtags",
  "create_time": 1234567890,
  "share_url": "https://www.tiktok.com/@user/video/123",
  "author": {
    "unique_id": "username",
    "nickname": "Display Name",
    "uid": "123"
  },
  "statistics": {
    "play_count": 1000000,
    "digg_count": 50000,
    "share_count": 5000,
    "comment_count": 2000,
    "collect_count": 1000,
    "download_count": 500
  },
  "music": {
    "title": "Sound Name",
    "author": "Sound Author"
  },
  "text_extra": [
    { "hashtag_name": "trending", "type": 1 }
  ]
}
```

## Error Handling

| Scenario | Action |
|----------|--------|
| Apify tool returns error | Report the error message. Common causes: invalid token, no credits, rate limits |
| Empty results | Report "No trending videos found for <country>" and stop |
| Partial results (fewer than requested) | Proceed normally, note the discrepancy in the summary |
| yt-dlp not installed when download=true | Report that yt-dlp is required and skip downloads |
| Download failures | Report which videos failed but do not fail the task |

## Notes

- The Apify actor may take 1-3 minutes depending on the limit
- Each run uses Apify compute units — monitor at https://console.apify.com/billing
- Not all countries have sufficient trending data; some may return fewer results than requested
