From 490b710c611d85b8e3b1e94565363e17e67e74ab Mon Sep 17 00:00:00 2001 From: Hampus Date: Sat, 15 Aug 2026 23:11:45 +0200 Subject: [PATCH] feat(api): allow bots to search messages within a single community (#1660) --- .../api/guild/services/GuildSearchService.ts | 97 +++++++++---------- fluxer_api/src/api/openapi/openapi.json | 2 +- .../src/api/search/GlobalSearchService.ts | 19 +--- .../search/controllers/SearchController.ts | 14 ++- fluxer_api/src/api/utils/ConcurrencyUtils.ts | 19 ++++ .../constants/src/ValidationErrorCodes.ts | 1 + packages/errors/src/i18n/ErrorCodeMappings.ts | 1 + packages/errors/src/i18n/ErrorI18nMessages.ts | 1 + .../errors/src/i18n/weblate/locales/ar.json | 1 + .../errors/src/i18n/weblate/locales/bg.json | 1 + .../errors/src/i18n/weblate/locales/cs.json | 1 + .../errors/src/i18n/weblate/locales/da.json | 1 + .../errors/src/i18n/weblate/locales/de.json | 1 + .../errors/src/i18n/weblate/locales/el.json | 1 + .../src/i18n/weblate/locales/en-GB.json | 1 + .../src/i18n/weblate/locales/es-419.json | 1 + .../src/i18n/weblate/locales/es-ES.json | 1 + .../errors/src/i18n/weblate/locales/fi.json | 1 + .../errors/src/i18n/weblate/locales/fr.json | 1 + .../errors/src/i18n/weblate/locales/he.json | 1 + .../errors/src/i18n/weblate/locales/hi.json | 1 + .../errors/src/i18n/weblate/locales/hr.json | 1 + .../errors/src/i18n/weblate/locales/hu.json | 1 + .../errors/src/i18n/weblate/locales/id.json | 1 + .../errors/src/i18n/weblate/locales/it.json | 1 + .../errors/src/i18n/weblate/locales/ja.json | 1 + .../errors/src/i18n/weblate/locales/ko.json | 1 + .../errors/src/i18n/weblate/locales/lt.json | 1 + .../errors/src/i18n/weblate/locales/nl.json | 1 + .../errors/src/i18n/weblate/locales/no.json | 1 + .../errors/src/i18n/weblate/locales/pl.json | 1 + .../src/i18n/weblate/locales/pt-BR.json | 1 + .../errors/src/i18n/weblate/locales/ro.json | 1 + .../errors/src/i18n/weblate/locales/ru.json | 1 + .../src/i18n/weblate/locales/sv-SE.json | 1 + .../errors/src/i18n/weblate/locales/th.json | 1 + .../errors/src/i18n/weblate/locales/tr.json | 1 + .../errors/src/i18n/weblate/locales/uk.json | 1 + .../errors/src/i18n/weblate/locales/vi.json | 1 + .../src/i18n/weblate/locales/zh-CN.json | 1 + .../src/i18n/weblate/locales/zh-TW.json | 1 + .../errors/src/i18n/weblate/messages.json | 1 + 42 files changed, 113 insertions(+), 75 deletions(-) create mode 100644 fluxer_api/src/api/utils/ConcurrencyUtils.ts diff --git a/fluxer_api/src/api/guild/services/GuildSearchService.ts b/fluxer_api/src/api/guild/services/GuildSearchService.ts index 49b736193..849fdd7f6 100644 --- a/fluxer_api/src/api/guild/services/GuildSearchService.ts +++ b/fluxer_api/src/api/guild/services/GuildSearchService.ts @@ -24,8 +24,13 @@ import {MessageSearchResponseMapper} from '../../search/MessageSearchResponseMap import {searchExistingMessages} from '../../search/MessageSearchResultReconciler'; import type {IUserRepository} from '../../user/IUserRepository'; import {canUserAccessNsfwContent} from '../../utils/AgeUtils'; +import {mapWithConcurrency} from '../../utils/ConcurrencyUtils'; import type {WorkerTaskName} from '../../worker/WorkerLaneConfig'; +const GUILD_FANOUT_CONCURRENCY = 16; +const PERMISSION_CHECK_CONCURRENCY = 64; +const CHANNEL_INDEX_JOB_ENQUEUE_CONCURRENCY = 16; + export class GuildSearchService { private readonly responseMapper: MessageSearchResponseMapper; @@ -95,15 +100,13 @@ export class GuildSearchService { const channel = channelMap.get(id.toString())!; return !(channel.isNsfw && !canIncludeNsfw); }); - const permissionResults = await Promise.all( - nsfwFilteredIds.map((channelId) => - this.gatewayService.checkPermission({ - guildId, - userId, - channelId, - permission: Permissions.VIEW_CHANNEL | Permissions.READ_MESSAGE_HISTORY, - }), - ), + const permissionResults = await mapWithConcurrency(nsfwFilteredIds, PERMISSION_CHECK_CONCURRENCY, (channelId) => + this.gatewayService.checkPermission({ + guildId, + userId, + channelId, + permission: Permissions.VIEW_CHANNEL | Permissions.READ_MESSAGE_HISTORY, + }), ); const validChannelIds: Array = []; for (let i = 0; i < nsfwFilteredIds.length; i++) { @@ -133,18 +136,16 @@ export class GuildSearchService { }) .map((id) => id.toString()); if (channelsToIndex.length > 0) { - await Promise.all( - channelsToIndex.map((channelId) => - this.workerService.addJob( - 'indexChannelMessages', - { - channelId, - }, - { - jobKey: `indexChannelMessages-${channelId}`, - maxAttempts: 3, - }, - ), + await mapWithConcurrency(channelsToIndex, CHANNEL_INDEX_JOB_ENQUEUE_CONCURRENCY, (channelId) => + this.workerService.addJob( + 'indexChannelMessages', + { + channelId, + }, + { + jobKey: `indexChannelMessages-${channelId}`, + maxAttempts: 3, + }, ), ); return {indexing: true}; @@ -267,16 +268,14 @@ export class GuildSearchService { } private async queueIndexingChannels(channelIds: Iterable): Promise { - await Promise.all( - Array.from(channelIds).map((channelId) => - this.workerService.addJob( - 'indexChannelMessages', - {channelId}, - { - jobKey: `indexChannelMessages-${channelId}`, - maxAttempts: 3, - }, - ), + await mapWithConcurrency(Array.from(channelIds), CHANNEL_INDEX_JOB_ENQUEUE_CONCURRENCY, (channelId) => + this.workerService.addJob( + 'indexChannelMessages', + {channelId}, + { + jobKey: `indexChannelMessages-${channelId}`, + maxAttempts: 3, + }, ), ); } @@ -290,42 +289,36 @@ export class GuildSearchService { const accessibleChannels = new Map(); const unindexedChannelIds = new Set(); const guildNsfwLevels = new Map(); - const [guildDataResults, guildChannelsResults, viewableChannelsResults] = await Promise.all([ - Promise.all(guildIds.map((guildId) => this.gatewayService.getGuildData({guildId, userId}))), - Promise.all(guildIds.map((guildId) => this.channelRepository.listGuildChannels(guildId))), - Promise.all(guildIds.map((guildId) => this.gatewayService.getViewableChannels({guildId, userId}))), - ]); - for (let i = 0; i < guildIds.length; i++) { - const guildData = guildDataResults[i]; - if (guildData) { - guildNsfwLevels.set(guildIds[i]!.toString(), guildData.nsfw_level); - } - } const permissionChecks: Array<{ channel: Channel; guildId: GuildID; }> = []; - for (let i = 0; i < guildIds.length; i++) { - const guildChannels = guildChannelsResults[i]!; - if (guildChannels.length === 0) { - continue; + await mapWithConcurrency(guildIds, GUILD_FANOUT_CONCURRENCY, async (guildId) => { + const [guildData, guildChannels, viewableChannels] = await Promise.all([ + this.gatewayService.getGuildData({guildId, userId}), + this.channelRepository.listGuildChannels(guildId), + this.gatewayService.getViewableChannels({guildId, userId}), + ]); + if (guildData) { + guildNsfwLevels.set(guildId.toString(), guildData.nsfw_level); } - const viewableChannelIds = new Set(viewableChannelsResults[i]!.map((channelId) => channelId.toString())); + const viewableChannelIds = new Set(viewableChannels.map((channelId) => channelId.toString())); for (const channel of guildChannels) { if (viewableChannelIds.has(channel.id.toString())) { - permissionChecks.push({channel, guildId: guildIds[i]!}); + permissionChecks.push({channel, guildId}); } } - } - const permissionResults = await Promise.all( - permissionChecks.map(({channel, guildId}) => + }); + const permissionResults = await mapWithConcurrency( + permissionChecks, + PERMISSION_CHECK_CONCURRENCY, + ({channel, guildId}) => this.gatewayService.checkPermission({ guildId, userId, channelId: channel.id, permission: Permissions.VIEW_CHANNEL | Permissions.READ_MESSAGE_HISTORY, }), - ), ); for (let i = 0; i < permissionChecks.length; i++) { if (!permissionResults[i]) { diff --git a/fluxer_api/src/api/openapi/openapi.json b/fluxer_api/src/api/openapi/openapi.json index 47605fd4b..a38772cf8 100644 --- a/fluxer_api/src/api/openapi/openapi.json +++ b/fluxer_api/src/api/openapi/openapi.json @@ -14978,7 +14978,7 @@ } }, "x-mint": {"metadata": {"title": "Search messages"}}, - "description": "Searches for messages across guilds and channels accessible to the authenticated user.", + "description": "Searches for messages across guilds and channels accessible to the authenticated user. Bots must supply a context guild or channel and may only use the current scope.", "security": [{"sessionToken": []}], "requestBody": { "required": true, diff --git a/fluxer_api/src/api/search/GlobalSearchService.ts b/fluxer_api/src/api/search/GlobalSearchService.ts index 7c341b90a..d14da450c 100644 --- a/fluxer_api/src/api/search/GlobalSearchService.ts +++ b/fluxer_api/src/api/search/GlobalSearchService.ts @@ -23,6 +23,7 @@ import type {Channel} from '../models/Channel'; import {getMessageSearchService} from '../SearchFactory'; import type {IUserRepository} from '../user/IUserRepository'; import {canUserAccessNsfwContent} from '../utils/AgeUtils'; +import {mapWithConcurrency} from '../utils/ConcurrencyUtils'; import type {WorkerTaskName} from '../worker/WorkerLaneConfig'; import {buildMessageSearchFilters} from './BuildMessageSearchFilters'; import {channelNeedsReindexing} from './ChannelIndexingUtils'; @@ -270,21 +271,3 @@ export class GlobalSearchService { return canUserAccessNsfwContent(user); } } - -async function mapWithConcurrency( - items: ReadonlyArray, - concurrency: number, - mapper: (item: T, index: number) => Promise, -): Promise> { - const results = new Array(items.length); - let nextIndex = 0; - async function worker(): Promise { - for (;;) { - const index = nextIndex++; - if (index >= items.length) return; - results[index] = await mapper(items[index]!, index); - } - } - await Promise.all(Array.from({length: Math.min(concurrency, items.length)}, () => worker())); - return results; -} diff --git a/fluxer_api/src/api/search/controllers/SearchController.ts b/fluxer_api/src/api/search/controllers/SearchController.ts index a5fc31a74..cd892b5f1 100644 --- a/fluxer_api/src/api/search/controllers/SearchController.ts +++ b/fluxer_api/src/api/search/controllers/SearchController.ts @@ -1,8 +1,10 @@ // SPDX-License-Identifier: AGPL-3.0-or-later +import {ValidationErrorCodes} from '@fluxer/constants/src/ValidationErrorCodes'; +import {InputValidationError} from '@fluxer/errors/src/domains/core/InputValidationError'; import {GlobalSearchMessagesRequest} from '@fluxer/schema/src/domains/message/MessageRequestSchemas'; import {MessageSearchResponse} from '@fluxer/schema/src/domains/message/MessageResponseSchemas'; -import {DefaultUserOnly, LoginRequired} from '../../middleware/AuthMiddleware'; +import {LoginRequired} from '../../middleware/AuthMiddleware'; import {RateLimitMiddleware} from '../../middleware/RateLimitMiddleware'; import {OpenAPI} from '../../middleware/ResponseTypeMiddleware'; import {RateLimitConfigs} from '../../RateLimitConfig'; @@ -14,11 +16,11 @@ export function SearchController(app: HonoApp) { '/search/messages', RateLimitMiddleware(RateLimitConfigs.SEARCH_MESSAGES), LoginRequired, - DefaultUserOnly, OpenAPI({ operationId: 'search_messages', summary: 'Search messages', - description: 'Searches for messages across guilds and channels accessible to the authenticated user.', + description: + 'Searches for messages across guilds and channels accessible to the authenticated user. Bots must supply a context guild or channel and may only use the current scope.', responseSchema: MessageSearchResponse, statusCode: 200, security: ['bearerToken', 'sessionToken'], @@ -27,7 +29,11 @@ export function SearchController(app: HonoApp) { Validator('json', GlobalSearchMessagesRequest), async (ctx) => { const params = ctx.req.valid('json'); - const userId = ctx.get('user').id; + const user = ctx.get('user'); + if (user.isBot && (params.scope ?? 'current') !== 'current') { + throw InputValidationError.fromCode('scope', ValidationErrorCodes.BOT_SEARCH_SCOPE_UNAVAILABLE); + } + const userId = user.id; const requestCache = ctx.get('requestCache'); const result = await ctx.get('searchService').searchMessages({userId, requestCache, data: params}); return ctx.json(result); diff --git a/fluxer_api/src/api/utils/ConcurrencyUtils.ts b/fluxer_api/src/api/utils/ConcurrencyUtils.ts new file mode 100644 index 000000000..1fccaba84 --- /dev/null +++ b/fluxer_api/src/api/utils/ConcurrencyUtils.ts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +export async function mapWithConcurrency( + items: ReadonlyArray, + concurrency: number, + mapper: (item: T, index: number) => Promise, +): Promise> { + const results = new Array(items.length); + let nextIndex = 0; + async function worker(): Promise { + for (;;) { + const index = nextIndex++; + if (index >= items.length) return; + results[index] = await mapper(items[index]!, index); + } + } + await Promise.all(Array.from({length: Math.min(concurrency, items.length)}, () => worker())); + return results; +} diff --git a/packages/constants/src/ValidationErrorCodes.ts b/packages/constants/src/ValidationErrorCodes.ts index 975cb7647..8aa791283 100644 --- a/packages/constants/src/ValidationErrorCodes.ts +++ b/packages/constants/src/ValidationErrorCodes.ts @@ -251,6 +251,7 @@ export const ValidationErrorCodes = { VISIONARY_REQUIRED_FOR_BOT_DISCRIMINATOR: 'VISIONARY_REQUIRED_FOR_BOT_DISCRIMINATOR', VISIONARY_REQUIRED_FOR_DISCRIMINATOR: 'VISIONARY_REQUIRED_FOR_DISCRIMINATOR', BOT_DISCRIMINATOR_CANNOT_BE_CHANGED: 'BOT_DISCRIMINATOR_CANNOT_BE_CHANGED', + BOT_SEARCH_SCOPE_UNAVAILABLE: 'BOT_SEARCH_SCOPE_UNAVAILABLE', VOICE_CHANNELS_CANNOT_BE_ABOVE_TEXT_CHANNELS: 'VOICE_CHANNELS_CANNOT_BE_ABOVE_TEXT_CHANNELS', WEBHOOK_NAME_LENGTH_INVALID: 'WEBHOOK_NAME_LENGTH_INVALID', ENTRANCE_SOUND_INVALID_FORMAT: 'ENTRANCE_SOUND_INVALID_FORMAT', diff --git a/packages/errors/src/i18n/ErrorCodeMappings.ts b/packages/errors/src/i18n/ErrorCodeMappings.ts index 8d4f60785..1ad3b248d 100644 --- a/packages/errors/src/i18n/ErrorCodeMappings.ts +++ b/packages/errors/src/i18n/ErrorCodeMappings.ts @@ -467,6 +467,7 @@ export const ErrorCodeToI18nKey = { 'premium_and_plans.visionary_required_for_bot_discriminator', [ValidationErrorCodes.VISIONARY_REQUIRED_FOR_DISCRIMINATOR]: 'premium_and_plans.visionary_required_for_discriminator', [ValidationErrorCodes.BOT_DISCRIMINATOR_CANNOT_BE_CHANGED]: 'bots.bot_discriminator_cannot_be_changed', + [ValidationErrorCodes.BOT_SEARCH_SCOPE_UNAVAILABLE]: 'bots.search_scope_unavailable', [ValidationErrorCodes.USER_MUST_BE_A_BOT_TO_BE_MARKED_AS_A_SYSTEM_USER]: 'admin_and_system.user_must_be_bot_for_system_user', [ValidationErrorCodes.USER_IS_NOT_BANNED]: 'moderation_and_reports.user_is_not_banned', diff --git a/packages/errors/src/i18n/ErrorI18nMessages.ts b/packages/errors/src/i18n/ErrorI18nMessages.ts index 8e4a601b2..36252f06b 100644 --- a/packages/errors/src/i18n/ErrorI18nMessages.ts +++ b/packages/errors/src/i18n/ErrorI18nMessages.ts @@ -181,6 +181,7 @@ export const ERROR_I18N_MESSAGES = { 'bots.bot_user_not_found': "Bot user wasn't found.", 'bots.invalid_response_type_for_non_bot': 'Response type must be code for non-bot scopes.', 'bots.not_a_bot_application': "This application isn't a bot.", + 'bots.search_scope_unavailable': 'Bots can only search within a single community or channel.', 'calls_and_voice.call_already_exists': 'A call is already in progress in this channel.', 'calls_and_voice.cannot_modify_voice_state': "You can't modify voice state.", 'calls_and_voice.invalid_or_restricted_rtc_region': 'Invalid or restricted RTC region: {region}.', diff --git a/packages/errors/src/i18n/weblate/locales/ar.json b/packages/errors/src/i18n/weblate/locales/ar.json index 7b3eafbea..5634725e2 100644 --- a/packages/errors/src/i18n/weblate/locales/ar.json +++ b/packages/errors/src/i18n/weblate/locales/ar.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "لم يتم العثور على مستخدم البوت.", "bots.invalid_response_type_for_non_bot": "يجب أن يكون نوع الاستجابة رمزًا للنطاقات غير البوت.", "bots.not_a_bot_application": "هذا التطبيق ليس بوتًا.", + "bots.search_scope_unavailable": "لا يمكن للبوتات البحث إلا داخل مجتمع واحد أو قناة واحدة.", "calls_and_voice.call_already_exists": "مكالمة جارية بالفعل في هذه القناة.", "calls_and_voice.cannot_modify_voice_state": "لا يمكنك تغيير حالة الصوت.", "calls_and_voice.invalid_or_restricted_rtc_region": "منطقة RTC غير صالحة أو مقيدة: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/bg.json b/packages/errors/src/i18n/weblate/locales/bg.json index 8755a6e4f..f10702e8b 100644 --- a/packages/errors/src/i18n/weblate/locales/bg.json +++ b/packages/errors/src/i18n/weblate/locales/bg.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Потребителят на бота не е намерен.", "bots.invalid_response_type_for_non_bot": "Типът на отговор трябва да е код за обхвати, различни от бот.", "bots.not_a_bot_application": "Това приложение не е бот.", + "bots.search_scope_unavailable": "Ботовете могат да търсят само в рамките на една общност или един канал.", "calls_and_voice.call_already_exists": "Вече има активно обаждане в този канал.", "calls_and_voice.cannot_modify_voice_state": "Не можеш да променяш гласовото си състояние.", "calls_and_voice.invalid_or_restricted_rtc_region": "Невалиден или ограничен RTC регион: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/cs.json b/packages/errors/src/i18n/weblate/locales/cs.json index 31c3e5001..ba55f147e 100644 --- a/packages/errors/src/i18n/weblate/locales/cs.json +++ b/packages/errors/src/i18n/weblate/locales/cs.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Uživatel bota nebyl nalezen.", "bots.invalid_response_type_for_non_bot": "Typ odpovědi musí být autorizační kód pro jiné rozsahy než pro boty.", "bots.not_a_bot_application": "Tato aplikace není bot.", + "bots.search_scope_unavailable": "Boti mohou vyhledávat pouze v rámci jedné komunity nebo jednoho kanálu.", "calls_and_voice.call_already_exists": "V tomto kanálu už se volá.", "calls_and_voice.cannot_modify_voice_state": "Nemůžeš měnit hlasový stav.", "calls_and_voice.invalid_or_restricted_rtc_region": "Neplatná nebo omezená RTC oblast: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/da.json b/packages/errors/src/i18n/weblate/locales/da.json index 94d66007e..c2745aecc 100644 --- a/packages/errors/src/i18n/weblate/locales/da.json +++ b/packages/errors/src/i18n/weblate/locales/da.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Bot-bruger blev ikke fundet.", "bots.invalid_response_type_for_non_bot": "Svartypen skal være kode for ikke-bot-tilladelser.", "bots.not_a_bot_application": "Denne applikation er ikke en bot.", + "bots.search_scope_unavailable": "Botter kan kun søge inden for én community eller én kanal.", "calls_and_voice.call_already_exists": "Et opkald er allerede i gang i denne kanal.", "calls_and_voice.cannot_modify_voice_state": "Du kan ikke ændre stemmestatus.", "calls_and_voice.invalid_or_restricted_rtc_region": "Ugyldig eller begrænset RTC-region: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/de.json b/packages/errors/src/i18n/weblate/locales/de.json index 521254e51..0e8209862 100644 --- a/packages/errors/src/i18n/weblate/locales/de.json +++ b/packages/errors/src/i18n/weblate/locales/de.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Der Bot-Benutzer wurde nicht gefunden.", "bots.invalid_response_type_for_non_bot": "Der Antworttyp muss für Nicht-Bot-Scopes \"code\" sein.", "bots.not_a_bot_application": "Diese Anwendung ist kein Bot.", + "bots.search_scope_unavailable": "Bots können nur innerhalb einer einzelnen Community oder eines einzelnen Kanals suchen.", "calls_and_voice.call_already_exists": "In diesem Kanal ist bereits ein Anruf aktiv.", "calls_and_voice.cannot_modify_voice_state": "Der Sprachstatus kann nicht geändert werden.", "calls_and_voice.invalid_or_restricted_rtc_region": "Ungültige oder beschränkte RTC-Region: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/el.json b/packages/errors/src/i18n/weblate/locales/el.json index 331c7f3f8..b8beb2953 100644 --- a/packages/errors/src/i18n/weblate/locales/el.json +++ b/packages/errors/src/i18n/weblate/locales/el.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Ο χρήστης bot δεν βρέθηκε.", "bots.invalid_response_type_for_non_bot": "Ο τύπος απόκρισης πρέπει να είναι code για πεδία εκτός bot.", "bots.not_a_bot_application": "Αυτή η εφαρμογή δεν είναι bot.", + "bots.search_scope_unavailable": "Τα bot μπορούν να κάνουν αναζήτηση μόνο σε μία κοινότητα ή σε ένα κανάλι.", "calls_and_voice.call_already_exists": "Υπάρχει ήδη μια κλήση σε αυτό το κανάλι.", "calls_and_voice.cannot_modify_voice_state": "Δεν μπορείς να τροποποιήσεις την κατάσταση φωνής.", "calls_and_voice.invalid_or_restricted_rtc_region": "Μη έγκυρη ή μη διαθέσιμη περιοχή RTC: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/en-GB.json b/packages/errors/src/i18n/weblate/locales/en-GB.json index 1e5fd173d..5c52ab651 100644 --- a/packages/errors/src/i18n/weblate/locales/en-GB.json +++ b/packages/errors/src/i18n/weblate/locales/en-GB.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Bot user wasn't found.", "bots.invalid_response_type_for_non_bot": "Response type must be code for non-bot scopes.", "bots.not_a_bot_application": "This application isn't a bot.", + "bots.search_scope_unavailable": "Bots can only search within a single community or channel.", "calls_and_voice.call_already_exists": "A call is already in progress in this channel.", "calls_and_voice.cannot_modify_voice_state": "You can't modify voice state.", "calls_and_voice.invalid_or_restricted_rtc_region": "Invalid or restricted RTC region: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/es-419.json b/packages/errors/src/i18n/weblate/locales/es-419.json index db8123b70..02c5fba4a 100644 --- a/packages/errors/src/i18n/weblate/locales/es-419.json +++ b/packages/errors/src/i18n/weblate/locales/es-419.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "No se encontró el usuario del bot.", "bots.invalid_response_type_for_non_bot": "El tipo de respuesta debe ser código para ámbitos que no son de bot.", "bots.not_a_bot_application": "Esta aplicación no es un bot.", + "bots.search_scope_unavailable": "Los bots solo pueden buscar dentro de una sola comunidad o canal.", "calls_and_voice.call_already_exists": "Ya hay una llamada en curso en este canal.", "calls_and_voice.cannot_modify_voice_state": "No puedes modificar el estado de voz.", "calls_and_voice.invalid_or_restricted_rtc_region": "Región RTC inválida o restringida: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/es-ES.json b/packages/errors/src/i18n/weblate/locales/es-ES.json index 3e8dfc205..134e58c69 100644 --- a/packages/errors/src/i18n/weblate/locales/es-ES.json +++ b/packages/errors/src/i18n/weblate/locales/es-ES.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "No se encontró el usuario del bot.", "bots.invalid_response_type_for_non_bot": "El tipo de respuesta debe ser code para los alcances que no sean de bot.", "bots.not_a_bot_application": "Esta aplicación no es un bot.", + "bots.search_scope_unavailable": "Los bots solo pueden buscar dentro de una sola comunidad o canal.", "calls_and_voice.call_already_exists": "Ya hay una llamada en curso en este canal.", "calls_and_voice.cannot_modify_voice_state": "No puedes modificar el estado de voz.", "calls_and_voice.invalid_or_restricted_rtc_region": "Región RTC no válida o restringida: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/fi.json b/packages/errors/src/i18n/weblate/locales/fi.json index 0438bf23a..ca807707b 100644 --- a/packages/errors/src/i18n/weblate/locales/fi.json +++ b/packages/errors/src/i18n/weblate/locales/fi.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Bottikäyttäjää ei löytynyt.", "bots.invalid_response_type_for_non_bot": "Vastaustyypin on oltava koodi muille kuin botin käyttöoikeuksille.", "bots.not_a_bot_application": "Tämä sovellus ei ole botti.", + "bots.search_scope_unavailable": "Botit voivat hakea vain yhden yhteisön tai kanavan sisältä.", "calls_and_voice.call_already_exists": "Puhelu on jo käynnissä tässä kanavassa.", "calls_and_voice.cannot_modify_voice_state": "Et voi muokata äänitilaa.", "calls_and_voice.invalid_or_restricted_rtc_region": "Virheellinen tai rajoitettu RTC-alue: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/fr.json b/packages/errors/src/i18n/weblate/locales/fr.json index 87421e495..be51b4862 100644 --- a/packages/errors/src/i18n/weblate/locales/fr.json +++ b/packages/errors/src/i18n/weblate/locales/fr.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "L'utilisateur bot n'a pas été trouvé.", "bots.invalid_response_type_for_non_bot": "Le type de réponse doit être \"code\" pour les portées qui ne sont pas des bots.", "bots.not_a_bot_application": "Cette application n'est pas un bot.", + "bots.search_scope_unavailable": "Les bots ne peuvent rechercher que dans une seule communauté ou un seul salon.", "calls_and_voice.call_already_exists": "Un appel est déjà en cours dans ce salon.", "calls_and_voice.cannot_modify_voice_state": "Tu ne peux pas modifier l'état vocal.", "calls_and_voice.invalid_or_restricted_rtc_region": "Région RTC invalide ou restreinte : {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/he.json b/packages/errors/src/i18n/weblate/locales/he.json index 0a6c76585..425f68bf6 100644 --- a/packages/errors/src/i18n/weblate/locales/he.json +++ b/packages/errors/src/i18n/weblate/locales/he.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "משתמש הבוט לא נמצא.", "bots.invalid_response_type_for_non_bot": "סוג התגובה חייב להיות 'code' עבור הרשאות שאינן של בוטים.", "bots.not_a_bot_application": "יישום זה אינו בוט.", + "bots.search_scope_unavailable": "בוטים יכולים לחפש רק בתוך קהילה אחת או ערוץ אחד.", "calls_and_voice.call_already_exists": "שיחה כבר מתקיימת בערוץ זה.", "calls_and_voice.cannot_modify_voice_state": "לא ניתן לשנות את המצב הקולי.", "calls_and_voice.invalid_or_restricted_rtc_region": "אזור RTC לא חוקי או מוגבל: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/hi.json b/packages/errors/src/i18n/weblate/locales/hi.json index 3d7f8a50e..2cd73c120 100644 --- a/packages/errors/src/i18n/weblate/locales/hi.json +++ b/packages/errors/src/i18n/weblate/locales/hi.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "बॉट यूज़र नहीं मिला।", "bots.invalid_response_type_for_non_bot": "नॉन-बॉट स्कोप के लिए रिस्पॉन्स टाइप कोड होना चाहिए।", "bots.not_a_bot_application": "यह एप्लीकेशन बॉट नहीं है।", + "bots.search_scope_unavailable": "बॉट केवल एक ही कम्युनिटी या चैनल के भीतर खोज सकते हैं।", "calls_and_voice.call_already_exists": "इस चैनल में पहले से ही एक कॉल चल रही है।", "calls_and_voice.cannot_modify_voice_state": "आप वॉइस स्टेट को बदल नहीं सकते।", "calls_and_voice.invalid_or_restricted_rtc_region": "अमान्य या प्रतिबंधित RTC रीजन: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/hr.json b/packages/errors/src/i18n/weblate/locales/hr.json index 7fddd5925..0d936f2cd 100644 --- a/packages/errors/src/i18n/weblate/locales/hr.json +++ b/packages/errors/src/i18n/weblate/locales/hr.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Korisnik bota nije pronađen.", "bots.invalid_response_type_for_non_bot": "Vrsta odgovora mora biti kod za opsege koji nisu botovi.", "bots.not_a_bot_application": "Ova aplikacija nije bot.", + "bots.search_scope_unavailable": "Botovi mogu pretraživati samo unutar jedne zajednice ili jednog kanala.", "calls_and_voice.call_already_exists": "Poziv je već u tijeku u ovom kanalu.", "calls_and_voice.cannot_modify_voice_state": "Ne možeš mijenjati stanje glasa.", "calls_and_voice.invalid_or_restricted_rtc_region": "Nevažeća ili ograničena RTC regija: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/hu.json b/packages/errors/src/i18n/weblate/locales/hu.json index 9a191755f..e3be73943 100644 --- a/packages/errors/src/i18n/weblate/locales/hu.json +++ b/packages/errors/src/i18n/weblate/locales/hu.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "A bot felhasználó nem található.", "bots.invalid_response_type_for_non_bot": "A válasz típusának kódnak kell lennie a nem bot hatókörökhöz.", "bots.not_a_bot_application": "Ez az alkalmazás nem bot.", + "bots.search_scope_unavailable": "A botok csak egyetlen közösségen vagy csatornán belül kereshetnek.", "calls_and_voice.call_already_exists": "Már folyamatban van egy hívás ezen a csatornán.", "calls_and_voice.cannot_modify_voice_state": "Nem módosíthatod a hangbeállításokat.", "calls_and_voice.invalid_or_restricted_rtc_region": "Érvénytelen vagy korlátozott RTC régió: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/id.json b/packages/errors/src/i18n/weblate/locales/id.json index 8c6fe843a..34c8b09e2 100644 --- a/packages/errors/src/i18n/weblate/locales/id.json +++ b/packages/errors/src/i18n/weblate/locales/id.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Pengguna bot tidak ditemukan.", "bots.invalid_response_type_for_non_bot": "Jenis respons harus berupa kode untuk cakupan non-bot.", "bots.not_a_bot_application": "Aplikasi ini bukan bot.", + "bots.search_scope_unavailable": "Bot hanya bisa mencari di dalam satu komunitas atau kanal.", "calls_and_voice.call_already_exists": "Panggilan sudah berlangsung di kanal ini.", "calls_and_voice.cannot_modify_voice_state": "Kamu tidak dapat mengubah status suara.", "calls_and_voice.invalid_or_restricted_rtc_region": "Wilayah RTC tidak valid atau dibatasi: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/it.json b/packages/errors/src/i18n/weblate/locales/it.json index f2a425eb5..a2640e72c 100644 --- a/packages/errors/src/i18n/weblate/locales/it.json +++ b/packages/errors/src/i18n/weblate/locales/it.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Utente bot non trovato.", "bots.invalid_response_type_for_non_bot": "Il tipo di risposta deve essere code per gli scope non-bot.", "bots.not_a_bot_application": "Questa applicazione non è un bot.", + "bots.search_scope_unavailable": "I bot possono cercare solo all'interno di una singola comunità o di un canale.", "calls_and_voice.call_already_exists": "Una chiamata è già in corso in questo canale.", "calls_and_voice.cannot_modify_voice_state": "Non puoi modificare lo stato vocale.", "calls_and_voice.invalid_or_restricted_rtc_region": "Regione RTC non valida o limitata: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/ja.json b/packages/errors/src/i18n/weblate/locales/ja.json index d83fe563d..15ca09341 100644 --- a/packages/errors/src/i18n/weblate/locales/ja.json +++ b/packages/errors/src/i18n/weblate/locales/ja.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "ボットユーザーが見つかりません。", "bots.invalid_response_type_for_non_bot": "ボット以外のスコープの場合、応答タイプはコードである必要があります。", "bots.not_a_bot_application": "このアプリケーションはボットではありません。", + "bots.search_scope_unavailable": "ボットは単一のコミュニティまたはチャンネル内でのみ検索できます。", "calls_and_voice.call_already_exists": "このチャンネルではすでに通話中です。", "calls_and_voice.cannot_modify_voice_state": "ボイスの状態は変更できません。", "calls_and_voice.invalid_or_restricted_rtc_region": "無効または制限されたRTCリージョンです: {region}。", diff --git a/packages/errors/src/i18n/weblate/locales/ko.json b/packages/errors/src/i18n/weblate/locales/ko.json index 4a156219c..f2341e27c 100644 --- a/packages/errors/src/i18n/weblate/locales/ko.json +++ b/packages/errors/src/i18n/weblate/locales/ko.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "봇 사용자를 찾을 수 없어요.", "bots.invalid_response_type_for_non_bot": "봇이 아닌 범위에는 응답 유형이 코드여야 해요.", "bots.not_a_bot_application": "이 애플리케이션은 봇이 아니에요.", + "bots.search_scope_unavailable": "봇은 커뮤니티 하나 또는 채널 하나 안에서만 검색할 수 있어요.", "calls_and_voice.call_already_exists": "이 채널에서 이미 통화가 진행 중이에요.", "calls_and_voice.cannot_modify_voice_state": "음성 상태를 수정할 수 없어요.", "calls_and_voice.invalid_or_restricted_rtc_region": "유효하지 않거나 제한된 RTC 지역이에요: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/lt.json b/packages/errors/src/i18n/weblate/locales/lt.json index b09c2547f..909d72b91 100644 --- a/packages/errors/src/i18n/weblate/locales/lt.json +++ b/packages/errors/src/i18n/weblate/locales/lt.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Roboto naudotojas nerastas.", "bots.invalid_response_type_for_non_bot": "Atsakymo tipas ne robotų teisėms turi būti kodas.", "bots.not_a_bot_application": "Ši programa nėra robotas.", + "bots.search_scope_unavailable": "Botai gali ieškoti tik vienoje bendruomenėje arba viename kanale.", "calls_and_voice.call_already_exists": "Šiame kanale jau vyksta skambutis.", "calls_and_voice.cannot_modify_voice_state": "Negali keisti balso būsenos.", "calls_and_voice.invalid_or_restricted_rtc_region": "Neteisingas arba apribotas RTC regionas: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/nl.json b/packages/errors/src/i18n/weblate/locales/nl.json index 85dffa1d7..354ce0470 100644 --- a/packages/errors/src/i18n/weblate/locales/nl.json +++ b/packages/errors/src/i18n/weblate/locales/nl.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Bot-gebruiker is niet gevonden.", "bots.invalid_response_type_for_non_bot": "Responstype moet 'code' zijn voor niet-bot-bereiken.", "bots.not_a_bot_application": "Deze applicatie is geen bot.", + "bots.search_scope_unavailable": "Bots kunnen alleen binnen één community of kanaal zoeken.", "calls_and_voice.call_already_exists": "Er is al een oproep bezig in dit kanaal.", "calls_and_voice.cannot_modify_voice_state": "Je kunt de spraakstatus niet wijzigen.", "calls_and_voice.invalid_or_restricted_rtc_region": "Ongeldige of beperkte RTC-regio: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/no.json b/packages/errors/src/i18n/weblate/locales/no.json index 105f91859..6aa68a2a0 100644 --- a/packages/errors/src/i18n/weblate/locales/no.json +++ b/packages/errors/src/i18n/weblate/locales/no.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Bot-bruker ble ikke funnet.", "bots.invalid_response_type_for_non_bot": "Svartypen må være kode for ikke-bot-omfang.", "bots.not_a_bot_application": "Denne applikasjonen er ikke en bot.", + "bots.search_scope_unavailable": "Botter kan bare søke innenfor ett community eller én kanal.", "calls_and_voice.call_already_exists": "En samtale er allerede i gang i denne kanalen.", "calls_and_voice.cannot_modify_voice_state": "Du kan ikke endre talestatus.", "calls_and_voice.invalid_or_restricted_rtc_region": "Ugyldig eller begrenset RTC-region: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/pl.json b/packages/errors/src/i18n/weblate/locales/pl.json index ca7c9e227..2f9608800 100644 --- a/packages/errors/src/i18n/weblate/locales/pl.json +++ b/packages/errors/src/i18n/weblate/locales/pl.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Nie znaleziono użytkownika bota.", "bots.invalid_response_type_for_non_bot": "Typ odpowiedzi musi być kodem dla zakresów niebędących botami.", "bots.not_a_bot_application": "Ta aplikacja nie jest botem.", + "bots.search_scope_unavailable": "Boty mogą wyszukiwać tylko w obrębie jednej społeczności lub jednego kanału.", "calls_and_voice.call_already_exists": "W tym kanale trwa już połączenie.", "calls_and_voice.cannot_modify_voice_state": "Nie możesz zmienić stanu połączenia głosowego.", "calls_and_voice.invalid_or_restricted_rtc_region": "Nieprawidłowy lub ograniczony region RTC: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/pt-BR.json b/packages/errors/src/i18n/weblate/locales/pt-BR.json index 35eb27c08..a0e6ddddc 100644 --- a/packages/errors/src/i18n/weblate/locales/pt-BR.json +++ b/packages/errors/src/i18n/weblate/locales/pt-BR.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "O usuário do bot não foi encontrado.", "bots.invalid_response_type_for_non_bot": "O tipo de resposta deve ser código para escopos que não são de bot.", "bots.not_a_bot_application": "Este app não é um bot.", + "bots.search_scope_unavailable": "Bots só podem pesquisar dentro de uma única comunidade ou canal.", "calls_and_voice.call_already_exists": "Já existe uma chamada neste canal.", "calls_and_voice.cannot_modify_voice_state": "Você não pode alterar o estado de voz.", "calls_and_voice.invalid_or_restricted_rtc_region": "Região RTC inválida ou restrita: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/ro.json b/packages/errors/src/i18n/weblate/locales/ro.json index bd5a8ff3e..66d40da45 100644 --- a/packages/errors/src/i18n/weblate/locales/ro.json +++ b/packages/errors/src/i18n/weblate/locales/ro.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Utilizatorul bot nu a fost găsit.", "bots.invalid_response_type_for_non_bot": "Tipul de răspuns trebuie să fie cod pentru domenii care nu sunt de bot.", "bots.not_a_bot_application": "Această aplicație nu este un bot.", + "bots.search_scope_unavailable": "Boții pot căuta doar într-o singură comunitate sau într-un singur canal.", "calls_and_voice.call_already_exists": "Un apel este deja în desfășurare pe acest canal.", "calls_and_voice.cannot_modify_voice_state": "Nu poți modifica starea vocală.", "calls_and_voice.invalid_or_restricted_rtc_region": "Regiune RTC invalidă sau restricționată: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/ru.json b/packages/errors/src/i18n/weblate/locales/ru.json index 0d61ce6b3..bd9f1ba53 100644 --- a/packages/errors/src/i18n/weblate/locales/ru.json +++ b/packages/errors/src/i18n/weblate/locales/ru.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Не найден бот-пользователь.", "bots.invalid_response_type_for_non_bot": "Тип ответа должен быть code для областей, не связанных с ботами.", "bots.not_a_bot_application": "Это приложение не является ботом.", + "bots.search_scope_unavailable": "Боты могут искать только в пределах одного сообщества или канала.", "calls_and_voice.call_already_exists": "В этом канале уже идёт звонок.", "calls_and_voice.cannot_modify_voice_state": "Ты не можешь изменить голосовое состояние.", "calls_and_voice.invalid_or_restricted_rtc_region": "Ограниченный или недействительный RTC-регион: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/sv-SE.json b/packages/errors/src/i18n/weblate/locales/sv-SE.json index 56f07eee9..db58e6729 100644 --- a/packages/errors/src/i18n/weblate/locales/sv-SE.json +++ b/packages/errors/src/i18n/weblate/locales/sv-SE.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Botanvändaren hittades inte.", "bots.invalid_response_type_for_non_bot": "Svarstypen måste vara kod för omfång som inte är botar.", "bots.not_a_bot_application": "Denna applikation är inte en bot.", + "bots.search_scope_unavailable": "Bots kan bara söka inom en enda community eller kanal.", "calls_and_voice.call_already_exists": "Det pågår redan ett samtal i den här kanalen.", "calls_and_voice.cannot_modify_voice_state": "Du kan inte ändra röststatus.", "calls_and_voice.invalid_or_restricted_rtc_region": "Ogiltig eller begränsad RTC-region: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/th.json b/packages/errors/src/i18n/weblate/locales/th.json index ee15aab7c..a50844e84 100644 --- a/packages/errors/src/i18n/weblate/locales/th.json +++ b/packages/errors/src/i18n/weblate/locales/th.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "ไม่พบผู้ใช้บอท", "bots.invalid_response_type_for_non_bot": "ประเภทการตอบกลับต้องเป็นโค้ดสำหรับขอบเขตที่ไม่ใช่บอท", "bots.not_a_bot_application": "แอปพลิเคชันนี้ไม่ใช่บอท", + "bots.search_scope_unavailable": "บอทสามารถค้นหาได้เฉพาะภายในคอมมูนิตี้เดียวหรือช่องเดียวเท่านั้น", "calls_and_voice.call_already_exists": "มีการโทรอยู่ในช่องนี้แล้ว", "calls_and_voice.cannot_modify_voice_state": "แก้ไขสถานะเสียงไม่ได้", "calls_and_voice.invalid_or_restricted_rtc_region": "ภูมิภาค RTC ไม่ถูกต้องหรือถูกจำกัด: {region}", diff --git a/packages/errors/src/i18n/weblate/locales/tr.json b/packages/errors/src/i18n/weblate/locales/tr.json index 907001505..6a8cfc5c3 100644 --- a/packages/errors/src/i18n/weblate/locales/tr.json +++ b/packages/errors/src/i18n/weblate/locales/tr.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Bot kullanıcısı bulunamadı.", "bots.invalid_response_type_for_non_bot": "Bot olmayan kapsamlar için yanıt türü kod olmalı.", "bots.not_a_bot_application": "Bu uygulama bir bot değil.", + "bots.search_scope_unavailable": "Botlar yalnızca tek bir toplulukta veya kanalda arama yapabilir.", "calls_and_voice.call_already_exists": "Bu kanalda zaten bir arama devam ediyor.", "calls_and_voice.cannot_modify_voice_state": "Ses durumunu değiştiremezsin.", "calls_and_voice.invalid_or_restricted_rtc_region": "Geçersiz veya kısıtlı RTC bölgesi: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/uk.json b/packages/errors/src/i18n/weblate/locales/uk.json index c1f85c1d0..e1132c25c 100644 --- a/packages/errors/src/i18n/weblate/locales/uk.json +++ b/packages/errors/src/i18n/weblate/locales/uk.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Користувача бота не знайдено.", "bots.invalid_response_type_for_non_bot": "Тип відповіді має бути кодом для дозволів, що не стосуються ботів.", "bots.not_a_bot_application": "Цей застосунок не є ботом.", + "bots.search_scope_unavailable": "Боти можуть шукати лише в межах однієї спільноти або одного каналу.", "calls_and_voice.call_already_exists": "У цьому каналі вже триває голосовий виклик.", "calls_and_voice.cannot_modify_voice_state": "Ти не можеш змінювати стан голосу.", "calls_and_voice.invalid_or_restricted_rtc_region": "Недійсний або обмежений RTC-регіон: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/vi.json b/packages/errors/src/i18n/weblate/locales/vi.json index 38d5e521c..025014bcd 100644 --- a/packages/errors/src/i18n/weblate/locales/vi.json +++ b/packages/errors/src/i18n/weblate/locales/vi.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Không tìm thấy người dùng bot.", "bots.invalid_response_type_for_non_bot": "Loại phản hồi phải là mã cho các phạm vi không phải bot.", "bots.not_a_bot_application": "Ứng dụng này không phải là bot.", + "bots.search_scope_unavailable": "Bot chỉ có thể tìm kiếm trong một cộng đồng hoặc một kênh duy nhất.", "calls_and_voice.call_already_exists": "Có một cuộc gọi đang diễn ra trong kênh này.", "calls_and_voice.cannot_modify_voice_state": "Bạn không thể sửa đổi trạng thái thoại.", "calls_and_voice.invalid_or_restricted_rtc_region": "Vùng RTC không hợp lệ hoặc bị hạn chế: {region}.", diff --git a/packages/errors/src/i18n/weblate/locales/zh-CN.json b/packages/errors/src/i18n/weblate/locales/zh-CN.json index 061aa288d..8ac071111 100644 --- a/packages/errors/src/i18n/weblate/locales/zh-CN.json +++ b/packages/errors/src/i18n/weblate/locales/zh-CN.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "未找到机器人用户。", "bots.invalid_response_type_for_non_bot": "非机器人范围的响应类型必须是代码。", "bots.not_a_bot_application": "此应用不是机器人。", + "bots.search_scope_unavailable": "机器人只能在单个社区或频道内搜索。", "calls_and_voice.call_already_exists": "此频道已有通话正在进行中。", "calls_and_voice.cannot_modify_voice_state": "你无法修改语音状态。", "calls_and_voice.invalid_or_restricted_rtc_region": "无效或受限的 RTC 区域:{region}。", diff --git a/packages/errors/src/i18n/weblate/locales/zh-TW.json b/packages/errors/src/i18n/weblate/locales/zh-TW.json index 77b8595d7..6092ed0e4 100644 --- a/packages/errors/src/i18n/weblate/locales/zh-TW.json +++ b/packages/errors/src/i18n/weblate/locales/zh-TW.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "找不到機器人使用者。", "bots.invalid_response_type_for_non_bot": "非機器人範圍的回應類型必須是授權碼。", "bots.not_a_bot_application": "此應用程式不是機器人。", + "bots.search_scope_unavailable": "機器人只能在單一社群或頻道內搜尋。", "calls_and_voice.call_already_exists": "此頻道已有通話正在進行中。", "calls_and_voice.cannot_modify_voice_state": "你無法修改語音狀態。", "calls_and_voice.invalid_or_restricted_rtc_region": "無效或受限制的 RTC 地區:{region}。", diff --git a/packages/errors/src/i18n/weblate/messages.json b/packages/errors/src/i18n/weblate/messages.json index 811dbf728..c3a4f2f8b 100644 --- a/packages/errors/src/i18n/weblate/messages.json +++ b/packages/errors/src/i18n/weblate/messages.json @@ -152,6 +152,7 @@ "bots.bot_user_not_found": "Bot user wasn't found.", "bots.invalid_response_type_for_non_bot": "Response type must be code for non-bot scopes.", "bots.not_a_bot_application": "This application isn't a bot.", + "bots.search_scope_unavailable": "Bots can only search within a single community or channel.", "calls_and_voice.call_already_exists": "A call is already in progress in this channel.", "calls_and_voice.cannot_modify_voice_state": "You can't modify voice state.", "calls_and_voice.invalid_or_restricted_rtc_region": "Invalid or restricted RTC region: {region}.",