feat: Implement webhook logic along with new entry typeform trigger
This commit is contained in:
@@ -2,6 +2,7 @@ import generateAuthUrl from './generate-auth-url';
|
||||
import verifyCredentials from './verify-credentials';
|
||||
import isStillVerified from './is-still-verified';
|
||||
import refreshToken from './refresh-token';
|
||||
import verifyWebhook from './verify-webhook';
|
||||
|
||||
export default {
|
||||
fields: [
|
||||
@@ -45,4 +46,5 @@ export default {
|
||||
verifyCredentials,
|
||||
isStillVerified,
|
||||
refreshToken,
|
||||
verifyWebhook,
|
||||
};
|
||||
|
20
packages/backend/src/apps/typeform/auth/verify-webhook.ts
Normal file
20
packages/backend/src/apps/typeform/auth/verify-webhook.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import crypto from 'crypto';
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import appConfig from '../../../config/app';
|
||||
|
||||
const verifyWebhook = async ($: IGlobalVariable) => {
|
||||
const signature = $.request.headers['typeform-signature'] as string;
|
||||
const isValid = verifySignature(signature, $.request.rawBody.toString());
|
||||
|
||||
return isValid;
|
||||
};
|
||||
|
||||
const verifySignature = function (receivedSignature: string, payload: string) {
|
||||
const hash = crypto
|
||||
.createHmac('sha256', appConfig.appSecretKey)
|
||||
.update(payload)
|
||||
.digest('base64');
|
||||
return receivedSignature === `sha256=${hash}`;
|
||||
};
|
||||
|
||||
export default verifyWebhook;
|
@@ -1,14 +1,16 @@
|
||||
import { IJSONObject } from '@automatisch/types';
|
||||
import appConfig from '../../../../config/app';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
|
||||
export default defineTrigger({
|
||||
name: 'New entry',
|
||||
key: 'newEntry',
|
||||
pollInterval: 15,
|
||||
type: 'webhook',
|
||||
description: 'Triggers when a new form submitted.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Form',
|
||||
key: 'form',
|
||||
key: 'formId',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'Pick a form to receive submissions.',
|
||||
@@ -26,7 +28,81 @@ export default defineTrigger({
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
// await getUserTweets($, { currentUser: true });
|
||||
async testRun($) {
|
||||
const createApiResponse = await $.http.get(
|
||||
`/forms/${$.step.parameters.formId}`
|
||||
);
|
||||
|
||||
const responsesApiResponse = await $.http.get(
|
||||
`/forms/${$.step.parameters.formId}/responses`
|
||||
);
|
||||
|
||||
const lastResponse = responsesApiResponse.data.items[0];
|
||||
|
||||
const computedResponseItem = {
|
||||
event_type: 'form_response',
|
||||
form_response: {
|
||||
form_id: $.step.parameters.formId,
|
||||
token: lastResponse.token,
|
||||
landed_at: lastResponse.landed_at,
|
||||
submitted_at: lastResponse.submitted_at,
|
||||
definion: {
|
||||
id: $.step.parameters.formId,
|
||||
title: createApiResponse.data.title,
|
||||
fields: createApiResponse.data?.fields?.map((field: IJSONObject) => ({
|
||||
id: field.id,
|
||||
ref: field.ref,
|
||||
type: field.type,
|
||||
title: field.title,
|
||||
properties: {},
|
||||
choices: (
|
||||
(field?.properties as IJSONObject)?.choices as IJSONObject[]
|
||||
)?.map((choice) => ({
|
||||
id: choice.id,
|
||||
label: choice.label,
|
||||
})),
|
||||
})),
|
||||
},
|
||||
answers: lastResponse.answers?.map((answer: IJSONObject) => ({
|
||||
type: answer.type,
|
||||
choice: {
|
||||
label: (answer?.choice as IJSONObject)?.label,
|
||||
},
|
||||
field: {
|
||||
id: (answer.field as IJSONObject).id,
|
||||
ref: (answer.field as IJSONObject).ref,
|
||||
type: (answer.field as IJSONObject).type,
|
||||
},
|
||||
})),
|
||||
},
|
||||
};
|
||||
|
||||
const dataItem = {
|
||||
raw: computedResponseItem,
|
||||
meta: {
|
||||
internalId: computedResponseItem.form_response.token,
|
||||
},
|
||||
};
|
||||
|
||||
$.pushTriggerItem(dataItem);
|
||||
},
|
||||
|
||||
async registerHook($) {
|
||||
const subscriptionPayload = {
|
||||
enabled: true,
|
||||
url: $.webhookUrl,
|
||||
secret: appConfig.appSecretKey,
|
||||
};
|
||||
|
||||
await $.http.put(
|
||||
`/forms/${$.step.parameters.formId}/webhooks/${$.flow.id}`,
|
||||
subscriptionPayload
|
||||
);
|
||||
},
|
||||
|
||||
async unregisterHook($) {
|
||||
await $.http.delete(
|
||||
`/forms/${$.step.parameters.formId}/webhooks/${$.flow.id}`
|
||||
);
|
||||
},
|
||||
});
|
||||
|
Reference in New Issue
Block a user