✨ Able to subscribe to realm
This commit is contained in:
parent
6f26a44838
commit
4d602220d2
@ -13,4 +13,6 @@ type Subscription struct {
|
|||||||
Tag Tag `json:"tag,omitempty"`
|
Tag Tag `json:"tag,omitempty"`
|
||||||
CategoryID *uint `json:"category_id,omitempty"`
|
CategoryID *uint `json:"category_id,omitempty"`
|
||||||
Category Category `json:"category,omitempty"`
|
Category Category `json:"category,omitempty"`
|
||||||
|
RealmID *uint `json:"realm_id,omitempty"`
|
||||||
|
Realm Realm `json:"realm,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,15 @@ func MapAPIs(app *fiber.App, baseURL string) {
|
|||||||
subscriptions.Get("/users/:userId", getSubscriptionOnUser)
|
subscriptions.Get("/users/:userId", getSubscriptionOnUser)
|
||||||
subscriptions.Get("/tags/:tagId", getSubscriptionOnTag)
|
subscriptions.Get("/tags/:tagId", getSubscriptionOnTag)
|
||||||
subscriptions.Get("/categories/:categoryId", getSubscriptionOnCategory)
|
subscriptions.Get("/categories/:categoryId", getSubscriptionOnCategory)
|
||||||
|
subscriptions.Get("/realms/:realmId", getSubscriptionOnRealm)
|
||||||
subscriptions.Post("/users/:userId", subscribeToUser)
|
subscriptions.Post("/users/:userId", subscribeToUser)
|
||||||
subscriptions.Post("/tags/:tagId", subscribeToTag)
|
subscriptions.Post("/tags/:tagId", subscribeToTag)
|
||||||
subscriptions.Post("/categories/:categoryId", subscribeToCategory)
|
subscriptions.Post("/categories/:categoryId", subscribeToCategory)
|
||||||
|
subscriptions.Post("/realms/:realmId", subscribeToRealm)
|
||||||
subscriptions.Delete("/users/:userId", unsubscribeFromUser)
|
subscriptions.Delete("/users/:userId", unsubscribeFromUser)
|
||||||
subscriptions.Delete("/tags/:tagId", unsubscribeFromTag)
|
subscriptions.Delete("/tags/:tagId", unsubscribeFromTag)
|
||||||
subscriptions.Delete("/categories/:categoryId", unsubscribeFromCategory)
|
subscriptions.Delete("/categories/:categoryId", unsubscribeFromCategory)
|
||||||
|
subscriptions.Delete("/realms/:realmId", unsubscribeFromRealm)
|
||||||
}
|
}
|
||||||
|
|
||||||
api.Get("/categories", listCategories)
|
api.Get("/categories", listCategories)
|
||||||
|
@ -76,6 +76,28 @@ func getSubscriptionOnCategory(c *fiber.Ctx) error {
|
|||||||
return c.JSON(subscription)
|
return c.JSON(subscription)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSubscriptionOnRealm(c *fiber.Ctx) error {
|
||||||
|
if err := gap.H.EnsureAuthenticated(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user := c.Locals("user").(models.Account)
|
||||||
|
|
||||||
|
realmId, err := c.ParamsInt("realmId", 0)
|
||||||
|
realm, err := services.GetRealmWithID(uint(realmId))
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("unable to get realm: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
subscription, err := services.GetSubscriptionOnRealm(user, realm)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("unable to get subscription: %v", err))
|
||||||
|
} else if subscription == nil {
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "subscription does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(subscription)
|
||||||
|
}
|
||||||
|
|
||||||
func subscribeToUser(c *fiber.Ctx) error {
|
func subscribeToUser(c *fiber.Ctx) error {
|
||||||
if err := gap.H.EnsureAuthenticated(c); err != nil {
|
if err := gap.H.EnsureAuthenticated(c); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -160,6 +182,34 @@ func subscribeToCategory(c *fiber.Ctx) error {
|
|||||||
return c.JSON(subscription)
|
return c.JSON(subscription)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func subscribeToRealm(c *fiber.Ctx) error {
|
||||||
|
if err := gap.H.EnsureAuthenticated(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user := c.Locals("user").(models.Account)
|
||||||
|
|
||||||
|
realmId, err := c.ParamsInt("realmId", 0)
|
||||||
|
realm, err := services.GetRealmWithID(uint(realmId))
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("unable to get realm: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
subscription, err := services.SubscribeToRealm(user, realm)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("unable to subscribe to realm: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = gap.H.RecordAuditLog(
|
||||||
|
user.ID,
|
||||||
|
"posts.subscribe.realms",
|
||||||
|
strconv.Itoa(int(realm.ID)),
|
||||||
|
c.IP(),
|
||||||
|
c.Get(fiber.HeaderUserAgent),
|
||||||
|
)
|
||||||
|
|
||||||
|
return c.JSON(subscription)
|
||||||
|
}
|
||||||
|
|
||||||
func unsubscribeFromUser(c *fiber.Ctx) error {
|
func unsubscribeFromUser(c *fiber.Ctx) error {
|
||||||
if err := gap.H.EnsureAuthenticated(c); err != nil {
|
if err := gap.H.EnsureAuthenticated(c); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -243,3 +293,31 @@ func unsubscribeFromCategory(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
return c.SendStatus(fiber.StatusOK)
|
return c.SendStatus(fiber.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unsubscribeFromRealm(c *fiber.Ctx) error {
|
||||||
|
if err := gap.H.EnsureAuthenticated(c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user := c.Locals("user").(models.Account)
|
||||||
|
|
||||||
|
realmId, err := c.ParamsInt("realmId", 0)
|
||||||
|
realm, err := services.GetRealmWithID(uint(realmId))
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("unable to get realm: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = services.UnsubscribeFromRealm(user, realm)
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("unable to unsubscribe from realm: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = gap.H.RecordAuditLog(
|
||||||
|
user.ID,
|
||||||
|
"posts.unsubscribe.realms",
|
||||||
|
strconv.Itoa(int(realm.ID)),
|
||||||
|
c.IP(),
|
||||||
|
c.Get(fiber.HeaderUserAgent),
|
||||||
|
)
|
||||||
|
|
||||||
|
return c.SendStatus(fiber.StatusOK)
|
||||||
|
}
|
||||||
|
@ -491,3 +491,14 @@ func TruncatePostContent(post models.Post) models.Post {
|
|||||||
|
|
||||||
return post
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TruncatePostContentShortThreshold = 80
|
||||||
|
|
||||||
|
func TruncatePostContentShort(content string) string {
|
||||||
|
length := TruncatePostContentShortThreshold
|
||||||
|
if len([]rune(content)) >= length {
|
||||||
|
return string([]rune(content)[:length]) + "..."
|
||||||
|
} else {
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetRealmWithExtID(id uint) (models.Realm, error) {
|
func GetRealmWithID(id uint) (models.Realm, error) {
|
||||||
var realm models.Realm
|
var realm models.Realm
|
||||||
pc, err := gap.H.GetServiceGrpcConn(hyper.ServiceTypeAuthProvider)
|
pc, err := gap.H.GetServiceGrpcConn(hyper.ServiceTypeAuthProvider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -47,6 +47,17 @@ func GetSubscriptionOnCategory(user models.Account, target models.Category) (*mo
|
|||||||
return &subscription, nil
|
return &subscription, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSubscriptionOnRealm(user models.Account, target models.Realm) (*models.Subscription, error) {
|
||||||
|
var subscription models.Subscription
|
||||||
|
if err := database.C.Where("follower_id = ? AND realm_id = ?", user.ID, target.ID).First(&subscription).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to get subscription: %v", err)
|
||||||
|
}
|
||||||
|
return &subscription, nil
|
||||||
|
}
|
||||||
|
|
||||||
func SubscribeToUser(user models.Account, target models.Account) (models.Subscription, error) {
|
func SubscribeToUser(user models.Account, target models.Account) (models.Subscription, error) {
|
||||||
var subscription models.Subscription
|
var subscription models.Subscription
|
||||||
if err := database.C.Where("follower_id = ? AND account_id = ?", user.ID, target.ID).First(&subscription).Error; err != nil {
|
if err := database.C.Where("follower_id = ? AND account_id = ?", user.ID, target.ID).First(&subscription).Error; err != nil {
|
||||||
@ -98,6 +109,23 @@ func SubscribeToCategory(user models.Account, target models.Category) (models.Su
|
|||||||
return subscription, err
|
return subscription, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SubscribeToRealm(user models.Account, target models.Realm) (models.Subscription, error) {
|
||||||
|
var subscription models.Subscription
|
||||||
|
if err := database.C.Where("follower_id = ? AND realm_id = ?", user.ID, target.ID).First(&subscription).Error; err != nil {
|
||||||
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return subscription, fmt.Errorf("subscription already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subscription = models.Subscription{
|
||||||
|
FollowerID: user.ID,
|
||||||
|
RealmID: &target.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := database.C.Save(&subscription).Error
|
||||||
|
return subscription, err
|
||||||
|
}
|
||||||
|
|
||||||
func UnsubscribeFromUser(user models.Account, target models.Account) error {
|
func UnsubscribeFromUser(user models.Account, target models.Account) error {
|
||||||
var subscription models.Subscription
|
var subscription models.Subscription
|
||||||
if err := database.C.Where("follower_id = ? AND account_id = ?", user.ID, target.ID).First(&subscription).Error; err != nil {
|
if err := database.C.Where("follower_id = ? AND account_id = ?", user.ID, target.ID).First(&subscription).Error; err != nil {
|
||||||
@ -137,6 +165,19 @@ func UnsubscribeFromCategory(user models.Account, target models.Category) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UnsubscribeFromRealm(user models.Account, target models.Realm) error {
|
||||||
|
var subscription models.Subscription
|
||||||
|
if err := database.C.Where("follower_id = ? AND realm_id = ?", user.ID, target.ID).First(&subscription).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
return fmt.Errorf("subscription does not exist")
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unable to check subscription is exists or not: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := database.C.Delete(&subscription).Error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func NotifyUserSubscription(poster models.Account, content string, title *string) error {
|
func NotifyUserSubscription(poster models.Account, content string, title *string) error {
|
||||||
var subscriptions []models.Subscription
|
var subscriptions []models.Subscription
|
||||||
if err := database.C.Where("account_id = ?", poster.ID).Preload("Follower").Find(&subscriptions).Error; err != nil {
|
if err := database.C.Where("account_id = ?", poster.ID).Preload("Follower").Find(&subscriptions).Error; err != nil {
|
||||||
@ -146,12 +187,7 @@ func NotifyUserSubscription(poster models.Account, content string, title *string
|
|||||||
nTitle := fmt.Sprintf("New post from %s (%s)", poster.Nick, poster.Name)
|
nTitle := fmt.Sprintf("New post from %s (%s)", poster.Nick, poster.Name)
|
||||||
nSubtitle := "From your subscription"
|
nSubtitle := "From your subscription"
|
||||||
|
|
||||||
var body string
|
body := TruncatePostContentShort(content)
|
||||||
if len(content) > 80 {
|
|
||||||
body = content[:80]
|
|
||||||
} else {
|
|
||||||
body = content
|
|
||||||
}
|
|
||||||
if title != nil {
|
if title != nil {
|
||||||
body = fmt.Sprintf("%s\n%s", *title, body)
|
body = fmt.Sprintf("%s\n%s", *title, body)
|
||||||
}
|
}
|
||||||
@ -193,12 +229,7 @@ func NotifyTagSubscription(poster models.Tag, og models.Account, content string,
|
|||||||
nTitle := fmt.Sprintf("New post in %s by %s (%s)", poster.Name, og.Nick, og.Name)
|
nTitle := fmt.Sprintf("New post in %s by %s (%s)", poster.Name, og.Nick, og.Name)
|
||||||
nSubtitle := "From your subscription"
|
nSubtitle := "From your subscription"
|
||||||
|
|
||||||
var body string
|
body := TruncatePostContentShort(content)
|
||||||
if len(content) > 80 {
|
|
||||||
body = content[:80]
|
|
||||||
} else {
|
|
||||||
body = content
|
|
||||||
}
|
|
||||||
if title != nil {
|
if title != nil {
|
||||||
body = fmt.Sprintf("%s\n%s", *title, body)
|
body = fmt.Sprintf("%s\n%s", *title, body)
|
||||||
}
|
}
|
||||||
@ -240,12 +271,49 @@ func NotifyCategorySubscription(poster models.Category, og models.Account, conte
|
|||||||
nTitle := fmt.Sprintf("New post in %s by %s (%s)", poster.Name, og.Nick, og.Name)
|
nTitle := fmt.Sprintf("New post in %s by %s (%s)", poster.Name, og.Nick, og.Name)
|
||||||
nSubtitle := "From your subscription"
|
nSubtitle := "From your subscription"
|
||||||
|
|
||||||
var body string
|
body := TruncatePostContentShort(content)
|
||||||
if len(content) > 80 {
|
if title != nil {
|
||||||
body = content[:80]
|
body = fmt.Sprintf("%s\n%s", *title, body)
|
||||||
} else {
|
}
|
||||||
body = content
|
|
||||||
}
|
userIDs := make([]uint64, 0, len(subscriptions))
|
||||||
|
for _, subscription := range subscriptions {
|
||||||
|
userIDs = append(userIDs, uint64(subscription.Follower.ID))
|
||||||
|
}
|
||||||
|
|
||||||
|
pc, err := gap.H.GetServiceGrpcConn(hyper.ServiceTypeAuthProvider)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
_, err = proto.NewNotifierClient(pc).NotifyUserBatch(ctx, &proto.NotifyUserBatchRequest{
|
||||||
|
UserId: userIDs,
|
||||||
|
Notify: &proto.NotifyRequest{
|
||||||
|
Topic: "interactive.subscription",
|
||||||
|
Title: nTitle,
|
||||||
|
Subtitle: &nSubtitle,
|
||||||
|
Body: body,
|
||||||
|
IsRealtime: false,
|
||||||
|
IsForcePush: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotifyRealmSubscription(poster models.Realm, og models.Account, content string, title *string) error {
|
||||||
|
var subscriptions []models.Subscription
|
||||||
|
if err := database.C.Where("realm_id = ?", poster.ID).Preload("Follower").Find(&subscriptions).Error; err != nil {
|
||||||
|
return fmt.Errorf("unable to get subscriptions: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nTitle := fmt.Sprintf("New post in %s by %s (%s)", poster.Name, og.Nick, og.Name)
|
||||||
|
nSubtitle := "From your subscription"
|
||||||
|
|
||||||
|
body := TruncatePostContentShort(content)
|
||||||
if title != nil {
|
if title != nil {
|
||||||
body = fmt.Sprintf("%s\n%s", *title, body)
|
body = fmt.Sprintf("%s\n%s", *title, body)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user