-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathtaghints.py
More file actions
356 lines (344 loc) · 15.7 KB
/
taghints.py
File metadata and controls
356 lines (344 loc) · 15.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
import re
from typing import Any, Dict, List, Match, Optional
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Message, MessageEntity
from telegram.ext.filters import MessageFilter
from components import const
from components.const import DOCS_URL, PTBCONTRIB_LINK
from components.entrytypes import TagHint
# Tag hints should be used for "meta" hints, i.e. pointing out how to use the PTB groups
# Explaining functionality should be done in the wiki instead.
#
# Note that wiki pages are available through the search directly, but the Ask-Right and MWE pages
# are needed so frequently that we provide tag hints for them ...
_TAG_HINTS: Dict[str, Dict[str, Any]] = {
"askright": {
"message": (
'{query} Please read <a href="https://github.com/python-telegram-bot/'
'python-telegram-bot/wiki/Ask-Right">this short article</a> and try again ;)'
),
"help": "The wiki page about asking technical questions",
"default": (
"Hey. In order for someone to be able to help you, you must ask a <b>good "
"technical question</b>."
),
},
"mwe": {
"message": (
"{query} Please follow these instructions on how to write a "
'<a href="https://github.com/python-telegram-bot/python-'
'telegram-bot/wiki/MWE">Minimal Working Example (MWE)</a>.'
),
"help": "How to build an MWE for PTB.",
"default": "Hey. Please provide a minimal working example (MWE).",
},
"inline": {
"message": (
f"Consider using me in inline-mode 😎 <code>@{const.SELF_BOT_NAME} " + "{query}</code>"
),
"default": "Your search terms",
"buttons": [[InlineKeyboardButton(text="🔎 Try it out", switch_inline_query="")]],
"help": "Give a query that will be used for a switch_to_inline-button",
},
"private": {
"message": "Please don't spam the group with {query}, and go to a private "
"chat with me instead. Thanks a lot, the other members will appreciate it 😊",
"default": "searches or commands",
"buttons": [
[
InlineKeyboardButton(
text="🤖 Go to private chat", url=f"https://t.me/{const.SELF_BOT_NAME}"
)
]
],
"help": "Tell a member to stop spamming and switch to a private chat",
},
"userbot": {
"message": (
'{query} Refer to <a href="https://telegra.ph/How-a-Userbot-superacharges-your-'
'Telegram-Bot-07-09">this article</a> to learn more about <b>Userbots</b>.'
),
"help": "What are Userbots?",
"default": "",
},
"meta": {
"message": (
'No need for meta questions. <a href="https://dontasktoask.com">Just ask</a>! 🤗'
'<i>"Has anyone done .. before?" </i>'
"Probably. <b>Just ask your question and somebody will help!</b>"
),
"help": "Show our stance on meta-questions",
},
"tutorial": {
"message": (
"{query}"
"We have compiled a list of learning resources <i>just for you</i>:\n\n"
'• <a href="https://wiki.python.org/moin/BeginnersGuide/NonProgrammers">As Beginner'
"</a>\n"
'• <a href="https://wiki.python.org/moin/BeginnersGuide/Programmers">As Programmer'
"</a>\n"
'• <a href="https://docs.python.org/3/tutorial/">Official Tutorial</a>\n'
'• <a href="http://www.diveintopython3.net/">Dive into Python</a>\n'
'• <a href="https://www.learnpython.org/">Learn Python</a>\n'
'• <a href="https://cscircles.cemc.uwaterloo.ca/">Computer Science Circles</a>\n'
'• <a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/'
'6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/">MIT '
"OpenCourse</a>\n"
'• <a href="https://docs.python-guide.org/">Hitchhiker’s Guide to Python</a>\n'
"• The @PythonRes Telegram Channel.\n"
'• Corey Schafer videos for <a href="https://www.youtube.com/watch?v=YYXdXT2l-Gg&list'
'=PL-osiE80TeTskrapNbzXhwoFUiLCjGgY7">beginners</a> and in <a href="https://www.'
'youtube.com/watch?v=YYXdXT2l-Gg&list=PL-osiE80TeTt2d9bfVyTiXJA-UTHn6WwU">general'
"</a>\n"
'• <a href="http://projectpython.net/chapter00/">Project Python</a>\n'
),
"help": "How to find a Python tutorial",
"default": (
"Oh, hey! There's someone new joining our awesome community of Python developers ❤️ "
),
},
"wronglib": {
"message": (
"{query} If you are using a different package/language, we are sure you can "
"find some kind of community help on their homepage. Here are a few links for other "
"popular libraries: "
'<a href="https://t.me/joinchat/Bn4ixj84FIZVkwhk2jag6A">pyTelegramBotApi</a>, '
'<a href="https://github.com/nickoala/telepot">Telepot</a>, '
'<a href="https://t.me/pyrogramchat">pyrogram</a>, '
'<a href="https://t.me/TelethonChat">Telethon</a>, '
'<a href="https://t.me/aiogram">aiogram</a>, '
'<a href="https://t.me/botogram_users">botogram</a>.'
),
"help": "Other Python wrappers for Telegram",
"default": (
"Hey, I think you're wrong 🧐\nThis is the support group of the "
"<code>python-telegram-bot</code> library."
),
},
"pastebin": {
"message": (
"{query} Please post code or tracebacks using a pastebin rather than via plain text "
"or a picture. https://pastebin.com/ is quite popular, but there are "
"<a href='https://github.com/lorien/awesome-pastebin'>many alternatives</a> "
"out there. Of course, for very short snippets, text is fine. Please at "
"least format it as monospace in that case."
),
"help": "Ask users not to post code as text or images.",
"default": "Hey.",
},
"doublepost": {
"message": (
"{query} Please don't double post. Questions usually are on-topic only in one of the "
"two groups anyway."
),
"help": "Ask users not to post the same question in both on- and off-topic.",
"default": "Hey.",
},
"xy": {
"message": (
'{query} This seems like an <a href="https://xyproblem.info">xy-problem</a> to me.'
),
"default": "Hey. What exactly do you want this for?",
"help": "Ask users for the actual use case.",
},
"dontping": {
"message": (
"{query} Please only mention or reply to users directly if you're following up on a "
"conversation with them. Otherwise just ask your question and wait if someone has a "
"solution for you - that's how this group works 😉 Also note that the "
"<code>@admin</code> tag is only to be used to report spam or abuse!"
),
"default": "Hey.",
"help": "Tell users not to ping randomly ping you.",
},
"read": {
"message": (
"I just pointed you to {query} and I have the strong feeling that <i>you did not "
"actually read it</i>. Please do so. If you don't understand everything and have "
"follow up questions, that's fine, but you can't expect me to repeat everything "
"<i>just for you</i> because you didn't feel like reading on your own. 😉"
),
"default": "a resource in the wiki, the docs or the examples",
"help": "Tell users to actually read the resources they were linked to",
},
"ptbcontrib": {
"message": (
"{query} <code>ptbcontrib</code> is a library that provides extensions for the "
"<code>python-telegram-bot</code> library that written and maintained by the "
"community of PTB users."
),
"default": "Hey.",
"buttons": [[InlineKeyboardButton(text="🔗 Take me there!", url=PTBCONTRIB_LINK)]],
"help": "Display a short info text about ptbcontrib",
},
"botlists": {
"message": (
"{query} This group is for technical questions that come up while you code your own "
"Telegram bot. If you are looking for ready-to-use bots, please have a look at "
"channels like @BotsArchive or @BotList/@BotlistBot. There are also a number of "
"websites that list existing bots."
),
"default": "Hey.",
"help": "Redirect users to lists of existing bots.",
},
"coc": {
"message": (
f'{{query}} Please read our <a href="{DOCS_URL}coc.html">Code of Conduct</a> and '
"stick to it. Note that violation of the CoC can lead to temporary or permanent "
"banishment from this group."
),
"default": "Hey.",
"help": "Remind the users of the Code of Conduct.",
},
"docs": {
"message": (
f"{{query}} You can find our documentation at <a href='{const.DOCS_URL}'>Read the "
f"Docs</a>. "
),
"default": "Hey.",
"help": "Point users to the documentation",
"group_command": True,
},
"wiki": {
"message": f"{{query}} You can find our wiki on <a href='{const.WIKI_URL}'>Github</a>.",
"default": "Hey.",
"help": "Point users to the wiki",
"group_command": True,
},
"help": {
"message": (
"{query} You can find an explanation of @roolsbot's functionality on '"
'<a href="https://github.com/python-telegram-bot/rules-bot/blob/master/README.md">'
"GitHub</a>."
),
"default": "Hey.",
"help": "Point users to the bots readme",
"group_command": True,
},
"upgrade": {
"message": (
"{query} You seem to be using a version <=13.15 of "
"<code>python-telegram-bot</code>. "
"Please note that we only provide support for the latest stable version and that the "
"library has undergone significant changes in v20. Please consider upgrading to v20 "
"by reading the release notes and the transition guide linked below."
),
"buttons": [
[
InlineKeyboardButton(
text="🔗 Release Notes",
url="https://telegra.ph/Release-notes-for-python-telegram-bot-v200a0-05-06",
),
InlineKeyboardButton(
text="🔗 Transition Guide",
url="https://github.com/python-telegram-bot/python-telegram-bot/wiki"
"/Transition-guide-to-Version-20.0",
),
]
],
"default": "Hey.",
"help": "Ask users to upgrade to the latest version of PTB",
"group_command": True,
},
"compat": {
"message": (
"{query} You seem to be using the new version (>=20.0) of "
"<code>python-telegram-bot</code> but your code is written for an older and "
"deprecated version (<=13.15).\nPlease update your code to the new v20 by reading"
" the release notes and the transition guide linked below.\nYou can also install a "
"version of PTB that is compatible with your code base, but please note that the "
"library has undergone significant changes in v20 and the older version is not "
"supported anymore. It may contain bugs that will not be fixed by the PTB team "
"and it also doesn't support new functions added by newer Bot API releases."
),
"buttons": [
[
InlineKeyboardButton(
text="🔗 Release Notes",
url="https://telegra.ph/Release-notes-for-python-telegram-bot-v200a0-05-06",
),
InlineKeyboardButton(
text="🔗 Transition Guide",
url="https://github.com/python-telegram-bot/python-telegram-bot/wiki"
"/Transition-guide-to-Version-20.0",
),
]
],
"default": "Hey.",
"help": "Point out compatibility issues of code and PTB version to users",
"group_command": True,
},
"llm": {
"message": (
"{query} This text reads like an AI/LLM was used to generate this. We found their "
"answers to be unfitting for this group. We are all about providing fine tuned help "
"for technical questions. These generated texts are often long winded, very "
"explanatory answers for steps which didn't need explaining, and then happen to miss "
"the actual underlying question completely or are outright false in the worst case."
"\n\n"
"Please refrain from this in the future. If you can answer a question yourself, we "
"are glad to see a precise, technical answer. If you can not answer a question, it's "
"better to just not reply instead of copy-pasting an autogenerated answer 😉."
),
"default": "Hey.",
"help": "Tell users not to use AI/LLM generated answers",
"group_command": True,
},
"traceback": {
"message": (
"{query} Please show the <i>full</i> traceback via a pastebin. Make sure to include "
"everything from the first <code>Traceback (most recent call last):</code> until the "
"last error message. https://pastebin.com/ is a popular pastebin service, but there "
"are <a href='https://github.com/lorien/awesome-pastebin'>many alternatives</a> out "
"there."
),
"default": "Hey.",
"help": "Ask for the full traceback",
"group_command": True,
},
}
# Sort the hints by key
_TAG_HINTS_SORTED = dict(sorted(_TAG_HINTS.items()))
# convert into proper objects
TAG_HINTS: Dict[str, TagHint] = {
key: TagHint(
tag=key,
message=value["message"],
description=value["help"],
default_query=value.get("default"),
inline_keyboard=InlineKeyboardMarkup(value["buttons"]) if "buttons" in value else None,
group_command=value.get("group_command", False),
)
for key, value in _TAG_HINTS_SORTED.items()
}
TAG_HINTS_PATTERN = re.compile(
# case insensitive
r"(?i)"
# join the /tags
r"((?P<tag_hint_with_username>(?P<tag_hint>"
rf'{"|".join(hint.short_name for hint in TAG_HINTS.values())})'
# don't allow the tag to be followed by '/' - That could be the start of the next tag
r"(?!/)"
# Optionally the bots username
rf"(@{re.escape(const.SELF_BOT_NAME)})?)"
# match everything that comes next as long as it's separated by a whitespace - important for
# inserting a custom query in inline mode
r"($| (?P<query>[^\/.]*)))"
)
class TagHintFilter(MessageFilter):
"""Custom filter class for filtering for tag hint messages"""
def __init__(self) -> None:
super().__init__(name="TageHintFilter", data_filter=True)
def filter(self, message: Message) -> Optional[Dict[str, List[Match]]]:
"""Does the filtering. Applies the regex and makes sure that only those tag hints are
handled, that are also marked as bot command.
"""
if not message.text:
return None
matches = []
command_texts = message.parse_entities([MessageEntity.BOT_COMMAND]).values()
for match in TAG_HINTS_PATTERN.finditer(message.text):
if match.groupdict()["tag_hint_with_username"] in command_texts:
matches.append(match)
if not matches:
return None
return {"matches": matches}