telegram notifications format headers, resolve #1202
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"golang.org/x/net/html"
|
||||
"io"
|
||||
"net/http"
|
||||
neturl "net/url"
|
||||
@@ -171,11 +172,12 @@ func buildMessage(req Request) ([]byte, error) {
|
||||
// returns HTML with only tags allowed in Telegram HTML message payload, also trims ending newlines
|
||||
// https://core.telegram.org/bots/api#html-style
|
||||
func telegramSupportedHTML(htmlText string) string {
|
||||
adjustedHTMLText := adjustHTMLTags(htmlText)
|
||||
p := bluemonday.NewPolicy()
|
||||
p.AllowElements("b", "strong", "i", "em", "u", "ins", "s", "strike", "del", "a", "code", "pre")
|
||||
p.AllowAttrs("href").OnElements("a")
|
||||
p.AllowAttrs("class").OnElements("code")
|
||||
return strings.TrimRight(p.Sanitize(htmlText), "\n")
|
||||
return strings.TrimRight(p.Sanitize(adjustedHTMLText), "\n")
|
||||
}
|
||||
|
||||
// returns text sanitized of symbols not allowed inside other HTML tags in Telegram HTML message payload
|
||||
@@ -188,6 +190,42 @@ func escapeTelegramText(text string) string {
|
||||
return text
|
||||
}
|
||||
|
||||
// telegram not allow h1-h6 tags
|
||||
// replace these tags with a combination of <b> and <i> for visual distinction
|
||||
func adjustHTMLTags(htmlText string) string {
|
||||
buff := strings.Builder{}
|
||||
tokenizer := html.NewTokenizer(strings.NewReader(htmlText))
|
||||
for {
|
||||
if tokenizer.Next() == html.ErrorToken {
|
||||
return buff.String()
|
||||
}
|
||||
token := tokenizer.Token()
|
||||
switch token.Type {
|
||||
case html.StartTagToken, html.EndTagToken:
|
||||
switch token.Data {
|
||||
case "h1", "h2", "h3":
|
||||
if token.Type == html.StartTagToken {
|
||||
buff.WriteString("<b>")
|
||||
}
|
||||
if token.Type == html.EndTagToken {
|
||||
buff.WriteString("</b>")
|
||||
}
|
||||
case "h4", "h5", "h6":
|
||||
if token.Type == html.StartTagToken {
|
||||
buff.WriteString("<i><b>")
|
||||
}
|
||||
if token.Type == html.EndTagToken {
|
||||
buff.WriteString("</b></i>")
|
||||
}
|
||||
default:
|
||||
buff.WriteString(token.String())
|
||||
}
|
||||
default:
|
||||
buff.WriteString(token.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SendVerification is not needed for telegram
|
||||
func (t *Telegram) SendVerification(_ context.Context, _ VerificationRequest) error {
|
||||
return nil
|
||||
|
||||
@@ -166,6 +166,16 @@ func TestTelegram_Send(t *testing.T) {
|
||||
`\"\u003ci\u003esome parent text with a \u003ca href=\"http://example.org\"\u003elink\u003c/a\u003e and special text:\u0026amp; \u0026lt; \u0026gt; \u0026amp;\u003c/i\u003e\"\n\n`+
|
||||
`↦ \u003ca href=\"http://example.org/\"\u003e[test title]\u003c/a\u003e","parse_mode":"HTML"}`,
|
||||
string(res))
|
||||
|
||||
// special case for text with h1-h6 header
|
||||
ch := store.Comment{Text: "<h1>Hello</h1><h6>World</h6>", ID: "555", Locator: store.Locator{URL: "http://example.org/"}}
|
||||
ch.User.Name = "from"
|
||||
res, err = buildMessage(Request{Comment: ch})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `{"text":"\u003ca href=\"http://example.org/#remark42__comment-555\"\u003efrom\u003c/a\u003e\n\n`+
|
||||
`\u003cb\u003eHello\u003c/b\u003e\u003ci\u003e\u003cb\u003eWorld\u003c/b\u003e\u003c/i\u003e`+
|
||||
`","parse_mode":"HTML"}`,
|
||||
string(res))
|
||||
}
|
||||
|
||||
func TestTelegram_SendVerification(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user