Subscriptions on the air

This commit is contained in:
LittleSheep 2024-09-17 00:35:42 +08:00
parent c01714b3fc
commit d2f24d0be2
2 changed files with 167 additions and 0 deletions

View File

@ -343,6 +343,27 @@ func NewPost(user models.Account, item models.Post) (models.Post, error) {
} }
} }
// Notify the subscriptions
if content, ok := item.Body["content"].(string); ok {
var title *string
title, _ = item.Body["title"].(*string)
go func() {
if err := NotifyUserSubscription(user, content, title); err != nil {
log.Error().Err(err).Msg("An error occurred when notifying subscriptions user by user...")
}
for _, tag := range item.Tags {
if err := NotifyTagSubscription(tag, user, content, title); err != nil {
log.Error().Err(err).Msg("An error occurred when notifying subscriptions user by tag...")
}
}
for _, category := range item.Categories {
if err := NotifyCategorySubscription(category, user, content, title); err != nil {
log.Error().Err(err).Msg("An error occurred when notifying subscriptions user by category...")
}
}
}()
}
log.Debug().Dur("elapsed", time.Since(start)).Msg("The post is posted.") log.Debug().Dur("elapsed", time.Since(start)).Msg("The post is posted.")
return item, nil return item, nil
} }

View File

@ -1,10 +1,15 @@
package services package services
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"time"
"git.solsynth.dev/hydrogen/dealer/pkg/hyper"
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
"git.solsynth.dev/hydrogen/interactive/pkg/internal/database" "git.solsynth.dev/hydrogen/interactive/pkg/internal/database"
"git.solsynth.dev/hydrogen/interactive/pkg/internal/gap"
"git.solsynth.dev/hydrogen/interactive/pkg/internal/models" "git.solsynth.dev/hydrogen/interactive/pkg/internal/models"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -134,3 +139,144 @@ func UnsubscribeFromCategory(user models.Account, target models.Category) error
err := database.C.Delete(&subscription).Error err := database.C.Delete(&subscription).Error
return err return err
} }
func NotifyUserSubscription(poster models.Account, content string, title *string) error {
var subscriptions []models.Subscription
if err := database.C.Where("account_id = ?", poster.ID).Preload("Follower").Find(&subscriptions).Error; err != nil {
return fmt.Errorf("unable to get subscriptions: %v", err)
}
nTitle := fmt.Sprintf("New post from %s (%s)", poster.Nick, poster.Name)
nSubtitle := "From your subscription"
var body string
if len(content) > 80 {
body = content[:80]
} else {
body = content
}
if title != nil {
body = fmt.Sprintf("%s\n%s", *title, body)
}
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 NotifyTagSubscription(poster models.Tag, og models.Account, content string, title *string) error {
var subscriptions []models.Subscription
if err := database.C.Where("tag_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"
var body string
if len(content) > 80 {
body = content[:80]
} else {
body = content
}
if title != nil {
body = fmt.Sprintf("%s\n%s", *title, body)
}
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 NotifyCategorySubscription(poster models.Category, og models.Account, content string, title *string) error {
var subscriptions []models.Subscription
if err := database.C.Where("category_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"
var body string
if len(content) > 80 {
body = content[:80]
} else {
body = content
}
if title != nil {
body = fmt.Sprintf("%s\n%s", *title, body)
}
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
}