update
1. add youtube command 2. add google webhook 3. add twitch oauth route 4. add api checkSession middleware
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"git.trj.tw/golang/mtfosbot/module/apis"
|
||||
|
||||
"git.trj.tw/golang/mtfosbot/module/config"
|
||||
)
|
||||
|
||||
var baseURL = "https://www.googleapis.com"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
type channelItem struct {
|
||||
ID string `json:"id"`
|
||||
Sinppet channelSinppet `json:"sinppet"`
|
||||
}
|
||||
type channelSinppet 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.Sinppet.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
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package twitch
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -234,3 +235,66 @@ func GetUserStreamStatus(ids []string) (info []*StreamInfo) {
|
||||
|
||||
return apiData.Data
|
||||
}
|
||||
|
||||
// TwitchTokenData -
|
||||
type TwitchTokenData struct {
|
||||
AccessToken string `json:"access_token" cc:"access_token"`
|
||||
RefreshToken string `json:"refresh_token" cc:"refresh_token"`
|
||||
ExpiresIn int64 `json:"expires_in" cc:"expires_in"`
|
||||
Scope string `json:"scope" cc:"scope"`
|
||||
TokenType string `json:"token_type" cc:"token_type"`
|
||||
}
|
||||
|
||||
// GetTokenData -
|
||||
func GetTokenData(code string) (token *TwitchTokenData, err error) {
|
||||
if len(code) == 0 {
|
||||
return nil, errors.New("code is empty")
|
||||
}
|
||||
conf := config.GetConf()
|
||||
twitchURL := "https://id.twitch.tv/oauth2/token"
|
||||
redirectTo := strings.TrimRight(conf.URL, "/") + "/twitch/oauth"
|
||||
|
||||
qs := url.Values{}
|
||||
qs.Add("client_id", conf.Twitch.ClientID)
|
||||
qs.Add("client_secret", conf.Twitch.ClientSecret)
|
||||
qs.Add("code", code)
|
||||
qs.Add("grant_type", "authorization_code")
|
||||
qs.Add("redirect_uri", redirectTo)
|
||||
|
||||
u, err := url.Parse(twitchURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u, err = u.Parse(qs.Encode())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reqObj := apis.RequestObj{
|
||||
URL: u.String(),
|
||||
Method: "POST",
|
||||
}
|
||||
req, err := apis.GetRequest(reqObj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 || strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") {
|
||||
return nil, errors.New("api response error")
|
||||
}
|
||||
|
||||
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(bodyBytes, &token)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user