feat: support Discord now
This commit is contained in:
@@ -50,7 +50,7 @@ _✨ 搭建专属于你的消息推送服务,支持多种消息推送方式,
|
|||||||
+ Bark App,
|
+ Bark App,
|
||||||
+ WebSocket 客户端([官方客户端](https://github.com/songquanpeng/personal-assistant),[接入文档](./docs/API.md#websocket-客户端)),
|
+ WebSocket 客户端([官方客户端](https://github.com/songquanpeng/personal-assistant),[接入文档](./docs/API.md#websocket-客户端)),
|
||||||
+ Telegram 机器人,
|
+ Telegram 机器人,
|
||||||
+ Discord 群机器人(WIP),
|
+ Discord 群机器人,
|
||||||
2. 多种用户登录注册方式:
|
2. 多种用户登录注册方式:
|
||||||
+ 邮箱登录注册以及通过邮箱进行密码重置。
|
+ 邮箱登录注册以及通过邮箱进行密码重置。
|
||||||
+ [GitHub 开放授权](https://github.com/settings/applications/new)。
|
+ [GitHub 开放授权](https://github.com/settings/applications/new)。
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package channel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"message-pusher/model"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type discordMessageRequest struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type discordMessageResponse struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendDiscordMessage(message *model.Message, user *model.User) error {
|
||||||
|
if user.DiscordWebhookURL == "" {
|
||||||
|
return errors.New("未配置 Discord 群机器人消息推送方式")
|
||||||
|
}
|
||||||
|
if message.Content == "" {
|
||||||
|
message.Content = message.Description
|
||||||
|
}
|
||||||
|
messageRequest := discordMessageRequest{
|
||||||
|
Content: message.Content,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(messageRequest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resp, err := http.Post(user.DiscordWebhookURL, "application/json", bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.StatusCode == http.StatusNoContent {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var res discordMessageResponse
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&res)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if res.Code != 0 {
|
||||||
|
return errors.New(res.Message)
|
||||||
|
}
|
||||||
|
if resp.StatusCode == http.StatusBadRequest {
|
||||||
|
return errors.New(resp.Status)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ const (
|
|||||||
TypeLark = "lark"
|
TypeLark = "lark"
|
||||||
TypeDing = "ding"
|
TypeDing = "ding"
|
||||||
TypeTelegram = "telegram"
|
TypeTelegram = "telegram"
|
||||||
|
TypeDiscord = "discord"
|
||||||
TypeBark = "bark"
|
TypeBark = "bark"
|
||||||
TypeClient = "client"
|
TypeClient = "client"
|
||||||
TypeNone = "none"
|
TypeNone = "none"
|
||||||
@@ -38,6 +39,8 @@ func SendMessage(message *model.Message, user *model.User) error {
|
|||||||
return SendClientMessage(message, user)
|
return SendClientMessage(message, user)
|
||||||
case TypeTelegram:
|
case TypeTelegram:
|
||||||
return SendTelegramMessage(message, user)
|
return SendTelegramMessage(message, user)
|
||||||
|
case TypeDiscord:
|
||||||
|
return SendDiscordMessage(message, user)
|
||||||
case TypeNone:
|
case TypeNone:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -425,6 +425,7 @@ func UpdateSelf(c *gin.Context) {
|
|||||||
ClientSecret: user.ClientSecret,
|
ClientSecret: user.ClientSecret,
|
||||||
TelegramBotToken: user.TelegramBotToken,
|
TelegramBotToken: user.TelegramBotToken,
|
||||||
TelegramChatId: user.TelegramChatId,
|
TelegramChatId: user.TelegramChatId,
|
||||||
|
DiscordWebhookURL: user.DiscordWebhookURL,
|
||||||
}
|
}
|
||||||
channel.TokenStoreUpdateUser(&cleanUser, originUser)
|
channel.TokenStoreUpdateUser(&cleanUser, originUser)
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -41,6 +41,7 @@ type User struct {
|
|||||||
ClientSecret string `json:"client_secret"`
|
ClientSecret string `json:"client_secret"`
|
||||||
TelegramBotToken string `json:"telegram_bot_token"`
|
TelegramBotToken string `json:"telegram_bot_token"`
|
||||||
TelegramChatId string `json:"telegram_chat_id"`
|
TelegramChatId string `json:"telegram_chat_id"`
|
||||||
|
DiscordWebhookURL string `json:"discord_webhook_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMaxUserId() int {
|
func GetMaxUserId() int {
|
||||||
@@ -77,7 +78,7 @@ func GetUserById(id int, selectAll bool) (*User, error) {
|
|||||||
"channel", "token",
|
"channel", "token",
|
||||||
"wechat_test_account_id", "wechat_test_account_template_id", "wechat_test_account_open_id",
|
"wechat_test_account_id", "wechat_test_account_template_id", "wechat_test_account_open_id",
|
||||||
"wechat_corp_account_id", "wechat_corp_account_agent_id", "wechat_corp_account_user_id", "wechat_corp_account_client_type",
|
"wechat_corp_account_id", "wechat_corp_account_agent_id", "wechat_corp_account_user_id", "wechat_corp_account_client_type",
|
||||||
"corp_webhook_url", "lark_webhook_url", "ding_webhook_url", "bark_server", "telegram_chat_id",
|
"corp_webhook_url", "lark_webhook_url", "ding_webhook_url", "bark_server", "telegram_chat_id", "discord_webhook_url",
|
||||||
}).First(&user, "id = ?", id).Error
|
}).First(&user, "id = ?", id).Error
|
||||||
}
|
}
|
||||||
return &user, err
|
return &user, err
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const PushSetting = () => {
|
|||||||
client_secret: '',
|
client_secret: '',
|
||||||
telegram_bot_token: '',
|
telegram_bot_token: '',
|
||||||
telegram_chat_id: '',
|
telegram_chat_id: '',
|
||||||
|
discord_webhook_url: '',
|
||||||
});
|
});
|
||||||
let [loading, setLoading] = useState(false);
|
let [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
@@ -117,6 +118,9 @@ const PushSetting = () => {
|
|||||||
data.telegram_bot_token = inputs.telegram_bot_token;
|
data.telegram_bot_token = inputs.telegram_bot_token;
|
||||||
data.telegram_chat_id = inputs.telegram_chat_id;
|
data.telegram_chat_id = inputs.telegram_chat_id;
|
||||||
break;
|
break;
|
||||||
|
case 'discord':
|
||||||
|
data.discord_webhook_url = inputs.discord_webhook_url;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
showError(`无效的参数:${which}`);
|
showError(`无效的参数:${which}`);
|
||||||
return;
|
return;
|
||||||
@@ -188,6 +192,7 @@ const PushSetting = () => {
|
|||||||
{ key: 'bark', text: 'Bark App', value: 'bark' },
|
{ key: 'bark', text: 'Bark App', value: 'bark' },
|
||||||
{ key: 'client', text: 'WebSocket 客户端', value: 'client' },
|
{ key: 'client', text: 'WebSocket 客户端', value: 'client' },
|
||||||
{ key: 'telegram', text: 'Telegram 机器人', value: 'telegram' },
|
{ key: 'telegram', text: 'Telegram 机器人', value: 'telegram' },
|
||||||
|
{ key: 'discord', text: 'Discord 群机器人', value: 'discord' },
|
||||||
]}
|
]}
|
||||||
value={inputs.channel}
|
value={inputs.channel}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
@@ -551,6 +556,28 @@ const PushSetting = () => {
|
|||||||
保存
|
保存
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={() => test('telegram')}>测试</Button>
|
<Button onClick={() => test('telegram')}>测试</Button>
|
||||||
|
<Divider />
|
||||||
|
<Header as='h3'>
|
||||||
|
Discord 群机器人设置(discord)
|
||||||
|
<Header.Subheader>
|
||||||
|
通过 Discord 群机器人进行推送,配置流程:选择一个 channel -> 设置
|
||||||
|
-> 整合 -> 创建 Webhook -> 点击复制 Webhook URL
|
||||||
|
</Header.Subheader>
|
||||||
|
</Header>
|
||||||
|
<Form.Group widths={2}>
|
||||||
|
<Form.Input
|
||||||
|
label='Webhook 地址'
|
||||||
|
name='discord_webhook_url'
|
||||||
|
onChange={handleInputChange}
|
||||||
|
autoComplete='off'
|
||||||
|
value={inputs.discord_webhook_url}
|
||||||
|
placeholder='在此填写 Discord 提供的 Webhook 地址'
|
||||||
|
/>
|
||||||
|
</Form.Group>
|
||||||
|
<Button onClick={() => submit('discord')} loading={loading}>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
<Button onClick={() => test('discord')}>测试</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
Reference in New Issue
Block a user