Skip to content

Commit cdff7c4

Browse files
authored
fix: add Sanitize HTML in inline query responses (#1)
* fix * Update README.md
1 parent f984cfc commit cdff7c4

File tree

2 files changed

+30
-15
lines changed

2 files changed

+30
-15
lines changed

.github/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ This project is licensed under the MIT License—see the [LICENSE](/LICENSE) fil
103103
[![Telegram](https://img.shields.io/badge/Telegram-Chat-blue.svg)](https://t.me/AshokShau)
104104
105105
106-
## Thanks
107-
- [Ashok Shau](https://github.com/AshokShau) for the project.
108-
- [PaulSonOfLars](https://github.com/PaulSonOfLars) for the [GoTgBot](https://github.com/PaulSonOfLars/gotgbot) library and [Api](https://github.com/PaulSonOfLars/telegram-bot-api-spec/raw/main/api.json).
106+
## Acknowledgments
107+
- **[Ashok Shau](https://github.com/AshokShau)**: For creating and maintaining this [project](https://github.com/AshokShau/BotApiDocs), which provides a solid foundation for building Telegram bots.
108+
109+
- **[PaulSonOfLars](https://github.com/PaulSonOfLars)**: For the invaluable [GoTgBot](https://github.com/PaulSonOfLars/gotgbot) library, which simplifies Telegram bot development in Go, and for the [API specification](https://github.com/PaulSonOfLars/telegram-bot-api-spec/raw/main/api.json) that serves as a reference for bot methods and types.

Telegram/modules/inline.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"log"
77
"math/rand"
88
"net/http"
9+
"regexp"
910
"strconv"
1011
"strings"
1112
"sync"
@@ -15,6 +16,8 @@ import (
1516
"github.com/PaulSonOfLars/gotgbot/v2/ext"
1617
)
1718

19+
const maxMessageLength = 4096 // Telegram's maximum message length
20+
1821
// apiCache is a global cache for storing API methods and types.
1922
var apiCache struct {
2023
sync.RWMutex
@@ -56,10 +59,6 @@ func fetchAPI() error {
5659
}
5760
defer resp.Body.Close()
5861

59-
if resp.StatusCode != http.StatusOK {
60-
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
61-
}
62-
6362
var apiDocs struct {
6463
Methods map[string]Method `json:"methods"`
6564
Types map[string]Type `json:"types"`
@@ -128,7 +127,7 @@ func sendEmptyQueryResponse(bot *gotgbot.Bot, ctx *ext.Context) error {
128127
IsPersonal: true,
129128
CacheTime: 5,
130129
Button: &gotgbot.InlineQueryResultsButton{
131-
Text: "Type '<your_query>' to search!",
130+
Text: "Type 'your_query' to search!",
132131
StartParameter: "start",
133132
},
134133
})
@@ -169,35 +168,43 @@ func sendNoResultsResponse(bot *gotgbot.Bot, ctx *ext.Context, query string) err
169168
func buildMethodMessage(method Method) string {
170169
var msgBuilder strings.Builder
171170
msgBuilder.WriteString(fmt.Sprintf("<b>%s</b>\n", method.Name))
172-
msgBuilder.WriteString(fmt.Sprintf("Description: %s\n\n", strings.Join(method.Description, ", ")))
171+
msgBuilder.WriteString(fmt.Sprintf("Description: %s\n\n", sanitizeHTML(strings.Join(method.Description, ", "))))
173172
msgBuilder.WriteString("<b>Returns:</b> " + strings.Join(method.Returns, ", ") + "\n")
174173

175174
if len(method.Fields) > 0 {
176175
msgBuilder.WriteString("<b>Fields:</b>\n")
177176
for _, field := range method.Fields {
178177
msgBuilder.WriteString(fmt.Sprintf("<code>%s</code> (<b>%s</b>) - Required: <code>%t</code>\n", field.Name, strings.Join(field.Types, ", "), field.Required))
179-
msgBuilder.WriteString(field.Description + "\n\n")
178+
msgBuilder.WriteString(sanitizeHTML(field.Description) + "\n\n")
180179
}
181180
}
182181

183-
return msgBuilder.String()
182+
message := msgBuilder.String()
183+
if len(message) > maxMessageLength {
184+
return fmt.Sprintf("See full documentation: %s", method.Href)
185+
}
186+
return message
184187
}
185188

186189
// buildTypeMessage builds a message string for a given API type.
187190
func buildTypeMessage(typ Type) string {
188191
var msgBuilder strings.Builder
189192
msgBuilder.WriteString(fmt.Sprintf("<b>%s</b>\n", typ.Name))
190-
msgBuilder.WriteString(fmt.Sprintf("Description: %s\n\n", strings.Join(typ.Description, ", ")))
193+
msgBuilder.WriteString(fmt.Sprintf("Description: %s\n\n", sanitizeHTML(strings.Join(typ.Description, ", "))))
191194

192195
if len(typ.Fields) > 0 {
193196
msgBuilder.WriteString("<b>Fields:</b>\n")
194197
for _, field := range typ.Fields {
195198
msgBuilder.WriteString(fmt.Sprintf("<code>%s</code> (<b>%s</b>) - Required: <code>%t</code>\n", field.Name, strings.Join(field.Types, ", "), field.Required))
196-
msgBuilder.WriteString(field.Description + "\n\n")
199+
msgBuilder.WriteString(sanitizeHTML(field.Description) + "\n\n")
197200
}
198201
}
199202

200-
return msgBuilder.String()
203+
message := msgBuilder.String()
204+
if len(message) > maxMessageLength {
205+
return fmt.Sprintf("See full documentation: %s", typ.Href)
206+
}
207+
return message
201208
}
202209

203210
// createInlineResult creates an inline query result for a given API method or type.
@@ -225,7 +232,7 @@ func createInlineResult(title, url, message, methodUrl string) gotgbot.InlineQue
225232
func noResultsArticle(query string) gotgbot.InlineQueryResult {
226233
ok := "botapi"
227234
return gotgbot.InlineQueryResultArticle{
228-
Id: "no_results",
235+
Id: strconv.Itoa(rand.Intn(100000)),
229236
Title: "No Results Found!",
230237
InputMessageContent: gotgbot.InputTextMessageContent{
231238
MessageText: fmt.Sprintf("<i>👋 Sorry, I couldn't find any results for '%s'. Try searching with a different keyword!</i>", query),
@@ -239,3 +246,10 @@ func noResultsArticle(query string) gotgbot.InlineQueryResult {
239246
},
240247
}
241248
}
249+
250+
// sanitizeHTML removes unsupported HTML tags from the message
251+
func sanitizeHTML(input string) string {
252+
// This regex matches any HTML tags that are not supported
253+
re := regexp.MustCompile(`<[^>]*>`)
254+
return re.ReplaceAllString(input, "")
255+
}

0 commit comments

Comments
 (0)