package regio43 import ( "encoding/json" "fmt" "io" "net/http" "net/url" "os" "time" ) type YoutubeChannel struct { Id string Name string } type PlaylistItem struct { Etag string Id string PublishedAt time.Time Channel YoutubeChannel VideoId string Title string Description string ThumbnailUrl string Position int } type PlaylistResponseSnippet struct { PublishedAt string `json:"publishedAt"` VideoOwnerChannelId string `json:"videoOwnerChannelId"` VideoOwnerChannelTitle string `json:"videoOwnerChannelTitle"` ResourceId PlaylistResponseResourceId `json:"resourceId"` Title string `json:"title"` Description string `json:"description"` Position int `json:"position"` } type PlaylistResponseItem struct { Etag string `json:"etag"` Id string `json:"id"` Snippet PlaylistResponseSnippet `json:"snippet"` } type PlaylistResponseResourceId struct { VideoId string `json:"videoId"` } type PlaylistResponse struct { Items []PlaylistResponseItem `json:"items"` NextPageToken string `json:"nextPageToken"` } func requestYouTubePlaylist(playlistId string, pageToken string) ([]PlaylistItem, string) { apiUrl, err := url.Parse("https://www.googleapis.com/youtube/v3/playlistItems") if err != nil { panic(err) } q := apiUrl.Query() q.Add("key", os.Getenv("GOOGLE_API_KEY")) q.Add("playlistId", playlistId) q.Add("part", "id,snippet,contentDetails,status") q.Add("maxResults", "50") if pageToken != "" { q.Add("pageToken", pageToken) } apiUrl.RawQuery = q.Encode() response, err := http.Get(apiUrl.String()) if err != nil { return nil, "" } body, err := io.ReadAll(response.Body) if err != nil { return nil, "" } //type playlistResponse PlaylistResponse var playlistItems PlaylistResponse err = json.Unmarshal(body, &playlistItems) if err != nil { return nil, "" } var items []PlaylistItem for _, item := range playlistItems.Items { publishedAt, err := time.Parse(time.RFC3339, item.Snippet.PublishedAt) if err != nil { panic(err) } items = append(items, PlaylistItem{ Etag: item.Etag, Id: item.Id, PublishedAt: publishedAt, VideoId: item.Snippet.ResourceId.VideoId, Title: item.Snippet.Title, Description: item.Snippet.Description, ThumbnailUrl: fmt.Sprint("https://youtubethumbnails.prettysunflower.moe/", item.Snippet.ResourceId.VideoId), Position: item.Snippet.Position, Channel: YoutubeChannel{ Id: item.Snippet.VideoOwnerChannelId, Name: item.Snippet.VideoOwnerChannelTitle, }, }) } return items, playlistItems.NextPageToken } func getPlaylistOfVideos(playlistId string) []PlaylistItem { var playlistItems []PlaylistItem nextPageToken := "" for { newItems, newNextPageToken := requestYouTubePlaylist(playlistId, nextPageToken) playlistItems = append(playlistItems, newItems...) if newNextPageToken == "" { return playlistItems } nextPageToken = newNextPageToken } }