-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
98 lines (88 loc) · 3.11 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
import * as awsx from '@pulumi/awsx';
import answersWebhookHandler from './answers-webhook-handler';
import answersRetrievalHandler from './answers-retrieval-handler';
import variantRevisionDeployedHandler from './variant-revision-deployed-handler';
const RESOURCE_NAME = 'my-formsort-answers';
const ANSWERS_WEBHOOK_PATH = 'api/answers-ingest';
const DEPLOYED_WEBHOOK_PATH = 'api/variant-revision-deployed';
const ANSWERS_RETRIEVAL_PATH = 'api/answers-retrieval';
const config = new pulumi.Config();
const formsortAPIKey = config.getSecret('formsortAPIKey');
const formsortWebhookSigningKey = config.getSecret('formsortWebhookSigningKey');
// Create an S3 bucket to store received answer webhooks
const answersBucket = new aws.s3.Bucket(RESOURCE_NAME);
const flowContentsBucket = new aws.s3.Bucket(`${RESOURCE_NAME}-flow-contents`);
const answersTable = new aws.dynamodb.Table('answersWebhookTable', {
attributes: [{ name: 'responder_uuid', type: 'S' }],
hashKey: 'responder_uuid',
billingMode: 'PAY_PER_REQUEST',
});
const answersWebhookLambda = new aws.lambda.CallbackFunction(
'answers-webhook-handler',
{
runtime: 'nodejs18.x',
callback: answersWebhookHandler,
environment: {
variables: {
ANSWERS_BUCKET_NAME: answersBucket.id,
ANSWERS_DYNAMO_TABLE_NAME: answersTable.name,
FORMSORT_WEBHOOK_SIGNING_KEY: formsortWebhookSigningKey ?? '',
},
},
}
);
const answersRetrievalLambda = new aws.lambda.CallbackFunction(
'answers-retrieval-handler',
{
runtime: 'nodejs18.x',
callback: answersRetrievalHandler,
environment: {
variables: {
ANSWERS_DYNAMO_TABLE_NAME: answersTable.name,
FLOW_CONTENTS_BUCKET_ID: flowContentsBucket.id,
FORMSORT_API_KEY: formsortAPIKey ?? '',
},
},
}
);
const variantRevisionDeployedLambda = new aws.lambda.CallbackFunction(
'variant-deployed-handler',
{
runtime: 'nodejs18.x',
callback: variantRevisionDeployedHandler,
environment: {
variables: {
FLOW_CONTENTS_BUCKET_ID: flowContentsBucket.id,
},
},
}
);
// Create an API gateway to expose the lambdas
const endpoint = new awsx.classic.apigateway.API(RESOURCE_NAME, {
routes: [
{
path: `/${ANSWERS_WEBHOOK_PATH}`,
method: 'POST',
eventHandler: answersWebhookLambda,
contentType: 'application/json',
},
{
// TODO: This route needs an authorizer, otherwise anyone is able to retrieve answers.
path: `/${ANSWERS_RETRIEVAL_PATH}`,
method: 'GET',
eventHandler: answersRetrievalLambda,
},
{
path: `/${DEPLOYED_WEBHOOK_PATH}`,
method: 'POST',
contentType: 'application/json',
eventHandler: variantRevisionDeployedLambda,
},
],
});
// Export variables useful for configuration
export const answersWebhookURL = pulumi.interpolate`${endpoint.url}${ANSWERS_WEBHOOK_PATH}`;
export const deploymentEventURL = pulumi.interpolate`${endpoint.url}${DEPLOYED_WEBHOOK_PATH}`;
export const answersRetrievalURL = pulumi.interpolate`${endpoint.url}${ANSWERS_RETRIEVAL_PATH}`;