reprogl

Форк
0
/
notification.go 
132 строки · 2.9 Кб
1
package telegram
2

3
import (
4
	"bytes"
5
	"encoding/json"
6
	"fmt"
7
	"io"
8
	"net/http"
9
	"regexp"
10
	"sync"
11
	"unicode/utf8"
12

13
	"xelbot.com/reprogl/api"
14
	"xelbot.com/reprogl/api/backend"
15
	"xelbot.com/reprogl/container"
16
	"xelbot.com/reprogl/models"
17
)
18

19
type message struct {
20
	Chat           int    `json:"chat_id"`
21
	Text           string `json:"text"`
22
	ParseMode      string `json:"parse_mode"`
23
	DisablePreview bool   `json:"disable_web_page_preview"`
24
}
25

26
var telegramLocker sync.Mutex
27

28
func SendNotification(
29
	app *container.Application,
30
	comment *backend.CreatedCommentDTO,
31
	article *models.ArticleForComment,
32
) {
33
	text := generateText(comment, article)
34
	app.InfoLog.Printf("Telegram notification text:\n%s", text)
35

36
	jsonBody, err := json.Marshal(createMessage(text))
37
	if err != nil {
38
		app.LogError(err)
39
		return
40
	}
41

42
	request, err := http.NewRequest(
43
		http.MethodPost,
44
		"https://api.telegram.org/bot"+container.GetConfig().TelegramToken+"/sendMessage",
45
		bytes.NewReader(jsonBody))
46
	if err != nil {
47
		app.LogError(err)
48
		return
49
	}
50

51
	request.Header.Set("Content-Type", "application/json")
52

53
	resp, err := send(request)
54
	if err != nil {
55
		app.LogError(err)
56
		return
57
	}
58

59
	defer resp.Body.Close()
60
	buf, err := io.ReadAll(resp.Body)
61
	if err != nil {
62
		app.LogError(err)
63
		return
64
	}
65

66
	app.InfoLog.Printf("Telegram answer:\nStatus: %s\n\n%s", resp.Status, string(buf))
67
}
68

69
func createMessage(text string) message {
70
	return message{
71
		Chat:           container.GetConfig().TelegramAdminID,
72
		Text:           text,
73
		ParseMode:      "MarkdownV2",
74
		DisablePreview: true,
75
	}
76
}
77

78
func generateText(
79
	comment *backend.CreatedCommentDTO,
80
	article *models.ArticleForComment,
81
) (msg string) {
82
	msg = fmt.Sprintf(
83
		"Кто\\-то оставил [комментарий](%s)\n\n*ID*: %d\n",
84
		container.GenerateAbsoluteURL("article", "slug", article.Slug),
85
		comment.ID,
86
	)
87
	if len(comment.Name) > 0 {
88
		msg += "*Name*: " + escapeMarkdownCharacters(comment.Name)
89
	}
90
	if len(comment.Country) > 0 {
91
		msg += " " + comment.Country + "\n"
92
	} else {
93
		msg += "\n"
94
	}
95
	if len(comment.Email) > 0 {
96
		msg += "*Email*: " + escapeMarkdownCharacters(comment.Email) + "\n"
97
	}
98
	if len(comment.Website) > 0 {
99
		msg += "*Website*: " + escapeMarkdownCharacters(comment.Website) + "\n"
100
	}
101

102
	msg += "\n" + escapeMarkdownCharacters(stripTags(comment.Text))
103

104
	return
105
}
106

107
func stripTags(content string) string {
108
	re := regexp.MustCompile(`<(.|\n)*?>`)
109

110
	return re.ReplaceAllString(content, "")
111
}
112

113
func escapeMarkdownCharacters(content string) string {
114
	buffer := make([]rune, 0, 2*utf8.RuneCountInString(content))
115
	for _, e := range []rune(content) {
116
		switch e {
117
		case '_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!':
118
			buffer = append(buffer, '\\', e)
119
		default:
120
			buffer = append(buffer, e)
121
		}
122
	}
123

124
	return string(buffer)
125
}
126

127
func send(req *http.Request) (*http.Response, error) {
128
	telegramLocker.Lock()
129
	defer telegramLocker.Unlock()
130

131
	return api.Send(req)
132
}
133

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.