diff --git a/channel/main.go b/channel/main.go
index 3b79730..f155e79 100644
--- a/channel/main.go
+++ b/channel/main.go
@@ -29,6 +29,8 @@ func SendMessage(message *model.Message, user *model.User, channel_ *model.Chann
return SendDiscordMessage(message, user, channel_)
case model.TypeNone:
return nil
+ case model.TypeOneBot:
+ return SendOneBotMessage(message, user, channel_)
default:
return errors.New("不支持的消息通道:" + channel_.Type)
}
diff --git a/channel/one-bot.go b/channel/one-bot.go
new file mode 100644
index 0000000..1af0709
--- /dev/null
+++ b/channel/one-bot.go
@@ -0,0 +1,85 @@
+package channel
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "message-pusher/model"
+ "net/http"
+ "strconv"
+ "strings"
+)
+
+type oneBotMessageRequest struct {
+ MessageType string `json:"message_type"`
+ UserId int64 `json:"user_id"`
+ GroupId int64 `json:"group_id"`
+ Message string `json:"message"`
+ AutoEscape bool `json:"auto_escape"`
+}
+
+type oneBotMessageResponse struct {
+ Message string `json:"message"`
+ Status string `json:"status"`
+ RetCode int `json:"retcode"`
+}
+
+func SendOneBotMessage(message *model.Message, user *model.User, channel_ *model.Channel) error {
+ url := fmt.Sprintf("%s/send_msg", channel_.URL)
+ req := oneBotMessageRequest{
+ Message: message.Content,
+ }
+ if message.Content == "" {
+ req.Message = message.Description
+ }
+ target := channel_.AccountId
+ if message.To != "" {
+ target = message.To
+ }
+ parts := strings.Split(target, "_")
+ var idStr string
+ var type_ string
+ if len(parts) == 1 {
+ type_ = "user"
+ idStr = parts[0]
+ } else if len(parts) == 2 {
+ type_ = parts[0]
+ idStr = parts[1]
+ } else {
+ return errors.New("无效的 OneBot 配置")
+ }
+ id, _ := strconv.ParseInt(idStr, 10, 64)
+ if type_ == "user" {
+ req.UserId = id
+ req.MessageType = "private"
+ } else if type_ == "group" {
+ req.GroupId = id
+ req.MessageType = "group"
+ } else {
+ return errors.New("无效的 OneBot 配置")
+ }
+ reqBody, err := json.Marshal(req)
+ if err != nil {
+ return err
+ }
+ request, _ := http.NewRequest("POST", url, bytes.NewReader(reqBody))
+ request.Header.Set("Authorization", "Bearer "+channel_.Secret)
+ request.Header.Set("Content-Type", "application/json")
+ resp, err := http.DefaultClient.Do(request)
+ if err != nil {
+ return err
+ }
+ if resp.StatusCode != 200 {
+ return errors.New(resp.Status)
+ }
+ var res oneBotMessageResponse
+ err = json.NewDecoder(resp.Body).Decode(&res)
+ if err != nil {
+ return err
+ }
+ if res.RetCode != 0 {
+ return errors.New(res.Message)
+ }
+ return nil
+}
diff --git a/model/channel.go b/model/channel.go
index ed9e863..77d2cbe 100644
--- a/model/channel.go
+++ b/model/channel.go
@@ -16,6 +16,7 @@ const (
TypeBark = "bark"
TypeClient = "client"
TypeNone = "none"
+ TypeOneBot = "one_bot"
)
type Channel struct {
diff --git a/web/src/constants/channel.constants.js b/web/src/constants/channel.constants.js
index f2f4449..e5c25ee 100644
--- a/web/src/constants/channel.constants.js
+++ b/web/src/constants/channel.constants.js
@@ -29,6 +29,12 @@ export const CHANNEL_OPTIONS = [
value: 'discord',
color: '#404eed',
},
+ {
+ key: 'one_bot',
+ text: 'OneBot 协议',
+ value: 'one_bot',
+ color: '#616cff',
+ },
{
key: 'none',
text: '不推送',
diff --git a/web/src/pages/Channel/EditChannel.js b/web/src/pages/Channel/EditChannel.js
index 1c1dc12..219aa48 100644
--- a/web/src/pages/Channel/EditChannel.js
+++ b/web/src/pages/Channel/EditChannel.js
@@ -61,7 +61,15 @@ const EditChannel = () => {
localInputs.app_id = `${inputs.corp_id}|${inputs.agent_id}`;
break;
case 'bark':
- localInputs.url = 'https://api.day.app';
+ if (localInputs.url === '') {
+ localInputs.url = 'https://api.day.app';
+ }
+ break;
+ case 'one_bot':
+ if (localInputs.url.endsWith('/')) {
+ localInputs.url = localInputs.url.slice(0, -1);
+ }
+ break;
}
if (isEditing) {
res = await API.put(`/api/channel/`, {
@@ -453,6 +461,42 @@ const EditChannel = () => {
>
);
+ case 'one_bot':
+ return (
+ <>
+