mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
feat(api): allow bots to search messages within a single community (#1660)
This commit is contained in:
1 parent
b5285019cd
commit
490b710c61
42 files changed
+113
-75
No files matched your search
@@ -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<T, TResult>(
|
||||
items: ReadonlyArray<T>,
|
||||
concurrency: number,
|
||||
mapper: (item: T, index: number) => Promise<TResult>,
|
||||
): Promise<Array<TResult>> {
|
||||
const results = new Array<TResult>(items.length);
|
||||
let nextIndex = 0;
|
||||
async function worker(): Promise<void> {
|
||||
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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user