Skip to content

Commit

Permalink
feat: add serverchan notify client
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-ding committed Feb 13, 2025
1 parent 8a4566a commit d44f786
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 37 deletions.
2 changes: 2 additions & 0 deletions db/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ func toNotificationClient(cl *ent.NotificationClient) (*NotificationClient, erro
settings = notifier.TelegramConfig{}
case "bark":
settings = notifier.BarkConfig{}
case "serverchan":
settings = notifier.ServerChanConfig{}
}
err := json.Unmarshal([]byte(cl.Settings), &settings)
if err != nil {
Expand Down
15 changes: 15 additions & 0 deletions pkg/notifier/clients_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package notifier

import "testing"

func TestServerChan(t *testing.T) {
s, err := NewServerChanClient(``)
if err != nil {
t.Error(err)
return
}
err = s.SendMsg("test")
if err != nil {
t.Error(err)
}
}
1 change: 1 addition & 0 deletions pkg/notifier/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func init() {
handler.Store("dingtalk", NewDingTalkClient)
handler.Store("telegram", NewTelegramClient)
handler.Store("bark", NewbarkClient)
handler.Store("serverchan", NewServerChanClient)
}

func Gethandler(name string) (HandlerFunc, bool) {
Expand Down
89 changes: 89 additions & 0 deletions pkg/notifier/serverchan.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package notifier

import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"regexp"
"strings"

"github.com/pkg/errors"
)

type ServerChanConfig struct {
Key string `json:"key"`
}

func NewServerChanClient(s string) (NotificationClient, error) {
var cfg ServerChanConfig
if err := json.Unmarshal([]byte(s), &cfg); err != nil {
return nil, errors.Wrap(err, "json")
}

return &ServerChan{Key: cfg.Key}, nil
}

type ServerChan struct {
Key string
}

func (s *ServerChan) SendMsg(msg string) error {
return scSend("Polaris", msg, s.Key)
}

func scSend(text string, desp string, key string) error {
data := url.Values{}
data.Set("text", text)
data.Set("desp", desp)

// 根据 sendkey 是否以 "sctp" 开头决定 API 的 URL
var apiUrl string
if strings.HasPrefix(key, "sctp") {
// 使用正则表达式提取数字部分
re := regexp.MustCompile(`sctp(\d+)t`)
matches := re.FindStringSubmatch(key)
if len(matches) > 1 {
num := matches[1]
apiUrl = fmt.Sprintf("https://%s.push.ft07.com/send/%s.send", num, key)
} else {
return errors.New("invalid sendkey format for sctp")
}
} else {
apiUrl = fmt.Sprintf("https://sctapi.ftqq.com/%s.send", key)
}

client := &http.Client{}
req, err := http.NewRequest("POST", apiUrl, strings.NewReader(data.Encode()))
if err != nil {
return err
}

req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
d, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
var r response
if err := json.Unmarshal(d, &r); err != nil {
return err
}

if r.Code != 0 {
return errors.New(r.Message)
}

return nil
}

type response struct {
Code int `json:"code"`
Message string `json:"message"`
}
65 changes: 65 additions & 0 deletions ui/lib/settings/notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ class _NotifierState extends ConsumerState<NotifierSettings> {
showBarkNotifierDetails(NotifierData());
},
),
),
SettingsCard(
child: InkWell(
child: const Center(
child: Text("Server酱"),
),
onTap: () {
Navigator.of(context).pop();
showServerChanNotifierDetails(NotifierData());
},
),
)
],
),
Expand All @@ -98,10 +109,64 @@ class _NotifierState extends ConsumerState<NotifierSettings> {
return showBarkNotifierDetails(notifier);
case "pushover":
return showPushoverNotifierDetails(notifier);
case "serverchan":
return showServerChanNotifierDetails(notifier);
}
return Future<void>.value();
}

Future<void> showServerChanNotifierDetails(NotifierData notifier) {
final _formKey = GlobalKey<FormBuilderState>();

var body = FormBuilder(
key: _formKey,
initialValue: {
"name": notifier.name,
"enabled": notifier.enabled ?? true,
"key": notifier.settings != null ? notifier.settings!["key"] : "",
},
child: Column(
children: [
const Text("https://sct.ftqq.com/"),
FormBuilderTextField(
name: "name",
decoration: Commons.requiredTextFieldStyle(text: "名称"),
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.required(),
),
FormBuilderTextField(
name: "key",
decoration: Commons.requiredTextFieldStyle(text: "Key"),
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.required(),
),
FormBuilderSwitch(name: "enabled", title: const Text("启用"))
],
),
);
onDelete() async {
return ref.read(notifiersDataProvider.notifier).delete(notifier.id!);
}

onSubmit() async {
if (_formKey.currentState!.saveAndValidate()) {
var values = _formKey.currentState!.value;
return ref.read(notifiersDataProvider.notifier).add(NotifierData(
name: values["name"],
service: "serverchan",
enabled: values["enabled"],
settings: {
"key": values["key"],
}));
} else {
throw "validation_error";
}
}

return showSettingDialog(
context, "Server酱", notifier.id != null, body, onSubmit, onDelete);
}

Future<void> showBarkNotifierDetails(NotifierData notifier) {
final _formKey = GlobalKey<FormBuilderState>();

Expand Down
Loading

0 comments on commit d44f786

Please sign in to comment.