mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-04-03 20:07:36 +03:00
120 lines
3.8 KiB
Go
120 lines
3.8 KiB
Go
package surge
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"strings"
|
|
|
|
"github.com/sagernet/sing-box/experimental/libbox/platform"
|
|
"github.com/sagernet/sing-box/script/jsc"
|
|
"github.com/sagernet/sing-box/script/modules/boxctx"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
"github.com/sagernet/sing/common/logger"
|
|
"github.com/sagernet/sing/service"
|
|
|
|
"github.com/dop251/goja"
|
|
)
|
|
|
|
type Notification struct {
|
|
class jsc.Class[*Module, *Notification]
|
|
logger logger.ContextLogger
|
|
tag string
|
|
platformInterface platform.Interface
|
|
}
|
|
|
|
func createNotification(module *Module) jsc.Class[*Module, *Notification] {
|
|
class := jsc.NewClass[*Module, *Notification](module)
|
|
class.DefineMethod("post", (*Notification).post)
|
|
class.DefineMethod("toString", (*Notification).toString)
|
|
return class
|
|
}
|
|
|
|
func newNotification(class jsc.Class[*Module, *Notification]) goja.Value {
|
|
context := boxctx.MustFromRuntime(class.Runtime())
|
|
return class.New(&Notification{
|
|
class: class,
|
|
logger: context.Logger,
|
|
tag: context.Tag,
|
|
platformInterface: service.FromContext[platform.Interface](context.Context),
|
|
})
|
|
}
|
|
|
|
func (s *Notification) post(call goja.FunctionCall) any {
|
|
var (
|
|
title string
|
|
subtitle string
|
|
body string
|
|
openURL string
|
|
clipboard string
|
|
mediaURL string
|
|
mediaData []byte
|
|
mediaType string
|
|
autoDismiss int
|
|
)
|
|
title = jsc.AssertString(s.class.Runtime(), call.Argument(0), "title", true)
|
|
subtitle = jsc.AssertString(s.class.Runtime(), call.Argument(1), "subtitle", true)
|
|
body = jsc.AssertString(s.class.Runtime(), call.Argument(2), "body", true)
|
|
options := jsc.AssertObject(s.class.Runtime(), call.Argument(3), "options", true)
|
|
if options != nil {
|
|
action := jsc.AssertString(s.class.Runtime(), options.Get("action"), "options.action", true)
|
|
switch action {
|
|
case "open-url":
|
|
openURL = jsc.AssertString(s.class.Runtime(), options.Get("url"), "options.url", false)
|
|
case "clipboard":
|
|
clipboard = jsc.AssertString(s.class.Runtime(), options.Get("clipboard"), "options.clipboard", false)
|
|
}
|
|
mediaURL = jsc.AssertString(s.class.Runtime(), options.Get("media-url"), "options.media-url", true)
|
|
mediaBase64 := jsc.AssertString(s.class.Runtime(), options.Get("media-base64"), "options.media-base64", true)
|
|
if mediaBase64 != "" {
|
|
mediaBinary, err := base64.StdEncoding.DecodeString(mediaBase64)
|
|
if err != nil {
|
|
panic(s.class.Runtime().NewGoError(E.Cause(err, "decode media-base64")))
|
|
}
|
|
mediaData = mediaBinary
|
|
mediaType = jsc.AssertString(s.class.Runtime(), options.Get("media-base64-mime"), "options.media-base64-mime", false)
|
|
}
|
|
autoDismiss = int(jsc.AssertInt(s.class.Runtime(), options.Get("auto-dismiss"), "options.auto-dismiss", true))
|
|
}
|
|
if title != "" && subtitle == "" && body == "" {
|
|
body = title
|
|
title = ""
|
|
} else if title != "" && subtitle != "" && body == "" {
|
|
body = subtitle
|
|
subtitle = ""
|
|
}
|
|
var builder strings.Builder
|
|
if title != "" {
|
|
builder.WriteString("[")
|
|
builder.WriteString(title)
|
|
if subtitle != "" {
|
|
builder.WriteString(" - ")
|
|
builder.WriteString(subtitle)
|
|
}
|
|
builder.WriteString("]: ")
|
|
}
|
|
builder.WriteString(body)
|
|
s.logger.Info("notification: " + builder.String())
|
|
if s.platformInterface != nil {
|
|
err := s.platformInterface.SendNotification(&platform.Notification{
|
|
Identifier: "surge-script-notification-" + s.tag,
|
|
TypeName: "Surge Script Notification (" + s.tag + ")",
|
|
TypeID: 11,
|
|
Title: title,
|
|
Subtitle: subtitle,
|
|
Body: body,
|
|
OpenURL: openURL,
|
|
Clipboard: clipboard,
|
|
MediaURL: mediaURL,
|
|
MediaData: mediaData,
|
|
MediaType: mediaType,
|
|
Timeout: autoDismiss,
|
|
})
|
|
if err != nil {
|
|
s.logger.Error(E.Cause(err, "send notification"))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Notification) toString(call goja.FunctionCall) any {
|
|
return "[sing-box Surge notification]"
|
|
}
|