feat: support channel OneBot now (close #64)
This commit is contained in:
@@ -29,6 +29,8 @@ func SendMessage(message *model.Message, user *model.User, channel_ *model.Chann
|
|||||||
return SendDiscordMessage(message, user, channel_)
|
return SendDiscordMessage(message, user, channel_)
|
||||||
case model.TypeNone:
|
case model.TypeNone:
|
||||||
return nil
|
return nil
|
||||||
|
case model.TypeOneBot:
|
||||||
|
return SendOneBotMessage(message, user, channel_)
|
||||||
default:
|
default:
|
||||||
return errors.New("不支持的消息通道:" + channel_.Type)
|
return errors.New("不支持的消息通道:" + channel_.Type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ const (
|
|||||||
TypeBark = "bark"
|
TypeBark = "bark"
|
||||||
TypeClient = "client"
|
TypeClient = "client"
|
||||||
TypeNone = "none"
|
TypeNone = "none"
|
||||||
|
TypeOneBot = "one_bot"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Channel struct {
|
type Channel struct {
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ export const CHANNEL_OPTIONS = [
|
|||||||
value: 'discord',
|
value: 'discord',
|
||||||
color: '#404eed',
|
color: '#404eed',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'one_bot',
|
||||||
|
text: 'OneBot 协议',
|
||||||
|
value: 'one_bot',
|
||||||
|
color: '#616cff',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'none',
|
key: 'none',
|
||||||
text: '不推送',
|
text: '不推送',
|
||||||
|
|||||||
@@ -61,7 +61,15 @@ const EditChannel = () => {
|
|||||||
localInputs.app_id = `${inputs.corp_id}|${inputs.agent_id}`;
|
localInputs.app_id = `${inputs.corp_id}|${inputs.agent_id}`;
|
||||||
break;
|
break;
|
||||||
case 'bark':
|
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) {
|
if (isEditing) {
|
||||||
res = await API.put(`/api/channel/`, {
|
res = await API.put(`/api/channel/`, {
|
||||||
@@ -453,6 +461,42 @@ const EditChannel = () => {
|
|||||||
</Form.Group>
|
</Form.Group>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
case 'one_bot':
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Message>
|
||||||
|
通过 OneBot 协议进行推送,可以使用 <a href='https://github.com/Mrs4s/go-cqhttp' target='_blank'>cqhttp</a> 等实现。
|
||||||
|
利用 OneBot 协议可以实现推送 QQ 消息。
|
||||||
|
</Message>
|
||||||
|
<Form.Group widths={2}>
|
||||||
|
<Form.Input
|
||||||
|
label='服务器地址'
|
||||||
|
name='url'
|
||||||
|
onChange={handleInputChange}
|
||||||
|
autoComplete='new-password'
|
||||||
|
value={inputs.url}
|
||||||
|
placeholder='在此填写服务器地址'
|
||||||
|
/>
|
||||||
|
<Form.Input
|
||||||
|
label='推送 key'
|
||||||
|
name='secret'
|
||||||
|
type='password'
|
||||||
|
onChange={handleInputChange}
|
||||||
|
autoComplete='new-password'
|
||||||
|
value={inputs.secret}
|
||||||
|
placeholder='在此填写服务器的 access token'
|
||||||
|
/>
|
||||||
|
<Form.Input
|
||||||
|
label='默认推送目标'
|
||||||
|
name='account_id'
|
||||||
|
onChange={handleInputChange}
|
||||||
|
autoComplete='new-password'
|
||||||
|
value={inputs.account_id}
|
||||||
|
placeholder='在此填写默认推送目标,例如 QQ 号,如果是群号则前面必须加上群号前缀,例如 group_123456789'
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
</>
|
||||||
|
);
|
||||||
case 'none':
|
case 'none':
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
Reference in New Issue
Block a user