select_target fixsync def select_target(update: Update, context:
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
ContextTypes.DEFAULT_TYPE):
query = update.callback_query
if not query:
return ConversationHandler.END
await query.answer()
data = (query.data or "")
async with AsyncSessionLocal() as session:
chat_id: str | None = None
markup: InlineKeyboardMarkup
| None = None
selected_title: str
| None = None
btns = []
if
data.startswith('channel_'):
channel_id
=
int(data.split('_',
1)[1])
#
ACL:
право
постинга
в
канал
me
=
await
get_or_create_admin(session,
update.effective_user.id)
allowed
=
await
has_scope_on_channel(session,
me.id,
channel_id,
SCOPE_POST)
if
not
allowed:
await
query.edit_message_text("У
вас
нет
права
постить
в
этот
канал.")
return
ConversationHandler.END
channel
=
(await
session.execute(sa_select(Channel).where(Channel.id
==
channel_id))).scalar_one_or_none()
if
not
channel:
await
query.edit_message_text("Канал
не
найден.")
return
ConversationHandler.END
chat_id
=
(channel.link
or
"").strip()
selected_title
=
channel.name
#
Кнопки
канала
btns
=
(await
session.execute(sa_select(Button).where(Button.channel_id
==
channel_id))).scalars().all()
if
btns:
rows
=
[[InlineKeyboardButton(str(b.name),
url=str(b.url))]
for
b
in
btns]
markup
=
InlineKeyboardMarkup(rows)
elif
data.startswith('group_'):
group_id
=
int(data.split('_',
1)[1])
group
=
(await
session.execute(sa_select(Group).where(Group.id
==
group_id))).scalar_one_or_none()
if
not
group:
await
query.edit_message_text("Группа
не
найдена.")
return
ConversationHandler.END
chat_id
=
(group.link
or
"").strip()
selected_title
=
group.name
#
Кнопки
группы
btns
=
(await
session.execute(sa_select(Button).where(Button.group_id
==
group_id))).scalars().all()
if
btns:
rows
=
[[InlineKeyboardButton(str(b.name),
url=str(b.url))]
for
b
in
btns]
markup
=
InlineKeyboardMarkup(rows)
if
not
chat_id
or
not
(chat_id.startswith('@')
or
chat_id.startswith('-')):
await
query.edit_message_text('Ошибка:
ссылка
должна
быть
username
(@channel)
или
числовой
ID
(-100...)')
return
ConversationHandler.END
#
DEBUG:
сколько
кнопок
нашли
и
есть
ли
markup
print(f"[DEBUG]
send
->
chat_id={chat_id}
title={selected_title!r}
buttons={len(btns)}
has_markup={bool(markup)}")
#
Текст
и
entities
(без
parse_mode)
ud
=
context.user_data
or
{}
text:
str
=
ud.get("text",
"")
or
""
entities:
List[MessageEntity]
=
ud.get("entities",
[])
or
[]
entities
=
_strip_broken_entities(entities)
entities
=
_split_custom_emoji_by_utf16(text,
entities)
#
Всегда
ручная
отправка
(send_*),
чтобы
гарантированно
приклеить
inline-клавиатуру
try:
sent_msg
=
None
if
"photo"
in
ud:
sent_msg
=
await
context.bot.send_photo(
chat_id=chat_id,
photo=ud["photo"],
caption=(text
or
None),
caption_entities=(entities
if
text
else
None),
reply_markup=markup,
)
elif
"animation"
in
ud:
sent_msg
=
await
context.bot.send_animation(
chat_id=chat_id,
animation=ud["animation"],
caption=(text
or
None),
caption_entities=(entities
if
text
else
None),
reply_markup=markup,
)
elif
"video"
in
ud:
sent_msg
=
await
context.bot.send_video(
chat_id=chat_id,
video=ud["video"],
caption=(text
or
None),
caption_entities=(entities
if
text
else
None),
reply_markup=markup,
)
elif
"document"
in
ud:
sent_msg
=
await
context.bot.send_document(
chat_id=chat_id,
document=ud["document"],
caption=(text
or
None),
caption_entities=(entities
if
text
else
None),
reply_markup=markup,
)
elif
"audio"
in
ud:
sent_msg
=
await
context.bot.send_audio(
chat_id=chat_id,
audio=ud["audio"],
caption=(text
or
None),
caption_entities=(entities
if
text
else
None),
reply_markup=markup,
)
elif
"voice"
in
ud:
sent_msg
=
await
context.bot.send_voice(
chat_id=chat_id,
voice=ud["voice"],
caption=(text
or
None),
caption_entities=(entities
if
text
else
None),
reply_markup=markup,
)
elif
"sticker"
in
ud:
sent_msg
=
await
context.bot.send_sticker(
chat_id=chat_id,
sticker=ud["sticker"],
reply_markup=markup,
)
if
text:
await
context.bot.send_message(chat_id=chat_id,
text=text,
entities=entities)
else:
sent_msg
=
await
context.bot.send_message(
chat_id=chat_id,
text=text,
entities=entities,
reply_markup=markup,
)
#
Страховка:
если
вдруг
Telegram
проглотил
клаву
—
доклеим
её
if
markup
and
getattr(sent_msg,
"message_id",
None):
t
This commit is contained in:
@@ -140,26 +140,26 @@ async def select_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
await update.message.reply_text('Выберите, куда отправить пост:', reply_markup=InlineKeyboardMarkup(keyboard))
|
||||
return SELECT_TARGET
|
||||
|
||||
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
if not query:
|
||||
return ConversationHandler.END
|
||||
await query.answer()
|
||||
|
||||
data = query.data
|
||||
data = (query.data or "")
|
||||
async with AsyncSessionLocal() as session:
|
||||
chat_id = None
|
||||
markup = None
|
||||
selected_title = None
|
||||
chat_id: str | None = None
|
||||
markup: InlineKeyboardMarkup | None = None
|
||||
selected_title: str | None = None
|
||||
btns = []
|
||||
|
||||
if data and data.startswith('channel_'):
|
||||
channel_id = int(data.split('_')[1])
|
||||
if data.startswith('channel_'):
|
||||
channel_id = int(data.split('_', 1)[1])
|
||||
|
||||
# ACL: право постинга в канал
|
||||
me = await get_or_create_admin(session, update.effective_user.id)
|
||||
if not await has_scope_on_channel(session, me.id, channel_id, SCOPE_POST):
|
||||
allowed = await has_scope_on_channel(session, me.id, channel_id, SCOPE_POST)
|
||||
if not allowed:
|
||||
await query.edit_message_text("У вас нет права постить в этот канал.")
|
||||
return ConversationHandler.END
|
||||
|
||||
@@ -171,12 +171,15 @@ async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
chat_id = (channel.link or "").strip()
|
||||
selected_title = channel.name
|
||||
|
||||
# Кнопки канала
|
||||
btns = (await session.execute(sa_select(Button).where(Button.channel_id == channel_id))).scalars().all()
|
||||
if btns:
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(str(b.name), url=str(b.url))] for b in btns])
|
||||
rows = [[InlineKeyboardButton(str(b.name), url=str(b.url))] for b in btns]
|
||||
markup = InlineKeyboardMarkup(rows)
|
||||
|
||||
elif data.startswith('group_'):
|
||||
group_id = int(data.split('_', 1)[1])
|
||||
|
||||
elif data and data.startswith('group_'):
|
||||
group_id = int(data.split('_')[1])
|
||||
group = (await session.execute(sa_select(Group).where(Group.id == group_id))).scalar_one_or_none()
|
||||
if not group:
|
||||
await query.edit_message_text("Группа не найдена.")
|
||||
@@ -185,75 +188,105 @@ async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
chat_id = (group.link or "").strip()
|
||||
selected_title = group.name
|
||||
|
||||
# Кнопки группы
|
||||
btns = (await session.execute(sa_select(Button).where(Button.group_id == group_id))).scalars().all()
|
||||
if btns:
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(str(b.name), url=str(b.url))] for b in btns]])
|
||||
rows = [[InlineKeyboardButton(str(b.name), url=str(b.url))] for b in btns]
|
||||
markup = InlineKeyboardMarkup(rows)
|
||||
|
||||
if not chat_id or not (chat_id.startswith('@') or chat_id.startswith('-')):
|
||||
await query.edit_message_text('Ошибка: ссылка должна быть @username или -100…')
|
||||
await query.edit_message_text('Ошибка: ссылка должна быть username (@channel) или числовой ID (-100...)')
|
||||
return ConversationHandler.END
|
||||
|
||||
# DEBUG: покажем, сколько кнопок нашли и куда шлём
|
||||
# DEBUG: сколько кнопок нашли и есть ли markup
|
||||
print(f"[DEBUG] send -> chat_id={chat_id} title={selected_title!r} buttons={len(btns)} has_markup={bool(markup)}")
|
||||
|
||||
# Текст и entities (без parse_mode)
|
||||
ud = context.user_data or {}
|
||||
text: str = ud.get("text", "") or ""
|
||||
entities: List[MessageEntity] = ud.get("entities", []) or []
|
||||
entities = _strip_broken_entities(entities)
|
||||
entities = _split_custom_emoji_by_utf16(text, entities)
|
||||
|
||||
# Всегда ручная отправка (send_*), чтобы гарантированно приклеить inline-клавиатуру
|
||||
try:
|
||||
sent_msg = None
|
||||
|
||||
# ВСЕГДА ручная отправка (никакого copyMessage), чтобы приклеить reply_markup
|
||||
if "photo" in ud:
|
||||
sent_msg = await context.bot.send_photo(chat_id=chat_id, photo=ud["photo"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup)
|
||||
sent_msg = await context.bot.send_photo(
|
||||
chat_id=chat_id,
|
||||
photo=ud["photo"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup,
|
||||
)
|
||||
elif "animation" in ud:
|
||||
sent_msg = await context.bot.send_animation(chat_id=chat_id, animation=ud["animation"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup)
|
||||
sent_msg = await context.bot.send_animation(
|
||||
chat_id=chat_id,
|
||||
animation=ud["animation"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup,
|
||||
)
|
||||
elif "video" in ud:
|
||||
sent_msg = await context.bot.send_video(chat_id=chat_id, video=ud["video"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup)
|
||||
sent_msg = await context.bot.send_video(
|
||||
chat_id=chat_id,
|
||||
video=ud["video"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup,
|
||||
)
|
||||
elif "document" in ud:
|
||||
sent_msg = await context.bot.send_document(chat_id=chat_id, document=ud["document"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup)
|
||||
sent_msg = await context.bot.send_document(
|
||||
chat_id=chat_id,
|
||||
document=ud["document"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup,
|
||||
)
|
||||
elif "audio" in ud:
|
||||
sent_msg = await context.bot.send_audio(chat_id=chat_id, audio=ud["audio"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup)
|
||||
sent_msg = await context.bot.send_audio(
|
||||
chat_id=chat_id,
|
||||
audio=ud["audio"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup,
|
||||
)
|
||||
elif "voice" in ud:
|
||||
sent_msg = await context.bot.send_voice(chat_id=chat_id, voice=ud["voice"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup)
|
||||
sent_msg = await context.bot.send_voice(
|
||||
chat_id=chat_id,
|
||||
voice=ud["voice"],
|
||||
caption=(text or None),
|
||||
caption_entities=(entities if text else None),
|
||||
reply_markup=markup,
|
||||
)
|
||||
elif "sticker" in ud:
|
||||
sent_msg = await context.bot.send_sticker(chat_id=chat_id, sticker=ud["sticker"], reply_markup=markup)
|
||||
sent_msg = await context.bot.send_sticker(
|
||||
chat_id=chat_id,
|
||||
sticker=ud["sticker"],
|
||||
reply_markup=markup,
|
||||
)
|
||||
if text:
|
||||
await context.bot.send_message(chat_id=chat_id, text=text, entities=entities)
|
||||
else:
|
||||
sent_msg = await context.bot.send_message(chat_id=chat_id, text=text, entities=entities, reply_markup=markup)
|
||||
sent_msg = await context.bot.send_message(
|
||||
chat_id=chat_id,
|
||||
text=text,
|
||||
entities=entities,
|
||||
reply_markup=markup,
|
||||
)
|
||||
|
||||
# страховка: если вдруг Telegram проглотил клаву — доклеим через edit_message_reply_markup
|
||||
# Страховка: если вдруг Telegram проглотил клаву — доклеим её
|
||||
if markup and getattr(sent_msg, "message_id", None):
|
||||
try:
|
||||
await context.bot.edit_message_reply_markup(chat_id=chat_id,
|
||||
message_id=sent_msg.message_id,
|
||||
reply_markup=markup)
|
||||
await context.bot.edit_message_reply_markup(
|
||||
chat_id=chat_id,
|
||||
message_id=sent_msg.message_id,
|
||||
reply_markup=markup,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
await query.edit_message_text(f'Пост отправлен{(" в: " + selected_title) if selected_title else "!"}')
|
||||
|
||||
except BadRequest as e:
|
||||
await query.edit_message_text(f'Ошибка отправки поста: {e}')
|
||||
|
||||
@@ -261,6 +294,7 @@ async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
|
||||
|
||||
|
||||
|
||||
new_post_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler("new_post", new_post_start)],
|
||||
states={
|
||||
|
||||
Reference in New Issue
Block a user