-
Notifications
You must be signed in to change notification settings - Fork 0
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
feat: integrate webhooks in the indexer #114
feat: integrate webhooks in the indexer #114
Conversation
Signed-off-by: david <[email protected]>
Signed-off-by: david <[email protected]>
Signed-off-by: david <[email protected]>
Signed-off-by: david <[email protected]>
…o david/acx-3360-add-persistence-to-webhooks-package-1
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.
few nits + few questions. Looks great
const response = await fetch(url, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: `Bearer ${apiKey}`, |
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.
OOC - why did we go with fetch vs axios
?
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.
🤷♂️ this package was started with fetch
so I went with it too. Also, I am a fan of using as few external packages as possible
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.
axios
has a nicer syntax tho...
@@ -6,7 +6,7 @@ export interface IEventProcessor { | |||
id: string, | |||
url: string, | |||
params: JSONValue, | |||
clientId?: string, | |||
clientId: number, |
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.
Could we not represent a number as a numeric string?
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.
not sure I understand the question. This change happened because I updated the WebhookClient
primary key from a string id computed by us to an incremental number managed by postgres
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.
i tihnk he means its more flexible to keep this as a string and use number.toString or parseInt to convert from and to postgres
packages/webhooks/src/router.ts
Outdated
res: express.Response, | ||
next: express.NextFunction, | ||
) => { | ||
try { | ||
const parsedBody = RegistrationParams.create(req.body); | ||
if (!req.token) { |
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.
If we created a local token variable const token = req.token
and checked it directly then we wouldn't need to typecast below.
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.
fixed
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.
OOC what if two or more separate clients ask to send data to the same callback url?
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.
I don't think that's possible because we check the callback url agains the domains list from the WebhookClient
and that table is managed manually by us for now
const q = this.queues[queue]; | ||
if (q) { | ||
await q.add(queue, message, options); | ||
} |
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.
const q = this.queues[queue]; | |
if (q) { | |
await q.add(queue, message, options); | |
} | |
await this.queues[queue]?.add(queue, message, options); |
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.
We may want to use this in multiple spots
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.
@james-a-morris I plan to add a warn
|| error
log on else
, that's why I used if
); | ||
} | ||
|
||
private async run(webhookRequestJob: WebhookRequestQueueJob) { |
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.
really against putting this business logic here, im happy to take a crack at refactoring this in a future pr though.
i think what id do is basically pass in the eventprocessor manager in the webhookrequestworker constructor, then assume whenever "run" is called, its a webhook registration, and call "register" on the eventprocessormanager, which will call the correct event processor and put the logic for pulling in initial state and calling webhook in there.
its a subtle change, but means that we could remove this worker if everythign resides on the same process
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.
I agree that this is not the best approach, but what if I place this worker in the indexer package?
put the logic for pulling in initial state and calling webhook in there.
I do feel that the write()
function should be called only externally and not from the webhooks package. The package should only deal with forwarding notification payloads from our systems to clients and not dealing at all from where write()
is being called. It can be procedural code, cron jobs, Bull workers, etc. wdyt?
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.
we should discuss further offline, but as of now i think this is ok, we can figure out how to change later
@@ -101,7 +113,7 @@ export class EventProcessorManager { | |||
this.logger.debug( | |||
`Attempting to unregister webhook of type: ${params.type} with ID: ${params.id}`, | |||
); | |||
const webhook = this.getEventProcessor(params.type); | |||
const webhook = this.getEventProcessor(params.type as WebhookTypes); |
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.
could make a function to assert this
data: event, | ||
}); | ||
webhookRequests.map((hook) => { | ||
const client = clientsMap[hook.clientId]; |
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.
theres a lot of work above just to get this cache, not sure why u dont just make this function async(you are already using promise.all even though function is currently sync), and query for the client directly here, and delete all the code from 54-69
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.
I removed Promise.all(). Basically I don't want to fetch the client for each request because this will trigger many duplicated queries, so I fetch only the unique clients
@@ -6,7 +6,7 @@ export interface IEventProcessor { | |||
id: string, | |||
url: string, | |||
params: JSONValue, | |||
clientId?: string, | |||
clientId: number, |
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.
i tihnk he means its more flexible to keep this as a string and use number.toString or parseInt to convert from and to postgres
ae14e87
into
david/acx-3360-add-persistence-to-webhooks-package
Signed-off-by: david <[email protected]> Co-authored-by: david <[email protected]>
WebhookRequest
queue