Un tracker de campagne UGC TikTok recherche des vidéos utilisant le hashtag de votre campagne via l'API de recherche TikTok, collecte les pseudos des créateurs et les statistiques d'engagement, et enregistre des instantanés quotidiens pour mesurer la portée de la campagne dans le temps.
Prérequis
- Python 3.9+
- Clé API Scavio avec accès TikTok
- SQLite (stdlib)
Parcours
Étape 1: Rechercher des vidéos TikTok par hashtag de campagne
Utilisez search/videos avec votre hashtag comme requête pour trouver toutes les publications UGC.
import requests
API_KEY = "your-scavio-api-key"
CAMPAIGN_HASHTAG = "#YourCampaign2026"
def get_campaign_videos(hashtag: str, max_pages: int = 5) -> list:
tag = hashtag.lstrip("#")
all_videos = []
cursor = 0
for _ in range(max_pages):
r = requests.post(
"https://api.scavio.dev/api/v1/tiktok/search/videos",
json={"query": f"#{tag}", "cursor": cursor, "count": 30},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=20
)
r.raise_for_status()
data = r.json()
batch = data.get("videos", [])
if not batch:
break
all_videos.extend(batch)
if not data.get("has_more"):
break
cursor = data.get("cursor", 0)
return all_videosÉtape 2: Extraire les données des créateurs et d'engagement
Analyser chaque vidéo pour obtenir le pseudo du créateur, le nombre de vues, de likes et de partages.
def extract_video_stats(videos: list) -> list:
records = []
for v in videos:
stats = v.get("stats", {})
records.append({
"video_id": v.get("id"),
"creator": v.get("author", {}).get("uniqueId"),
"description": v.get("desc", "")[:100],
"plays": stats.get("playCount", 0),
"likes": stats.get("diggCount", 0),
"comments": stats.get("commentCount", 0),
"shares": stats.get("shareCount", 0)
})
return recordsÉtape 3: Stocker dans SQLite et calculer les totaux
Enregistrer des instantanés quotidiens et additionner l'engagement à l'échelle de la campagne.
import sqlite3
from datetime import date
def init_db(path="ugc_tracker.db"):
conn = sqlite3.connect(path)
conn.execute("""
CREATE TABLE IF NOT EXISTS ugc_posts (
date TEXT, video_id TEXT, creator TEXT,
plays INTEGER, likes INTEGER, comments INTEGER, shares INTEGER,
PRIMARY KEY (date, video_id)
)
""")
conn.commit()
return conn
def save_and_summarize(conn, records: list) -> dict:
today = str(date.today())
for r in records:
conn.execute("INSERT OR REPLACE INTO ugc_posts VALUES (?,?,?,?,?,?,?)",
(today, r["video_id"], r["creator"], r["plays"], r["likes"], r["comments"], r["shares"]))
conn.commit()
totals = {"posts": len(records), "total_plays": sum(r["plays"] for r in records),
"total_likes": sum(r["likes"] for r in records),
"unique_creators": len(set(r["creator"] for r in records))}
return totalsExemple Python
import requests
import sqlite3
from datetime import date
API_KEY = "your-scavio-api-key"
CAMPAIGN_HASHTAG = "YourCampaign2026"
def get_campaign_videos(hashtag, max_pages=5):
all_videos, cursor = [], 0
for _ in range(max_pages):
r = requests.post("https://api.scavio.dev/api/v1/tiktok/search/videos",
json={"query": f"#{hashtag}", "cursor": cursor, "count": 30},
headers={"Authorization": f"Bearer {API_KEY}"}, timeout=20)
r.raise_for_status()
data = r.json()
batch = data.get("videos", [])
if not batch: break
all_videos.extend(batch)
if not data.get("has_more"): break
cursor = data.get("cursor", 0)
return all_videos
def extract_stats(videos):
return [{"video_id": v.get("id"), "creator": v.get("author",{}).get("uniqueId"),
"plays": v.get("stats",{}).get("playCount",0),
"likes": v.get("stats",{}).get("diggCount",0),
"shares": v.get("stats",{}).get("shareCount",0)} for v in videos]
def init_db(path="ugc_tracker.db"):
conn = sqlite3.connect(path)
conn.execute("CREATE TABLE IF NOT EXISTS ugc (date TEXT, video_id TEXT, creator TEXT, plays INTEGER, likes INTEGER, shares INTEGER, PRIMARY KEY (date, video_id))")
conn.commit()
return conn
def run_tracker():
conn = init_db()
videos = get_campaign_videos(CAMPAIGN_HASHTAG)
records = extract_stats(videos)
today = str(date.today())
for r in records:
conn.execute("INSERT OR REPLACE INTO ugc VALUES (?,?,?,?,?,?)",
(today, r["video_id"], r["creator"], r["plays"], r["likes"], r["shares"]))
conn.commit()
total_plays = sum(r["plays"] for r in records)
unique_creators = len(set(r["creator"] for r in records))
top = sorted(records, key=lambda x: x["plays"], reverse=True)[:3]
print(f"Campaign #{CAMPAIGN_HASHTAG} — {today}")
print(f"Posts: {len(records)} | Creators: {unique_creators} | Total plays: {total_plays:,}")
print("\nTop posts:")
for r in top:
print(f" @{r['creator']}: {r['plays']:,} plays")
if __name__ == "__main__":
run_tracker()Exemple JavaScript
const API_KEY = 'your-scavio-api-key';
const HASHTAG = 'YourCampaign2026';
async function getCampaignVideos(hashtag, maxPages = 5) {
const videos = [];
let cursor = 0;
for (let i = 0; i < maxPages; i++) {
const res = await fetch('https://api.scavio.dev/api/v1/tiktok/search/videos', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${API_KEY}` },
body: JSON.stringify({ query: `#${hashtag}`, cursor, count: 30 })
});
const data = await res.json();
const batch = data.videos ?? [];
if (!batch.length) break;
videos.push(...batch);
if (!data.has_more) break;
cursor = data.cursor ?? 0;
}
return videos;
}
const videos = await getCampaignVideos(HASHTAG);
const totalPlays = videos.reduce((s, v) => s + (v.stats?.playCount ?? 0), 0);
const creators = new Set(videos.map(v => v.author?.uniqueId)).size;
console.log(`Posts: ${videos.length} | Creators: ${creators} | Total plays: ${totalPlays.toLocaleString()}`);Sortie attendue
Campaign #YourCampaign2026 - 2026-05-22
Posts: 147 | Creators: 89 | Total plays: 4,821,032
Top posts:
@topcreatora: 892,441 plays
@creatorb: 441,209 plays
@creatorc: 312,887 plays