channels/telegram/telegram.go
package telegram
import (
"encoding/json"
"io/ioutil"
"net/http"
"os"
"regexp"
log "github.com/Ptt-Alertor/logrus"
"strconv"
"github.com/Ptt-Alertor/ptt-alertor/command"
"github.com/Ptt-Alertor/ptt-alertor/myutil"
"github.com/go-telegram-bot-api/telegram-bot-api"
"github.com/julienschmidt/httprouter"
)
var (
bot *tgbotapi.BotAPI
err error
token = os.Getenv("TELEGRAM_TOKEN")
host = os.Getenv("APP_HOST")
)
func init() {
bot, err = tgbotapi.NewBotAPI(token)
if err != nil {
log.WithError(err).Fatal("Telegram Bot Initialize Failed")
}
// bot.Debug = true
log.Info("Telegram Authorized on " + bot.Self.UserName)
webhookConfig := tgbotapi.NewWebhook(host + "/telegram/" + token)
webhookConfig.MaxConnections = 100
_, err = bot.SetWebhook(webhookConfig)
if err != nil {
log.WithError(err).Fatal("Telegram Bot Set Webhook Failed")
}
log.Info("Telegram Bot Sets Webhook Success")
}
// HandleRequest handles request from webhook
func HandleRequest(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
bytes, err := ioutil.ReadAll(r.Body)
if err != nil {
log.WithError(err).Error("Telegram Read Request Body Failed")
}
var update tgbotapi.Update
json.Unmarshal(bytes, &update)
if update.CallbackQuery != nil {
handleCallbackQuery(update)
return
}
if update.Message != nil {
if update.Message.IsCommand() {
handleCommand(update)
return
}
if update.Message.Text != "" {
handleText(update)
return
}
}
}
func handleCallbackQuery(update tgbotapi.Update) {
var responseText string
userID := strconv.Itoa(update.CallbackQuery.From.ID)
switch update.CallbackQuery.Data {
case "CANCEL":
responseText = "取消"
default:
responseText = command.HandleCommand(update.CallbackQuery.Data, userID, true)
}
SendTextMessage(update.CallbackQuery.Message.Chat.ID, responseText)
}
// help - 所有指令清單
// list - 設定清單
// ranking - 熱門關鍵字、作者、推文數
// add - 新增看板關鍵字、作者、推文數
// del - 刪除看板關鍵字、作者、推文數
// showkeyboard - 顯示快捷小鍵盤
// hidekeyboard - 隱藏快捷小鍵盤
func handleCommand(update tgbotapi.Update) {
var responseText string
userID := strconv.Itoa(update.Message.From.ID)
chatID := update.Message.Chat.ID
switch update.Message.Command() {
case "add", "del":
text := update.Message.Command() + " " + update.Message.CommandArguments()
responseText = command.HandleCommand(text, userID, true)
case "start":
command.HandleTelegramFollow(userID, chatID)
responseText = "歡迎使用 Ptt Alertor\n輸入「指令」查看相關功能。\n\n觀看Demo:\nhttps://media.giphy.com/media/3ohzdF6vidM6I49lQs/giphy.gif"
case "help":
responseText = command.HandleCommand("help", userID, true)
case "list":
responseText = command.HandleCommand("list", userID, true)
case "ranking":
responseText = command.HandleCommand("ranking", userID, true)
case "showkeyboard":
showReplyKeyboard(chatID)
return
case "hidekeyboard":
hideReplyKeyboard(chatID)
return
default:
responseText = "I don't know the command"
}
SendTextMessage(chatID, responseText)
}
func handleText(update tgbotapi.Update) {
var responseText string
userID := strconv.Itoa(update.Message.From.ID)
chatID := update.Message.Chat.ID
text := update.Message.Text
if match, _ := regexp.MatchString("^(刪除|刪除作者)+\\s.*\\*+", text); match {
sendConfirmation(chatID, text)
return
}
responseText = command.HandleCommand(text, userID, true)
SendTextMessage(chatID, responseText)
}
func sendConfirmation(chatID int64, cmd string) {
markup := tgbotapi.NewInlineKeyboardMarkup(
tgbotapi.NewInlineKeyboardRow(
tgbotapi.NewInlineKeyboardButtonData("是", cmd),
tgbotapi.NewInlineKeyboardButtonData("否", "CANCEL"),
))
msg := tgbotapi.NewMessage(chatID, "確定"+cmd+"?")
msg.ReplyMarkup = markup
_, err := bot.Send(msg)
if err != nil {
log.WithError(err).Error("Telegram Send Confirmation Failed")
}
}
const maxCharacters = 4096
// SendTextMessage sends text message to chatID
func SendTextMessage(chatID int64, text string) {
for _, msg := range myutil.SplitTextByLineBreak(text, maxCharacters) {
sendTextMessage(chatID, msg)
}
}
func sendTextMessage(chatID int64, text string) {
msg := tgbotapi.NewMessage(chatID, text)
msg.DisableWebPagePreview = true
_, err := bot.Send(msg)
if err != nil {
log.WithError(err).Error("Telegram Send Message Failed")
}
}
func showReplyKeyboard(chatID int64) {
keyboard := tgbotapi.NewReplyKeyboard(
tgbotapi.NewKeyboardButtonRow(
tgbotapi.NewKeyboardButton("清單"),
tgbotapi.NewKeyboardButton("推文清單"),
tgbotapi.NewKeyboardButton("排行"),
tgbotapi.NewKeyboardButton("指令"),
))
msg := tgbotapi.NewMessage(chatID, "顯示小鍵盤")
msg.ReplyMarkup = keyboard
_, err := bot.Send(msg)
if err != nil {
log.WithError(err).Error("Telegram Show Reply Keyboard Failed")
}
}
func hideReplyKeyboard(chatID int64) {
msg := tgbotapi.NewMessage(chatID, "隱藏小鍵盤")
msg.ReplyMarkup = tgbotapi.NewRemoveKeyboard(true)
_, err := bot.Send(msg)
if err != nil {
log.WithError(err).Error("Telegram Hide Reply Keyboard Failed")
}
}