mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 13:54:02 +00:00
Fix Bind Topic Error by making callback handling more robust
- Wrap answerCallbackQuery and editMessageText in try-catch to handle expired queries - Answer callback queries as early as possible - Add setup_tracking to allowed pending action types for better type safety - Ignore 'query is too old' and 'message is not modified' errors gracefully
This commit is contained in:
@@ -945,16 +945,22 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (result.status === 'rejected') {
|
if (result.status === 'rejected') {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text: adminRejectionMessage(locale, result.reason),
|
.answerCallbackQuery({
|
||||||
show_alert: true
|
text: adminRejectionMessage(locale, result.reason),
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.answerCallbackQuery({
|
try {
|
||||||
text: t.setup.approvedMemberToast(result.member.displayName)
|
await ctx.answerCallbackQuery({
|
||||||
})
|
text: t.setup.approvedMemberToast(result.member.displayName)
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
// Ignore stale query
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx.msg) {
|
if (ctx.msg) {
|
||||||
const refreshed = await options.householdAdminService.listPendingMembers({
|
const refreshed = await options.householdAdminService.listPendingMembers({
|
||||||
@@ -963,13 +969,17 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (refreshed.status === 'ok') {
|
if (refreshed.status === 'ok') {
|
||||||
if (refreshed.members.length === 0) {
|
try {
|
||||||
await ctx.editMessageText(t.setup.pendingMembersEmpty(refreshed.householdName))
|
if (refreshed.members.length === 0) {
|
||||||
} else {
|
await ctx.editMessageText(t.setup.pendingMembersEmpty(refreshed.householdName))
|
||||||
const reply = pendingMembersReply(locale, refreshed)
|
} else {
|
||||||
await ctx.editMessageText(reply.text, {
|
const reply = pendingMembersReply(locale, refreshed)
|
||||||
reply_markup: reply.reply_markup
|
await ctx.editMessageText(reply.text, {
|
||||||
})
|
reply_markup: reply.reply_markup
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignore message edit errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -989,10 +999,12 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
const t = getBotTranslations(locale).setup
|
const t = getBotTranslations(locale).setup
|
||||||
|
|
||||||
if (!isGroupChat(ctx)) {
|
if (!isGroupChat(ctx)) {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text: t.useButtonInGroup,
|
.answerCallbackQuery({
|
||||||
show_alert: true
|
text: t.useButtonInGroup,
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1004,18 +1016,22 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
: null
|
: null
|
||||||
|
|
||||||
if (!actorIsAdmin) {
|
if (!actorIsAdmin) {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text: t.onlyTelegramAdminsBindTopics,
|
.answerCallbackQuery({
|
||||||
show_alert: true
|
text: t.onlyTelegramAdminsBindTopics,
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!household) {
|
if (!household) {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text: t.householdNotConfigured,
|
.answerCallbackQuery({
|
||||||
show_alert: true
|
text: t.householdNotConfigured,
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,13 +1047,15 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (result.status === 'rejected') {
|
if (result.status === 'rejected') {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text:
|
.answerCallbackQuery({
|
||||||
result.reason === 'not_admin'
|
text:
|
||||||
? t.onlyTelegramAdminsBindTopics
|
result.reason === 'not_admin'
|
||||||
: t.householdNotConfigured,
|
? t.onlyTelegramAdminsBindTopics
|
||||||
show_alert: true
|
: t.householdNotConfigured,
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1050,15 +1068,23 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
botUsername: ctx.me.username
|
botUsername: ctx.me.username
|
||||||
})
|
})
|
||||||
|
|
||||||
await ctx.answerCallbackQuery({
|
try {
|
||||||
text: t.setupTopicCreated(setupTopicRoleLabel(locale, role), topicName)
|
await ctx.answerCallbackQuery({
|
||||||
})
|
text: t.setupTopicCreated(setupTopicRoleLabel(locale, role), topicName)
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
// Ignore stale query
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx.msg) {
|
if (ctx.msg) {
|
||||||
await ctx.editMessageText(
|
try {
|
||||||
reply.text,
|
await ctx.editMessageText(
|
||||||
'reply_markup' in reply ? { reply_markup: reply.reply_markup } : {}
|
reply.text,
|
||||||
)
|
'reply_markup' in reply ? { reply_markup: reply.reply_markup } : {}
|
||||||
|
)
|
||||||
|
} catch {
|
||||||
|
// Ignore message edit errors
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message =
|
const message =
|
||||||
@@ -1067,10 +1093,12 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
? t.setupTopicCreateForbidden
|
? t.setupTopicCreateForbidden
|
||||||
: t.setupTopicCreateFailed
|
: t.setupTopicCreateFailed
|
||||||
|
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text: message,
|
.answerCallbackQuery({
|
||||||
show_alert: true
|
text: message,
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1085,10 +1113,12 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
const t = getBotTranslations(locale).setup
|
const t = getBotTranslations(locale).setup
|
||||||
|
|
||||||
if (!isGroupChat(ctx)) {
|
if (!isGroupChat(ctx)) {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text: t.useButtonInGroup,
|
.answerCallbackQuery({
|
||||||
show_alert: true
|
text: t.useButtonInGroup,
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1098,10 +1128,12 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
const actorIsAdmin = await isGroupAdmin(ctx)
|
const actorIsAdmin = await isGroupAdmin(ctx)
|
||||||
|
|
||||||
if (!actorIsAdmin) {
|
if (!actorIsAdmin) {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text: t.onlyTelegramAdminsBindTopics,
|
.answerCallbackQuery({
|
||||||
show_alert: true
|
text: t.onlyTelegramAdminsBindTopics,
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1113,27 +1145,37 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (result.status === 'rejected') {
|
if (result.status === 'rejected') {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx
|
||||||
text:
|
.answerCallbackQuery({
|
||||||
result.reason === 'not_admin'
|
text:
|
||||||
? t.onlyTelegramAdminsBindTopics
|
result.reason === 'not_admin'
|
||||||
: t.householdNotConfigured,
|
? t.onlyTelegramAdminsBindTopics
|
||||||
show_alert: true
|
: t.householdNotConfigured,
|
||||||
})
|
show_alert: true
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.answerCallbackQuery({
|
try {
|
||||||
text: t.topicBoundSuccess(
|
await ctx.answerCallbackQuery({
|
||||||
setupTopicRoleLabel(locale, role),
|
text: t.topicBoundSuccess(
|
||||||
result.household.householdName
|
setupTopicRoleLabel(locale, role),
|
||||||
)
|
result.household.householdName
|
||||||
})
|
)
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
// Ignore stale query
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx.msg) {
|
if (ctx.msg) {
|
||||||
await ctx.editMessageText(
|
try {
|
||||||
t.topicBoundSuccess(setupTopicRoleLabel(locale, role), result.household.householdName)
|
await ctx.editMessageText(
|
||||||
)
|
t.topicBoundSuccess(setupTopicRoleLabel(locale, role), result.household.householdName)
|
||||||
|
)
|
||||||
|
} catch {
|
||||||
|
// Ignore message edit errors
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to update the main /setup checklist if it exists
|
// Try to update the main /setup checklist if it exists
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ function parsePendingActionType(raw: string): TelegramPendingActionType {
|
|||||||
return raw
|
return raw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (raw === 'setup_tracking') {
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error(`Unexpected telegram pending action type: ${raw}`)
|
throw new Error(`Unexpected telegram pending action type: ${raw}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ export const TELEGRAM_PENDING_ACTION_TYPES = [
|
|||||||
'payment_topic_clarification',
|
'payment_topic_clarification',
|
||||||
'payment_topic_confirmation',
|
'payment_topic_confirmation',
|
||||||
'reminder_utility_entry',
|
'reminder_utility_entry',
|
||||||
'setup_topic_binding'
|
'setup_topic_binding',
|
||||||
|
'setup_tracking'
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export type TelegramPendingActionType = (typeof TELEGRAM_PENDING_ACTION_TYPES)[number]
|
export type TelegramPendingActionType = (typeof TELEGRAM_PENDING_ACTION_TYPES)[number]
|
||||||
|
|||||||
Reference in New Issue
Block a user