From 8c432b9b682a28a9f72f1d8b32b7864ea3f6bdb9 Mon Sep 17 00:00:00 2001 From: JayChen Date: Tue, 25 Jun 2019 17:02:03 +0800 Subject: [PATCH] add pre group one bot setting --- model/line_bot.go | 37 +++++++++++++++++++ model/line_group.go | 29 +++++++++++---- module/apis/line/line.go | 26 +++++++------- module/background/facebook.go | 8 ++++- module/background/twitch.go | 8 ++++- module/line-message/message-event.go | 8 +++-- module/line-message/message-type.go | 44 ++++++++++++++--------- module/message-command/message-command.go | 13 +++++-- router/api/line.go | 15 +++++++- router/google/youtube.go | 7 +++- router/line/line.go | 29 +++++++++++---- router/private/private.go | 15 ++++++-- schema | 2 +- 13 files changed, 185 insertions(+), 56 deletions(-) create mode 100644 model/line_bot.go diff --git a/model/line_bot.go b/model/line_bot.go new file mode 100644 index 0000000..4983bdc --- /dev/null +++ b/model/line_bot.go @@ -0,0 +1,37 @@ +package model + +import ( + "database/sql" + "errors" + "time" +) + +// LineBot - +type LineBot struct { + ID string `db:"id" cc:"id"` + Name string `db:"name" cc:"name"` + AccessToken string `db:"access_token" cc:"access_token"` + Secret string `db:"secret" cc:"secret"` + Ctime time.Time `db:"ctime" cc:"ctime"` + Mtime time.Time `db:"mtime" cc:"mtime"` +} + +// GetBotInfo - +func GetBotInfo(id string) (bot *LineBot, err error) { + if len(id) == 0 { + return nil, errors.New("id is emptu") + } + + query := `select + "id", "name", "access_token", "secret", "ctime", "mtime" + from public."line_bot" + where + "id" = $1` + bot = &LineBot{} + err = x.Get(bot, query, id) + if err == sql.ErrNoRows { + return nil, nil + } + + return +} diff --git a/model/line_group.go b/model/line_group.go index a8b5594..30cf814 100644 --- a/model/line_group.go +++ b/model/line_group.go @@ -2,17 +2,19 @@ package model import ( "database/sql" + "errors" "time" ) // LineGroup - struct type LineGroup struct { - ID string `db:"id" cc:"id"` - Name string `db:"name" cc:"name"` - Notify bool `db:"notify" cc:"notify"` - Owner string `db:"owner" cc:"owner"` - Ctime time.Time `db:"ctime" cc:"ctime"` - Mtime time.Time `db:"mtime" cc:"ctime"` + ID string `db:"id" cc:"id"` + Name string `db:"name" cc:"name"` + Notify bool `db:"notify" cc:"notify"` + Owner string `db:"owner" cc:"owner"` + Ctime time.Time `db:"ctime" cc:"ctime"` + Mtime time.Time `db:"mtime" cc:"ctime"` + BotID sql.NullString `db:"bot_id" cc:"bot_id"` } // CheckGroup - @@ -75,3 +77,18 @@ func (p *LineGroup) DeleteGroup() (err error) { _, err = x.Exec(`delete from "public"."line_group" where "id" = $1`, p.ID) return } + +// GetBot - get group binding bot +func (p *LineGroup) GetBot() (bot *LineBot, err error) { + id, err := p.BotID.Value() + if err != nil { + return nil, err + } + var botid string + var ok bool + if botid, ok = id.(string); !ok { + return nil, errors.New("botid get fail") + } + bot, err = GetBotInfo(botid) + return +} diff --git a/module/apis/line/line.go b/module/apis/line/line.go index 8217def..fcb163a 100644 --- a/module/apis/line/line.go +++ b/module/apis/line/line.go @@ -13,7 +13,6 @@ import ( "strings" "git.trj.tw/golang/mtfosbot/module/apis" - "git.trj.tw/golang/mtfosbot/module/config" ) // TextMessage - line text message object @@ -66,11 +65,10 @@ func getURL(p string) (string, bool) { return str, true } -func getHeaders() map[string]string { +func getHeaders(token string) map[string]string { m := make(map[string]string) - conf := config.GetConf() m["Content-Type"] = "application/json" - m["Authorization"] = fmt.Sprintf("Bearer %s", conf.Line.Access) + m["Authorization"] = fmt.Sprintf("Bearer %s", token) return m } @@ -104,7 +102,7 @@ func checkMessageObject(m interface{}) interface{} { } // PushMessage - -func PushMessage(target string, message ...interface{}) { +func PushMessage(accessToken, target string, message ...interface{}) { log.Println("push target :::: ", target) if len(target) == 0 || len(message) == 0 { return @@ -145,7 +143,7 @@ func PushMessage(target string, message ...interface{}) { reqObj := apis.RequestObj{ Method: "POST", URL: apiURL, - Headers: getHeaders(), + Headers: getHeaders(accessToken), Body: byteReader, } @@ -163,7 +161,7 @@ func PushMessage(target string, message ...interface{}) { } // ReplyMessage - -func ReplyMessage(replyToken string, message ...interface{}) { +func ReplyMessage(accessToken, replyToken string, message ...interface{}) { if len(replyToken) == 0 || len(message) == 0 { return } @@ -201,7 +199,7 @@ func ReplyMessage(replyToken string, message ...interface{}) { reqObj := apis.RequestObj{ Method: "POST", URL: apiURL, - Headers: getHeaders(), + Headers: getHeaders(accessToken), Body: byteReader, } @@ -217,9 +215,9 @@ func ReplyMessage(replyToken string, message ...interface{}) { } // GetUserInfo - -func GetUserInfo(u, g string) (user *LineUserInfo, err error) { +func GetUserInfo(accessToken, u, g string) (user *LineUserInfo, err error) { urlPath := fmt.Sprintf("/v2/bot/group/%s/member/%s", g, u) - header := getHeaders() + header := getHeaders(accessToken) apiURL, ok := getURL(urlPath) if !ok { return nil, errors.New("url parser fail") @@ -263,9 +261,9 @@ func GetUserInfo(u, g string) (user *LineUserInfo, err error) { } // GetContentHead - -func GetContentHead(id string) (mime string, err error) { +func GetContentHead(accessToken, id string) (mime string, err error) { urlPath := fmt.Sprintf("/v2/bot/message/%s/content", id) - header := getHeaders() + header := getHeaders(accessToken) u, ok := getURL(urlPath) if !ok { return "", errors.New("get url fail") @@ -294,9 +292,9 @@ func GetContentHead(id string) (mime string, err error) { } // DownloadContent - -func DownloadContent(id string, w io.Writer) (err error) { +func DownloadContent(accessToken, id string, w io.Writer) (err error) { urlPath := fmt.Sprintf("/v2/bot/message/%s/content", id) - header := getHeaders() + header := getHeaders(accessToken) u, ok := getURL(urlPath) if !ok { return errors.New("get url fail") diff --git a/module/background/facebook.go b/module/background/facebook.go index c7a4517..d85bcd2 100644 --- a/module/background/facebook.go +++ b/module/background/facebook.go @@ -2,6 +2,7 @@ package background import ( "fmt" + "log" "net/http" "regexp" "sort" @@ -138,6 +139,11 @@ func getPageHTML(page *model.FacebookPage) { for _, v := range page.Groups { if v.Notify { + bot, err := v.GetBot() + if err != nil || bot == nil { + log.Println("get group binding bot fail :: ", err) + continue + } tmpl := v.Tmpl if len(tmpl) > 0 { tmpl = strings.Replace(tmpl, "{link}", lastData.Link, -1) @@ -148,7 +154,7 @@ func getPageHTML(page *model.FacebookPage) { msg := line.TextMessage{ Text: tmpl, } - line.PushMessage(v.ID, msg) + line.PushMessage(bot.AccessToken, v.ID, msg) } } } diff --git a/module/background/twitch.go b/module/background/twitch.go index 1002052..26e1129 100644 --- a/module/background/twitch.go +++ b/module/background/twitch.go @@ -2,6 +2,7 @@ package background import ( "fmt" + "log" "strings" "time" @@ -61,6 +62,11 @@ func checkStream(ch *model.TwitchChannel, info *twitch.StreamInfo) { link := fmt.Sprintf("https://twitch.tv/%s", ch.Name) for _, v := range ch.Groups { if v.Notify { + bot, err := v.GetBot() + if err != nil || bot == nil { + log.Println("get group binding bot fail :: ", err) + continue + } tmpl := v.Tmpl if len(tmpl) > 0 { tmpl = strings.Replace(tmpl, "{txt}", info.Title, -1) @@ -71,7 +77,7 @@ func checkStream(ch *model.TwitchChannel, info *twitch.StreamInfo) { msg := line.TextMessage{ Text: tmpl, } - line.PushMessage(v.ID, msg) + line.PushMessage(bot.AccessToken, v.ID, msg) } } } diff --git a/module/line-message/message-event.go b/module/line-message/message-event.go index 1801bee..6167543 100644 --- a/module/line-message/message-event.go +++ b/module/line-message/message-event.go @@ -7,11 +7,13 @@ import ( ) // MessageEvent - -func MessageEvent(e *lineobj.EventObject) { - +func MessageEvent(botid string, e *lineobj.EventObject) { + if len(botid) == 0 { + return + } switch e.Type { case "message": - messageType(e) + messageType(botid, e) break default: fmt.Println("line webhook type not match") diff --git a/module/line-message/message-type.go b/module/line-message/message-type.go index f5dd893..0c78253 100644 --- a/module/line-message/message-type.go +++ b/module/line-message/message-type.go @@ -16,7 +16,7 @@ import ( msgcmd "git.trj.tw/golang/mtfosbot/module/message-command" ) -func messageType(e *lineobj.EventObject) { +func messageType(botid string, e *lineobj.EventObject) { msg := e.Message mtype, ok := msg["type"] if !ok { @@ -26,17 +26,17 @@ func messageType(e *lineobj.EventObject) { if t, ok := mtype.(string); ok { switch t { case "text": - textMsg(e) + textMsg(botid, e) break case "image": - imageMsg(e) + imageMsg(botid, e) break } } return } -func textMsg(e *lineobj.EventObject) { +func textMsg(botid string, e *lineobj.EventObject) { msg := e.Message mtxt, ok := msg["text"] if !ok { @@ -46,14 +46,14 @@ func textMsg(e *lineobj.EventObject) { // group action if e.Source.Type == "group" { if txt, ok := mtxt.(string); ok { - msgcmd.ParseLineMsg(txt, e.ReplyToken, e.Source) - saveTextMsgToLog(txt, e.Source) + msgcmd.ParseLineMsg(botid, txt, e.ReplyToken, e.Source) + saveTextMsgToLog(botid, txt, e.Source) } } return } -func imageMsg(e *lineobj.EventObject) { +func imageMsg(botid string, e *lineobj.EventObject) { msg := e.Message imgID, ok := msg["id"] if !ok { @@ -62,19 +62,19 @@ func imageMsg(e *lineobj.EventObject) { // group action if e.Source.Type == "group" { if id, ok := imgID.(string); ok { - saveImageMsgToLog(id, e.Source) + saveImageMsgToLog(botid, id, e.Source) } } } -func getSourceUser(uid, gid string) (u *model.LineUser, err error) { +func getSourceUser(accessToken, uid, gid string) (u *model.LineUser, err error) { userData, err := model.GetLineUserByID(uid) if err != nil { return } if userData == nil { - tmpu, err := line.GetUserInfo(uid, gid) + tmpu, err := line.GetUserInfo(accessToken, uid, gid) if err != nil || tmpu == nil { return nil, err } @@ -87,7 +87,7 @@ func getSourceUser(uid, gid string) (u *model.LineUser, err error) { } } else { if userData.Mtime.Unix() < (time.Now().Unix() - 86400) { - tmpu, err := line.GetUserInfo(uid, gid) + tmpu, err := line.GetUserInfo(accessToken, uid, gid) if err != nil || tmpu == nil { return nil, err } @@ -102,8 +102,13 @@ func getSourceUser(uid, gid string) (u *model.LineUser, err error) { return userData, nil } -func saveTextMsgToLog(txt string, s *lineobj.SourceObject) { - u, err := getSourceUser(s.UserID, s.GroupID) +func saveTextMsgToLog(botid, txt string, s *lineobj.SourceObject) { + bot, err := model.GetBotInfo(botid) + if err != nil || bot == nil { + fmt.Println("get bot info fail :: ", err) + return + } + u, err := getSourceUser(bot.AccessToken, s.UserID, s.GroupID) if err != nil || u == nil { return } @@ -112,13 +117,18 @@ func saveTextMsgToLog(txt string, s *lineobj.SourceObject) { model.AddLineMessageLog(s.GroupID, s.UserID, txt, "text") } -func saveImageMsgToLog(id string, s *lineobj.SourceObject) { - u, err := getSourceUser(s.UserID, s.GroupID) +func saveImageMsgToLog(botid, id string, s *lineobj.SourceObject) { + bot, err := model.GetBotInfo(botid) + if err != nil || bot == nil { + fmt.Println("get bot info fail :: ", err) + return + } + u, err := getSourceUser(bot.AccessToken, s.UserID, s.GroupID) if err != nil || u == nil { return } - mime, err := line.GetContentHead(id) + mime, err := line.GetContentHead(bot.AccessToken, id) if err != nil || len(mime) == 0 { return } @@ -150,7 +160,7 @@ func saveImageMsgToLog(id string, s *lineobj.SourceObject) { } defer w.Close() - err = line.DownloadContent(id, w) + err = line.DownloadContent(bot.AccessToken, id, w) if err != nil { return } diff --git a/module/message-command/message-command.go b/module/message-command/message-command.go index 046a505..7664f7c 100644 --- a/module/message-command/message-command.go +++ b/module/message-command/message-command.go @@ -1,6 +1,7 @@ package msgcmd import ( + "fmt" "regexp" "strings" @@ -22,10 +23,15 @@ func parseCMD(in string) (c [][]string) { } // ParseLineMsg - -func ParseLineMsg(txt, replyToken string, source *lineobj.SourceObject) { +func ParseLineMsg(botid, txt, replyToken string, source *lineobj.SourceObject) { if source.Type != "group" { return } + bot, err := model.GetBotInfo(botid) + if err != nil || bot == nil { + fmt.Println("get bot err or no bot :: ", err) + return + } strs := strings.Split(strings.Trim(txt, " "), " ") // skip empty string @@ -57,7 +63,7 @@ func ParseLineMsg(txt, replyToken string, source *lineobj.SourceObject) { m := parseResult(v) msgs = append(msgs, m) } - line.ReplyMessage(replyToken, msgs...) + line.ReplyMessage(bot.AccessToken, replyToken, msgs...) } else { // key cmd @@ -72,7 +78,8 @@ func ParseLineMsg(txt, replyToken string, source *lineobj.SourceObject) { m := parseResult(v) msgs = append(msgs, m) } - line.ReplyMessage(replyToken, msgs...) + + line.ReplyMessage(bot.AccessToken, replyToken, msgs...) } } diff --git a/router/api/line.go b/router/api/line.go index 5142e7d..86c01da 100644 --- a/router/api/line.go +++ b/router/api/line.go @@ -27,7 +27,20 @@ func PushLineMessage(c *context.Context) { textObj := line.TextMessage{} textObj.Text = bodyData.Message - line.PushMessage(bodyData.Group, textObj) + group, err := model.GetLineGroup(bodyData.Group) + if err != nil { + c.ServerError(nil) + log.Println("get group :: ", err) + return + } + bot, err := group.GetBot() + if err != nil || bot == nil { + log.Println("get group binding bot fail :: ", err) + c.ServerError(nil) + return + } + + line.PushMessage(bot.AccessToken, bodyData.Group, textObj) c.Success(nil) } diff --git a/router/google/youtube.go b/router/google/youtube.go index bdc7f2f..7444ed0 100644 --- a/router/google/youtube.go +++ b/router/google/youtube.go @@ -129,6 +129,11 @@ func GetNotifyWebhook(c *context.Context) { for _, v := range yt.Groups { log.Println("group data :::: ", v, v.Notify, v.Name, v.ID) + bot, err := v.GetBot() + if err != nil || bot == nil { + log.Println("get group binding bot fail :: ", err) + continue + } if v.Notify == true { str := v.Tmpl log.Println("template :::: ", str) @@ -144,7 +149,7 @@ func GetNotifyWebhook(c *context.Context) { } log.Println("msg ::::: ", msg) - lineapi.PushMessage(v.ID, msg) + lineapi.PushMessage(bot.AccessToken, v.ID, msg) } } diff --git a/router/line/line.go b/router/line/line.go index 463ec57..ed008ec 100644 --- a/router/line/line.go +++ b/router/line/line.go @@ -7,9 +7,9 @@ import ( "encoding/json" "io/ioutil" - "git.trj.tw/golang/mtfosbot/module/config" + "git.trj.tw/golang/mtfosbot/model" "git.trj.tw/golang/mtfosbot/module/context" - "git.trj.tw/golang/mtfosbot/module/line-message" + linemsg "git.trj.tw/golang/mtfosbot/module/line-message" lineobj "git.trj.tw/golang/mtfosbot/module/line-message/line-object" ) @@ -42,10 +42,21 @@ func VerifyLine(c *context.Context) { return } - conf := config.GetConf() + botid, ok := c.GetQuery("id") + if !ok || len(botid) == 0 { + c.CustomRes(403, map[string]string{ + "message": "no bot data", + }) + } - hash := hmac.New(sha256.New, []byte(conf.Line.Secret)) - _, err := hash.Write(raw) + bot, err := model.GetBotInfo(botid) + if err != nil { + c.ServerError(nil) + return + } + + hash := hmac.New(sha256.New, []byte(bot.Secret)) + _, err = hash.Write(raw) if err != nil { c.ServerError(nil) return @@ -70,6 +81,12 @@ func GetLineMessage(c *context.Context) { if raw, ok = rawbody.([]byte); !ok { c.DataFormat("body type error") } + botid, ok := c.GetQuery("id") + if !ok || len(botid) == 0 { + c.CustomRes(403, map[string]string{ + "message": "no bot data", + }) + } events := struct { Events []*lineobj.EventObject `json:"events"` @@ -83,7 +100,7 @@ func GetLineMessage(c *context.Context) { if len(events.Events) > 0 { for _, v := range events.Events { - go linemsg.MessageEvent(v) + go linemsg.MessageEvent(botid, v) } } diff --git a/router/private/private.go b/router/private/private.go index c5b1209..65a3af9 100644 --- a/router/private/private.go +++ b/router/private/private.go @@ -2,6 +2,7 @@ package private import ( "fmt" + "log" "strings" "git.trj.tw/golang/mtfosbot/model" @@ -107,6 +108,11 @@ func UpdateFacebookPagePost(c *context.Context) { for _, g := range page.Groups { if g.Notify { + bot, err := g.GetBot() + if err != nil || bot == nil { + log.Println("get group binding bot fail ::: ", err) + continue + } tmpl := g.Tmpl if len(tmpl) > 0 { tmpl = strings.Replace(tmpl, "{link}", v.Link, -1) @@ -117,7 +123,7 @@ func UpdateFacebookPagePost(c *context.Context) { msg := line.TextMessage{ Text: tmpl, } - line.PushMessage(g.ID, msg) + line.PushMessage(bot.AccessToken, g.ID, msg) } } } @@ -169,6 +175,11 @@ func UpdateInstagramPost(c *context.Context) { for _, g := range ig.Groups { if g.Notify { + bot, err := g.GetBot() + if err != nil || bot == nil { + log.Println("get group binding bot fail :: ", err) + continue + } tmpl := g.Tmpl if len(tmpl) > 0 { tmpl = strings.Replace(tmpl, "{link}", v.Link, -1) @@ -178,7 +189,7 @@ func UpdateInstagramPost(c *context.Context) { } msg := line.TextMessage{Text: tmpl} - line.PushMessage(g.ID, msg) + line.PushMessage(bot.AccessToken, g.ID, msg) } } } diff --git a/schema b/schema index f0a256f..3bdfd83 160000 --- a/schema +++ b/schema @@ -1 +1 @@ -Subproject commit f0a256f088c78dcd6d7d576e768724de656f5a53 +Subproject commit 3bdfd83583b60d443e0c958e7991c579176f298e