Przeglądaj źródła

feat: now support Telegram bot

JustSong 3 lat temu
rodzic
commit
a36d21d18e
5 zmienionych plików z 99 dodań i 1 usunięć
  1. 2 0
      channel/main.go
  2. 53 0
      channel/telegram.go
  3. 3 0
      controller/user.go
  4. 3 1
      model/user.go
  5. 38 0
      web/src/components/PushSetting.js

+ 2 - 0
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)
 	}

+ 53 - 0
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
+}

+ 3 - 0
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)
 

+ 3 - 1
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

+ 38 - 0
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 = () => {
             保存
           </Button>
           <Button onClick={() => test('client')}>测试</Button>
+          <Divider />
+          <Header as='h3'>
+            Telegram 机器人设置(telegram)
+            <Header.Subheader>
+              通过 Telegram 机器人进行消息推送。
+            </Header.Subheader>
+          </Header>
+          <Form.Group widths={2}>
+            <Form.Input
+              label='Telegram 机器人令牌'
+              name='telegram_bot_token'
+              type='password'
+              onChange={handleInputChange}
+              autoComplete='off'
+              value={inputs.telegram_bot_token}
+              placeholder='在此设置 Telegram 机器人令牌'
+            />
+            <Form.Input
+              label='Telegram 会话 ID'
+              name='telegram_chat_id'
+              type='text'
+              onChange={handleInputChange}
+              autoComplete='off'
+              value={inputs.telegram_chat_id}
+              placeholder='在此设置 Telegram 会话 ID'
+            />
+          </Form.Group>
+          <Button onClick={() => submit('telegram')} loading={loading}>
+            保存
+          </Button>
+          <Button onClick={() => test('telegram')}>测试</Button>
         </Form>
       </Grid.Column>
     </Grid>