diff --git a/go.mod b/go.mod index b16f812..9cc1528 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21.6 require ( git.solsynth.dev/hydrogen/paperclip v0.0.0-20240518085442-715238074040 - git.solsynth.dev/hydrogen/passport v0.0.0-20240517123434-ebef35a619f5 + git.solsynth.dev/hydrogen/passport v0.0.0-20240607130225-b76e7d41cf36 github.com/go-playground/validator/v10 v10.17.0 github.com/gofiber/fiber/v2 v2.52.4 github.com/gofiber/template/html/v2 v2.1.1 @@ -16,8 +16,8 @@ require ( github.com/rs/zerolog v1.31.0 github.com/samber/lo v1.39.0 github.com/spf13/viper v1.18.2 - golang.org/x/crypto v0.23.0 - google.golang.org/grpc v1.61.1 + golang.org/x/crypto v0.24.0 + google.golang.org/grpc v1.64.0 gorm.io/datatypes v1.2.0 gorm.io/driver/postgres v1.5.4 gorm.io/gorm v1.25.6 @@ -32,7 +32,7 @@ require ( github.com/go-sql-driver/mysql v1.7.1 // indirect github.com/gofiber/template v1.8.3 // indirect github.com/gofiber/utils v1.1.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect @@ -65,12 +65,12 @@ require ( github.com/valyala/tcplisten v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect - google.golang.org/protobuf v1.32.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gorm.io/driver/mysql v1.5.2 // indirect diff --git a/go.sum b/go.sum index 0cfbcca..b6275d4 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ git.solsynth.dev/hydrogen/paperclip v0.0.0-20240518085442-715238074040 h1:B/3gXF git.solsynth.dev/hydrogen/paperclip v0.0.0-20240518085442-715238074040/go.mod h1:uTNEtJcNdgt7DhOgsewPaLQQ5kTN9H+tGNRT2CshHGs= git.solsynth.dev/hydrogen/passport v0.0.0-20240517123434-ebef35a619f5 h1:iEnty5+OHZiIaa27/e9qXfj7lmlhUVe8Oog/BJmLsRM= git.solsynth.dev/hydrogen/passport v0.0.0-20240517123434-ebef35a619f5/go.mod h1:mEcDEKashAh3jvoGDbNLefK+HgsJaMj4xEc6vkLZ+Zc= +git.solsynth.dev/hydrogen/passport v0.0.0-20240607130225-b76e7d41cf36 h1:L/dlFeiIr3WB22y15FP8LVe/ylrJzu7+8SzejcFg7nI= +git.solsynth.dev/hydrogen/passport v0.0.0-20240607130225-b76e7d41cf36/go.mod h1:UuE3QXf2540Xs1GmViUSZ3V0ILtiYePZ5iXfZhzlSo4= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -46,6 +48,7 @@ github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EO github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -160,6 +163,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uyPfhPeDWD+n+JgppptE= golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -170,11 +174,13 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -186,6 +192,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -195,6 +202,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -203,12 +211,15 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c h1:NUsgEN92SQQqzfA+YtqYNqYmB3DMMYLlIwUZAQFVFbo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/server/posts_api.go b/pkg/server/posts_api.go index 026bf3a..ce61360 100644 --- a/pkg/server/posts_api.go +++ b/pkg/server/posts_api.go @@ -236,7 +236,7 @@ func reactPost(c *fiber.Ctx) error { reaction.PostID = &res.ID } - if positive, reaction, err := services.ReactPost(reaction); err != nil { + if positive, reaction, err := services.ReactPost(user, reaction); err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) } else { return c.Status(lo.Ternary(positive, fiber.StatusCreated, fiber.StatusNoContent)).JSON(reaction) diff --git a/pkg/services/accounts.go b/pkg/services/accounts.go index 5b70cea..2ba319b 100644 --- a/pkg/services/accounts.go +++ b/pkg/services/accounts.go @@ -31,24 +31,25 @@ func GetAccountFriend(userId, relatedId uint, status int) (*proto.FriendshipResp }) } -func NotifyAccount(user models.Account, subject, content string, realtime bool, links ...*proto.NotifyLink) error { +func NotifyPosterAccount(user models.Account, subject, content string, links ...*proto.NotifyLink) error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() _, err := grpc.Notify.NotifyUser(ctx, &proto.NotifyRequest{ ClientId: viper.GetString("passport.client_id"), ClientSecret: viper.GetString("passport.client_secret"), + Type: "notifications.interactive.feedback", Subject: subject, Content: content, Links: links, RecipientId: uint64(user.ExternalID), - IsRealtime: realtime, - IsImportant: false, + IsRealtime: false, + IsForcePush: true, }) if err != nil { log.Warn().Err(err).Msg("An error occurred when notify account...") } else { - log.Debug().Uint("external", user.ExternalID).Msg("Notified account.") + log.Debug().Uint("eid", user.ExternalID).Msg("Notified account.") } return err diff --git a/pkg/services/posts.go b/pkg/services/posts.go index 05ae904..ec343d7 100644 --- a/pkg/services/posts.go +++ b/pkg/services/posts.go @@ -267,27 +267,24 @@ func NewPost(user models.Account, item models.Post) (models.Post, error) { // Notify the original poster its post has been replied if item.ReplyID != nil { - go func() { - var op models.Post - if err := database.C. - Where("id = ?", item.ReplyID). - Preload("Author"). - First(&op).Error; err == nil { - if op.Author.ID != user.ID { - postUrl := fmt.Sprintf("https://%s/posts/%s", viper.GetString("domain"), item.Alias) - err := NotifyAccount( - op.Author, - fmt.Sprintf("%s replied you", user.Nick), - fmt.Sprintf("%s (%s) replied your post #%s.", user.Nick, user.Name, op.Alias), - false, - &proto.NotifyLink{Label: "Related post", Url: postUrl}, - ) - if err != nil { - log.Error().Err(err).Msg("An error occurred when notifying user...") - } + var op models.Post + if err := database.C. + Where("id = ?", item.ReplyID). + Preload("Author"). + First(&op).Error; err == nil { + if op.Author.ID != user.ID { + postUrl := fmt.Sprintf("https://%s/posts/%s", viper.GetString("domain"), item.Alias) + err := NotifyPosterAccount( + op.Author, + fmt.Sprintf("%s replied you", user.Nick), + fmt.Sprintf("%s (%s) replied your post #%s.", user.Nick, user.Name, op.Alias), + &proto.NotifyLink{Label: "Related post", Url: postUrl}, + ) + if err != nil { + log.Error().Err(err).Msg("An error occurred when notifying user...") } } - }() + } } return item, nil @@ -308,9 +305,28 @@ func DeletePost(item models.Post) error { return database.C.Delete(&item).Error } -func ReactPost(reaction models.Reaction) (bool, models.Reaction, error) { +func ReactPost(user models.Account, reaction models.Reaction) (bool, models.Reaction, error) { if err := database.C.Where(reaction).First(&reaction).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { + var op models.Post + if err := database.C. + Where("id = ?", reaction.PostID). + Preload("Author"). + First(&op).Error; err == nil { + if op.Author.ID != user.ID { + postUrl := fmt.Sprintf("https://%s/posts/%s", viper.GetString("domain"), op.Alias) + err := NotifyPosterAccount( + op.Author, + fmt.Sprintf("%s reacted your post", user.Nick), + fmt.Sprintf("%s (%s) reacted your post a %s", user.Nick, user.Name, reaction.Symbol), + &proto.NotifyLink{Label: "Related post", Url: postUrl}, + ) + if err != nil { + log.Error().Err(err).Msg("An error occurred when notifying user...") + } + } + } + return true, reaction, database.C.Save(&reaction).Error } else { return true, reaction, err