♻️ Better notification system
This commit is contained in:
parent
b925d54000
commit
332557778d
60
.idea/workspace.xml
generated
60
.idea/workspace.xml
generated
@ -5,15 +5,15 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":sparkles: Apple push notification services">
|
<list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":sparkles: Apple push notification services">
|
||||||
<change afterPath="$PROJECT_DIR$/pkg/services/external_apns.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/go.mod" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pkg/grpc/notify.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/grpc/notify.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/go.sum" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pkg/grpc/proto/notify.pb.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/grpc/proto/notify.pb.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/pkg/cmd/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/cmd/main.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pkg/grpc/proto/notify.proto" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/grpc/proto/notify.proto" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/pkg/grpc/proto/notify_grpc.pb.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/grpc/proto/notify_grpc.pb.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/pkg/models/notifications.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/models/notifications.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pkg/models/notifications.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/models/notifications.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/pkg/services/external_firebase.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/services/external_firebase.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pkg/server/notifications_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/notifications_api.go" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/pkg/server/notify_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/notify_api.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/pkg/services/notifications.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/services/notifications.go" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pkg/services/notifications.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/services/notifications.go" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/settings.toml" beforeDir="false" afterPath="$PROJECT_DIR$/settings.toml" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@ -48,33 +48,33 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"DefaultGoTemplateProperty": "Go File",
|
"DefaultGoTemplateProperty": "Go File",
|
||||||
"Go Build.Backend.executor": "Run",
|
"Go Build.Backend.executor": "Run",
|
||||||
"Go 构建.Backend.executor": "Run",
|
"Go 构建.Backend.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
||||||
"RunOnceActivity.go.migrated.go.modules.settings": "true",
|
"RunOnceActivity.go.migrated.go.modules.settings": "true",
|
||||||
"RunOnceActivity.go.modules.automatic.dependencies.download": "true",
|
"RunOnceActivity.go.modules.automatic.dependencies.download": "true",
|
||||||
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
||||||
"git-widget-placeholder": "master",
|
"git-widget-placeholder": "master",
|
||||||
"go.import.settings.migrated": "true",
|
"go.import.settings.migrated": "true",
|
||||||
"go.sdk.automatically.set": "true",
|
"go.sdk.automatically.set": "true",
|
||||||
"last_opened_file_path": "/Users/littlesheep/Documents/Projects/Hydrogen/Passport/pkg/services",
|
"last_opened_file_path": "/Users/littlesheep/Documents/Projects/Hydrogen/Passport/pkg/services",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"run.code.analysis.last.selected.profile": "pProject Default",
|
"run.code.analysis.last.selected.profile": "pProject Default",
|
||||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
},
|
},
|
||||||
"keyToStringList": {
|
"keyToStringList": {
|
||||||
"DatabaseDriversLRU": [
|
"DatabaseDriversLRU": [
|
||||||
"postgresql"
|
"postgresql"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}]]></component>
|
}</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="$PROJECT_DIR$/pkg/services" />
|
<recent name="$PROJECT_DIR$/pkg/services" />
|
||||||
|
@ -2,6 +2,7 @@ package grpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
||||||
@ -20,6 +21,9 @@ func (v *Server) NotifyUser(_ context.Context, in *proto.NotifyRequest) (*proto.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var metadata map[string]any
|
||||||
|
_ = jsoniter.Unmarshal(in.GetMetadata(), &metadata)
|
||||||
|
|
||||||
links := lo.Map(in.GetLinks(), func(item *proto.NotifyLink, index int) models.NotificationLink {
|
links := lo.Map(in.GetLinks(), func(item *proto.NotifyLink, index int) models.NotificationLink {
|
||||||
return models.NotificationLink{
|
return models.NotificationLink{
|
||||||
Label: item.Label,
|
Label: item.Label,
|
||||||
@ -28,12 +32,13 @@ func (v *Server) NotifyUser(_ context.Context, in *proto.NotifyRequest) (*proto.
|
|||||||
})
|
})
|
||||||
|
|
||||||
notification := models.Notification{
|
notification := models.Notification{
|
||||||
|
Type: in.GetType(),
|
||||||
Subject: in.GetSubject(),
|
Subject: in.GetSubject(),
|
||||||
Content: in.GetContent(),
|
Content: in.GetContent(),
|
||||||
|
Metadata: metadata,
|
||||||
Links: links,
|
Links: links,
|
||||||
IsImportant: in.GetIsImportant(),
|
|
||||||
IsRealtime: in.GetIsRealtime(),
|
IsRealtime: in.GetIsRealtime(),
|
||||||
ReadAt: nil,
|
IsForcePush: in.GetIsForcePush(),
|
||||||
RecipientID: user.ID,
|
RecipientID: user.ID,
|
||||||
SenderID: &client.ID,
|
SenderID: &client.ID,
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.33.0
|
// protoc-gen-go v1.33.0
|
||||||
// protoc v4.25.3
|
// protoc v5.26.1
|
||||||
// source: notify.proto
|
// source: notify.proto
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
@ -80,14 +80,16 @@ type NotifyRequest struct {
|
|||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Subject string `protobuf:"bytes,1,opt,name=subject,proto3" json:"subject,omitempty"`
|
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
||||||
Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"`
|
Subject string `protobuf:"bytes,2,opt,name=subject,proto3" json:"subject,omitempty"`
|
||||||
Links []*NotifyLink `protobuf:"bytes,3,rep,name=links,proto3" json:"links,omitempty"`
|
Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"`
|
||||||
IsImportant bool `protobuf:"varint,4,opt,name=is_important,json=isImportant,proto3" json:"is_important,omitempty"`
|
Metadata []byte `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"`
|
||||||
RecipientId uint64 `protobuf:"varint,5,opt,name=recipient_id,json=recipientId,proto3" json:"recipient_id,omitempty"`
|
Links []*NotifyLink `protobuf:"bytes,5,rep,name=links,proto3" json:"links,omitempty"`
|
||||||
ClientId string `protobuf:"bytes,6,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
|
RecipientId uint64 `protobuf:"varint,6,opt,name=recipient_id,json=recipientId,proto3" json:"recipient_id,omitempty"`
|
||||||
ClientSecret string `protobuf:"bytes,7,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
|
ClientId string `protobuf:"bytes,7,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
|
||||||
IsRealtime bool `protobuf:"varint,8,opt,name=is_realtime,json=isRealtime,proto3" json:"is_realtime,omitempty"`
|
ClientSecret string `protobuf:"bytes,8,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
|
||||||
|
IsRealtime bool `protobuf:"varint,9,opt,name=is_realtime,json=isRealtime,proto3" json:"is_realtime,omitempty"`
|
||||||
|
IsForcePush bool `protobuf:"varint,10,opt,name=is_force_push,json=isForcePush,proto3" json:"is_force_push,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *NotifyRequest) Reset() {
|
func (x *NotifyRequest) Reset() {
|
||||||
@ -122,6 +124,13 @@ func (*NotifyRequest) Descriptor() ([]byte, []int) {
|
|||||||
return file_notify_proto_rawDescGZIP(), []int{1}
|
return file_notify_proto_rawDescGZIP(), []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *NotifyRequest) GetType() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Type
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (x *NotifyRequest) GetSubject() string {
|
func (x *NotifyRequest) GetSubject() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Subject
|
return x.Subject
|
||||||
@ -136,6 +145,13 @@ func (x *NotifyRequest) GetContent() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *NotifyRequest) GetMetadata() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Metadata
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (x *NotifyRequest) GetLinks() []*NotifyLink {
|
func (x *NotifyRequest) GetLinks() []*NotifyLink {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Links
|
return x.Links
|
||||||
@ -143,13 +159,6 @@ func (x *NotifyRequest) GetLinks() []*NotifyLink {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *NotifyRequest) GetIsImportant() bool {
|
|
||||||
if x != nil {
|
|
||||||
return x.IsImportant
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *NotifyRequest) GetRecipientId() uint64 {
|
func (x *NotifyRequest) GetRecipientId() uint64 {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.RecipientId
|
return x.RecipientId
|
||||||
@ -178,6 +187,13 @@ func (x *NotifyRequest) GetIsRealtime() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *NotifyRequest) GetIsForcePush() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.IsForcePush
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type NotifyReply struct {
|
type NotifyReply struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@ -232,33 +248,36 @@ var file_notify_proto_rawDesc = []byte{
|
|||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x34, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4c,
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x34, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4c,
|
||||||
0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01,
|
0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01,
|
||||||
0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c,
|
0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c,
|
||||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x95, 0x02, 0x0a, 0x0d,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0xc6, 0x02, 0x0a, 0x0d,
|
||||||
0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
|
0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
|
||||||
0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,
|
||||||
0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65,
|
0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01,
|
||||||
0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
|
0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63,
|
||||||
0x74, 0x12, 0x27, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f,
|
||||||
|
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||||
|
0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||||
|
0x61, 0x12, 0x27, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
|
||||||
0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4c,
|
0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4c,
|
||||||
0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73,
|
0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65,
|
||||||
0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
|
0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04,
|
||||||
0x52, 0x0b, 0x69, 0x73, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x12, 0x21, 0x0a,
|
0x52, 0x0b, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a,
|
||||||
0x0c, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20,
|
0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
|
||||||
0x01, 0x28, 0x04, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64,
|
0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c,
|
||||||
0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20,
|
0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28,
|
||||||
0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a,
|
0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12,
|
||||||
0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x07,
|
0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72,
|
0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65,
|
||||||
0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d,
|
0x12, 0x22, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x75, 0x73,
|
||||||
0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x61, 0x6c, 0x74,
|
0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x46, 0x6f, 0x72, 0x63, 0x65,
|
||||||
0x69, 0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0b, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x70,
|
0x50, 0x75, 0x73, 0x68, 0x22, 0x26, 0x0a, 0x0b, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65,
|
||||||
0x6c, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20,
|
0x70, 0x6c, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x01,
|
||||||
0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x53, 0x65, 0x6e, 0x74, 0x32, 0x42, 0x0a, 0x06, 0x4e,
|
0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x53, 0x65, 0x6e, 0x74, 0x32, 0x42, 0x0a, 0x06,
|
||||||
0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x38, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55,
|
0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x38, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79,
|
||||||
0x73, 0x65, 0x72, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69,
|
0x55, 0x73, 0x65, 0x72, 0x12, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x74,
|
||||||
0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42,
|
0x74, 0x6f, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00,
|
||||||
0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||||
0x6f, 0x33,
|
0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -14,14 +14,16 @@ message NotifyLink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message NotifyRequest {
|
message NotifyRequest {
|
||||||
string subject = 1;
|
string type = 1;
|
||||||
string content = 2;
|
string subject = 2;
|
||||||
repeated NotifyLink links = 3;
|
string content = 3;
|
||||||
bool is_important = 4;
|
bytes metadata = 4;
|
||||||
uint64 recipient_id = 5;
|
repeated NotifyLink links = 5;
|
||||||
string client_id = 6;
|
uint64 recipient_id = 6;
|
||||||
string client_secret = 7;
|
string client_id = 7;
|
||||||
bool is_realtime = 8;
|
string client_secret = 8;
|
||||||
|
bool is_realtime = 9;
|
||||||
|
bool is_force_push = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
message NotifyReply {
|
message NotifyReply {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.3.0
|
// - protoc-gen-go-grpc v1.3.0
|
||||||
// - protoc v4.25.3
|
// - protoc v5.26.1
|
||||||
// source: notify.proto
|
// source: notify.proto
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
|
|
||||||
"gorm.io/datatypes"
|
"gorm.io/datatypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,9 +12,8 @@ type Notification struct {
|
|||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Metadata datatypes.JSONMap `json:"metadata"`
|
Metadata datatypes.JSONMap `json:"metadata"`
|
||||||
Links datatypes.JSONSlice[NotificationLink] `json:"links"`
|
Links datatypes.JSONSlice[NotificationLink] `json:"links"`
|
||||||
IsImportant bool `json:"is_important"`
|
|
||||||
IsRealtime bool `json:"is_realtime" gorm:"-"`
|
IsRealtime bool `json:"is_realtime" gorm:"-"`
|
||||||
ReadAt *time.Time `json:"read_at"`
|
IsForcePush bool `json:"is_force_push" gorm:"-"`
|
||||||
SenderID *uint `json:"sender_id"`
|
SenderID *uint `json:"sender_id"`
|
||||||
RecipientID uint `json:"recipient_id"`
|
RecipientID uint `json:"recipient_id"`
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/utils"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/database"
|
"git.solsynth.dev/hydrogen/passport/pkg/database"
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
||||||
|
"git.solsynth.dev/hydrogen/passport/pkg/utils"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/samber/lo"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getNotifications(c *fiber.Ctx) error {
|
func getNotifications(c *fiber.Ctx) error {
|
||||||
@ -16,12 +13,7 @@ func getNotifications(c *fiber.Ctx) error {
|
|||||||
take := c.QueryInt("take", 0)
|
take := c.QueryInt("take", 0)
|
||||||
offset := c.QueryInt("offset", 0)
|
offset := c.QueryInt("offset", 0)
|
||||||
|
|
||||||
only_unread := !c.QueryBool("past", false)
|
|
||||||
|
|
||||||
tx := database.C.Where(&models.Notification{RecipientID: user.ID}).Model(&models.Notification{})
|
tx := database.C.Where(&models.Notification{RecipientID: user.ID}).Model(&models.Notification{})
|
||||||
if only_unread {
|
|
||||||
tx = tx.Where("read_at IS NULL")
|
|
||||||
}
|
|
||||||
|
|
||||||
var count int64
|
var count int64
|
||||||
var notifications []models.Notification
|
var notifications []models.Notification
|
||||||
@ -33,7 +25,6 @@ func getNotifications(c *fiber.Ctx) error {
|
|||||||
if err := tx.
|
if err := tx.
|
||||||
Limit(take).
|
Limit(take).
|
||||||
Offset(offset).
|
Offset(offset).
|
||||||
Order("read_at desc").
|
|
||||||
Find(¬ifications).Error; err != nil {
|
Find(¬ifications).Error; err != nil {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
@ -56,9 +47,7 @@ func markNotificationRead(c *fiber.Ctx) error {
|
|||||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
notify.ReadAt = lo.ToPtr(time.Now())
|
if err := database.C.Delete(¬ify).Error; err != nil {
|
||||||
|
|
||||||
if err := database.C.Save(¬ify).Error; err != nil {
|
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
} else {
|
} else {
|
||||||
return c.SendStatus(fiber.StatusOK)
|
return c.SendStatus(fiber.StatusOK)
|
||||||
@ -78,7 +67,7 @@ func markNotificationReadBatch(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
if err := database.C.Model(&models.Notification{}).
|
if err := database.C.Model(&models.Notification{}).
|
||||||
Where("recipient_id = ? AND id IN ?", user.ID, data.MessageIDs).
|
Where("recipient_id = ? AND id IN ?", user.ID, data.MessageIDs).
|
||||||
Updates(&models.Notification{ReadAt: lo.ToPtr(time.Now())}).Error; err != nil {
|
Delete(&models.Notification{}).Error; err != nil {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
} else {
|
} else {
|
||||||
return c.SendStatus(fiber.StatusOK)
|
return c.SendStatus(fiber.StatusOK)
|
||||||
|
@ -11,10 +11,12 @@ func notifyUser(c *fiber.Ctx) error {
|
|||||||
var data struct {
|
var data struct {
|
||||||
ClientID string `json:"client_id" validate:"required"`
|
ClientID string `json:"client_id" validate:"required"`
|
||||||
ClientSecret string `json:"client_secret" validate:"required"`
|
ClientSecret string `json:"client_secret" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required"`
|
||||||
Subject string `json:"subject" validate:"required,max=1024"`
|
Subject string `json:"subject" validate:"required,max=1024"`
|
||||||
Content string `json:"content" validate:"required,max=3072"`
|
Content string `json:"content" validate:"required,max=4096"`
|
||||||
|
Metadata map[string]any `json:"metadata"`
|
||||||
Links []models.NotificationLink `json:"links"`
|
Links []models.NotificationLink `json:"links"`
|
||||||
IsImportant bool `json:"is_important"`
|
IsForcePush bool `json:"is_force_push"`
|
||||||
IsRealtime bool `json:"is_realtime"`
|
IsRealtime bool `json:"is_realtime"`
|
||||||
UserID uint `json:"user_id" validate:"required"`
|
UserID uint `json:"user_id" validate:"required"`
|
||||||
}
|
}
|
||||||
@ -34,12 +36,12 @@ func notifyUser(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
notification := models.Notification{
|
notification := models.Notification{
|
||||||
|
Type: data.Type,
|
||||||
Subject: data.Subject,
|
Subject: data.Subject,
|
||||||
Content: data.Content,
|
Content: data.Content,
|
||||||
Links: data.Links,
|
Links: data.Links,
|
||||||
IsImportant: data.IsImportant,
|
|
||||||
IsRealtime: data.IsRealtime,
|
IsRealtime: data.IsRealtime,
|
||||||
ReadAt: nil,
|
IsForcePush: data.IsForcePush,
|
||||||
RecipientID: user.ID,
|
RecipientID: user.ID,
|
||||||
SenderID: &client.ID,
|
SenderID: &client.ID,
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func PushNotification(notification models.Notification) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip push notification when frontend notify is available
|
// Skip push notification when frontend notify is available
|
||||||
if frontendAvailable {
|
if frontendAvailable && !notification.IsForcePush {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user