-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathauxiaProxyRouter.ts
More file actions
162 lines (134 loc) · 4.39 KB
/
auxiaProxyRouter.ts
File metadata and controls
162 lines (134 loc) · 4.39 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import express, { Router } from 'express';
import { getSsmValue } from '../utils/ssm';
export interface AuxiaRouterConfig {
apiKey: string;
projectId: string;
userId: string;
}
interface AuxiaApiRequestPayloadContextualAttributes {
key: string;
stringValue: string;
}
interface AuxiaApiRequestPayloadSurface {
surface: string;
minimumTreatmentCount: number;
maximumTreatmentCount: number;
}
interface AuxiaAPIRequestPayload {
projectId: string;
userId: string;
contextualAttributes: AuxiaApiRequestPayloadContextualAttributes[];
surfaces: AuxiaApiRequestPayloadSurface[];
languageCode: string;
}
interface AuxiaAPIAnswerDataUserTreatment {
treatmentId: string;
treatmentTrackingId: string;
rank: string;
contentLanguageCode: string;
treatmentContent: string;
treatmentType: string;
surface: string;
}
interface AuxiaAPIAnswerData {
responseId: string;
userTreatments: AuxiaAPIAnswerDataUserTreatment[];
}
interface AuxiaProxyResponseData {
shouldShowSignInGate: boolean;
}
const buildAuxiaAPIRequestPayload = (projectId: string, userId: string): AuxiaAPIRequestPayload => {
// For the moment we are hard coding the data provided in contextualAttributes and surfaces.
return {
projectId: projectId,
userId: userId,
contextualAttributes: [
{
key: 'profile_id',
stringValue: 'pr1234',
},
{
key: 'last_action',
stringValue: 'button_x_clicked',
},
],
surfaces: [
{
surface: 'ARTICLE_PAGE',
minimumTreatmentCount: 1,
maximumTreatmentCount: 5,
},
],
languageCode: 'en-GB',
};
};
const fetchAuxiaData = async (
apiKey: string,
projectId: string,
userId: string,
): Promise<AuxiaAPIAnswerData> => {
const url = 'https://apis.auxia.io/v1/GetTreatments';
const headers = {
'Content-Type': 'application/json',
'x-api-key': apiKey,
};
const payload = buildAuxiaAPIRequestPayload(projectId, userId);
const params = {
method: 'POST',
headers: headers,
body: JSON.stringify(payload),
};
const response = await fetch(url, params);
const responseBody = await response.json();
return Promise.resolve(responseBody as AuxiaAPIAnswerData);
};
const buildAuxiaProxyResponseData = (auxiaData: AuxiaAPIAnswerData): AuxiaProxyResponseData => {
// This is the most important function of this router, it takes the answer from auxia and
// and decides if the sign in gate should be shown or not.
// In the current interpretation we are saying that a non empty userTreatments array means
// that the sign in gate should be shown.
const shouldShowSignInGate = auxiaData.userTreatments.length > 0;
return { shouldShowSignInGate };
};
export const getAuxiaRouterConfig = async (): Promise<AuxiaRouterConfig> => {
const apiKey = await getSsmValue('PROD', 'auxia-api-key');
if (apiKey === undefined) {
throw new Error('auxia-api-key is undefined');
}
const projectId = await getSsmValue('PROD', 'auxia-projectId');
if (projectId === undefined) {
throw new Error('auxia-projectId is undefined');
}
const userId = await getSsmValue('PROD', 'auxia-userId');
if (userId === undefined) {
throw new Error('auxia-userId is undefined');
}
return Promise.resolve({
apiKey,
projectId,
userId,
});
};
export const buildAuxiaProxyRouter = (config: AuxiaRouterConfig): Router => {
const router = Router();
router.post(
'/auxia',
// We are disabling that check for now, we will re-enable it later when we have a
// better understanding of the request payload.
// bodyContainsAllFields(['tracking', 'targeting']),
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
try {
const auxiaData = await fetchAuxiaData(
config.apiKey,
config.projectId,
config.userId,
);
const response = buildAuxiaProxyResponseData(auxiaData);
res.send(response);
} catch (error) {
next(error);
}
},
);
return router;
};