Теперь капча генерируется полностью в памяти, никаких временных файлов на диске — всё стало быстрее и чище.
Картинка капчи стала сложнее: добавил шум, линии, точки, блюр и разные шрифты. Теперь распознать её ботом или через OCR стало намного труднее.
Убрал все лишние операции с диском, теперь всё работает через оперативную память.
В целом код стал проще, быстрее и надёжнее.
1753959632595.pngNGSH · 31 Июл 2025 в 14:01' data-fancybox="lb-post-1625731" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="https://www.blast.hk/attachments/275477/" style="cursor: pointer;" title="1753959632595.png">
https://forum.antichat.xyz/attachmen...4e1b9eac07.png
captcha telegram bot::
Код:
import
os
import
logging
import
random
import
io
from
PIL
import
Image
,
ImageDraw
,
ImageFont
,
ImageFilter
from
telegram
import
Update
,
InlineKeyboardMarkup
,
InlineKeyboardButton
,
InputMediaPhoto
from
telegram
.
ext
import
(
Application
,
CommandHandler
,
MessageHandler
,
CallbackContext
,
CallbackQueryHandler
,
filters
)
TOKEN
=
"Сюда ты должен вставить свой токен бота"
user_data
=
{
}
logging
.
basicConfig
(
format
=
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
,
level
=
logging
.
INFO
)
logger
=
logging
.
getLogger
(
__name__
)
def
generate_captcha
(
user_id
:
int
)
:
captcha_text
=
''
.
join
(
random
.
choices
(
'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
,
k
=
5
)
)
width
,
height
=
220
,
100
image
=
Image
.
new
(
'RGB'
,
(
width
,
height
)
,
(
255
,
255
,
255
)
)
draw
=
ImageDraw
.
Draw
(
image
)
fonts
=
[
ImageFont
.
truetype
(
"arial.ttf"
,
48
)
,
ImageFont
.
truetype
(
"arialbd.ttf"
,
48
)
,
]
for
i
,
char
in
enumerate
(
captcha_text
)
:
font
=
random
.
choice
(
fonts
)
x
=
20
+
i
*
35
+
random
.
randint
(
-
5
,
5
)
y
=
20
+
random
.
randint
(
-
10
,
10
)
draw
.
text
(
(
x
,
y
)
,
char
,
font
=
font
,
fill
=
(
random
.
randint
(
0
,
120
)
,
random
.
randint
(
0
,
120
)
,
random
.
randint
(
0
,
120
)
)
)
for
_
in
range
(
8
)
:
x1
,
y1
=
random
.
randint
(
0
,
width
)
,
random
.
randint
(
0
,
height
)
x2
,
y2
=
random
.
randint
(
0
,
width
)
,
random
.
randint
(
0
,
height
)
draw
.
line
(
(
(
x1
,
y1
)
,
(
x2
,
y2
)
)
,
fill
=
(
random
.
randint
(
100
,
200
)
,
random
.
randint
(
100
,
200
)
,
random
.
randint
(
100
,
200
)
)
,
width
=
2
)
for
_
in
range
(
300
)
:
x
,
y
=
random
.
randint
(
0
,
width
)
,
random
.
randint
(
0
,
height
)
draw
.
point
(
(
x
,
y
)
,
fill
=
(
random
.
randint
(
0
,
255
)
,
random
.
randint
(
0
,
255
)
,
random
.
randint
(
0
,
255
)
)
)
image
=
image
.
filter
(
ImageFilter
.
GaussianBlur
(
1.2
)
)
img_bytes
=
io
.
BytesIO
(
)
image
.
save
(
img_bytes
,
format
=
'PNG'
)
img_bytes
.
seek
(
0
)
return
captcha_text
,
img_bytes
def
fuzzy_match
(
a
,
b
,
max_distance
=
1
)
:
if
len
(
a
)
!=
len
(
b
)
:
return
False
return
sum
(
x
!=
y
for
x
,
y
in
zip
(
a
,
b
)
)
=
3
:
await
update
.
message
.
reply_text
(
"🚫 Превышено число попыток! Запустите /start заново"
)
return
if
fuzzy_match
(
user_input
,
captcha_data
[
'captcha'
]
)
:
user_data
[
user_id
]
[
'passed'
]
=
True
await
update
.
message
.
reply_text
(
"✅ Капча пройдена успешно!\n\nТеперь вы можете использовать бота!\nПопробуйте команду: /hello"
)
else
:
user_data
[
user_id
]
[
'attempts'
]
+=
1
attempts_left
=
3
-
user_data
[
user_id
]
[
'attempts'
]
await
update
.
message
.
reply_text
(
f"❌ Неверно! Осталось попыток:{attempts_left}\nПопробуйте еще раз или обновите капчу"
)
async
def
hello
(
update
:
Update
,
context
:
CallbackContext
)
:
user_id
=
update
.
effective_user
.
id
if
user_data
.
get
(
user_id
,
{
}
)
.
get
(
'passed'
)
:
await
update
.
message
.
reply_text
(
f"👋 Привет,{update.effective_user.first_name}!"
)
else
:
await
update
.
message
.
reply_text
(
"🚫 Сначала пройдите капчу через /start"
)
def
main
(
)
:
application
=
Application
.
builder
(
)
.
token
(
TOKEN
)
.
build
(
)
application
.
add_handler
(
CommandHandler
(
"start"
,
start
)
)
application
.
add_handler
(
CommandHandler
(
"hello"
,
hello
)
)
application
.
add_handler
(
MessageHandler
(
filters
.
TEXT
&
~
filters
.
COMMAND
,
verify_captcha
)
)
application
.
add_handler
(
CallbackQueryHandler
(
refresh_captcha
,
pattern
=
'^refresh$'
)
)
application
.
run_polling
(
)
if
__name__
==
'__main__'
:
main
(
)
|