162 lines
3.3 KiB
Go
162 lines
3.3 KiB
Go
package google
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"git.trj.tw/golang/mtfosbot/module/apis"
|
|
jsoniter "github.com/json-iterator/go"
|
|
|
|
"git.trj.tw/golang/mtfosbot/module/config"
|
|
)
|
|
|
|
var baseURL = "https://www.googleapis.com"
|
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
|
|
|
func getURL(p string, querystring ...interface{}) (string, bool) {
|
|
u, err := url.Parse(baseURL)
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
ref, err := u.Parse(p)
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
if len(querystring) > 0 {
|
|
switch querystring[0].(type) {
|
|
case string:
|
|
ref, err = ref.Parse(fmt.Sprintf("?%s", (querystring[0].(string))))
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
break
|
|
default:
|
|
}
|
|
}
|
|
|
|
str := ref.String()
|
|
return str, true
|
|
}
|
|
|
|
func getHeaders(token ...interface{}) map[string]string {
|
|
m := make(map[string]string)
|
|
m["Content-Type"] = "application/json"
|
|
return m
|
|
}
|
|
|
|
// ChannelItem -
|
|
type ChannelItem struct {
|
|
ID string `json:"id"`
|
|
Snippet ChannelSnippet `json:"snippet"`
|
|
}
|
|
|
|
// ChannelSnippet -
|
|
type ChannelSnippet struct {
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
CustomURL string `json:"customUrl"`
|
|
}
|
|
|
|
// QueryYoutubeName -
|
|
func QueryYoutubeName(id string) (n string, err error) {
|
|
conf := config.GetConf()
|
|
if len(id) == 0 {
|
|
return "", errors.New("id is empty")
|
|
}
|
|
qs := url.Values{}
|
|
qs.Add("id", id)
|
|
qs.Add("key", conf.Google.APIKey)
|
|
qs.Add("part", "snippet")
|
|
|
|
apiURL, ok := getURL("/youtube/v3/channels", qs.Encode())
|
|
if !ok {
|
|
return "", errors.New("url parser fail")
|
|
}
|
|
reqObj := apis.RequestObj{
|
|
Method: "GET",
|
|
URL: apiURL,
|
|
Headers: getHeaders(),
|
|
}
|
|
|
|
req, err := apis.GetRequest(reqObj)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 || !strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") {
|
|
return "", errors.New("api response fail")
|
|
}
|
|
|
|
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
apiRes := struct {
|
|
Items []ChannelItem `json:"items"`
|
|
}{}
|
|
|
|
err = json.Unmarshal(bodyBytes, &apiRes)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if len(apiRes.Items) == 0 {
|
|
return "", errors.New("channel data not found")
|
|
}
|
|
|
|
for _, v := range apiRes.Items {
|
|
if v.ID == id {
|
|
return v.Snippet.Title, nil
|
|
}
|
|
}
|
|
|
|
return "", errors.New("channel data not found")
|
|
}
|
|
|
|
// SubscribeYoutube -
|
|
func SubscribeYoutube(id string) {
|
|
if len(id) == 0 {
|
|
return
|
|
}
|
|
conf := config.GetConf()
|
|
apiURL := "https://pubsubhubbub.appspot.com/subscribe"
|
|
cbURL, err := url.Parse(conf.URL)
|
|
if err != nil {
|
|
return
|
|
}
|
|
cbURL, err = cbURL.Parse(fmt.Sprintf("/google/youtube/webhook?id=%s", id))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
qs := url.Values{}
|
|
qs.Add("hub.mode", "subscribe")
|
|
qs.Add("hub.verify", "async")
|
|
qs.Add("hub.topic", fmt.Sprintf("https://www.youtube.com/xml/feeds/videos.xml?channel_id=%s", id))
|
|
qs.Add("hub.callback", cbURL.String())
|
|
qs.Add("hub.lease_seconds", "86400")
|
|
|
|
req, err := http.NewRequest("POST", apiURL, strings.NewReader(qs.Encode()))
|
|
if err != nil {
|
|
return
|
|
}
|
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
return
|
|
}
|