Skip to content

Instantly share code, notes, and snippets.

@guregu
Created November 3, 2020 14:50
Show Gist options
  • Save guregu/96ebc935ef479423eb105c958b7cad4d to your computer and use it in GitHub Desktop.
Save guregu/96ebc935ef479423eb105c958b7cad4d to your computer and use it in GitHub Desktop.
telegram message sending and webhook
package mail
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
var TelegramAuthToken string // set this
type TelegramButton struct {
Text string `json:"text"`
URL string `json:"url,omitempty"`
Callback string `json:"callback_data,omitempty"`
}
func SendTelegram(to int64, content string, buttons ...TelegramButton) error {
type replyMarkup struct {
Keyboard [][]TelegramButton `json:"inline_keyboard"`
}
msg := struct {
ChatID int64 `json:"chat_id"`
Text string `json:"text"`
ParseMode string `json:"parse_mode"`
DisablePreview bool `json:"disable_web_page_preview"`
ReplyMarkup *replyMarkup `json:"reply_markup,omitempty"`
}{
ChatID: to,
Text: content,
ParseMode: "HTML",
DisablePreview: true,
}
if len(buttons) > 0 {
msg.ReplyMarkup = &replyMarkup{
Keyboard: [][]TelegramButton{buttons},
}
}
url := telegramURL("sendMessage")
enc, err := json.Marshal(msg)
if err != nil {
return err
}
resp, err := http.Post(url, "application/json", bytes.NewReader(enc))
if err != nil {
return err
}
defer resp.Body.Close()
var result struct {
OK bool `json:"ok"`
Desc string `json:"description"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return err
}
if !result.OK {
return fmt.Errorf("telegram API error: %s", result.Desc)
}
return nil
}
func GetTelegramBotInfo() (id int64, username string, err error) {
var result struct {
OK bool `json:"ok"`
Result struct {
ID int64 `json:"id"`
Username string `json:"username"`
} `json:"result"`
Desc string `json:"description"`
}
url := telegramURL("getMe")
resp, err := http.Get(url)
if err != nil {
return 0, "", err
}
defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return 0, "", err
}
if !result.OK {
return 0, "", fmt.Errorf("telegram API error: %s", result.Desc)
}
return result.Result.ID, result.Result.Username, nil
}
func SetTelegramWebhook(href string) error {
var result struct {
OK bool `json:"ok"`
Result bool `json:"result"`
Desc string `json:"description"`
}
url := telegramURL("getMe")
url += "?url=" + href
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return err
}
if !result.OK {
return fmt.Errorf("telegram API error: %s", result.Desc)
}
return nil
}
const telegramAPIFmt = "https://api.telegram.org/bot%s/%s"
func telegramURL(method string) string {
return fmt.Sprintf(telegramAPIFmt, TelegramAuthToken, method)
}
package web
import (
"encoding/json"
"fmt"
"net/http"
"log"
"strings"
)
func TelegramWebhook(w http.ResponseWriter, r *http.Request) {
type update struct {
ID int64 `json:"update_id"`
Message struct {
ID int64 `json:"message_id"`
Date int `json:"date"`
Text string `json:"text"`
From struct {
ID int64 `json:"id"`
Username string `json:"username"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Lang string `json:"language_code"`
} `json:"from"`
Chat struct {
ID int64 `json:"id"`
Type string `json:"type"`
Username string `json:"username"`
} `json:"chat`
} `json:"message"`
}
defer r.Body.Close()
var up update
if err := json.NewDecoder(r.Body).Decode(&up); err != nil {
panic(err)
}
msg := up.Message.Text
switch {
case msg == "":
return
case strings.HasPrefix(msg, "/start"):
if err := email.SendTelegram(up.Message.Chat.ID, "Hello world"); err != nil {
log.Println("TELEGRAM HOOK ERROR:", err)
return
}
// save up.Message.From.ID and .Chat.ID somewhere
default:
if err := email.SendTelegram(up.Message.Chat.ID, "何?"); err != nil {
log.Println("TELEGRAM HOOK ERROR:", err)
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment