add form submission hooks
This commit is contained in:
parent
92261e78e4
commit
b3ba5cfc51
@ -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
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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<FormDocument>,
|
||||
@InjectModel(FormFieldSchemaName) private readonly formFieldModel: Model<FormFieldDocument>,
|
||||
@InjectModel(FormHookSchemaName) private readonly formHookModel: Model<FormHookDocument>,
|
||||
) {
|
||||
}
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -14,29 +14,32 @@ export class SubmissionHookService {
|
||||
}
|
||||
|
||||
public async process(submission: SubmissionDocument): Promise<void> {
|
||||
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<any> {
|
||||
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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user