mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 12:04:02 +00:00
feat(bot): restore /bind command and improve /setup welcoming experience
This commit is contained in:
@@ -874,13 +874,14 @@ describe('registerHouseholdSetupCommands', () => {
|
|||||||
chat_id: -100123456
|
chat_id: -100123456
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
expect(sendPayload.text).toContain('Kojori House is ready!')
|
expect(sendPayload.text).toContain('Welcome! Kojori House is successfully registered')
|
||||||
expect(sendPayload.text).toContain('Topics: 0/5 configured')
|
expect(sendPayload.text).toContain("Let's configure your household topics to get started")
|
||||||
expect(sendPayload.text).toContain('⚪ purchases')
|
expect(sendPayload.text).toContain('(0/5)')
|
||||||
expect(sendPayload.text).toContain('⚪ payments')
|
expect(sendPayload.text).toContain('⚪ Purchases')
|
||||||
|
expect(sendPayload.text).toContain('⚪ Payments')
|
||||||
// Check that join household button exists
|
// Check that join household button exists
|
||||||
expect(JSON.stringify(sendPayload.reply_markup)).toContain('Join household')
|
expect(JSON.stringify(sendPayload.reply_markup)).toContain('Join household')
|
||||||
expect(JSON.stringify(sendPayload.reply_markup)).toContain('+ purchases')
|
expect(JSON.stringify(sendPayload.reply_markup)).toContain('Setup Purchases')
|
||||||
expect(JSON.stringify(sendPayload.reply_markup)).toContain('setup_topic:create:purchase')
|
expect(JSON.stringify(sendPayload.reply_markup)).toContain('setup_topic:create:purchase')
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -998,7 +999,7 @@ describe('registerHouseholdSetupCommands', () => {
|
|||||||
method: 'answerCallbackQuery',
|
method: 'answerCallbackQuery',
|
||||||
payload: {
|
payload: {
|
||||||
callback_query_id: 'callback-1',
|
callback_query_id: 'callback-1',
|
||||||
text: 'purchases topic created and bound: Shared purchases.'
|
text: 'Purchases topic created and bound: Shared purchases.'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
expect(calls[3]).toMatchObject({
|
expect(calls[3]).toMatchObject({
|
||||||
@@ -1006,7 +1007,7 @@ describe('registerHouseholdSetupCommands', () => {
|
|||||||
payload: {
|
payload: {
|
||||||
chat_id: -100123456,
|
chat_id: -100123456,
|
||||||
message_id: 91,
|
message_id: 91,
|
||||||
text: expect.stringContaining('✅ purchases')
|
text: expect.stringContaining('✅ Purchases')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1134,7 +1135,7 @@ describe('registerHouseholdSetupCommands', () => {
|
|||||||
method: 'sendMessage',
|
method: 'sendMessage',
|
||||||
payload: {
|
payload: {
|
||||||
chat_id: -100123456,
|
chat_id: -100123456,
|
||||||
text: 'Setup state reset for Kojori House. Run /setup again to bind topics from scratch.'
|
text: 'Setup state reset for Kojori House. Run /setup again to configure topics from scratch.'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
expect(await repository.listHouseholdTopicBindings('household-1')).toEqual([])
|
expect(await repository.listHouseholdTopicBindings('household-1')).toEqual([])
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { resolveReplyLocale } from './bot-locale'
|
|||||||
|
|
||||||
const APPROVE_MEMBER_CALLBACK_PREFIX = 'approve_member:'
|
const APPROVE_MEMBER_CALLBACK_PREFIX = 'approve_member:'
|
||||||
const SETUP_CREATE_TOPIC_CALLBACK_PREFIX = 'setup_topic:create:'
|
const SETUP_CREATE_TOPIC_CALLBACK_PREFIX = 'setup_topic:create:'
|
||||||
const SETUP_BIND_TOPIC_ACTION = 'setup_topic_binding' as const
|
|
||||||
const HOUSEHOLD_TOPIC_ROLE_ORDER: readonly HouseholdTopicRole[] = [
|
const HOUSEHOLD_TOPIC_ROLE_ORDER: readonly HouseholdTopicRole[] = [
|
||||||
'chat',
|
'chat',
|
||||||
'purchase',
|
'purchase',
|
||||||
@@ -39,11 +39,6 @@ function isGroupChat(ctx: Context): ctx is Context & {
|
|||||||
return ctx.chat?.type === 'group' || ctx.chat?.type === 'supergroup'
|
return ctx.chat?.type === 'group' || ctx.chat?.type === 'supergroup'
|
||||||
}
|
}
|
||||||
|
|
||||||
function isTopicMessage(ctx: Context): boolean {
|
|
||||||
const message = ctx.msg
|
|
||||||
return !!message && 'is_topic_message' in message && message.is_topic_message === true
|
|
||||||
}
|
|
||||||
|
|
||||||
async function isGroupAdmin(ctx: Context): Promise<boolean> {
|
async function isGroupAdmin(ctx: Context): Promise<boolean> {
|
||||||
if (!ctx.chat || !ctx.from) {
|
if (!ctx.chat || !ctx.from) {
|
||||||
return false
|
return false
|
||||||
@@ -79,63 +74,6 @@ function unsetupRejectionMessage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindRejectionMessage(
|
|
||||||
locale: BotLocale,
|
|
||||||
reason: 'not_admin' | 'household_not_found' | 'not_topic_message'
|
|
||||||
): string {
|
|
||||||
const t = getBotTranslations(locale).setup
|
|
||||||
switch (reason) {
|
|
||||||
case 'not_admin':
|
|
||||||
return t.onlyTelegramAdminsBindTopics
|
|
||||||
case 'household_not_found':
|
|
||||||
return t.householdNotConfigured
|
|
||||||
case 'not_topic_message':
|
|
||||||
return t.useCommandInTopic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function bindTopicUsageMessage(
|
|
||||||
locale: BotLocale,
|
|
||||||
role: 'chat' | 'purchase' | 'feedback' | 'reminders' | 'payments'
|
|
||||||
): string {
|
|
||||||
const t = getBotTranslations(locale).setup
|
|
||||||
|
|
||||||
switch (role) {
|
|
||||||
case 'chat':
|
|
||||||
return t.useBindChatTopicInGroup
|
|
||||||
case 'purchase':
|
|
||||||
return t.useBindPurchaseTopicInGroup
|
|
||||||
case 'feedback':
|
|
||||||
return t.useBindFeedbackTopicInGroup
|
|
||||||
case 'reminders':
|
|
||||||
return t.useBindRemindersTopicInGroup
|
|
||||||
case 'payments':
|
|
||||||
return t.useBindPaymentsTopicInGroup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function bindTopicSuccessMessage(
|
|
||||||
locale: BotLocale,
|
|
||||||
role: 'chat' | 'purchase' | 'feedback' | 'reminders' | 'payments',
|
|
||||||
householdName: string,
|
|
||||||
threadId: string
|
|
||||||
): string {
|
|
||||||
const t = getBotTranslations(locale).setup
|
|
||||||
|
|
||||||
switch (role) {
|
|
||||||
case 'chat':
|
|
||||||
return t.chatTopicSaved(householdName, threadId)
|
|
||||||
case 'purchase':
|
|
||||||
return t.purchaseTopicSaved(householdName, threadId)
|
|
||||||
case 'feedback':
|
|
||||||
return t.feedbackTopicSaved(householdName, threadId)
|
|
||||||
case 'reminders':
|
|
||||||
return t.remindersTopicSaved(householdName, threadId)
|
|
||||||
case 'payments':
|
|
||||||
return t.paymentsTopicSaved(householdName, threadId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function adminRejectionMessage(
|
function adminRejectionMessage(
|
||||||
locale: BotLocale,
|
locale: BotLocale,
|
||||||
reason: 'not_admin' | 'household_not_found' | 'pending_not_found'
|
reason: 'not_admin' | 'household_not_found' | 'pending_not_found'
|
||||||
@@ -473,63 +411,6 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleBindTopicCommand(
|
|
||||||
ctx: Context,
|
|
||||||
role: 'chat' | 'purchase' | 'feedback' | 'reminders' | 'payments'
|
|
||||||
): Promise<void> {
|
|
||||||
const locale = await resolveReplyLocale({
|
|
||||||
ctx,
|
|
||||||
repository: options.householdConfigurationRepository
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!isGroupChat(ctx)) {
|
|
||||||
await ctx.reply(bindTopicUsageMessage(locale, role))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const actorIsAdmin = await isGroupAdmin(ctx)
|
|
||||||
const telegramThreadId =
|
|
||||||
isTopicMessage(ctx) && ctx.msg && 'message_thread_id' in ctx.msg
|
|
||||||
? ctx.msg.message_thread_id?.toString()
|
|
||||||
: undefined
|
|
||||||
const result = await options.householdSetupService.bindTopic({
|
|
||||||
actorIsAdmin,
|
|
||||||
telegramChatId: ctx.chat.id.toString(),
|
|
||||||
role,
|
|
||||||
...(telegramThreadId
|
|
||||||
? {
|
|
||||||
telegramThreadId
|
|
||||||
}
|
|
||||||
: {})
|
|
||||||
})
|
|
||||||
|
|
||||||
if (result.status === 'rejected') {
|
|
||||||
await ctx.reply(bindRejectionMessage(locale, result.reason))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
options.logger?.info(
|
|
||||||
{
|
|
||||||
event: 'household_setup.topic_bound',
|
|
||||||
role: result.binding.role,
|
|
||||||
telegramChatId: result.household.telegramChatId,
|
|
||||||
telegramThreadId: result.binding.telegramThreadId,
|
|
||||||
householdId: result.household.householdId,
|
|
||||||
actorTelegramUserId: ctx.from?.id?.toString()
|
|
||||||
},
|
|
||||||
'Household topic bound'
|
|
||||||
)
|
|
||||||
|
|
||||||
await ctx.reply(
|
|
||||||
bindTopicSuccessMessage(
|
|
||||||
locale,
|
|
||||||
role,
|
|
||||||
result.household.householdName,
|
|
||||||
result.binding.telegramThreadId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
options.bot.command('start', async (ctx) => {
|
options.bot.command('start', async (ctx) => {
|
||||||
const fallbackLocale = await resolveReplyLocale({
|
const fallbackLocale = await resolveReplyLocale({
|
||||||
ctx,
|
ctx,
|
||||||
@@ -714,7 +595,7 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
if (result.status === 'noop') {
|
if (result.status === 'noop') {
|
||||||
await options.promptRepository?.clearPendingActionsForChat(
|
await options.promptRepository?.clearPendingActionsForChat(
|
||||||
telegramChatId,
|
telegramChatId,
|
||||||
SETUP_BIND_TOPIC_ACTION
|
'setup_topic_binding'
|
||||||
)
|
)
|
||||||
await ctx.reply(t.setup.unsetupNoop)
|
await ctx.reply(t.setup.unsetupNoop)
|
||||||
return
|
return
|
||||||
@@ -722,7 +603,7 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
|
|
||||||
await options.promptRepository?.clearPendingActionsForChat(
|
await options.promptRepository?.clearPendingActionsForChat(
|
||||||
telegramChatId,
|
telegramChatId,
|
||||||
SETUP_BIND_TOPIC_ACTION
|
'setup_topic_binding'
|
||||||
)
|
)
|
||||||
|
|
||||||
options.logger?.info(
|
options.logger?.info(
|
||||||
@@ -738,103 +619,6 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
await ctx.reply(t.setup.unsetupComplete(result.household.householdName))
|
await ctx.reply(t.setup.unsetupComplete(result.household.householdName))
|
||||||
})
|
})
|
||||||
|
|
||||||
options.bot.command('bind_chat_topic', async (ctx) => {
|
|
||||||
await handleBindTopicCommand(ctx, 'chat')
|
|
||||||
})
|
|
||||||
|
|
||||||
options.bot.command('bind_purchase_topic', async (ctx) => {
|
|
||||||
await handleBindTopicCommand(ctx, 'purchase')
|
|
||||||
})
|
|
||||||
|
|
||||||
options.bot.command('bind_feedback_topic', async (ctx) => {
|
|
||||||
await handleBindTopicCommand(ctx, 'feedback')
|
|
||||||
})
|
|
||||||
|
|
||||||
options.bot.command('bind_reminders_topic', async (ctx) => {
|
|
||||||
await handleBindTopicCommand(ctx, 'reminders')
|
|
||||||
})
|
|
||||||
|
|
||||||
options.bot.command('bind_payments_topic', async (ctx) => {
|
|
||||||
await handleBindTopicCommand(ctx, 'payments')
|
|
||||||
})
|
|
||||||
|
|
||||||
options.bot.command('bind', async (ctx) => {
|
|
||||||
const locale = await resolveReplyLocale({
|
|
||||||
ctx,
|
|
||||||
repository: options.householdConfigurationRepository
|
|
||||||
})
|
|
||||||
const t = getBotTranslations(locale)
|
|
||||||
|
|
||||||
if (!isGroupChat(ctx)) {
|
|
||||||
await ctx.reply(t.setup.useBindInTopic)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options.householdConfigurationRepository) {
|
|
||||||
await ctx.reply(t.setup.householdNotConfigured)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const household = await options.householdConfigurationRepository.getTelegramHouseholdChat(
|
|
||||||
ctx.chat.id.toString()
|
|
||||||
)
|
|
||||||
if (!household) {
|
|
||||||
await ctx.reply(t.setup.householdNotConfigured)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(await isGroupAdmin(ctx))) {
|
|
||||||
await ctx.reply(t.setup.onlyTelegramAdminsBindTopics)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const telegramThreadId =
|
|
||||||
ctx.msg && 'message_thread_id' in ctx.msg ? ctx.msg.message_thread_id?.toString() : null
|
|
||||||
|
|
||||||
// If not in a topic, show error
|
|
||||||
if (!telegramThreadId) {
|
|
||||||
await ctx.reply(t.setup.useBindInTopic)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this topic is already bound
|
|
||||||
const existingBinding =
|
|
||||||
await options.householdConfigurationRepository.findHouseholdTopicByTelegramContext({
|
|
||||||
telegramChatId: ctx.chat.id.toString(),
|
|
||||||
telegramThreadId
|
|
||||||
})
|
|
||||||
|
|
||||||
if (existingBinding) {
|
|
||||||
const roleLabel = setupTopicRoleLabel(locale, existingBinding.role)
|
|
||||||
await ctx.reply(t.setup.topicAlreadyBound(roleLabel))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all existing bindings to show which roles are available
|
|
||||||
const bindings = await options.householdConfigurationRepository.listHouseholdTopicBindings(
|
|
||||||
household.householdId
|
|
||||||
)
|
|
||||||
const boundRoles = new Set(bindings.map((b) => b.role))
|
|
||||||
const availableRoles = HOUSEHOLD_TOPIC_ROLE_ORDER.filter((role) => !boundRoles.has(role))
|
|
||||||
|
|
||||||
if (availableRoles.length === 0) {
|
|
||||||
await ctx.reply(t.setup.allRolesConfigured)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show role selection buttons
|
|
||||||
await ctx.reply(t.setup.bindSelectRole, {
|
|
||||||
reply_markup: {
|
|
||||||
inline_keyboard: availableRoles.map((role) => [
|
|
||||||
{
|
|
||||||
text: setupTopicRoleLabel(locale, role),
|
|
||||||
callback_data: `bind_topic:${role}:${telegramThreadId}`
|
|
||||||
}
|
|
||||||
])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
options.bot.command('pending_members', async (ctx) => {
|
options.bot.command('pending_members', async (ctx) => {
|
||||||
const locale = await resolveReplyLocale({
|
const locale = await resolveReplyLocale({
|
||||||
ctx,
|
ctx,
|
||||||
@@ -974,6 +758,67 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
options.bot.command('bind', async (ctx) => {
|
||||||
|
const locale = await resolveReplyLocale({
|
||||||
|
ctx,
|
||||||
|
repository: options.householdConfigurationRepository
|
||||||
|
})
|
||||||
|
const t = getBotTranslations(locale)
|
||||||
|
|
||||||
|
if (!isGroupChat(ctx)) {
|
||||||
|
await ctx.reply(t.setup.useSetupInGroup)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx.message?.message_thread_id) {
|
||||||
|
await ctx.reply(t.setup.useCommandInTopic)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const actorIsAdmin = await isGroupAdmin(ctx)
|
||||||
|
if (!actorIsAdmin) {
|
||||||
|
await ctx.reply(t.setup.onlyTelegramAdminsBindTopics)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const telegramChatId = ctx.chat.id.toString()
|
||||||
|
const household = options.householdConfigurationRepository
|
||||||
|
? await options.householdConfigurationRepository.getTelegramHouseholdChat(telegramChatId)
|
||||||
|
: null
|
||||||
|
|
||||||
|
if (!household) {
|
||||||
|
await ctx.reply(t.setup.householdNotConfigured)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const bindings = options.householdConfigurationRepository
|
||||||
|
? await options.householdConfigurationRepository.listHouseholdTopicBindings(
|
||||||
|
household.householdId
|
||||||
|
)
|
||||||
|
: []
|
||||||
|
|
||||||
|
const configuredRoles = new Set(bindings.map((b) => b.role))
|
||||||
|
const availableRoles = HOUSEHOLD_TOPIC_ROLE_ORDER.filter((role) => !configuredRoles.has(role))
|
||||||
|
|
||||||
|
if (availableRoles.length === 0) {
|
||||||
|
await ctx.reply(t.setup.allRolesConfigured)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = availableRoles.map((role) => [
|
||||||
|
{
|
||||||
|
text: setupTopicRoleLabel(locale, role),
|
||||||
|
callback_data: `bind_topic:${role}:${ctx.message!.message_thread_id}`
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
await ctx.reply(t.setup.bindSelectRole, {
|
||||||
|
reply_markup: {
|
||||||
|
inline_keyboard: rows
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
options.bot.callbackQuery(
|
options.bot.callbackQuery(
|
||||||
new RegExp(`^${APPROVE_MEMBER_CALLBACK_PREFIX}(\\d+)$`),
|
new RegExp(`^${APPROVE_MEMBER_CALLBACK_PREFIX}(\\d+)$`),
|
||||||
async (ctx) => {
|
async (ctx) => {
|
||||||
@@ -1095,7 +940,10 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
|
|
||||||
if (result.status === 'rejected') {
|
if (result.status === 'rejected') {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx.answerCallbackQuery({
|
||||||
text: bindRejectionMessage(locale, result.reason),
|
text:
|
||||||
|
result.reason === 'not_admin'
|
||||||
|
? t.onlyTelegramAdminsBindTopics
|
||||||
|
: t.householdNotConfigured,
|
||||||
show_alert: true
|
show_alert: true
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -1133,9 +981,8 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bind topic callback from /bind command
|
|
||||||
options.bot.callbackQuery(
|
options.bot.callbackQuery(
|
||||||
new RegExp(`^bind_topic:(chat|purchase|feedback|reminders|payments):(\\d+)$`),
|
/^bind_topic:(chat|purchase|feedback|reminders|payments):(\d+)$/,
|
||||||
async (ctx) => {
|
async (ctx) => {
|
||||||
const locale = await resolveReplyLocale({
|
const locale = await resolveReplyLocale({
|
||||||
ctx,
|
ctx,
|
||||||
@@ -1151,7 +998,11 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const role = ctx.match[1] as HouseholdTopicRole
|
||||||
|
const telegramThreadId = ctx.match[2]!
|
||||||
|
const telegramChatId = ctx.chat.id.toString()
|
||||||
const actorIsAdmin = await isGroupAdmin(ctx)
|
const actorIsAdmin = await isGroupAdmin(ctx)
|
||||||
|
|
||||||
if (!actorIsAdmin) {
|
if (!actorIsAdmin) {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx.answerCallbackQuery({
|
||||||
text: t.onlyTelegramAdminsBindTopics,
|
text: t.onlyTelegramAdminsBindTopics,
|
||||||
@@ -1160,19 +1011,19 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const role = ctx.match[1] as HouseholdTopicRole
|
|
||||||
const telegramThreadId = ctx.match[2]!
|
|
||||||
|
|
||||||
const result = await options.householdSetupService.bindTopic({
|
const result = await options.householdSetupService.bindTopic({
|
||||||
actorIsAdmin,
|
actorIsAdmin,
|
||||||
telegramChatId: ctx.chat.id.toString(),
|
telegramChatId,
|
||||||
telegramThreadId,
|
telegramThreadId,
|
||||||
role
|
role
|
||||||
})
|
})
|
||||||
|
|
||||||
if (result.status === 'rejected') {
|
if (result.status === 'rejected') {
|
||||||
await ctx.answerCallbackQuery({
|
await ctx.answerCallbackQuery({
|
||||||
text: bindRejectionMessage(locale, result.reason),
|
text:
|
||||||
|
result.reason === 'not_admin'
|
||||||
|
? t.onlyTelegramAdminsBindTopics
|
||||||
|
: t.householdNotConfigured,
|
||||||
show_alert: true
|
show_alert: true
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -1185,10 +1036,11 @@ export function registerHouseholdSetupCommands(options: {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Edit the role selection message to show success
|
if (ctx.msg) {
|
||||||
await ctx.editMessageText(
|
await ctx.editMessageText(
|
||||||
t.topicBoundSuccess(setupTopicRoleLabel(locale, role), result.household.householdName)
|
t.topicBoundSuccess(setupTopicRoleLabel(locale, role), result.household.householdName)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,7 @@ export const enBotTranslations: BotTranslationCatalog = {
|
|||||||
cancel: 'Cancel the current prompt',
|
cancel: 'Cancel the current prompt',
|
||||||
setup: 'Register this group as a household',
|
setup: 'Register this group as a household',
|
||||||
unsetup: 'Reset topic setup for this group',
|
unsetup: 'Reset topic setup for this group',
|
||||||
bind_chat_topic: 'Bind the current topic for casual conversation',
|
bind: 'Bind current topic to a specific role',
|
||||||
bind_purchase_topic: 'Bind the current topic as purchases',
|
|
||||||
bind_feedback_topic: 'Bind the current topic as feedback',
|
|
||||||
bind_reminders_topic: 'Bind the current topic as reminders',
|
|
||||||
bind_payments_topic: 'Bind the current topic as payments',
|
|
||||||
bind: 'Bind current topic to a household role',
|
|
||||||
join_link: 'Get a shareable link for new members to join',
|
join_link: 'Get a shareable link for new members to join',
|
||||||
payment_add: 'Record your rent or utilities payment',
|
payment_add: 'Record your rent or utilities payment',
|
||||||
pending_members: 'List pending household join requests',
|
pending_members: 'List pending household join requests',
|
||||||
@@ -56,12 +51,19 @@ export const enBotTranslations: BotTranslationCatalog = {
|
|||||||
joinRequestSent: (householdName) =>
|
joinRequestSent: (householdName) =>
|
||||||
`Join request sent for ${householdName}. Wait for a household admin to confirm you.`,
|
`Join request sent for ${householdName}. Wait for a household admin to confirm you.`,
|
||||||
setupSummary: ({ householdName, created }) =>
|
setupSummary: ({ householdName, created }) =>
|
||||||
`${created ? '✅' : 'ℹ️'} ${householdName} is ${created ? 'ready' : 'already registered'}!`,
|
`${created ? '✨' : 'ℹ️'} Welcome! ${householdName} is ${created ? 'successfully registered' : 'already active'} and ready to help.`,
|
||||||
setupTopicsHeading: (configured, total) => `Topics: ${configured}/${total} configured`,
|
setupTopicsHeading: (configured, total) =>
|
||||||
|
`Let's configure your household topics to get started (${configured}/${total}):`,
|
||||||
setupTopicBound: (role) => `✅ ${role}`,
|
setupTopicBound: (role) => `✅ ${role}`,
|
||||||
setupTopicMissing: (role) => `⚪ ${role}`,
|
setupTopicMissing: (role) => `⚪ ${role}`,
|
||||||
setupTopicCreateButton: (role) => `+ ${role}`,
|
setupTopicCreateButton: (role) => `Setup ${role}`,
|
||||||
setupTopicBindButton: (role) => `Bind ${role}`,
|
setupTopicBindButton: (role) => `Bind ${role}`,
|
||||||
|
useBindInTopic: 'Run /bind inside a topic to link it to a role.',
|
||||||
|
topicAlreadyBound: (role) => `This topic is already linked to ${role}.`,
|
||||||
|
bindSelectRole: 'Link this topic to:',
|
||||||
|
topicBoundSuccess: (role, householdName) =>
|
||||||
|
`Successfully linked as ${role} for ${householdName}.`,
|
||||||
|
allRolesConfigured: 'All topic roles are already configured.',
|
||||||
setupTopicCreateFailed:
|
setupTopicCreateFailed:
|
||||||
'I could not create that topic. Check bot admin permissions and forum settings.',
|
'I could not create that topic. Check bot admin permissions and forum settings.',
|
||||||
setupTopicCreateForbidden:
|
setupTopicCreateForbidden:
|
||||||
@@ -73,15 +75,15 @@ export const enBotTranslations: BotTranslationCatalog = {
|
|||||||
setupTopicBindRoleName: (role) => {
|
setupTopicBindRoleName: (role) => {
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case 'chat':
|
case 'chat':
|
||||||
return 'chat'
|
return 'Discussions'
|
||||||
case 'purchase':
|
case 'purchase':
|
||||||
return 'purchases'
|
return 'Purchases'
|
||||||
case 'feedback':
|
case 'feedback':
|
||||||
return 'feedback'
|
return 'Feedback'
|
||||||
case 'reminders':
|
case 'reminders':
|
||||||
return 'reminders'
|
return 'Reminders'
|
||||||
case 'payments':
|
case 'payments':
|
||||||
return 'payments'
|
return 'Payments'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setupTopicSuggestedName: (role) => {
|
setupTopicSuggestedName: (role) => {
|
||||||
@@ -101,23 +103,8 @@ export const enBotTranslations: BotTranslationCatalog = {
|
|||||||
onlyTelegramAdminsUnsetup: 'Only Telegram group admins can run /unsetup.',
|
onlyTelegramAdminsUnsetup: 'Only Telegram group admins can run /unsetup.',
|
||||||
useUnsetupInGroup: 'Use /unsetup inside the household group.',
|
useUnsetupInGroup: 'Use /unsetup inside the household group.',
|
||||||
unsetupComplete: (householdName) =>
|
unsetupComplete: (householdName) =>
|
||||||
`Setup state reset for ${householdName}. Run /setup again to bind topics from scratch.`,
|
`Setup state reset for ${householdName}. Run /setup again to configure topics from scratch.`,
|
||||||
unsetupNoop: 'Nothing to reset for this group yet. Run /setup when you are ready.',
|
unsetupNoop: 'Nothing to reset for this group yet. Run /setup when you are ready.',
|
||||||
useBindChatTopicInGroup: 'Use /bind_chat_topic inside the household group topic.',
|
|
||||||
chatTopicSaved: (householdName, threadId) =>
|
|
||||||
`Chat topic saved for ${householdName} (thread ${threadId}).`,
|
|
||||||
useBindPurchaseTopicInGroup: 'Use /bind_purchase_topic inside the household group topic.',
|
|
||||||
purchaseTopicSaved: (householdName, threadId) =>
|
|
||||||
`Purchase topic saved for ${householdName} (thread ${threadId}).`,
|
|
||||||
useBindFeedbackTopicInGroup: 'Use /bind_feedback_topic inside the household group topic.',
|
|
||||||
feedbackTopicSaved: (householdName, threadId) =>
|
|
||||||
`Feedback topic saved for ${householdName} (thread ${threadId}).`,
|
|
||||||
useBindRemindersTopicInGroup: 'Use /bind_reminders_topic inside the household group topic.',
|
|
||||||
remindersTopicSaved: (householdName, threadId) =>
|
|
||||||
`Reminders topic saved for ${householdName} (thread ${threadId}).`,
|
|
||||||
useBindPaymentsTopicInGroup: 'Use /bind_payments_topic inside the household group topic.',
|
|
||||||
paymentsTopicSaved: (householdName, threadId) =>
|
|
||||||
`Payments topic saved for ${householdName} (thread ${threadId}).`,
|
|
||||||
usePendingMembersInGroup: 'Use /pending_members inside the household group.',
|
usePendingMembersInGroup: 'Use /pending_members inside the household group.',
|
||||||
useApproveMemberInGroup: 'Use /approve_member inside the household group.',
|
useApproveMemberInGroup: 'Use /approve_member inside the household group.',
|
||||||
approveMemberUsage: 'Usage: /approve_member <telegram_user_id>',
|
approveMemberUsage: 'Usage: /approve_member <telegram_user_id>',
|
||||||
@@ -130,12 +117,7 @@ export const enBotTranslations: BotTranslationCatalog = {
|
|||||||
useJoinLinkInGroup: 'Use /join_link inside the household group.',
|
useJoinLinkInGroup: 'Use /join_link inside the household group.',
|
||||||
joinLinkUnavailable: 'Could not generate join link.',
|
joinLinkUnavailable: 'Could not generate join link.',
|
||||||
joinLinkReady: (link, householdName) =>
|
joinLinkReady: (link, householdName) =>
|
||||||
`Join link for ${householdName}:\n${link}\n\nAnyone with this link can join the household. Share it carefully.`,
|
`Join link for ${householdName}:\n${link}\n\nAnyone with this link can join the household. Share it carefully.`
|
||||||
useBindInTopic: 'Use /bind inside a topic to bind it to a role.',
|
|
||||||
topicAlreadyBound: (role) => `This topic is already bound as ${role}.`,
|
|
||||||
bindSelectRole: 'Bind this topic as:',
|
|
||||||
topicBoundSuccess: (role, householdName) => `Bound as ${role} for ${householdName}.`,
|
|
||||||
allRolesConfigured: 'All topic roles are already configured.'
|
|
||||||
},
|
},
|
||||||
anonymousFeedback: {
|
anonymousFeedback: {
|
||||||
title: 'Anonymous household note',
|
title: 'Anonymous household note',
|
||||||
@@ -147,7 +129,7 @@ export const enBotTranslations: BotTranslationCatalog = {
|
|||||||
multipleHouseholds:
|
multipleHouseholds:
|
||||||
'You belong to multiple households. Open the target household from its group until household selection is added.',
|
'You belong to multiple households. Open the target household from its group until household selection is added.',
|
||||||
feedbackTopicMissing:
|
feedbackTopicMissing:
|
||||||
'Anonymous feedback is not configured for your household yet. Ask an admin to run /bind_feedback_topic.',
|
'Anonymous feedback is not configured for your household yet. Ask an admin to run /setup and create a feedback topic.',
|
||||||
duplicate: 'This anonymous feedback message was already processed.',
|
duplicate: 'This anonymous feedback message was already processed.',
|
||||||
delivered: 'Anonymous feedback delivered.',
|
delivered: 'Anonymous feedback delivered.',
|
||||||
savedButPostFailed: 'Anonymous feedback was saved, but posting failed. Try again later.',
|
savedButPostFailed: 'Anonymous feedback was saved, but posting failed. Try again later.',
|
||||||
@@ -325,7 +307,7 @@ export const enBotTranslations: BotTranslationCatalog = {
|
|||||||
},
|
},
|
||||||
payments: {
|
payments: {
|
||||||
topicMissing:
|
topicMissing:
|
||||||
'Payments topic is not configured for this household yet. Ask an admin to run /bind_payments_topic.',
|
'Payments topic is not configured for this household yet. Ask an admin to run /setup and create a payments topic.',
|
||||||
balanceReply: (kind) =>
|
balanceReply: (kind) =>
|
||||||
kind === 'rent' ? 'Current rent payment guidance:' : 'Current utilities payment guidance:',
|
kind === 'rent' ? 'Current rent payment guidance:' : 'Current utilities payment guidance:',
|
||||||
proposal: (kind, amount, currency) =>
|
proposal: (kind, amount, currency) =>
|
||||||
|
|||||||
@@ -9,12 +9,7 @@ export const ruBotTranslations: BotTranslationCatalog = {
|
|||||||
cancel: 'Отменить текущий ввод',
|
cancel: 'Отменить текущий ввод',
|
||||||
setup: 'Подключить эту группу как дом',
|
setup: 'Подключить эту группу как дом',
|
||||||
unsetup: 'Сбросить настройку топиков для этой группы',
|
unsetup: 'Сбросить настройку топиков для этой группы',
|
||||||
bind_chat_topic: 'Назначить текущий топик для разговоров',
|
bind: 'Привязать текущий топик к конкретной роли',
|
||||||
bind_purchase_topic: 'Назначить текущий топик для покупок',
|
|
||||||
bind_feedback_topic: 'Назначить текущий топик для анонимных сообщений',
|
|
||||||
bind_reminders_topic: 'Назначить текущий топик для напоминаний',
|
|
||||||
bind_payments_topic: 'Назначить текущий топик для оплат',
|
|
||||||
bind: 'Привязать текущий топик к роли дома',
|
|
||||||
join_link: 'Получить ссылку для приглашения новых участников',
|
join_link: 'Получить ссылку для приглашения новых участников',
|
||||||
payment_add: 'Подтвердить оплату аренды или коммуналки',
|
payment_add: 'Подтвердить оплату аренды или коммуналки',
|
||||||
pending_members: 'Показать ожидающие заявки на вступление',
|
pending_members: 'Показать ожидающие заявки на вступление',
|
||||||
@@ -58,12 +53,19 @@ export const ruBotTranslations: BotTranslationCatalog = {
|
|||||||
joinRequestSent: (householdName) =>
|
joinRequestSent: (householdName) =>
|
||||||
`Заявка на вступление в ${householdName} отправлена. Дождитесь подтверждения от админа дома.`,
|
`Заявка на вступление в ${householdName} отправлена. Дождитесь подтверждения от админа дома.`,
|
||||||
setupSummary: ({ householdName, created }) =>
|
setupSummary: ({ householdName, created }) =>
|
||||||
`${created ? '✅' : 'ℹ️'} ${householdName} ${created ? 'готов' : 'уже подключён'}!`,
|
`${created ? '✨' : 'ℹ️'} Добро пожаловать! Дом ${householdName} ${created ? 'успешно зарегистрирован' : 'уже активен'} и готов к работе.`,
|
||||||
setupTopicsHeading: (configured, total) => `Топики: ${configured}/${total} настроено`,
|
setupTopicsHeading: (configured, total) =>
|
||||||
|
`Давайте настроим топики для вашего дома (${configured}/${total}):`,
|
||||||
setupTopicBound: (role) => `✅ ${role}`,
|
setupTopicBound: (role) => `✅ ${role}`,
|
||||||
setupTopicMissing: (role) => `⚪ ${role}`,
|
setupTopicMissing: (role) => `⚪ ${role}`,
|
||||||
setupTopicCreateButton: (role) => `+ ${role}`,
|
setupTopicCreateButton: (role) => `Настроить ${role}`,
|
||||||
setupTopicBindButton: (role) => `Привязать ${role}`,
|
setupTopicBindButton: (role) => `Привязать ${role}`,
|
||||||
|
useBindInTopic: 'Используйте /bind внутри топика, чтобы привязать его к роли.',
|
||||||
|
topicAlreadyBound: (role) => `Этот топик уже привязан к роли «${role}».`,
|
||||||
|
bindSelectRole: 'Привязать этот топик к:',
|
||||||
|
topicBoundSuccess: (role, householdName) =>
|
||||||
|
`Топик успешно привязан как «${role}» для ${householdName}.`,
|
||||||
|
allRolesConfigured: 'Все роли топиков уже настроены.',
|
||||||
setupTopicCreateFailed:
|
setupTopicCreateFailed:
|
||||||
'Не удалось создать этот топик. Проверьте права бота и включённые форум-топики в группе.',
|
'Не удалось создать этот топик. Проверьте права бота и включённые форум-топики в группе.',
|
||||||
setupTopicCreateForbidden:
|
setupTopicCreateForbidden:
|
||||||
@@ -75,15 +77,15 @@ export const ruBotTranslations: BotTranslationCatalog = {
|
|||||||
setupTopicBindRoleName: (role) => {
|
setupTopicBindRoleName: (role) => {
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case 'chat':
|
case 'chat':
|
||||||
return 'разговоров'
|
return 'Общение'
|
||||||
case 'purchase':
|
case 'purchase':
|
||||||
return 'покупки'
|
return 'Покупки'
|
||||||
case 'feedback':
|
case 'feedback':
|
||||||
return 'обратной связи'
|
return 'Фидбек'
|
||||||
case 'reminders':
|
case 'reminders':
|
||||||
return 'напоминаний'
|
return 'Напоминания'
|
||||||
case 'payments':
|
case 'payments':
|
||||||
return 'оплат'
|
return 'Оплаты'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setupTopicSuggestedName: (role) => {
|
setupTopicSuggestedName: (role) => {
|
||||||
@@ -103,23 +105,8 @@ export const ruBotTranslations: BotTranslationCatalog = {
|
|||||||
onlyTelegramAdminsUnsetup: 'Только админы Telegram-группы могут запускать /unsetup.',
|
onlyTelegramAdminsUnsetup: 'Только админы Telegram-группы могут запускать /unsetup.',
|
||||||
useUnsetupInGroup: 'Используйте /unsetup внутри группы дома.',
|
useUnsetupInGroup: 'Используйте /unsetup внутри группы дома.',
|
||||||
unsetupComplete: (householdName) =>
|
unsetupComplete: (householdName) =>
|
||||||
`Состояние настройки для ${householdName} сброшено. Запустите /setup ещё раз, чтобы заново привязать топики.`,
|
`Состояние настройки для ${householdName} сброшено. Запустите /setup ещё раз, чтобы заново настроить топики.`,
|
||||||
unsetupNoop: 'Для этой группы пока нечего сбрасывать. Когда будете готовы, запустите /setup.',
|
unsetupNoop: 'Для этой группы пока нечего сбрасывать. Когда будете готовы, запустите /setup.',
|
||||||
useBindChatTopicInGroup: 'Используйте /bind_chat_topic внутри топика группы дома.',
|
|
||||||
chatTopicSaved: (householdName, threadId) =>
|
|
||||||
`Топик для разговоров сохранён для ${householdName} (тред ${threadId}).`,
|
|
||||||
useBindPurchaseTopicInGroup: 'Используйте /bind_purchase_topic внутри топика группы дома.',
|
|
||||||
purchaseTopicSaved: (householdName, threadId) =>
|
|
||||||
`Топик покупок сохранён для ${householdName} (тред ${threadId}).`,
|
|
||||||
useBindFeedbackTopicInGroup: 'Используйте /bind_feedback_topic внутри топика группы дома.',
|
|
||||||
feedbackTopicSaved: (householdName, threadId) =>
|
|
||||||
`Топик обратной связи сохранён для ${householdName} (тред ${threadId}).`,
|
|
||||||
useBindRemindersTopicInGroup: 'Используйте /bind_reminders_topic внутри топика группы дома.',
|
|
||||||
remindersTopicSaved: (householdName, threadId) =>
|
|
||||||
`Топик напоминаний сохранён для ${householdName} (тред ${threadId}).`,
|
|
||||||
useBindPaymentsTopicInGroup: 'Используйте /bind_payments_topic внутри топика группы дома.',
|
|
||||||
paymentsTopicSaved: (householdName, threadId) =>
|
|
||||||
`Топик оплат сохранён для ${householdName} (тред ${threadId}).`,
|
|
||||||
usePendingMembersInGroup: 'Используйте /pending_members внутри группы дома.',
|
usePendingMembersInGroup: 'Используйте /pending_members внутри группы дома.',
|
||||||
useApproveMemberInGroup: 'Используйте /approve_member внутри группы дома.',
|
useApproveMemberInGroup: 'Используйте /approve_member внутри группы дома.',
|
||||||
approveMemberUsage: 'Использование: /approve_member <telegram_user_id>',
|
approveMemberUsage: 'Использование: /approve_member <telegram_user_id>',
|
||||||
@@ -132,12 +119,7 @@ export const ruBotTranslations: BotTranslationCatalog = {
|
|||||||
useJoinLinkInGroup: 'Используйте /join_link внутри группы дома.',
|
useJoinLinkInGroup: 'Используйте /join_link внутри группы дома.',
|
||||||
joinLinkUnavailable: 'Не удалось сгенерировать ссылку для вступления.',
|
joinLinkUnavailable: 'Не удалось сгенерировать ссылку для вступления.',
|
||||||
joinLinkReady: (link, householdName) =>
|
joinLinkReady: (link, householdName) =>
|
||||||
`Поделитесь этой ссылкой, чтобы пригласить участников в ${householdName}:\n\n${link}\n\nЛюбой, у кого есть эта ссылка, может подать заявку на вступление.`,
|
`Поделитесь этой ссылкой, чтобы пригласить участников в ${householdName}:\n\n${link}\n\nЛюбой, у кого есть эта ссылка, может подать заявку на вступление.`
|
||||||
useBindInTopic: 'Используйте /bind внутри топика, чтобы привязать его к роли.',
|
|
||||||
topicAlreadyBound: (role) => `Этот топик уже привязан как ${role}.`,
|
|
||||||
bindSelectRole: 'Привязать этот топик как:',
|
|
||||||
topicBoundSuccess: (role, householdName) => `Привязан как ${role} для ${householdName}.`,
|
|
||||||
allRolesConfigured: 'Все роли топиков уже настроены.'
|
|
||||||
},
|
},
|
||||||
anonymousFeedback: {
|
anonymousFeedback: {
|
||||||
title: 'Анонимное сообщение по дому',
|
title: 'Анонимное сообщение по дому',
|
||||||
@@ -149,7 +131,7 @@ export const ruBotTranslations: BotTranslationCatalog = {
|
|||||||
multipleHouseholds:
|
multipleHouseholds:
|
||||||
'Вы состоите в нескольких домах. Откройте нужный дом из его группы, пока выбор дома ещё не добавлен.',
|
'Вы состоите в нескольких домах. Откройте нужный дом из его группы, пока выбор дома ещё не добавлен.',
|
||||||
feedbackTopicMissing:
|
feedbackTopicMissing:
|
||||||
'Для вашего дома ещё не настроен анонимный топик. Попросите админа выполнить /bind_feedback_topic.',
|
'Для вашего дома ещё не настроен анонимный топик. Попросите админа выполнить /setup и создать топик для обратной связи.',
|
||||||
duplicate: 'Это анонимное сообщение уже было обработано.',
|
duplicate: 'Это анонимное сообщение уже было обработано.',
|
||||||
delivered: 'Анонимное сообщение отправлено.',
|
delivered: 'Анонимное сообщение отправлено.',
|
||||||
savedButPostFailed:
|
savedButPostFailed:
|
||||||
@@ -329,7 +311,7 @@ export const ruBotTranslations: BotTranslationCatalog = {
|
|||||||
},
|
},
|
||||||
payments: {
|
payments: {
|
||||||
topicMissing:
|
topicMissing:
|
||||||
'Для этого дома ещё не настроен топик оплат. Попросите админа выполнить /bind_payments_topic.',
|
'Для этого дома ещё не настроен топик оплат. Попросите админа выполнить /setup и создать топик для оплат.',
|
||||||
balanceReply: (kind) =>
|
balanceReply: (kind) =>
|
||||||
kind === 'rent' ? 'Текущая сводка по аренде:' : 'Текущая сводка по коммуналке:',
|
kind === 'rent' ? 'Текущая сводка по аренде:' : 'Текущая сводка по коммуналке:',
|
||||||
proposal: (kind, amount, currency) =>
|
proposal: (kind, amount, currency) =>
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ export type TelegramCommandName =
|
|||||||
| 'setup'
|
| 'setup'
|
||||||
| 'unsetup'
|
| 'unsetup'
|
||||||
| 'bind'
|
| 'bind'
|
||||||
| 'bind_chat_topic'
|
|
||||||
| 'bind_purchase_topic'
|
|
||||||
| 'bind_feedback_topic'
|
|
||||||
| 'bind_reminders_topic'
|
|
||||||
| 'bind_payments_topic'
|
|
||||||
| 'join_link'
|
| 'join_link'
|
||||||
| 'payment_add'
|
| 'payment_add'
|
||||||
| 'pending_members'
|
| 'pending_members'
|
||||||
@@ -25,11 +20,6 @@ export interface BotCommandDescriptions {
|
|||||||
cancel: string
|
cancel: string
|
||||||
setup: string
|
setup: string
|
||||||
unsetup: string
|
unsetup: string
|
||||||
bind_chat_topic: string
|
|
||||||
bind_purchase_topic: string
|
|
||||||
bind_feedback_topic: string
|
|
||||||
bind_reminders_topic: string
|
|
||||||
bind_payments_topic: string
|
|
||||||
bind: string
|
bind: string
|
||||||
join_link: string
|
join_link: string
|
||||||
payment_add: string
|
payment_add: string
|
||||||
@@ -100,16 +90,11 @@ export interface BotTranslationCatalog {
|
|||||||
useUnsetupInGroup: string
|
useUnsetupInGroup: string
|
||||||
unsetupComplete: (householdName: string) => string
|
unsetupComplete: (householdName: string) => string
|
||||||
unsetupNoop: string
|
unsetupNoop: string
|
||||||
useBindChatTopicInGroup: string
|
useBindInTopic: string
|
||||||
chatTopicSaved: (householdName: string, threadId: string) => string
|
topicAlreadyBound: (role: string) => string
|
||||||
useBindPurchaseTopicInGroup: string
|
bindSelectRole: string
|
||||||
purchaseTopicSaved: (householdName: string, threadId: string) => string
|
topicBoundSuccess: (role: string, householdName: string) => string
|
||||||
useBindFeedbackTopicInGroup: string
|
allRolesConfigured: string
|
||||||
feedbackTopicSaved: (householdName: string, threadId: string) => string
|
|
||||||
useBindRemindersTopicInGroup: string
|
|
||||||
remindersTopicSaved: (householdName: string, threadId: string) => string
|
|
||||||
useBindPaymentsTopicInGroup: string
|
|
||||||
paymentsTopicSaved: (householdName: string, threadId: string) => string
|
|
||||||
usePendingMembersInGroup: string
|
usePendingMembersInGroup: string
|
||||||
useApproveMemberInGroup: string
|
useApproveMemberInGroup: string
|
||||||
approveMemberUsage: string
|
approveMemberUsage: string
|
||||||
@@ -121,11 +106,6 @@ export interface BotTranslationCatalog {
|
|||||||
useJoinLinkInGroup: string
|
useJoinLinkInGroup: string
|
||||||
joinLinkUnavailable: string
|
joinLinkUnavailable: string
|
||||||
joinLinkReady: (link: string, householdName: string) => string
|
joinLinkReady: (link: string, householdName: string) => string
|
||||||
useBindInTopic: string
|
|
||||||
topicAlreadyBound: (role: string) => string
|
|
||||||
bindSelectRole: string
|
|
||||||
topicBoundSuccess: (role: string, householdName: string) => string
|
|
||||||
allRolesConfigured: string
|
|
||||||
}
|
}
|
||||||
anonymousFeedback: {
|
anonymousFeedback: {
|
||||||
title: string
|
title: string
|
||||||
|
|||||||
@@ -36,11 +36,6 @@ const GROUP_ADMIN_COMMAND_NAMES = [
|
|||||||
'setup',
|
'setup',
|
||||||
'unsetup',
|
'unsetup',
|
||||||
'bind',
|
'bind',
|
||||||
'bind_chat_topic',
|
|
||||||
'bind_purchase_topic',
|
|
||||||
'bind_feedback_topic',
|
|
||||||
'bind_reminders_topic',
|
|
||||||
'bind_payments_topic',
|
|
||||||
'join_link',
|
'join_link',
|
||||||
'pending_members',
|
'pending_members',
|
||||||
'approve_member'
|
'approve_member'
|
||||||
|
|||||||
Reference in New Issue
Block a user