docs YouTube Analytics API 수정 및 오디언스 인사이트 단위 수정
parent
a1192193e5
commit
8fe0512608
|
|
@ -267,7 +267,7 @@ async def get_dashboard_stats(
|
|||
Dashboard.platform == "youtube",
|
||||
Dashboard.platform_user_id == social_account.platform_user_id,
|
||||
Dashboard.uploaded_at >= start_dt,
|
||||
Dashboard.uploaded_at <= kpi_end_dt,
|
||||
Dashboard.uploaded_at <= end_dt,
|
||||
)
|
||||
)
|
||||
period_video_count = count_result.scalar() or 0
|
||||
|
|
|
|||
|
|
@ -418,8 +418,8 @@ class DataProcessor:
|
|||
# === 연령/성별 데이터 처리 ===
|
||||
demo_rows = demographics_data.get("rows", [])
|
||||
|
||||
age_map: dict[str, int] = {}
|
||||
gender_map = {"male": 0, "female": 0}
|
||||
age_map: dict[str, float] = {}
|
||||
gender_map_f: dict[str, float] = {"male": 0.0, "female": 0.0}
|
||||
|
||||
for row in demo_rows:
|
||||
if len(row) < 3:
|
||||
|
|
@ -427,27 +427,21 @@ class DataProcessor:
|
|||
|
||||
age_group = row[0] # "age18-24"
|
||||
gender = row[1] # "male" or "female"
|
||||
views = row[2]
|
||||
viewer_pct = row[2] # viewerPercentage (이미 % 값, 예: 45.5)
|
||||
|
||||
# 연령대별 집계 (age18-24 → 18-24)
|
||||
# 연령대별 집계: 남녀 비율 합산 (age18-24 → 18-24)
|
||||
age_label = age_group.replace("age", "")
|
||||
age_map[age_label] = age_map.get(age_label, 0) + views
|
||||
age_map[age_label] = age_map.get(age_label, 0.0) + viewer_pct
|
||||
|
||||
# 성별 집계
|
||||
if gender in gender_map:
|
||||
gender_map[gender] += views
|
||||
if gender in gender_map_f:
|
||||
gender_map_f[gender] += viewer_pct
|
||||
|
||||
# 연령대별 비율 계산
|
||||
total_demo_views = sum(age_map.values())
|
||||
age_groups = [
|
||||
{
|
||||
"label": age,
|
||||
"percentage": int(
|
||||
(count / total_demo_views * 100) if total_demo_views > 0 else 0
|
||||
),
|
||||
}
|
||||
for age, count in sorted(age_map.items())
|
||||
{"label": age, "percentage": int(round(pct))}
|
||||
for age, pct in sorted(age_map.items())
|
||||
]
|
||||
gender_map = {k: int(round(v)) for k, v in gender_map_f.items()}
|
||||
|
||||
# === 지역 데이터 처리 ===
|
||||
geo_rows = geography_data.get("rows", [])
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ class YouTubeAnalyticsService:
|
|||
self._fetch_monthly_data(video_ids, previous_start, previous_end, access_token),
|
||||
self._fetch_top_videos(video_ids, start_date, _kpi_end, access_token),
|
||||
self._fetch_demographics(start_date, _kpi_end, access_token),
|
||||
self._fetch_region(video_ids, start_date, _kpi_end, access_token),
|
||||
self._fetch_region(start_date, _kpi_end, access_token),
|
||||
]
|
||||
else: # mode == "day"
|
||||
tasks = [
|
||||
|
|
@ -134,7 +134,7 @@ class YouTubeAnalyticsService:
|
|||
self._fetch_daily_data(video_ids, day_previous_start, day_previous_end, access_token),
|
||||
self._fetch_top_videos(video_ids, start_date, end_date, access_token),
|
||||
self._fetch_demographics(start_date, end_date, access_token),
|
||||
self._fetch_region(video_ids, start_date, end_date, access_token),
|
||||
self._fetch_region(start_date, end_date, access_token),
|
||||
]
|
||||
|
||||
# 병렬 실행
|
||||
|
|
@ -206,8 +206,6 @@ class YouTubeAnalyticsService:
|
|||
estimatedMinutesWatched, averageViewDuration,
|
||||
subscribersGained]
|
||||
|
||||
Note:
|
||||
annotationClickThroughRate는 2019년 annotations 기능 제거로 deprecated.
|
||||
"""
|
||||
logger.debug(
|
||||
f"[YouTubeAnalyticsService._fetch_kpi] START - video_count={len(video_ids)}"
|
||||
|
|
@ -218,7 +216,7 @@ class YouTubeAnalyticsService:
|
|||
"startDate": start_date,
|
||||
"endDate": end_date,
|
||||
"metrics": "views,likes,comments,shares,estimatedMinutesWatched,averageViewDuration,subscribersGained",
|
||||
# "filters": f"video=={','.join(video_ids)}",
|
||||
"filters": f"video=={','.join(video_ids)}",
|
||||
}
|
||||
|
||||
result = await self._call_api(params, access_token)
|
||||
|
|
@ -393,7 +391,6 @@ class YouTubeAnalyticsService:
|
|||
|
||||
async def _fetch_region(
|
||||
self,
|
||||
video_ids: list[str],
|
||||
start_date: str,
|
||||
end_date: str,
|
||||
access_token: str,
|
||||
|
|
@ -403,7 +400,6 @@ class YouTubeAnalyticsService:
|
|||
지역별 조회수 분포를 조회합니다 (상위 5개).
|
||||
|
||||
Args:
|
||||
video_ids: YouTube 영상 ID 리스트
|
||||
start_date: 조회 시작일 (YYYY-MM-DD)
|
||||
end_date: 조회 종료일 (YYYY-MM-DD)
|
||||
access_token: OAuth 2.0 액세스 토큰
|
||||
|
|
@ -421,9 +417,7 @@ class YouTubeAnalyticsService:
|
|||
"endDate": end_date,
|
||||
"dimensions": "country",
|
||||
"metrics": "views",
|
||||
"filters": f"video=={','.join(video_ids)}",
|
||||
"sort": "-views",
|
||||
"maxResults": "5",
|
||||
}
|
||||
|
||||
result = await self._call_api(params, access_token)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ API 요청 시 `dimensions` 파라미터에 들어갈 수 있는 값들입니다
|
|||
| -------------- | ------- | --------------------------- | -------------- |
|
||||
| `**ageGroup`** | **연령대** | 시청자 연령 분포 (18-24, 25-34...) | `video`와 혼용 불가 |
|
||||
| `**gender`** | **성별** | 남녀 성비 (male, female) | `video`와 혼용 불가 |
|
||||
| `**country`** | **국가** | 국가별 시청자 수 (KR, US...) | 지도 차트용 |
|
||||
| `**country`** | **국가** | 국가별 시청자 수 (KR, US...) | 지도 차트용, 채널 전체 기준 |
|
||||
|
||||
|
||||
### C. 유입 및 기기 (Traffic Device)
|
||||
|
|
@ -84,22 +84,76 @@ API 요청 시 `dimensions` 파라미터에 들어갈 수 있는 값들입니다
|
|||
|
||||
---
|
||||
|
||||
## 3. 자주 쓰는 조합 (Best Practice)
|
||||
## 3. 현재 사용 중인 API 호출 조합
|
||||
|
||||
대시보드에서 실제로 사용하는 7가지 호출 조합입니다. 모두 `ids=channel==MINE`으로 고정합니다.
|
||||
|
||||
### 1. KPI 요약 (`_fetch_kpi`) — 현재/이전 기간 각 1회
|
||||
|
||||
| 파라미터 | 값 |
|
||||
| ---------- | ------------------------------------------------------------------------------------- |
|
||||
| dimensions | (없음) |
|
||||
| metrics | `views, likes, comments, shares, estimatedMinutesWatched, averageViewDuration, subscribersGained` |
|
||||
| filters | `video==ID1,ID2,...` (업로드된 영상 ID 최대 30개) |
|
||||
|
||||
> 현재/이전 기간을 각각 호출하여 trend(증감률) 계산에 사용.
|
||||
|
||||
---
|
||||
|
||||
### 2. 월별 추이 차트 (`_fetch_monthly_data`) — 최근 12개월 / 이전 12개월 각 1회
|
||||
|
||||
| 파라미터 | 값 |
|
||||
| ---------- | -------------------- |
|
||||
| dimensions | `month` |
|
||||
| metrics | `views` |
|
||||
| filters | `video==ID1,ID2,...` |
|
||||
| sort | `month` |
|
||||
|
||||
---
|
||||
|
||||
### 3. 일별 추이 차트 (`_fetch_daily_data`) — 최근 30일 / 이전 30일 각 1회
|
||||
|
||||
| 파라미터 | 값 |
|
||||
| ---------- | -------------------- |
|
||||
| dimensions | `day` |
|
||||
| metrics | `views` |
|
||||
| filters | `video==ID1,ID2,...` |
|
||||
| sort | `day` |
|
||||
|
||||
---
|
||||
|
||||
### 4. 인기 영상 TOP 4 (`_fetch_top_videos`)
|
||||
|
||||
| 파라미터 | 값 |
|
||||
| ---------- | ------------------------ |
|
||||
| dimensions | `video` |
|
||||
| metrics | `views, likes, comments` |
|
||||
| filters | `video==ID1,ID2,...` |
|
||||
| sort | `-views` |
|
||||
| maxResults | `4` |
|
||||
|
||||
---
|
||||
|
||||
### 5. 시청자 연령/성별 분포 (`_fetch_demographics`) — 채널 전체 기준
|
||||
|
||||
| 파라미터 | 값 |
|
||||
| ---------- | ----------------------- |
|
||||
| dimensions | `ageGroup, gender` |
|
||||
| metrics | `viewerPercentage` |
|
||||
|
||||
> `ageGroup`, `gender` 차원은 `video` 필터와 혼용 불가 → 채널 전체 시청자 기준.
|
||||
|
||||
---
|
||||
|
||||
### 6. 지역별 조회수 TOP 5 (`_fetch_region`) — 채널 전체 기준
|
||||
|
||||
| 파라미터 | 값 |
|
||||
| ---------- | -------------------- |
|
||||
| dimensions | `country` |
|
||||
| metrics | `views` |
|
||||
| sort | `-views` |
|
||||
| maxResults | `5` |
|
||||
|
||||
1. **프로젝트 전체 요약 (KPI)**
|
||||
- `dimensions`: (없음)
|
||||
- `metrics`: `views,likes,estimatedRevenue`
|
||||
- `filters`: `video==ID1,ID2...`
|
||||
2. **일별 성장 그래프 (Line Chart)**
|
||||
- `dimensions`: `day`
|
||||
- `metrics`: `views`
|
||||
- `filters`: `video==ID1,ID2...`
|
||||
- `sort`: `day`
|
||||
3. **인기 영상 랭킹 (Table)**
|
||||
- `dimensions`: `video`
|
||||
- `metrics`: `views,averageViewDuration`
|
||||
- `filters`: `video==ID1,ID2...`
|
||||
- `sort`: `-views`
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue