diff --git a/channel/main.go b/channel/main.go index 7eca2ab..dcad14c 100644 --- a/channel/main.go +++ b/channel/main.go @@ -46,6 +46,8 @@ func (message *Message) Send(user *model.User) error { return SendBarkMessage(message, user) case TypeClient: return SendClientMessage(message, user) + case TypeTelegram: + return SendTelegramMessage(message, user) default: return errors.New("不支持的消息通道:" + message.Channel) } diff --git a/channel/telegram.go b/channel/telegram.go new file mode 100644 index 0000000..2b2d001 --- /dev/null +++ b/channel/telegram.go @@ -0,0 +1,53 @@ +package channel + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "message-pusher/model" + "net/http" +) + +type telegramMessageRequest struct { + ChatId string `json:"chat_id"` + Text string `json:"text"` + ParseMode string `json:"parse_mode"` +} + +type telegramMessageResponse struct { + Ok bool `json:"ok"` + Description string `json:"description"` +} + +func SendTelegramMessage(message *Message, user *model.User) error { + if user.TelegramBotToken == "" || user.TelegramChatId == "" { + return errors.New("未配置 Telegram 机器人消息推送方式") + } + messageRequest := telegramMessageRequest{ + ChatId: user.TelegramChatId, + Text: message.Content, + ParseMode: "markdown", + } + if messageRequest.Text == "" { + messageRequest.Text = message.Description + } + jsonData, err := json.Marshal(messageRequest) + if err != nil { + return err + } + resp, err := http.Post(fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", user.TelegramBotToken), "application/json", + bytes.NewBuffer(jsonData)) + if err != nil { + return err + } + var res telegramMessageResponse + err = json.NewDecoder(resp.Body).Decode(&res) + if err != nil { + return err + } + if !res.Ok { + return errors.New(res.Description) + } + return nil +} diff --git a/controller/user.go b/controller/user.go index 6e909c8..b13b5ef 100644 --- a/controller/user.go +++ b/controller/user.go @@ -392,6 +392,7 @@ func UpdateSelf(c *gin.Context) { }) return } + // White list mode. For safe :) cleanUser := model.User{ Id: c.GetInt("id"), Username: user.Username, @@ -417,6 +418,8 @@ func UpdateSelf(c *gin.Context) { BarkServer: user.BarkServer, BarkSecret: user.BarkSecret, ClientSecret: user.ClientSecret, + TelegramBotToken: user.TelegramBotToken, + TelegramChatId: user.TelegramChatId, } channel.TokenStoreUpdateUser(&cleanUser, originUser) diff --git a/model/user.go b/model/user.go index abeb7fe..238777e 100644 --- a/model/user.go +++ b/model/user.go @@ -39,6 +39,8 @@ type User struct { BarkServer string `json:"bark_server"` BarkSecret string `json:"bark_secret"` ClientSecret string `json:"client_secret"` + TelegramBotToken string `json:"telegram_bot_token"` + TelegramChatId string `json:"telegram_chat_id"` } func GetMaxUserId() int { @@ -75,7 +77,7 @@ func GetUserById(id int, selectAll bool) (*User, error) { "channel", "token", "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", - "corp_webhook_url", "lark_webhook_url", "ding_webhook_url", "bark_server", + "corp_webhook_url", "lark_webhook_url", "ding_webhook_url", "bark_server", "telegram_chat_id", }).First(&user, "id = ?", id).Error } return &user, err diff --git a/web/src/components/PushSetting.js b/web/src/components/PushSetting.js index 8a1d802..aaab55b 100644 --- a/web/src/components/PushSetting.js +++ b/web/src/components/PushSetting.js @@ -32,6 +32,8 @@ const PushSetting = () => { bark_server: '', bark_secret: '', client_secret: '', + telegram_bot_token: '', + telegram_chat_id: '', }); let [loading, setLoading] = useState(false); @@ -110,6 +112,10 @@ const PushSetting = () => { case 'client': data.client_secret = inputs.client_secret; break; + case 'telegram': + data.telegram_bot_token = inputs.telegram_bot_token; + data.telegram_chat_id = inputs.telegram_chat_id; + break; default: showError(`无效的参数:${which}`); return; @@ -156,6 +162,7 @@ const PushSetting = () => { { key: 'ding', text: '钉钉群机器人', value: 'ding' }, { key: 'bark', text: 'Bark App', value: 'bark' }, { key: 'client', text: 'WebSocket 客户端', value: 'client' }, + { key: 'telegram', text: 'Telegram 机器人', value: 'telegram' }, ]} value={inputs.channel} onChange={handleInputChange} @@ -478,6 +485,37 @@ const PushSetting = () => { 保存 + +
+ Telegram 机器人设置(telegram) + + 通过 Telegram 机器人进行消息推送。 + +
+ + + + + +