π¦ Release Notes v2.0.2
ΠΠ°ΡΠ° Π²ΡΠΏΡΡΠΊΠ°: 11 ΠΌΠ°ΡΡΠ° 2026 Π³.
Π‘ΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Π²Π΅ΡΡΠΈΠΉ: v2.0.1...v2.0.2
π― ΠΡΠ½ΠΎΠ²Π½ΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡβ
π Π£Π»ΡΡΡΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ Ρ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»Π°ΠΌΠΈβ
1. Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅Π΄ΠΈΠ° Π½Π° Π³ΡΡΠΏΠΏΡ ΠΏΡΠΈ ΠΎΡΠΏΡΠ°Π²ΠΊΠ΅β
ΠΡΠΎΠ±Π»Π΅ΠΌΠ°: Telegram Π½Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΌΠ΅ΡΠΈΠ²Π°ΡΡ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΡ Ρ Π΄ΡΡΠ³ΠΈΠΌΠΈ ΡΠΈΠΏΠ°ΠΌΠΈ ΠΌΠ΅Π΄ΠΈΠ° (photo, video, audio) Π² ΠΎΠ΄Π½ΠΎΠΉ Π³ΡΡΠΏΠΏΠ΅ sendMediaGroup.
Π Π΅ΡΠ΅Π½ΠΈΠ΅:
- ΠΠΎΠΊΡΠΌΠ΅Π½ΡΡ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΉ Π³ΡΡΠΏΠΏΠΎΠΉ ΡΠ΅ΡΠ΅Π·
send_media_group - Photo/Video/Audio ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ Π²ΠΌΠ΅ΡΡΠ΅ Π² ΠΎΠ΄Π½ΠΎΠΉ Π³ΡΡΠΏΠΏΠ΅
- ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΡ ΠΊΠΎΠ΄Π° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΡΠΈΠΏΡ ΠΈ ΡΠ°Π·Π΄Π΅Π»ΡΠ΅Ρ ΠΈΡ
ΠΠΎΠ²ΡΠ΅ ΡΡΠΈΠ»ΠΈΡΡ:
| Π€Π°ΠΉΠ» | ΠΠ°Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ |
|---|---|
get-media-type-by-url.ts | ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ° ΠΌΠ΅Π΄ΠΈΠ° ΠΏΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ URL |
group-media-by-type.ts | ΠΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠ° ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»ΠΎΠ² ΠΏΠΎ ΡΠΈΠΏΠ°ΠΌ |
split-media-for-sending.ts | Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π½Π° groupable ΠΈ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΡ |
can-send-in-one-group.ts | ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ Π²ΠΌΠ΅ΡΡΠ΅ |
ΠΡΠΈΠΌΠ΅Ρ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°:
# ΠΡΡΠΏΠΏΠ° ΠΌΠ΅Π΄ΠΈΠ° (photo/video/audio)
media_group = []
media_group.append(InputMediaPhoto(media="file1.jpg", caption="Π’Π΅ΠΊΡΡ"))
media_group.append(InputMediaVideo(media="file2.mp4"))
await bot.send_media_group(chat_id, media_group)
# ΠΡΡΠΏΠΏΠ° Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΎΠ² (ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ)
document_group = []
document_group.append(InputMediaDocument(media="file3.pdf"))
document_group.append(InputMediaDocument(media="file4.docx"))
await bot.send_media_group(chat_id, document_group)
2. ΠΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ Ρ ΠΌΠ΅Π΄ΠΈΠ°Π³ΡΡΠΏΠΏΠ°ΠΌΠΈβ
ΠΡΠΎΠ±Π»Π΅ΠΌΠ°: Π aiogram 3.x ΠΌΠ΅ΡΠΎΠ΄ send_media_group() Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ reply_markup.
Π Π΅ΡΠ΅Π½ΠΈΠ΅:
- ΠΠ΅Π΄ΠΈΠ°Π³ΡΡΠΏΠΏΠ° ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΡΡ Π±Π΅Π· ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ
- ΠΠ»Π°Π²ΠΈΠ°ΡΡΡΠ° ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΡΠ°Π·Ρ ΠΏΠΎΡΠ»Π΅ ΠΌΠ΅Π΄ΠΈΠ°Π³ΡΡΠΏΠΏΡ
ΠΡΠΈΠΌΠ΅Ρ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°:
# ΠΡΠΏΡΠ°Π²ΠΊΠ° ΠΌΠ΅Π΄ΠΈΠ°Π³ΡΡΠΏΠΏΡ
sent_messages = await bot.send_media_group(chat_id, media_group)
# ΠΡΠΏΡΠ°Π²ΠΊΠ° ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΠΌ
if keyboard is not None:
await bot.send_message(chat_id, text, reply_markup=keyboard)
3. ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΏΡΡΠΌΡΡ URL Π² attachedMediaβ
ΠΡΠΎΠ±Π»Π΅ΠΌΠ°: ΠΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»Ρ Ρ ΠΏΡΡΠΌΡΠΌΠΈ URL (http/https) Π½Π΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ»ΠΈΡΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ ΠΈΡΠΊΠ°Π» ΠΈΡ Π² ΠΠ.
Π Π΅ΡΠ΅Π½ΠΈΠ΅:
collectMediaVariablesΡΠ΅ΠΏΠ΅ΡΡ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΠΏΡΡΠΌΡΠ΅ URL Π²mediaVariablesMapgenerateAttachedMediaSendCodeΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΠΏΡΡΠΌΡΠ΅ URL Π½Π°ΠΏΡΡΠΌΡΡ, Π±Π΅Π· ΠΏΠΎΠΈΡΠΊΠ° Π² ΠΠ- Π’ΠΈΠΏ ΠΌΠ΅Π΄ΠΈΠ° ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΡΡ ΠΏΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»Π° Π² URL
ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠ΅ ΡΠΎΡΠΌΠ°ΡΡ:
| Π’ΠΈΠΏ | Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ |
|---|---|
| Photo | jpg, jpeg, png, gif, webp, bmp |
| Video | mp4, avi, mov, webm |
| Audio | mp3, wav, ogg |
| Document | ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ |
π¨ Π£Π»ΡΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°β
4. Π‘ΠΊΡΡΡΠΈΠ΅ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»ΠΎΠ² ΠΏΡΠΈ Π²ΠΊΠ»ΡΡΠ΅Π½Π½ΠΎΠΉ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΠ΅β
Π€ΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»:
- ΠΡΠΈ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΈ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ ΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ >1 ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»ΠΎΠ² β ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠ΅ΡΠ²ΡΠΉ
- ΠΡΡΠ°Π»ΡΠ½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ ΡΠΎΡ ΡΠ°Π½ΡΡΡΡΡ, Π½ΠΎ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡΡΡ Ρ ΠΏΠΎΠΌΠ΅ΡΠΊΠΎΠΉ "Π‘ΠΊΡΡΡ"
- Π‘ΠΊΡΡΡΡΠ΅ ΡΠ°ΠΉΠ»Ρ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡΡΡ:
- ΠΠΎΠ»ΡΠΏΡΠΎΠ·ΡΠ°ΡΠ½ΡΠΌ ΡΠΎΠ½ΠΎΠΌ (opacity-60)
- Π‘Π΅ΡΠΎΠΉ ΡΠ°ΠΌΠΊΠΎΠΉ Π²ΠΌΠ΅ΡΡΠΎ Π·Π΅Π»ΡΠ½ΠΎΠΉ
- Π§ΡΡΠ½ΠΎΠΉ ΠΏΠ»Π°ΡΠΊΠΎΠΉ "Π‘ΠΊΡΡΡ" ΠΏΠΎΠ²Π΅ΡΡ ΠΏΡΠ΅Π²ΡΡ
- ΠΠ΅ΠΉΠ΄ΠΆΠ΅ΠΌ "Π‘ΠΊΡΡΡ" ΡΡΠ΄ΠΎΠΌ Ρ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ
ΠΠ½ΠΎΠΏΠΊΠ° "ΠΠΊΠ»ΡΡΠΈΡΡ Π²ΡΠ΅ ΡΠ°ΠΉΠ»Ρ":
- ΠΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΏΠΈΡΠΊΠΎΠΌ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΈ ΠΏΠΎΠ»Π΅ΠΌ Π²Π²ΠΎΠ΄Π°
- ΠΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ ΠΎΡΠΊΠ»ΡΡΠ°Π΅Ρ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ (
keyboardType = 'none') - ΠΡΠ΅ ΡΠ°ΠΉΠ»Ρ ΡΠ½ΠΎΠ²Π° ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡΡΡ ΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ
ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ:
- ΠΡΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π²ΡΠΎΡΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΠ° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΎΡΠΊΠ»ΡΡΠ°Π΅ΡΡΡ
useEffectΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅Ρ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΈ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡkeyboardType: 'none'- ΠΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠΎΡ
ΡΠ°Π½ΡΠ΅ΡΡΡ Π²
project.jsonΠΈ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΠΌΠΎΠΌ ΠΊΠΎΠ΄Π΅
5. ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΡΠ°ΡΠΊΡΡΡΠΈΠ΅ ΡΠ΅ΠΊΡΠΈΠΉ ΠΏΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ ΠΊΠΎΠ½ΡΠ΅Π½ΡΠ°β
Π Π°Π½ΡΡΠ΅: ΠΡΠ΅ ΡΠ΅ΠΊΡΠΈΠΈ (ΠΊΡΠΎΠΌΠ΅ "Π’Π΅ΠΊΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ") Π±ΡΠ»ΠΈ ΡΠ²ΡΡΠ½ΡΡΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
Π’Π΅ΠΏΠ΅ΡΡ: Π‘Π΅ΠΊΡΠΈΠΈ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ°ΡΠΊΡΡΠ²Π°ΡΡΡΡ, Π΅ΡΠ»ΠΈ Π² Π½ΠΈΡ Π΅ΡΡΡ ΠΊΠΎΠ½ΡΠ΅Π½Ρ:
| Π‘Π΅ΠΊΡΠΈΡ | Π£ΡΠ»ΠΎΠ²ΠΈΠ΅ ΡΠ°ΡΠΊΡΡΡΠΈΡ |
|---|---|
| π ΠΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»Ρ | ΠΡΡΡ attachedMedia, imageUrl, videoUrl, audioUrl, documentUrl |
| β¨οΈ ΠΠ»Π°Π²ΠΈΠ°ΡΡΡΠ° | ΠΡΡΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΈΠ»ΠΈ Π²ΠΊΠ»ΡΡΠ΅Π½Π° ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΠ° (inline/reply) |
| β‘ ΠΠ²ΡΠΎΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ | ΠΠΊΠ»ΡΡΡΠ½ Π°Π²ΡΠΎΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ |
| π Π£ΡΠ»ΠΎΠ²Π½ΡΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ | ΠΡΡΡ ΡΡΠ»ΠΎΠ²Π½ΡΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ |
| π€ ΠΠ²ΠΎΠ΄ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ | ΠΠΊΠ»ΡΡΡΠ½ ΡΠ±ΠΎΡ Π²Π²ΠΎΠ΄Π° (ΡΠ΅ΠΊΡΡ, ΡΠΎΡΠΎ, Π²ΠΈΠ΄Π΅ΠΎ, Π°ΡΠ΄ΠΈΠΎ, Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΡ) |
6. Π£Π²Π΅Π»ΠΈΡΠ΅Π½ ΡΠ°Π·ΠΌΠ΅Ρ ΠΏΠ°Π½Π΅Π»ΠΈ ΡΠ²ΠΎΠΉΡΡΠ² ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡβ
ΠΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅: Π Π°Π·ΠΌΠ΅Ρ ΠΏΠ°Π½Π΅Π»ΠΈ ΡΠ²ΠΎΠΉΡΡΠ² ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ Ρ 20% Π΄ΠΎ 25% ΡΠΊΡΠ°Π½Π°.
ΠΠ°Π»Π°Π½Ρ ΠΌΠ°ΠΊΠ΅ΡΠ°:
- Π‘Π°ΠΉΠ΄Π±Π°Ρ (ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ): 20%
- Π₯ΠΎΠ»ΡΡ: 30%
- ΠΠ°Π½Π΅Π»Ρ ΡΠ²ΠΎΠΉΡΡΠ²: 25%
- ΠΡΡΠ°Π»ΡΠ½ΠΎΠ΅: ΡΠ°ΠΏΠΊΠ°
π§© ΠΠΎΠ²ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡβ
InfoBlockβ
Π£Π½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½ΡΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ Π΄Π»Ρ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΎΠ½Π½ΡΡ Π±Π»ΠΎΠΊΠΎΠ² Ρ Π²Π°ΡΠΈΠ°Π½ΡΠ°ΠΌΠΈ:
<InfoBlock
variant="warning" // info | warning | recommendation
title="β οΈ ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ"
description="ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅"
/>
Π€Π°ΠΉΠ»: client/components/ui/info-block.tsx
ToggleGroupβ
ΠΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ Π΄Π»Ρ Π³ΡΡΠΏΠΏ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ°ΡΠ΅Π»Π΅ΠΉ:
<ToggleGroup
title="ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ"
icon="fa-icon"
colorClasses={{ title: '...', icon: '...' }}
configs={configs}
selectedNode={node}
onNodeUpdate={onNodeUpdate}
description="ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅"
/>
Π€Π°ΠΉΠ»: client/components/editor/properties/components/media/toggle-group.tsx
MediaFileCardβ
ΠΠ°ΡΡΠΎΡΠΊΠ° ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»Π° Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ ΡΠΊΡΡΡΡΡ ΡΠ°ΠΉΠ»ΠΎΠ²:
<MediaFileCard
url="https://..."
fileName="Π€Π°ΠΉΠ» 1"
fileType="image"
isHidden={false}
onRemove={handleRemove}
/>
Π€Π°ΠΉΠ»: client/components/editor/properties/media/media-file-card.tsx
MediaAttachmentsPreviewβ
ΠΡΠ΅Π²ΡΡ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»ΠΎΠ² Π½Π° ΠΊΠ°Π½Π²Π°ΡΠ΅ Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ ΡΠΊΡΡΡΠΈΡ ΠΏΡΠΈ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΠ΅:
<MediaAttachmentsPreview node={node} />
Π€Π°ΠΉΠ»: client/components/editor/canvas/canvas-node/media-attachments-preview.tsx
π¦ ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π²Π΅ΡΡΠΈΠΈβ
- ΠΠ΅ΡΡΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π° Ρ
2.0.1Π΄ΠΎ2.0.2 - VersionBadge β ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅Ρ Π°ΠΊΡΡΠ°Π»ΡΠ½ΡΡ Π²Π΅ΡΡΠΈΡ
π Π‘ΡΠ°ΡΠΈΡΡΠΈΠΊΠ° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉβ
| ΠΠ°ΡΠ΅Π³ΠΎΡΠΈΡ | Π€Π°ΠΉΠ»ΠΎΠ² ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ | Π‘ΡΡΠΎΠΊ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ | Π‘ΡΡΠΎΠΊ ΡΠ΄Π°Π»Π΅Π½ΠΎ |
|---|---|---|---|
| ΠΠ΅Π½Π΅ΡΠ°ΡΠΎΡ ΠΌΠ΅Π΄ΠΈΠ° | 8 | 600+ | 200+ |
| UI ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ | 10 | 400+ | 300+ |
| Π Π΅ΡΠ°ΠΊΡΠΎΡΠΈΠ½Π³ | 16 | 500+ | 800+ |
| ΠΡΠ΅Π³ΠΎ | 34 | 1514 | 1342 |
π§ Π’Π΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π΄Π΅ΡΠ°Π»ΠΈβ
Π‘ΡΡΡΠΊΡΡΡΠ° ΡΡΠΈΠ»ΠΈΡ ΠΌΠ΅Π΄ΠΈΠ°β
// client/lib/bot-generator/MediaHandler/utils/
get-media-type-by-url.ts // ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ° ΠΏΠΎ URL
group-media-by-type.ts // ΠΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠ° ΠΏΠΎ ΡΠΈΠΏΠ°ΠΌ
split-media-for-sending.ts // Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ
can-send-in-one-group.ts // ΠΡΠΎΠ²Π΅ΡΠΊΠ° ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΎΡΡΠΈ
index.ts // ΠΠΊΡΠΏΠΎΡΡ Π²ΡΠ΅Ρ
ΡΡΠΈΠ»ΠΈΡ
ΠΡΠΈΠΌΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΡΠΈΠ»ΠΈΡβ
import { splitMediaForSending, getMediaTypeByUrl } from './utils';
// Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅Π΄ΠΈΠ°
const { groupable, documents } = splitMediaForSending(mediaUrls);
// groupable: ['file1.jpg', 'file2.mp4', 'file3.mp3']
// documents: ['file4.pdf', 'file5.docx']
// ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ°
const type = getMediaTypeByUrl('https://example.com/file.jpg');
// 'photo'
ΠΠΎΠ³ΠΈΠΊΠ° ΡΠΊΡΡΡΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²β
// Π multi-media-selector.tsx
const hasKeyboard = keyboardType === 'inline' || keyboardType === 'reply';
const isHidden = hasKeyboard && index > 0;
// ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ
useEffect(() => {
if (value.length > 1 && hasKeyboard && onNodeUpdate && nodeId) {
onNodeUpdate(nodeId, { keyboardType: 'none' });
}
}, [value.length, hasKeyboard, onNodeUpdate, nodeId]);
ΠΠ²ΡΠΎΡΠ°ΡΠΊΡΡΡΠΈΠ΅ ΡΠ΅ΠΊΡΠΈΠΉβ
// Π properties-panel.tsx
useEffect(() => {
if (!selectedNode?.data) return;
// Π‘Π΅ΠΊΡΠΈΡ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»ΠΎΠ²
const hasMedia = selectedNode.data.attachedMedia?.length > 0 ||
selectedNode.data.imageUrl ||
selectedNode.data.videoUrl;
if (hasMedia && !isMediaSectionOpen) {
setIsMediaSectionOpen(true);
}
// Π‘Π΅ΠΊΡΠΈΡ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ
const hasKeyboard = selectedNode.data.keyboardType !== 'none';
const hasButtons = selectedNode.data.buttons?.length > 0;
if ((hasKeyboard || hasButtons) && !isKeyboardSectionOpen) {
setIsKeyboardSectionOpen(true);
}
// ... ΠΈ ΡΠ°ΠΊ Π΄Π°Π»Π΅Π΅ Π΄Π»Ρ Π΄ΡΡΠ³ΠΈΡ
ΡΠ΅ΠΊΡΠΈΠΉ
}, [selectedNode?.data, selectedNode?.id]);
π Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ°β
ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Ρ v2.0.1:β
# ΠΠ±Π½ΠΎΠ²ΠΈΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡ
git pull origin main
# Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ
cd client
npm install
# Π‘ΠΎΠ±Π΅ΡΠΈΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡ
npm run build
# ΠΠ°ΠΏΡΡΡΠΈΡΠ΅
npm run start
Π§Π΅ΡΠ΅Π· Docker:β
# ΠΠ΅ΡΠ΅ΡΠΎΠ±Π΅ΡΠΈΡΠ΅ ΠΎΠ±ΡΠ°Π·
docker-compose build --no-cache
# ΠΠ°ΠΏΡΡΡΠΈΡΠ΅
docker-compose up -d
β οΈ ΠΠ°ΠΆΠ½ΡΠ΅ Π·Π°ΠΌΠ΅ΡΠ°Π½ΠΈΡβ
Π‘ΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΎΡΡΡ Ρ aiogram 3.xβ
ΠΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ ΠΊΠΎΠ΄Π° ΡΡΠΈΡΡΠ²Π°ΡΡ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ aiogram 3.x:
send_media_group()Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρreply_markup- ΠΠ»Π°Π²ΠΈΠ°ΡΡΡΠ° ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΠΌ
- ΠΡΠΎ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π²ΠΎ Π²ΡΠ΅Ρ ΡΠ»ΡΡΠ°ΡΡ
ΠΠ±ΡΠ°ΡΠ½Π°Ρ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΎΡΡΡβ
- ΠΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡ
- Π‘ΡΠ°ΡΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΡ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ
- ΠΠΎΠ²ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΊ Π½ΠΎΠ²ΡΠΌ ΡΠ·Π»Π°ΠΌ
ΠΠΈΠ³ΡΠ°ΡΠΈΡ ΠΏΡΠΎΠ΅ΠΊΡΠΎΠ²β
ΠΡΠΎΠ΅ΠΊΡΡ, ΡΠΎΠ·Π΄Π°Π½Π½ΡΠ΅ Π² ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΡ Π²Π΅ΡΡΠΈΡΡ , Π½Π΅ ΡΡΠ΅Π±ΡΡΡ ΠΌΠΈΠ³ΡΠ°ΡΠΈΠΈ. ΠΠΎΠ²ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΡΠ·Π»ΠΎΠ².
π ΠΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡβ
| ΠΡΠΎΠ±Π»Π΅ΠΌΠ° | Π Π΅ΡΠ΅Π½ΠΈΠ΅ |
|---|---|
send_media_group() got an unexpected keyword argument 'reply_markup' | ΠΠ»Π°Π²ΠΈΠ°ΡΡΡΠ° ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΡΠ΅Π· send_message() |
| ΠΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»Ρ Ρ ΠΏΡΡΠΌΡΠΌΠΈ URL Π½Π΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ»ΠΈΡΡ | ΠΡΡΠΌΡΠ΅ URL ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π½Π°ΠΏΡΡΠΌΡΡ, Π±Π΅Π· ΠΏΠΎΠΈΡΠΊΠ° Π² ΠΠ |
| ΠΠΎΠΊΡΠΌΠ΅Π½ΡΡ Π²ΡΠ·ΡΠ²Π°Π»ΠΈ ΠΎΡΠΈΠ±ΠΊΡ Telegram | ΠΠΎΠΊΡΠΌΠ΅Π½ΡΡ ΡΠ°Π·Π΄Π΅Π»ΡΡΡΡΡ ΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΉ Π³ΡΡΠΏΠΏΠΎΠΉ |
| Π‘Π΅ΠΊΡΠΈΠΈ ΡΠ²ΠΎΡΠ°ΡΠΈΠ²Π°Π»ΠΈΡΡ ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΈ ΡΠ·Π»ΠΎΠ² | Π‘Π΅ΠΊΡΠΈΠΈ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ°ΡΠΊΡΡΠ²Π°ΡΡΡΡ ΠΏΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ ΠΊΠΎΠ½ΡΠ΅Π½ΡΠ° |
π Π§Π΅ΠΊ-Π»ΠΈΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉβ
- Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅Π΄ΠΈΠ° Π½Π° Π³ΡΡΠΏΠΏΡ (Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ)
- ΠΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ Ρ ΠΌΠ΅Π΄ΠΈΠ°Π³ΡΡΠΏΠΏΠ°ΠΌΠΈ
- ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΏΡΡΠΌΡΡ URL Π² attachedMedia
- Π‘ΠΊΡΡΡΠΈΠ΅ Π»ΠΈΡΠ½ΠΈΡ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»ΠΎΠ² ΠΏΡΠΈ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΠ΅
- ΠΠ½ΠΎΠΏΠΊΠ° "ΠΠΊΠ»ΡΡΠΈΡΡ Π²ΡΠ΅ ΡΠ°ΠΉΠ»Ρ"
- ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊΠ»Π°Π²ΠΈΠ°ΡΡΡΡ ΠΏΡΠΈ >1 ΡΠ°ΠΉΠ»ΠΎΠ²
- ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΡΠ°ΡΠΊΡΡΡΠΈΠ΅ ΡΠ΅ΠΊΡΠΈΠΉ
- Π£Π²Π΅Π»ΠΈΡΠ΅Π½ ΡΠ°Π·ΠΌΠ΅Ρ ΠΏΠ°Π½Π΅Π»ΠΈ ΡΠ²ΠΎΠΉΡΡΠ² Π΄ΠΎ 25%
- ΠΠΎΠ²ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ
- Π£ΡΠΈΠ»ΠΈΡΡ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΠΌΠ΅Π΄ΠΈΠ°Π³ΡΡΠΏΠΏΠ°ΠΌΠΈ
- ΠΠ±Π½ΠΎΠ²Π»Π΅Π½Π° Π²Π΅ΡΡΠΈΡ Π΄ΠΎ 2.0.2
π Π‘ΡΡΠ»ΠΊΠΈβ
- ΠΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΡΠ΅Π»ΠΈΠ·Π°
- Π‘ΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
- ΠΠΎΠ»Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ²
ΠΠΎΠ»Π½ΡΠΉ ΡΠΏΠΈΡΠΎΠΊ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ: ΠΠΎΠΌΠΌΠΈΡΡ v2.0.1...v2.0.2