-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix webhook issue #6711
Fix webhook issue #6711
Changes from 5 commits
d65b05f
3744da4
678bc66
d9ec628
2442e3a
0fe882a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,4 +45,4 @@ | |
} | ||
], | ||
"extends": "../../tsconfig.base.json" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,20 @@ | ||
import { Logger } from '@nestjs/common'; | ||
|
||
import { Like } from 'typeorm'; | ||
|
||
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface'; | ||
|
||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; | ||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; | ||
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; | ||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; | ||
import { | ||
CallWebhookJob, | ||
CallWebhookJobData, | ||
} from 'src/engine/api/graphql/workspace-query-runner/jobs/call-webhook.job'; | ||
import { InjectMessageQueue } from 'src/engine/integrations/message-queue/decorators/message-queue.decorator'; | ||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator'; | ||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator'; | ||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator'; | ||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; | ||
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service'; | ||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||
import { WebhookWorkspaceEntity } from 'src/modules/webhook/standard-objects/webhook.workspace-entity'; | ||
|
||
export enum CallWebhookJobsJobOperation { | ||
create = 'create', | ||
|
@@ -32,42 +34,38 @@ export class CallWebhookJobsJob { | |
private readonly logger = new Logger(CallWebhookJobsJob.name); | ||
|
||
constructor( | ||
private readonly workspaceDataSourceService: WorkspaceDataSourceService, | ||
private readonly dataSourceService: DataSourceService, | ||
@InjectMessageQueue(MessageQueue.webhookQueue) | ||
private readonly messageQueueService: MessageQueueService, | ||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager, | ||
) {} | ||
|
||
@Process(CallWebhookJobsJob.name) | ||
async handle(data: CallWebhookJobsJobData): Promise<void> { | ||
const dataSourceMetadata = | ||
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail( | ||
data.workspaceId, | ||
); | ||
const workspaceDataSource = | ||
await this.workspaceDataSourceService.connectToWorkspaceDataSource( | ||
const webhookRepository = | ||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WebhookWorkspaceEntity>( | ||
data.workspaceId, | ||
'webhook', | ||
); | ||
|
||
const nameSingular = data.objectMetadataItem.nameSingular; | ||
const operation = data.operation; | ||
const eventType = `${operation}.${nameSingular}`; | ||
const webhooks: { id: string; targetUrl: string }[] = | ||
await workspaceDataSource?.query( | ||
` | ||
SELECT * FROM ${dataSourceMetadata.schema}."webhook" | ||
WHERE operation LIKE '%${eventType}%' | ||
OR operation LIKE '%*.${nameSingular}%' | ||
OR operation LIKE '%${operation}.*%' | ||
OR operation LIKE '%*.*%' | ||
`, | ||
); | ||
const eventName = `${nameSingular}.${operation}`; | ||
|
||
const webhooks = await webhookRepository.find({ | ||
where: [ | ||
{ operation: Like(`%${eventName}%`) }, | ||
{ operation: Like(`%*.${operation}%`) }, | ||
{ operation: Like(`%${nameSingular}.*%`) }, | ||
{ operation: Like('%*.*%') }, | ||
], | ||
}); | ||
|
||
webhooks.forEach((webhook) => { | ||
this.messageQueueService.add<CallWebhookJobData>( | ||
CallWebhookJob.name, | ||
{ | ||
targetUrl: webhook.targetUrl, | ||
eventType, | ||
eventName, | ||
objectMetadata: { | ||
id: data.objectMetadataItem.id, | ||
nameSingular: data.objectMetadataItem.nameSingular, | ||
|
@@ -83,7 +81,7 @@ export class CallWebhookJobsJob { | |
|
||
if (webhooks.length) { | ||
this.logger.log( | ||
`CallWebhookJobsJob on eventType '${eventType}' called on webhooks ids [\n"${webhooks | ||
`CallWebhookJobsJob on eventName '${event}' called on webhooks ids [\n"${webhooks | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic: 'event' is undefined. Should be 'eventName'. |
||
.map((webhook) => webhook.id) | ||
.join('",\n"')}"\n]`, | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,24 +40,18 @@ export class UserService extends TypeOrmQueryService<User> { | |
return null; | ||
} | ||
|
||
console.time('loadWorkspaceMember repo'); | ||
const workspaceMemberRepository = | ||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>( | ||
user.defaultWorkspaceId, | ||
'workspaceMember', | ||
); | ||
|
||
console.timeEnd('loadWorkspaceMember repo'); | ||
|
||
console.time('loadWorkspaceMember find'); | ||
const workspaceMember = await workspaceMemberRepository.findOne({ | ||
where: { | ||
userId: user.id, | ||
}, | ||
}); | ||
|
||
console.timeEnd('loadWorkspaceMember find'); | ||
|
||
return workspaceMember; | ||
} | ||
|
||
|
@@ -66,21 +60,14 @@ export class UserService extends TypeOrmQueryService<User> { | |
return []; | ||
} | ||
|
||
console.time('loadWorkspaceMembers repo'); | ||
const workspaceMemberRepository = | ||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkspaceMemberWorkspaceEntity>( | ||
workspace.id, | ||
'workspaceMember', | ||
); | ||
|
||
console.timeEnd('loadWorkspaceMembers repo'); | ||
|
||
console.time('loadWorkspaceMembers find'); | ||
|
||
const workspaceMembers = workspaceMemberRepository.find(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic: Missing await keyword for asynchronous operation |
||
|
||
console.timeEnd('loadWorkspaceMembers find'); | ||
|
||
return workspaceMembers; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,15 +16,13 @@ export class CacheManager<T> { | |
return this.cache.get(cacheKey)!; | ||
} | ||
|
||
// Remove old entries with the same workspaceId | ||
for (const key of this.cache.keys()) { | ||
if (key.startsWith(`${workspaceId}-`)) { | ||
await onDelete?.(this.cache.get(key)!); | ||
this.cache.delete(key); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: Consider using |
||
|
||
// Create a new value using the factory callback | ||
const value = await factory(); | ||
|
||
if (!value) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Consider using an array of strings for operations and use
In
operator instead of multipleLike
conditions for better performance.