-
Notifications
You must be signed in to change notification settings - Fork 2
Auxia Integration (Part 1) #1265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
6a80812
introduce the auxia router as a copy of the header router
shtukas f25a160
First version of an Auxia answer
shtukas e057528
skeleton of the auxia proxy
shtukas a366670
implement call to auxia and returning correct values to the client
shtukas b087d9a
move API key to Parameter store
shtukas d7d0bff
move config to Parameter Store
shtukas 3b8a958
remove unecessary comments
shtukas 0770b4e
remove comment
shtukas 8f4af1b
remove comment
shtukas 05e20e5
allow access ssm parameters
shtukas b8ee9be
get credentials from s3 (temporary)
shtukas d13317d
refactor ssm
tomrf1 c659342
update lock
tomrf1 10fdff4
tidy up
tomrf1 d07786a
tidy up
tomrf1 24931fb
Merge pull request #1267 from guardian/tf-fix-ssm
shtukas File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,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); | ||
shtukas marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| 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; | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import * as AWS from 'aws-sdk'; | ||
|
|
||
| export async function getSsmValue(stage: string, id: string): Promise<string | undefined> { | ||
| const name = `/membership/support-dotcom-components/${stage}/${id}`; | ||
| const client = new AWS.SSM({ region: 'eu-west-1' }); | ||
|
|
||
| const response = await client | ||
| .getParameter({ | ||
| Name: name, | ||
| }) | ||
| .promise(); | ||
|
|
||
| return response.Parameter?.Value; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.