diff --git a/src/dto/form/form.update.input.ts b/src/dto/form/form.update.input.ts index 392d957..69d3dfb 100644 --- a/src/dto/form/form.update.input.ts +++ b/src/dto/form/form.update.input.ts @@ -1,6 +1,7 @@ import { Field, ID, InputType } from '@nestjs/graphql'; import { DesignInput } from './design.input'; import { FormFieldInput } from './form.field.input'; +import { FormHookInput } from './form.hook.input' import { PageInput } from './page.input'; import { RespondentNotificationsInput } from './respondent.notifications.input'; import { SelfNotificationsInput } from './self.notifications.input'; @@ -25,6 +26,9 @@ export class FormUpdateInput { @Field(() => [FormFieldInput], { nullable: true }) readonly fields: FormFieldInput[] + @Field(() => [FormHookInput], { nullable: true }) + readonly hooks: FormHookInput[] + @Field({ nullable: true }) readonly design: DesignInput diff --git a/src/schema/form.schema.ts b/src/schema/form.schema.ts index db3964e..b5a1229 100644 --- a/src/schema/form.schema.ts +++ b/src/schema/form.schema.ts @@ -3,7 +3,7 @@ import { matchType } from '../config/fields'; import { defaultLanguage, languages } from '../config/languages'; import { ButtonDocument, ButtonSchema } from './button.schema'; import { FormFieldDocument, FormFieldSchema } from './form.field.schema'; -import { FormHookDocument } from './form.hook.schema' +import { FormHookDocument, FormHookSchema } from './form.hook.schema' import { UserDocument, UserSchemaName } from './user.schema'; import { VisitorDataDocument, VisitorDataSchema } from './visitor.data.schema'; @@ -118,6 +118,10 @@ export const FormSchema = new Schema({ type: [FormFieldSchema], default: [], }, + hooks: { + type: [FormHookSchema], + default: [], + }, admin: { type: Schema.Types.ObjectId, ref: UserSchemaName, diff --git a/src/service/form/form.update.service.ts b/src/service/form/form.update.service.ts index c4cc5ea..1682d1b 100644 --- a/src/service/form/form.update.service.ts +++ b/src/service/form/form.update.service.ts @@ -3,6 +3,7 @@ import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { FormUpdateInput } from '../../dto/form/form.update.input'; import { FormFieldDocument, FormFieldSchemaName } from '../../schema/form.field.schema'; +import { FormHookDocument, FormHookSchemaName } from '../../schema/form.hook.schema' import { FormDocument, FormSchemaName } from '../../schema/form.schema'; @Injectable() @@ -10,6 +11,7 @@ export class FormUpdateService { constructor( @InjectModel(FormSchemaName) private readonly formModel: Model, @InjectModel(FormFieldSchemaName) private readonly formFieldModel: Model, + @InjectModel(FormHookSchemaName) private readonly formHookModel: Model, ) { } @@ -71,6 +73,27 @@ export class FormUpdateService { form.set('fields', nextFields) } + if (input.hooks !== undefined) { + const nextHooks = input.hooks.map((nextHook) => { + let hook = form.hooks && form.hooks.find(hook => hook.id.toString() === nextHook.id) + + if (!hook) { + hook = new this.formHookModel({}) + } + + // ability for other fields to apply mapping + hook.set('url', nextHook.url) + + if (nextHook.format !== undefined) { + hook.set('format', nextHook.format) + } + + return hook + }) + + form.set('hooks', nextHooks) + } + const extractField = (id) => { if (id && fieldMapping[id]) { return fieldMapping[id] diff --git a/src/service/submission/submission.hook.service.ts b/src/service/submission/submission.hook.service.ts index c84e7ff..371af3d 100644 --- a/src/service/submission/submission.hook.service.ts +++ b/src/service/submission/submission.hook.service.ts @@ -14,29 +14,32 @@ export class SubmissionHookService { } public async process(submission: SubmissionDocument): Promise { + if (!submission.populated('form')) { + submission.populate('form') + await submission.execPopulate() + } + await Promise.all(submission.form.hooks.map(async (hook) => { if (!hook.enabled) { return } try { - await this.httpService.post( + const response = await this.httpService.post( hook.url, await this.format(submission, hook.format) - ) + ).toPromise() + + console.log('sent', response.data) } catch (e) { this.logger.error(`failed to post to "${hook.url}: ${e.message}`) + this.logger.error(e.stack) throw e } })) } private async format(submission: SubmissionDocument, format?: string): Promise { - if (!submission.populated('form')) { - submission.populate('form') - await submission.execPopulate() - } - const fields = {} submission.form.fields.forEach((field) => { fields[field.id] = field @@ -48,12 +51,15 @@ export class SubmissionHookService { created: submission.created, lastModified: submission.lastModified, fields: submission.fields.map((submissionField) => { - const formField = submission.form.fields.find(formField => formField.id.toString() === submissionField.field) + const formField = submission.form.fields.find(formField => formField.id.toString() === submissionField.field) || { + id: submissionField.field, + slug: null + } return { field: formField.id, slug: formField.slug || null, - value: submissionField.fieldValue + ...submissionField.fieldValue } }) }