Skip to content

Commit

Permalink
Merge pull request #208 from mattzcarey/feat/lambda-welcome-email
Browse files Browse the repository at this point in the history
feat: add welcome email to add user lambda
  • Loading branch information
SEBRATHEZEBRA authored Aug 23, 2023
2 parents 447c894 + e17a688 commit c5c3f48
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 67 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
GITHUB_SHA: ${{ github.sha }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
CLOUDFLARE_WORKER_HEALTH_URL: ${{ secrets.CLOUDFLARE_WORKER_HEALTH_URL }}

steps:
- uses: actions/checkout@v2
Expand All @@ -35,6 +36,9 @@ jobs:

- name: Run unit tests
run: npm run test-unit

- name: Run integration tests
run: npm run test-integ

- name: Run prompt tests
run: npm run test -- --ci=github --model=gpt-3.5-turbo
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testRegex: '/src/.*.test.ts',
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"start": "ts-node ./src/index.ts review",
"test": "ts-node ./src/index.ts test",
"test-unit": "dotenv -e .env jest",
"test-integ": "jest -c services/tests/jest.config.js",
"build": "node utils/build.js",
"postbuild": "node utils/shebang.js && chmod +x ./dist/index.js"
},
Expand Down
13 changes: 13 additions & 0 deletions services/tests/emailWorker.integ.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as dotenv from 'dotenv';

dotenv.config({ path: './services/tests/.env' });

describe("CloudFlare email worker health test", () => {
test("Should return 200 after successfully hitting the CloudFlare health endpoint", async() => {
const res = await fetch(process.env.CLOUDFLARE_WORKER_HEALTH_URL ?? "", {
method: "GET",
});

expect(res.status).toEqual(200);
});
});
6 changes: 6 additions & 0 deletions services/tests/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testRegex: '/services/tests/.*.integ.test.ts',
};
4 changes: 3 additions & 1 deletion services/web-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
Involves starting our SST dev environment.

```bash
npx sst dev
npx sst dev --stage <stage>
```

Remember to use the same stage for both your SST and CDK stack.

Next in a separate terminal:

```bash
Expand Down
89 changes: 89 additions & 0 deletions services/web-app/functions/add-user/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { DynamoDBStreamEvent } from "aws-lambda";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { PutCommand, DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
import fetch from "node-fetch";
import { getVariableFromSSM } from "../../../core/functions/helpers/getVariable";
import { Config } from "sst/node/config";

const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);

const postEmail = async(email: string, name: string) => {
const url = await getVariableFromSSM(process.env.CLOUDFLARE_WORKER_URL_NAME) ?? "";
return await fetch(url.concat("api/email"), {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": await getVariableFromSSM(
process.env.CLOUDFLARE_WORKER_TOKEN_NAME ?? ""
),
},
body: JSON.stringify({
"to": {"email": email, "name": name },
"from": { "email": "[email protected]", "name": "Matt from Orion Tools" },
"subject": "Welcome to Code Review GPT",
"html": "<p>Thanks for signing up for Orion tools. We aim to make the best AI powered dev tools. We hope you enjoy using our code review product. <br/>Here is a <a href=\"https://github.com/mattzcarey/code-review-gpt\">link</a> to the repo, give it a star. Here is a <a href=\"https://join.slack.com/t/orion-tools/shared_invite/zt-20x79nfgm-UGIHK1uWGQ59JQTpODYDwg\">link</a> to our slack community.</p>"
}),
});
};

export const main = async (event: DynamoDBStreamEvent) => {
if (event.Records == null) {
return Promise.resolve({
statusCode: 400,
body: "The request does not contain a any dynamodb records as expected.",
});
}

try {
if (event.Records[0].dynamodb?.NewImage) {
const record = event.Records[0].dynamodb?.NewImage;
const userId = record.id['S'];
const name = record.name['S'];
const email = record.email['S'];
const pictureUrl = record.image['S'];

if (userId === undefined || name === undefined || email === undefined || pictureUrl === undefined) {
return Promise.resolve({
statusCode: 400,
body: "The request record does not contain the expected data.",
});
}

const res = await postEmail(email, name);
if (!res.ok) {
console.error("Failed to send welcome email due to this status code: ", res.status);
}

const command = new PutCommand({
TableName: `${process.env.SST_STAGE}-crgpt-data`,
Item: {
PK: `USERID#${userId}`,
SK: "ROOT",
userId: userId,
name: name,
email: email,
pictureUrl: pictureUrl,
},
});
await docClient.send(command);

return Promise.resolve({
statusCode: 200,
body: "Successfully added new user to the user db",
});
} else {
return Promise.resolve({
statusCode: 400,
body: "Dynamodb record did not contain any new users",
});
}
} catch (err) {
console.error(err);

return Promise.resolve({
statusCode: 500,
body: "Error when updating user.",
});
}
};
18 changes: 18 additions & 0 deletions services/web-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions services/web-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
"typescript": "5.1.6"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.119",
"@types/node-fetch": "^2.6.4",
"aws-cdk-lib": "2.84.0",
"constructs": "10.1.156",
"sst": "^2.22.10"
Expand Down
61 changes: 0 additions & 61 deletions services/web-app/src/functions/add-user/index.ts

This file was deleted.

10 changes: 5 additions & 5 deletions services/web-app/sst.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Tags } from "aws-cdk-lib";
import { SSTConfig } from "sst";
import { Config, NextjsSite, Table } from "sst/constructs";
import { getStage } from '../core/helpers';

export default {
config(_input) {
Expand Down Expand Up @@ -34,11 +33,12 @@ export default {
consumers: {
consumer1: {
function: {
handler: "src/functions/add-user/index.main",
permissions: ["dynamodb"],
handler: "/functions/add-user/index.main",
permissions: ["dynamodb", "ssm"],
environment: {
STAGE: getStage(),
}
CLOUDFLARE_WORKER_TOKEN_NAME: "CLOUDFLARE_WORKER_TOKEN",
CLOUDFLARE_WORKER_URL_NAME: "CLOUDFLARE_WORKER_URL",
},
},
filters: [
{
Expand Down

0 comments on commit c5c3f48

Please sign in to comment.