diff --git a/migrations/1528538599_app.down.sql b/migrations/1528538599_app.down.sql new file mode 100644 index 0000000..c8e61f9 --- /dev/null +++ b/migrations/1528538599_app.down.sql @@ -0,0 +1 @@ +alter table mg_user rename to user; \ No newline at end of file diff --git a/migrations/1528538599_app.up.sql b/migrations/1528538599_app.up.sql new file mode 100644 index 0000000..f82d578 --- /dev/null +++ b/migrations/1528538599_app.up.sql @@ -0,0 +1 @@ +alter table users rename to mg_user; \ No newline at end of file diff --git a/models.go b/models.go index da5d99c..d0845a1 100644 --- a/models.go +++ b/models.go @@ -28,8 +28,8 @@ type Bot struct { Active bool `json:"active,omitempty"` } -// Users model -type Users struct { +// User model +type User struct { ID int `gorm:"primary_key"` ExternalID int `gorm:"external_id;not null;unique"` UserPhotoURL string `gorm:"user_photo_url type:varchar(255)"` @@ -38,5 +38,9 @@ type Users struct { UpdatedAt time.Time } +func (User) TableName() string { + return "mg_user" +} + //Bots list type Bots []Bot diff --git a/repository.go b/repository.go index 7ccb82a..99727e6 100644 --- a/repository.go +++ b/repository.go @@ -48,13 +48,6 @@ func getBotByToken(token string) (*Bot, error) { return &bot, nil } -func getBotByChannel(ch uint64) *Bot { - var bot Bot - orm.DB.First(&bot, "channel = ?", ch) - - return &bot -} - func (b *Bot) setBotActivity() error { return orm.DB.Model(b).Where("token = ?", b.Token).Update("Active", !b.Active).Error } @@ -76,6 +69,13 @@ func (c Connection) getBotsByClientID() Bots { return b } +func getBotByChannelAndCID(connectionID int, ch uint64) *Bot { + var bot Bot + orm.DB.First(&bot, "connection_id = ? AND channel = ?", connectionID, ch) + + return &bot +} + func getConnectionById(id int) *Connection { var connection Connection orm.DB.First(&connection, "id = ?", id) @@ -83,18 +83,18 @@ func getConnectionById(id int) *Connection { return &connection } -func (u *Users) save() error { +func (u *User) save() error { return orm.DB.Save(u).Error } -func getUserByExternalID(eid int) *Users { - user := Users{} +func getUserByExternalID(eid int) *User { + var user User orm.DB.First(&user, "external_id = ?", eid) return &user } //Expired method -func (u *Users) Expired(updateInterval int) bool { +func (u *User) Expired(updateInterval int) bool { return time.Now().After(u.UpdatedAt.Add(time.Hour * time.Duration(updateInterval))) } diff --git a/routing.go b/routing.go index cfd578e..6bf01e1 100644 --- a/routing.go +++ b/routing.go @@ -86,7 +86,9 @@ func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.Handl http.NotFound(w, r) return } - fn(w, r, m[2]) + raven.CapturePanic(func() { + fn(w, r, m[2]) + }, nil) } } @@ -504,7 +506,10 @@ func activityHandler(w http.ResponseWriter, r *http.Request) { return } - body, err := ioutil.ReadAll(r.Body) + r.ParseForm() + var rec v5.Activity + + err := json.Unmarshal([]byte(r.FormValue("activity")), &rec) if err != nil { raven.CaptureErrorAndWait(err, nil) res.Error = localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "wrong_data"}) @@ -518,24 +523,8 @@ func activityHandler(w http.ResponseWriter, r *http.Request) { return } - var rec v5.ActivityCallback - - err = json.Unmarshal(body, &rec) - if err != nil { - raven.CaptureErrorAndWait(err, nil) - res.Error = localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "wrong_data"}) - jsonString, err := json.Marshal(res) - if err != nil { - raven.CaptureErrorAndWait(err, nil) - logger.Error(err) - return - } - w.Write(jsonString) - return - } - - c := getConnection(rec.ClientId) - c.Active = rec.Activity.Active && !rec.Activity.Freeze + c := getConnection(r.FormValue("clientId")) + c.Active = rec.Active && !rec.Freeze if err := c.setConnectionActivity(); err != nil { raven.CaptureErrorAndWait(err, nil) diff --git a/telegram.go b/telegram.go index 94e4607..391b3cc 100644 --- a/telegram.go +++ b/telegram.go @@ -73,51 +73,52 @@ func telegramWebhookHandler(w http.ResponseWriter, r *http.Request, token string return } - user := getUserByExternalID(update.Message.From.ID) - - if user.Expired(config.UpdateInterval) || user.ID == 0 { - fileID, fileURL, err := GetFileIDAndURL(b.Token, update.Message.From.ID) - if err != nil { - raven.CaptureErrorAndWait(err, nil) - logger.Error(err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - if fileID != user.UserPhotoID && fileURL != "" { - picURL, err := UploadUserAvatar(fileURL) - if err != nil { - raven.CaptureErrorAndWait(err, nil) - logger.Error(err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - user.UserPhotoID = fileID - user.UserPhotoURL = picURL - } - - if user.ExternalID == 0 { - user.ExternalID = update.Message.From.ID - } - - err = user.save() - if err != nil { - raven.CaptureErrorAndWait(err, nil) - logger.Error(err) - w.WriteHeader(http.StatusInternalServerError) - return - } - } - - if config.Debug { - logger.Debugf("telegramWebhookHandler user %v", user) - } - var client = v1.New(c.MGURL, c.MGToken) if update.Message != nil { if update.Message.Text != "" { + + user := getUserByExternalID(update.Message.From.ID) + + if user.Expired(config.UpdateInterval) || user.ID == 0 { + fileID, fileURL, err := GetFileIDAndURL(b.Token, update.Message.From.ID) + if err != nil { + raven.CaptureErrorAndWait(err, nil) + logger.Error(err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + if fileID != user.UserPhotoID && fileURL != "" { + picURL, err := UploadUserAvatar(fileURL) + if err != nil { + raven.CaptureErrorAndWait(err, nil) + logger.Error(err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + user.UserPhotoID = fileID + user.UserPhotoURL = picURL + } + + if user.ExternalID == 0 { + user.ExternalID = update.Message.From.ID + } + + err = user.save() + if err != nil { + raven.CaptureErrorAndWait(err, nil) + logger.Error(err) + w.WriteHeader(http.StatusInternalServerError) + return + } + } + + if config.Debug { + logger.Debugf("telegramWebhookHandler user %v", user) + } + snd := v1.SendData{ Message: v1.SendMessage{ Message: v1.Message{ @@ -185,6 +186,21 @@ func telegramWebhookHandler(w http.ResponseWriter, r *http.Request, token string func mgWebhookHandler(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() + clientID := r.Header.Get("Clientid") + if clientID == "" { + logger.Error("mgWebhookHandler clientID is empty") + w.WriteHeader(http.StatusBadRequest) + return + } + + c := getConnection(clientID) + if !c.Active { + logger.Error(c.ClientID, "mgWebhookHandler: connection deactivated") + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("Connection deactivated")) + return + } + bytes, err := ioutil.ReadAll(r.Body) if err != nil { raven.CaptureErrorAndWait(err, nil) @@ -209,7 +225,7 @@ func mgWebhookHandler(w http.ResponseWriter, r *http.Request) { uid, _ := strconv.Atoi(msg.Data.ExternalMessageID) cid, _ := strconv.ParseInt(msg.Data.ExternalChatID, 10, 64) - b := getBotByChannel(msg.Data.ChannelID) + b := getBotByChannelAndCID(c.ID, msg.Data.ChannelID) if b.ID == 0 || !b.Active { logger.Error(msg.Data.ChannelID, "mgWebhookHandler: missing or deactivated") w.WriteHeader(http.StatusBadRequest) @@ -217,14 +233,6 @@ func mgWebhookHandler(w http.ResponseWriter, r *http.Request) { return } - c := getConnectionById(b.ConnectionID) - if !c.Active { - logger.Error(c.ClientID, "mgWebhookHandler: connection deactivated") - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("Connection deactivated")) - return - } - bot, err := tgbotapi.NewBotAPI(b.Token) if err != nil { raven.CaptureErrorAndWait(err, nil) @@ -254,7 +262,7 @@ func mgWebhookHandler(w http.ResponseWriter, r *http.Request) { } if config.Debug { - logger.Debugf("mgWebhookHandler sent response %v", rsp) + logger.Debugf("mgWebhookHandler sent response %v", string(rsp)) } w.WriteHeader(http.StatusOK)