diff --git a/packages/nocodb/src/services/hook-handler.service.ts b/packages/nocodb/src/services/hook-handler.service.ts index a64b248b1e..a204e89c9f 100644 --- a/packages/nocodb/src/services/hook-handler.service.ts +++ b/packages/nocodb/src/services/hook-handler.service.ts @@ -29,117 +29,125 @@ export class HookHandlerService implements OnModuleInit, OnModuleDestroy { context: NcContext, { hookName, prevData, newData, user, viewId, modelId, tnPath }, ): Promise { - const view = await View.get(context, viewId); - const model = await Model.get(context, modelId); + try { + const view = await View.get(context, viewId); + const model = await Model.get(context, modelId); - // handle form view data submission - if ( - (hookName === 'after.insert' || hookName === 'after.bulkInsert') && - view.type === ViewTypes.FORM - ) { - try { - const formView = await view.getView(context); - - const emails = Object.entries(JSON.parse(formView?.email) || {}) - .filter((a) => a[1]) - .map((a) => a[0]); + // handle form view data submission + if ( + (hookName === 'after.insert' || hookName === 'after.bulkInsert') && + view.type === ViewTypes.FORM + ) { + try { + const formView = await view.getView(context); - if (emails?.length) { - const { columns } = await FormView.getWithInfo( - context, - formView.fk_view_id, - ); - const allColumns = await model.getColumns(context); - const fieldById = columns.reduce( - (o: Record, f: FormColumnType) => { - return Object.assign(o, { [f.fk_column_id]: f }); - }, - {}, - ); - let order = 1; - const filteredColumns = allColumns - ?.map((c: ColumnType) => { - return { - ...c, - fk_column_id: c.id, - fk_view_id: formView.fk_view_id, - ...(fieldById[c.id] ? fieldById[c.id] : {}), - order: (fieldById[c.id] && fieldById[c.id].order) || order++, - id: fieldById[c.id] && fieldById[c.id].id, - }; - }) - .sort((a: ColumnType, b: ColumnType) => a.order - b.order) - .filter( - (f: ColumnType & FormColumnType) => - f.show && - f.uidt !== UITypes.Rollup && - f.uidt !== UITypes.Lookup && - f.uidt !== UITypes.Formula && - f.uidt !== UITypes.QrCode && - f.uidt !== UITypes.Barcode && - f.uidt !== UITypes.SpecificDBType, - ) - .sort((a: ColumnType, b: ColumnType) => a.order - b.order) - .map((c: ColumnType & FormColumnType) => { - c.required = !!(c.required || 0); - return c; - }); + const emails = Object.entries(JSON.parse(formView?.email) || {}) + .filter((a) => a[1]) + .map((a) => a[0]); - const transformedData = _transformSubmittedFormDataForEmail( - newData, - formView, - filteredColumns, - ); - (await NcPluginMgrv2.emailAdapter(false))?.mailSend({ - to: emails.join(','), - subject: 'NocoDB Form', - html: ejs.render(formSubmissionEmailTemplate, { - data: transformedData, - tn: tnPath, - _tn: model.title, - }), - }); - } - } catch (e) { - this.logger.error({ - error: e, - details: 'Error while sending form submission email', - hookName, - }); - } - } + if (emails?.length) { + const { columns } = await FormView.getWithInfo( + context, + formView.fk_view_id, + ); + const allColumns = await model.getColumns(context); + const fieldById = columns.reduce( + (o: Record, f: FormColumnType) => { + return Object.assign(o, { [f.fk_column_id]: f }); + }, + {}, + ); + let order = 1; + const filteredColumns = allColumns + ?.map((c: ColumnType) => { + return { + ...c, + fk_column_id: c.id, + fk_view_id: formView.fk_view_id, + ...(fieldById[c.id] ? fieldById[c.id] : {}), + order: (fieldById[c.id] && fieldById[c.id].order) || order++, + id: fieldById[c.id] && fieldById[c.id].id, + }; + }) + .sort((a: ColumnType, b: ColumnType) => a.order - b.order) + .filter( + (f: ColumnType & FormColumnType) => + f.show && + f.uidt !== UITypes.Rollup && + f.uidt !== UITypes.Lookup && + f.uidt !== UITypes.Formula && + f.uidt !== UITypes.QrCode && + f.uidt !== UITypes.Barcode && + f.uidt !== UITypes.SpecificDBType, + ) + .sort((a: ColumnType, b: ColumnType) => a.order - b.order) + .map((c: ColumnType & FormColumnType) => { + c.required = !!(c.required || 0); + return c; + }); - const [event, operation] = hookName.split('.'); - const hooks = await Hook.list(context, { - fk_model_id: modelId, - event: event as HookType['event'], - operation: operation as HookType['operation'], - }); - for (const hook of hooks) { - if (hook.active) { - try { - await this.jobsService.add(JobTypes.HandleWebhook, { - context, - hookId: hook.id, - modelId, - viewId, - prevData, - newData, - user, - }); + const transformedData = _transformSubmittedFormDataForEmail( + newData, + formView, + filteredColumns, + ); + (await NcPluginMgrv2.emailAdapter(false))?.mailSend({ + to: emails.join(','), + subject: 'NocoDB Form', + html: ejs.render(formSubmissionEmailTemplate, { + data: transformedData, + tn: tnPath, + _tn: model.title, + }), + }); + } } catch (e) { this.logger.error({ error: e, - details: 'Error while invoking webhook', - hook: hook.id, + details: 'Error while sending form submission email', + hookName, }); } } + + const [event, operation] = hookName.split('.'); + const hooks = await Hook.list(context, { + fk_model_id: modelId, + event: event as HookType['event'], + operation: operation as HookType['operation'], + }); + for (const hook of hooks) { + if (hook.active) { + try { + await this.jobsService.add(JobTypes.HandleWebhook, { + context, + hookId: hook.id, + modelId, + viewId, + prevData, + newData, + user, + }); + } catch (e) { + this.logger.error({ + error: e, + details: 'Error while invoking webhook', + hook: hook.id, + }); + } + } + } + } catch (e) { + this.logger.error({ + error: e, + details: 'Error while handling hook', + hookName, + }); } } onModuleInit(): any { - this.unsubscribe = this.eventEmitter.on(HANDLE_WEBHOOK, async (arg) => { + this.unsubscribe = this.eventEmitter.on(HANDLE_WEBHOOK, (arg) => { const { context, ...rest } = arg; return this.handleHooks(context, rest); });