feat(bots): Implement comprehensive bot system with autonomous posting, content management, and API endpoints
- Add bot management system with creation, suspension, and reinstatement functionality - Implement autonomous bot posting with scheduling, rate limiting, and content generation - Add content fetching system supporting RSS feeds and multiple content sources - Implement LLM-based content generation with customizable bot personalities - Add mention handling and automated response system for bot interactions - Implement API key management with encryption using AUTH_SECRET for simplified deployment - Add comprehensive bot logging system for activity tracking and error monitoring - Create bot administration pages and settings UI for managing bot configurations - Add database migrations for bot system schema including users, sources, and content items - Implement cron job system for automated bot operations and scheduled tasks - Add extensive test coverage with unit and property-based tests for core bot modules - Simplify encryption by deriving keys from AUTH_SECRET instead of separate environment variable - Implement automatic content fetching on post trigger with retry logic - Add Reddit-specific link preview handling using oEmbed API for reliable metadata extraction - Create utility scripts for bot inspection and cleanup operations - Add comprehensive bot system documentation and improvement tracking
This commit is contained in:
@@ -31,18 +31,21 @@ export async function GET(request: Request) {
|
||||
limit,
|
||||
});
|
||||
|
||||
const sanitized = results.map((post) => ({
|
||||
id: post.id,
|
||||
content: post.content,
|
||||
createdAt: post.createdAt,
|
||||
isRemoved: post.isRemoved,
|
||||
removedReason: post.removedReason,
|
||||
author: {
|
||||
id: post.author.id,
|
||||
handle: post.author.handle,
|
||||
displayName: post.author.displayName,
|
||||
},
|
||||
}));
|
||||
const sanitized = results.map((post) => {
|
||||
const author = post.author as { id: string; handle: string; displayName: string | null };
|
||||
return {
|
||||
id: post.id,
|
||||
content: post.content,
|
||||
createdAt: post.createdAt,
|
||||
isRemoved: post.isRemoved,
|
||||
removedReason: post.removedReason,
|
||||
author: {
|
||||
id: author.id,
|
||||
handle: author.handle,
|
||||
displayName: author.displayName,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return NextResponse.json({ posts: sanitized });
|
||||
} catch (error) {
|
||||
|
||||
@@ -44,17 +44,20 @@ export async function GET(request: Request) {
|
||||
})
|
||||
: [];
|
||||
|
||||
const postTargets = postTargetsRaw.map((post) => ({
|
||||
id: post.id,
|
||||
content: post.content,
|
||||
createdAt: post.createdAt,
|
||||
isRemoved: post.isRemoved,
|
||||
author: {
|
||||
id: post.author.id,
|
||||
handle: post.author.handle,
|
||||
displayName: post.author.displayName,
|
||||
},
|
||||
}));
|
||||
const postTargets = postTargetsRaw.map((post) => {
|
||||
const author = post.author as { id: string; handle: string; displayName: string | null };
|
||||
return {
|
||||
id: post.id,
|
||||
content: post.content,
|
||||
createdAt: post.createdAt,
|
||||
isRemoved: post.isRemoved,
|
||||
author: {
|
||||
id: author.id,
|
||||
handle: author.handle,
|
||||
displayName: author.displayName,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const userTargets = userTargetsRaw.map((user) => ({
|
||||
id: user.id,
|
||||
@@ -67,24 +70,30 @@ export async function GET(request: Request) {
|
||||
const postMap = new Map(postTargets.map((post) => [post.id, post]));
|
||||
const userMap = new Map(userTargets.map((user) => [user.id, user]));
|
||||
|
||||
const reportsWithTargets = reportRows.map((report) => ({
|
||||
id: report.id,
|
||||
targetType: report.targetType,
|
||||
targetId: report.targetId,
|
||||
reason: report.reason,
|
||||
status: report.status,
|
||||
createdAt: report.createdAt,
|
||||
reporter: report.reporter
|
||||
? { id: report.reporter.id, handle: report.reporter.handle }
|
||||
: null,
|
||||
resolver: report.resolver
|
||||
? { id: report.resolver.id, handle: report.resolver.handle }
|
||||
: null,
|
||||
target:
|
||||
report.targetType === 'post'
|
||||
? postMap.get(report.targetId) || null
|
||||
: userMap.get(report.targetId) || null,
|
||||
}));
|
||||
type UserInfo = { id: string; handle: string };
|
||||
|
||||
const reportsWithTargets = reportRows.map((report) => {
|
||||
const reporter = report.reporter as UserInfo | null;
|
||||
const resolver = report.resolver as UserInfo | null;
|
||||
return {
|
||||
id: report.id,
|
||||
targetType: report.targetType,
|
||||
targetId: report.targetId,
|
||||
reason: report.reason,
|
||||
status: report.status,
|
||||
createdAt: report.createdAt,
|
||||
reporter: reporter
|
||||
? { id: reporter.id, handle: reporter.handle }
|
||||
: null,
|
||||
resolver: resolver
|
||||
? { id: resolver.id, handle: resolver.handle }
|
||||
: null,
|
||||
target:
|
||||
report.targetType === 'post'
|
||||
? postMap.get(report.targetId) || null
|
||||
: userMap.get(report.targetId) || null,
|
||||
};
|
||||
});
|
||||
|
||||
return NextResponse.json({ reports: reportsWithTargets });
|
||||
} catch (error) {
|
||||
|
||||
@@ -24,6 +24,7 @@ export async function GET(request: Request) {
|
||||
isSilenced: users.isSilenced,
|
||||
silenceReason: users.silenceReason,
|
||||
createdAt: users.createdAt,
|
||||
isBot: users.isBot,
|
||||
})
|
||||
.from(users)
|
||||
.orderBy(desc(users.createdAt))
|
||||
|
||||
Reference in New Issue
Block a user