package news import ( "ArinDash/config" "encoding/json" "io" "log" "net/http" "strings" "unicode" ) const apiBaseURL = "https://newsapi.org/v2/top-headlines" type configFile struct { News newsConfig } type newsConfig struct { ApiKey string Sources string } type News struct { Status string `json:"status"` TotalResults int `json:"totalResults"` Articles []Article `json:"articles"` } type Article struct { Source Source `json:"source"` Author string `json:"author"` Title string `json:"title"` Description string `json:"description"` URL string `json:"url"` URLToImage string `json:"urlToImage"` PublishedAt string `json:"publishedAt"` Content string `json:"content"` } type Source struct { ID string `json:"id"` Name string `json:"name"` } func FetchNews() News { cfg := &configFile{} config.LoadConfig(cfg) client := &http.Client{} if cfg.News.ApiKey == "" { return News{ Status: "No API key provided", } } req, err := http.NewRequest("GET", apiBaseURL+"?sources="+cfg.News.Sources+"&pageSize=100&apiKey="+cfg.News.ApiKey, nil) if err != nil { return News{ Status: err.Error(), } } resp, err := client.Do(req) if err != nil { return News{ Status: err.Error(), } } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { return } }(resp.Body) respBody, err := io.ReadAll(resp.Body) if err != nil { return News{ Status: err.Error(), } } news := News{} err = json.Unmarshal(respBody, &news) if err != nil { log.Fatal(err) } sanitizeNews(&news) return news } func sanitizeNews(news *News) { news.Status = removeInvisibleCharacters(news.Status) for i := range news.Articles { news.Articles[i].Author = removeInvisibleCharacters(news.Articles[i].Author) news.Articles[i].Title = removeInvisibleCharacters(news.Articles[i].Title) news.Articles[i].Description = removeInvisibleCharacters(news.Articles[i].Description) news.Articles[i].URL = removeInvisibleCharacters(news.Articles[i].URL) news.Articles[i].URLToImage = removeInvisibleCharacters(news.Articles[i].URLToImage) news.Articles[i].PublishedAt = removeInvisibleCharacters(news.Articles[i].PublishedAt) news.Articles[i].Content = removeInvisibleCharacters(news.Articles[i].Content) news.Articles[i].Source.ID = removeInvisibleCharacters(news.Articles[i].Source.ID) news.Articles[i].Source.Name = removeInvisibleCharacters(news.Articles[i].Source.Name) } } func removeInvisibleCharacters(s string) string { return strings.Map(func(r rune) rune { switch r { case '\u00A0': return ' ' case '\r', '\u2028', '\u2029': return ' ' } if unicode.Is(unicode.Cf, r) { return ' ' } return r }, s) }