| import os |
| import requests |
|
|
| YT_API_KEY = os.getenv("YT_API_KEY") |
|
|
|
|
| def get_latest_video_id(channel_id, device_name=None, playlist_id=None): |
| """ |
| Return the videoId of the most recently published video from either: |
| - a specific playlist (if playlist_id is provided or can be resolved from device_name), or |
| - the channel (if only channel_id is provided). |
| |
| This does NOT rely on playlist UI ordering; it walks the whole playlist and |
| picks the newest item by snippet.publishedAt. |
| """ |
| if device_name is None and playlist_id is None: |
| raise ValueError("Must specify either device_name or playlist_id") |
|
|
| if device_name is not None and playlist_id is not None: |
| |
| print("Both device_name and playlist_id entered.. device_name will be ignored.") |
|
|
| |
| |
| |
| if playlist_id is None: |
| playlists_url = "https://www.googleapis.com/youtube/v3/playlists" |
| playlists_params = { |
| "part": "snippet", |
| "channelId": channel_id, |
| "maxResults": 50, |
| "key": YT_API_KEY, |
| } |
|
|
| res = requests.get(playlists_url, params=playlists_params) |
| res.raise_for_status() |
| playlists = res.json().get("items", []) |
|
|
| for p in playlists: |
| title = p["snippet"]["title"].lower() |
| if device_name.lower() in title: |
| playlist_id = p["id"] |
| break |
|
|
| if not playlist_id: |
| raise Exception(f"No playlist found matching device name '{device_name}'") |
|
|
| |
| |
| |
| if playlist_id: |
| playlist_url = "https://www.googleapis.com/youtube/v3/playlistItems" |
| latest_video_id = None |
| latest_published_at = None |
| page_token = None |
|
|
| while True: |
| playlist_params = { |
| "part": "snippet,contentDetails", |
| "playlistId": playlist_id, |
| "maxResults": 50, |
| "key": YT_API_KEY, |
| } |
| if page_token: |
| playlist_params["pageToken"] = page_token |
|
|
| playlist_res = requests.get(playlist_url, params=playlist_params) |
| playlist_res.raise_for_status() |
| data = playlist_res.json() |
|
|
| for item in data.get("items", []): |
| snippet = item.get("snippet", {}) |
| published_at = snippet.get("publishedAt") |
| if not published_at: |
| continue |
|
|
| |
| video_id = item.get("contentDetails", {}).get("videoId") |
| if not video_id: |
| |
| video_id = ( |
| snippet.get("resourceId", {}) or {} |
| ).get("videoId") |
|
|
| if not video_id: |
| continue |
|
|
| if latest_published_at is None or published_at > latest_published_at: |
| latest_published_at = published_at |
| latest_video_id = video_id |
|
|
| page_token = data.get("nextPageToken") |
| if not page_token: |
| break |
|
|
| return latest_video_id |
|
|
| |
| |
| |
| search_url = "https://www.googleapis.com/youtube/v3/search" |
| search_params = { |
| "part": "snippet", |
| "channelId": channel_id, |
| "maxResults": 1, |
| "order": "date", |
| "type": "video", |
| "key": YT_API_KEY, |
| } |
|
|
| res = requests.get(search_url, params=search_params) |
| res.raise_for_status() |
| items = res.json().get("items", []) |
|
|
| if not items: |
| return None |
|
|
| return items[0]["id"]["videoId"] |
|
|