Skip to content

Commit

Permalink
[DEV-2017] Resync user on active campaign (#1269)
Browse files Browse the repository at this point in the history
* sync user wip

* sync user

* changeset

* Update .changeset/cuddly-cats-retire.md

Co-authored-by: Marco Ponchia <[email protected]>

* Update packages/active-campaign-client/src/index.ts

Co-authored-by: Marco Ponchia <[email protected]>

* Update packages/active-campaign-client/src/index.ts

Co-authored-by: Marco Ponchia <[email protected]>

* Update packages/active-campaign-client/src/helpers/resyncUser.ts

Co-authored-by: Marco Ponchia <[email protected]>

* pr comments

* Update packages/active-campaign-client/src/handlers/resyncUserHandler.ts

Co-authored-by: marcobottaro <[email protected]>

* Update packages/active-campaign-client/src/handlers/resyncUserHandler.ts

Co-authored-by: marcobottaro <[email protected]>

* pr changes

* pr changes

---------

Co-authored-by: t <[email protected]>
Co-authored-by: Marco Ponchia <[email protected]>
Co-authored-by: marcobottaro <[email protected]>
  • Loading branch information
4 people authored Dec 18, 2024
1 parent 63c19a7 commit 5e861a0
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-cats-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"active-campaign-client": minor
---

Add resync user handler
82 changes: 82 additions & 0 deletions packages/active-campaign-client/src/handlers/resyncUserHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { deleteContact } from '../helpers/deleteContact';
import { getUserFromCognitoUsername } from '../helpers/getUserFromCognito';
import { getSubscribedWebinars } from '../helpers/getSubscribedWebinars';
import { addContact } from '../helpers/addContact';
import { APIGatewayProxyResult, SQSEvent } from 'aws-lambda';
import { addContactToList } from '../helpers/manageListSubscription';
import { queueEventParser } from '../helpers/queueEventParser';

export async function resyncUserHandler(event: {
readonly Records: SQSEvent['Records'];
}): Promise<APIGatewayProxyResult> {
try {
const queueEvent = queueEventParser(event);
const cognitoUsername = queueEvent.detail.additionalEventData.sub;
const deletionResult = await deleteContact(cognitoUsername);
if (
deletionResult.statusCode !== 200 &&
deletionResult.statusCode !== 404
) {
// eslint-disable-next-line functional/no-throw-statements
throw new Error('Error adding contact');
}

const user = await getUserFromCognitoUsername(cognitoUsername);

if (!user) {
console.log(
`User: ${cognitoUsername} not present on Cognito, sync done.`
);
return {
statusCode: 200,
body: JSON.stringify({
message: 'User not present on Cognito, sync done.',
}),
};
}

const userWebinarsSubscriptions = await getSubscribedWebinars(
cognitoUsername
);

const webinarIds = JSON.parse(userWebinarsSubscriptions.body)
.map(
(webinar: { readonly webinarId: { readonly S: string } }) =>
webinar?.webinarId?.S
)
.filter(Boolean);

const res = await addContact(user);
if (res.statusCode !== 200) {
// eslint-disable-next-line functional/no-throw-statements
throw new Error('Error adding contact');
}

await webinarIds.reduce(
async (
prevPromise: Promise<APIGatewayProxyResult>,
webinarId: string
) => {
await prevPromise;
try {
const result = await addContactToList(cognitoUsername, webinarId);
console.log('Add contact to list result:', result, webinarId); // TODO: Remove after testing
await new Promise((resolve) => setTimeout(resolve, 1000)); // wait 1 sec to avoid rate limiting
} catch (e) {
console.error('Error adding contact to list', e); // TODO: Remove after testing
}
},
Promise.resolve()
);

return {
statusCode: 200,
body: JSON.stringify({ message: 'User resynced' }),
};
} catch (error) {
return {
statusCode: 500,
body: JSON.stringify({ message: error }),
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { DynamoDBClient, QueryCommand } from '@aws-sdk/client-dynamodb';
import { APIGatewayProxyResult } from 'aws-lambda';

export async function getSubscribedWebinars(
username: string
): Promise<APIGatewayProxyResult> {
try {
const dynamoClient = new DynamoDBClient({ region: process.env.AWS_REGION });
const command = new QueryCommand({
TableName: process.env.DYNAMO_WEBINARS_TABLE_NAME,
KeyConditionExpression: 'username = :username',
ExpressionAttributeValues: {
':username': { S: username },
},
});

const response = await dynamoClient.send(command);
console.log('getWebinarSubscriptions', response);
return {
statusCode: 200,
body: JSON.stringify(response.Items),
};
} catch (error) {
console.error('Error querying items by username:', error);
return {
statusCode: 500,
body: JSON.stringify({ message: 'Internal server error' }),
};
}
}
16 changes: 11 additions & 5 deletions packages/active-campaign-client/src/helpers/getUserFromCognito.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@ import { QueueEvent } from '../types/queueEvent';
import { listUsersCommandOutputToUser } from './listUsersCommandOutputToUser';

export async function getUserFromCognito(queueEvent: QueueEvent) {
const username = queueEvent.detail.additionalEventData.sub;
const user = await getUserFromCognitoUsername(username);
if (!user) {
// eslint-disable-next-line functional/no-throw-statements
throw new Error('User not found');
}
return user;
}

export async function getUserFromCognitoUsername(username: string) {
const command = new ListUsersCommand({
UserPoolId: process.env.COGNITO_USER_POOL_ID,
Filter: `username = "${queueEvent.detail.additionalEventData.sub}"`,
Filter: `username = "${username}"`,
});
const listUsersCommandOutput = await cognitoClient.send(command);
const user = listUsersCommandOutputToUser(listUsersCommandOutput);
if (!user) {
// eslint-disable-next-line functional/no-throw-statements
throw new Error('User not found');
}
console.log('User:', JSON.stringify(user, null, 2)); // TODO: Remove after testing
return user;
}
7 changes: 7 additions & 0 deletions packages/active-campaign-client/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { SQSEvent } from 'aws-lambda';
import { sqsQueueHandler } from './handlers/sqsQueueHandler';
import { resyncUserHandler } from './handlers/resyncUserHandler';

export async function sqsQueue(event: {
readonly Records: SQSEvent['Records'];
}) {
return await sqsQueueHandler(event);
}

export async function resyncQueue(event: {
readonly Records: SQSEvent['Records'];
}) {
return await resyncUserHandler(event);
}

0 comments on commit 5e861a0

Please sign in to comment.