mirror of https://github.com/buster-so/buster.git
Update should take chat screenshot
This commit is contained in:
parent
9d0a48aa67
commit
edcb3ad577
|
@ -1,12 +1,20 @@
|
||||||
|
import { screenshots_task_keys } from '@buster-app/trigger/task-keys';
|
||||||
|
import type { TakeChatScreenshotTrigger } from '@buster-app/trigger/task-schemas';
|
||||||
import { checkPermission } from '@buster/access-controls';
|
import { checkPermission } from '@buster/access-controls';
|
||||||
import type { User } from '@buster/database/queries';
|
import type { User } from '@buster/database/queries';
|
||||||
import { getChatWithDetails, getMessagesForChatWithUserDetails } from '@buster/database/queries';
|
import {
|
||||||
|
getChatWithDetails,
|
||||||
|
getMessagesForChatWithUserDetails,
|
||||||
|
getUserOrganizationId,
|
||||||
|
} from '@buster/database/queries';
|
||||||
import {
|
import {
|
||||||
GetChatRequestParamsSchema,
|
GetChatRequestParamsSchema,
|
||||||
GetChatRequestQuerySchema,
|
GetChatRequestQuerySchema,
|
||||||
type GetChatResponse,
|
type GetChatResponse,
|
||||||
} from '@buster/server-shared/chats';
|
} from '@buster/server-shared/chats';
|
||||||
import { zValidator } from '@hono/zod-validator';
|
import { zValidator } from '@hono/zod-validator';
|
||||||
|
import { shouldTakeScreenshot } from '@shared-helpers/screenshots';
|
||||||
|
import { tasks } from '@trigger.dev/sdk';
|
||||||
import { Hono } from 'hono';
|
import { Hono } from 'hono';
|
||||||
import { HTTPException } from 'hono/http-exception';
|
import { HTTPException } from 'hono/http-exception';
|
||||||
import { throwUnauthorizedError } from '../../../../shared-helpers/asset-public-access';
|
import { throwUnauthorizedError } from '../../../../shared-helpers/asset-public-access';
|
||||||
|
@ -40,6 +48,27 @@ const app = new Hono().get(
|
||||||
|
|
||||||
const response: GetChatResponse = await getChatHandler(getChatHandlerParams);
|
const response: GetChatResponse = await getChatHandler(getChatHandlerParams);
|
||||||
|
|
||||||
|
const tag = `take-chat-screenshot-${id}`;
|
||||||
|
if (
|
||||||
|
!response.screenshot_taken_at &&
|
||||||
|
(await shouldTakeScreenshot({
|
||||||
|
tag,
|
||||||
|
key: screenshots_task_keys.take_chat_screenshot,
|
||||||
|
context: c,
|
||||||
|
}))
|
||||||
|
) {
|
||||||
|
tasks.trigger(
|
||||||
|
screenshots_task_keys.take_chat_screenshot,
|
||||||
|
{
|
||||||
|
chatId: id,
|
||||||
|
isNewChatMessage: false,
|
||||||
|
organizationId: (await getUserOrganizationId(user.id))?.organizationId || '',
|
||||||
|
accessToken: c.get('accessToken'),
|
||||||
|
} satisfies TakeChatScreenshotTrigger,
|
||||||
|
{ tags: [tag] }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return c.json(response);
|
return c.json(response);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -207,6 +207,7 @@ export async function buildChatWithMessages(
|
||||||
permission,
|
permission,
|
||||||
workspace_sharing: chat.workspaceSharing || 'none',
|
workspace_sharing: chat.workspaceSharing || 'none',
|
||||||
workspace_member_count: workspaceMemberCount,
|
workspace_member_count: workspaceMemberCount,
|
||||||
|
screenshot_taken_at: chat.screenshotTakenAt || null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ const app = new Hono()
|
||||||
organizationId: (await getUserOrganizationId(user.id))?.organizationId || '',
|
organizationId: (await getUserOrganizationId(user.id))?.organizationId || '',
|
||||||
accessToken: c.get('accessToken'),
|
accessToken: c.get('accessToken'),
|
||||||
} satisfies TakeReportScreenshotTrigger,
|
} satisfies TakeReportScreenshotTrigger,
|
||||||
{ concurrencyKey: `take-report-screenshot-${reportId}-${versionNumber}` }
|
{ tags: [tag] }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@ import type { screenshots_task_keys } from '@buster-app/trigger/task-keys';
|
||||||
import { runs } from '@trigger.dev/sdk';
|
import { runs } from '@trigger.dev/sdk';
|
||||||
import type { Context } from 'hono';
|
import type { Context } from 'hono';
|
||||||
|
|
||||||
|
// This helper ensures that we do not run multiple trigger jobs for the same screenshot task concurrently.
|
||||||
|
// It checks if a job for the given tag and key is already running or queued before starting a new one.
|
||||||
|
|
||||||
export const shouldTakeScreenshot = async ({
|
export const shouldTakeScreenshot = async ({
|
||||||
tag,
|
tag,
|
||||||
key,
|
key,
|
||||||
|
|
|
@ -522,11 +522,12 @@ export const analystAgentTask: ReturnType<
|
||||||
const supabaseUser = await getSupabaseUser(payload.access_token);
|
const supabaseUser = await getSupabaseUser(payload.access_token);
|
||||||
if (supabaseUser) {
|
if (supabaseUser) {
|
||||||
await tasks.trigger(
|
await tasks.trigger(
|
||||||
screenshots_task_keys.take_chart_screenshot,
|
screenshots_task_keys.take_chat_screenshot,
|
||||||
{
|
{
|
||||||
chatId: messageContext.chatId,
|
chatId: messageContext.chatId,
|
||||||
organizationId: messageContext.organizationId,
|
organizationId: messageContext.organizationId,
|
||||||
accessToken: payload.access_token,
|
accessToken: payload.access_token,
|
||||||
|
isNewChatMessage: true,
|
||||||
} satisfies TakeChatScreenshotTrigger,
|
} satisfies TakeChatScreenshotTrigger,
|
||||||
{ concurrencyKey: `take-dashboard-screenshot-${payload.message_id}` }
|
{ concurrencyKey: `take-dashboard-screenshot-${payload.message_id}` }
|
||||||
);
|
);
|
||||||
|
|
|
@ -28,6 +28,7 @@ export type TakeReportScreenshotTrigger = z.infer<typeof TakeReportScreenshotTri
|
||||||
|
|
||||||
export const TakeChatScreenshotTriggerSchema = GetChatScreenshotHandlerArgsSchema.extend({
|
export const TakeChatScreenshotTriggerSchema = GetChatScreenshotHandlerArgsSchema.extend({
|
||||||
chatId: z.string(),
|
chatId: z.string(),
|
||||||
|
isNewChatMessage: z.boolean(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TakeChatScreenshotTrigger = z.infer<typeof TakeChatScreenshotTriggerSchema>;
|
export type TakeChatScreenshotTrigger = z.infer<typeof TakeChatScreenshotTriggerSchema>;
|
||||||
|
|
|
@ -1,22 +1,33 @@
|
||||||
|
import { hasChatScreenshotBeenTakenWithin } from '@buster/database/queries';
|
||||||
import { getChatScreenshot } from '@buster/server-shared/screenshots/methods';
|
import { getChatScreenshot } from '@buster/server-shared/screenshots/methods';
|
||||||
import { logger, schemaTask } from '@trigger.dev/sdk';
|
import { logger, schemaTask } from '@trigger.dev/sdk';
|
||||||
import { TakeChatScreenshotTriggerSchema } from './schemas';
|
import dayjs from 'dayjs';
|
||||||
|
import { type TakeChatScreenshotTrigger, TakeChatScreenshotTriggerSchema } from './schemas';
|
||||||
import { screenshots_task_keys } from './task-keys';
|
import { screenshots_task_keys } from './task-keys';
|
||||||
import { uploadScreenshotHandler } from './upload-screenshot-handler';
|
import { uploadScreenshotHandler } from './upload-screenshot-handler';
|
||||||
|
|
||||||
export const takeChartScreenshotHandlerTask: ReturnType<
|
export const takeChartScreenshotHandlerTask: ReturnType<
|
||||||
typeof schemaTask<
|
typeof schemaTask<
|
||||||
typeof screenshots_task_keys.take_chart_screenshot,
|
typeof screenshots_task_keys.take_chat_screenshot,
|
||||||
typeof TakeChatScreenshotTriggerSchema,
|
typeof TakeChatScreenshotTriggerSchema,
|
||||||
{ success: boolean } | undefined
|
{ success: boolean } | undefined
|
||||||
>
|
>
|
||||||
> = schemaTask({
|
> = schemaTask({
|
||||||
id: screenshots_task_keys.take_chart_screenshot,
|
id: screenshots_task_keys.take_chat_screenshot,
|
||||||
schema: TakeChatScreenshotTriggerSchema,
|
schema: TakeChatScreenshotTriggerSchema,
|
||||||
run: async (args) => {
|
run: async (args) => {
|
||||||
logger.info('Getting chart screenshot', { args });
|
logger.info('Getting chart screenshot', { args });
|
||||||
|
|
||||||
const { chatId, organizationId } = args;
|
const { chatId, isNewChatMessage, organizationId } = args;
|
||||||
|
|
||||||
|
const shouldTakeNewScreenshot = await shouldTakeChatScreenshot({
|
||||||
|
chatId,
|
||||||
|
isNewChatMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!shouldTakeNewScreenshot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const screenshotBuffer = await getChatScreenshot(args);
|
const screenshotBuffer = await getChatScreenshot(args);
|
||||||
|
|
||||||
|
@ -34,3 +45,18 @@ export const takeChartScreenshotHandlerTask: ReturnType<
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const shouldTakeChatScreenshot = async (
|
||||||
|
args: Pick<TakeChatScreenshotTrigger, 'chatId' | 'isNewChatMessage'>
|
||||||
|
) => {
|
||||||
|
if (args.isNewChatMessage) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isScreenshotExpired = await hasChatScreenshotBeenTakenWithin(
|
||||||
|
args.chatId,
|
||||||
|
dayjs().subtract(4, 'weeks')
|
||||||
|
);
|
||||||
|
|
||||||
|
return !isScreenshotExpired;
|
||||||
|
};
|
||||||
|
|
|
@ -2,6 +2,6 @@ export const screenshots_task_keys = {
|
||||||
take_metric_screenshot: 'take-metric-screenshot',
|
take_metric_screenshot: 'take-metric-screenshot',
|
||||||
take_dashboard_screenshot: 'take-dashboard-screenshot',
|
take_dashboard_screenshot: 'take-dashboard-screenshot',
|
||||||
take_report_screenshot: 'take-report-screenshot',
|
take_report_screenshot: 'take-report-screenshot',
|
||||||
take_chart_screenshot: 'take-chart-screenshot',
|
take_chat_screenshot: 'take-chart-screenshot',
|
||||||
take_collection_screenshot: 'take-collection-screenshot',
|
take_collection_screenshot: 'take-collection-screenshot',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -30,6 +30,7 @@ export const ChatWithMessagesSchema = z.object({
|
||||||
created_by_id: z.string(),
|
created_by_id: z.string(),
|
||||||
created_by_name: z.string(),
|
created_by_name: z.string(),
|
||||||
created_by_avatar: z.string().nullable(),
|
created_by_avatar: z.string().nullable(),
|
||||||
|
screenshot_taken_at: z.string().nullable(),
|
||||||
...ShareConfigSchema.shape,
|
...ShareConfigSchema.shape,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue