Skip to content

Commit

Permalink
Merge branch 'develop' into dependabot/npm_and_yarn/undici-5.26.3
Browse files Browse the repository at this point in the history
  • Loading branch information
ankushdharkar authored Dec 20, 2023
2 parents aed9cdd + 2a2308e commit 8575b71
Show file tree
Hide file tree
Showing 25 changed files with 675 additions and 68 deletions.
33 changes: 33 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Date: `<DATE>`

Developer Name: `<DEVELOPER NAME>`

----

## Issue Ticket Number:-
`<ISSUE NUMBER>`

## Description:
`<DESCRIPTION>`


Is Under Feature Flag
- [ ] Yes
- [ ] No

Database changes
- [ ] Yes
- [ ] No

Breaking changes (If your feature is breaking/missing something please mention pending tickets)
- [ ] Yes
- [ ] No

Is Development Tested?

- [ ] Yes
- [ ] No


### Add relevant Screenshot below ( e.g test coverage etc. )

17 changes: 12 additions & 5 deletions .github/workflows/production.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@ jobs:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v2
- uses: cloudflare/wrangler-action@2.0.0
- uses: actions/checkout@v3
- run: npm install
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{secrets.CLOUDFLARE_API_TOKEN}}
accountId: ${{secrets.CLOUDFLARE_ACCOUNT_ID}}
environment: ${{ vars.CURRENT_ENVIRONMENT }}
command: deploy --env ${{ vars.CURRENT_ENVIRONMENT }}
secrets: |
CRON_JOB_PRIVATE_KEY
CURRENT_ENVIRONMENT
CRON_JOB_PRIVATE_KEY
DISCORD_BOT_PRIVATE_KEY
DISCORD_BOT_API_URL
env:
CURRENT_ENVIRONMENT: production
CRON_JOB_PRIVATE_KEY: ${{secrets.CRON_JOB_PRIVATE_KEY}}
CLOUDFLARE_API_TOKEN: ${{secrets.CLOUDFLARE_API_TOKEN}}
CLOUDFLARE_ACCOUNT_ID: ${{secrets.CLOUDFLARE_ACCOUNT_ID}}
CURRENT_ENVIRONMENT: ${{vars.CURRENT_ENVIRONMENT}}
CRON_JOB_PRIVATE_KEY: ${{secrets.CRON_JOB_PRIVATE_KEY}}
DISCORD_BOT_PRIVATE_KEY: ${{secrets.DISCORD_BOT_PRIVATE_KEY}}
DISCORD_BOT_API_URL: ${{secrets.DISCORD_BOT_API_URL}}
17 changes: 12 additions & 5 deletions .github/workflows/staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@ jobs:
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v2
- uses: cloudflare/wrangler-action@2.0.0
- uses: actions/checkout@v3
- run: npm install
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{secrets.CLOUDFLARE_API_TOKEN}}
accountId: ${{secrets.CLOUDFLARE_ACCOUNT_ID}}
environment: ${{ vars.CURRENT_ENVIRONMENT }}
command: deploy --env ${{ vars.CURRENT_ENVIRONMENT }}
secrets: |
CRON_JOB_PRIVATE_KEY
CURRENT_ENVIRONMENT
CRON_JOB_PRIVATE_KEY
DISCORD_BOT_PRIVATE_KEY
DISCORD_BOT_API_URL
env:
CURRENT_ENVIRONMENT: staging
CRON_JOB_PRIVATE_KEY: ${{secrets.CRON_JOB_PRIVATE_KEY}}
CLOUDFLARE_API_TOKEN: ${{secrets.CLOUDFLARE_API_TOKEN}}
CLOUDFLARE_ACCOUNT_ID: ${{secrets.CLOUDFLARE_ACCOUNT_ID}}
CURRENT_ENVIRONMENT: ${{vars.CURRENT_ENVIRONMENT}}
CRON_JOB_PRIVATE_KEY: ${{secrets.CRON_JOB_PRIVATE_KEY}}
DISCORD_BOT_PRIVATE_KEY: ${{secrets.DISCORD_BOT_PRIVATE_KEY}}
DISCORD_BOT_API_URL: ${{secrets.DISCORD_BOT_API_URL}}
3 changes: 2 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ jobs:
- uses: actions/checkout@v2
- run: npm install
- run: npm run lint-check
- run: npm run format-check
- run: npm run format-check
- run: npm run test
7 changes: 7 additions & 0 deletions __mocks__/@tsndr/cloudflare-worker-jwt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const mockJwt = {
sign: jest.fn().mockImplementation(() => {
return "SIGNED_JWT";
}),
};

export default mockJwt;
10 changes: 5 additions & 5 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"ts-jest": "29.1.1",
"ts-node": "10.9.1",
"typescript": "5.1.6",
"wrangler": "3.0.0"
"wrangler": "3.1.1"
},
"dependencies": {
"@tsndr/cloudflare-worker-jwt": "2.2.1"
Expand Down
37 changes: 24 additions & 13 deletions src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { env } from '../types/global.types';
import { MISSED_UPDATES_DEVELOPMENT_ROLE_ID, MISSED_UPDATES_PROD_ROLE_ID, MISSED_UPDATES_STAGING_ROLE_ID } from '../constants/commons';
import { RDS_BASE_API_URL, RDS_BASE_DEVELOPMENT_API_URL, RDS_BASE_STAGING_API_URL } from '../constants/urls';
import { env, environment } from '../types/global.types';

export const handleConfig = (env: env) => {
let baseUrl: string;
if (env.CURRENT_ENVIRONMENT) {
if (env.CURRENT_ENVIRONMENT.toLowerCase() === 'production') {
baseUrl = 'https://api.realdevsquad.com';
} else {
baseUrl = 'https://staging-api.realdevsquad.com';
}
} else {
baseUrl = 'https://staging-api.realdevsquad.com';
}
return { baseUrl };
const config = (env: env) => {
const environment: environment = {
production: {
RDS_BASE_API_URL: RDS_BASE_API_URL,
DISCORD_BOT_API_URL: env.DISCORD_BOT_API_URL,
MISSED_UPDATES_ROLE_ID: MISSED_UPDATES_PROD_ROLE_ID,
},
staging: {
RDS_BASE_API_URL: RDS_BASE_STAGING_API_URL,
DISCORD_BOT_API_URL: env.DISCORD_BOT_API_URL,
MISSED_UPDATES_ROLE_ID: MISSED_UPDATES_STAGING_ROLE_ID,
},
default: {
RDS_BASE_API_URL: RDS_BASE_DEVELOPMENT_API_URL,
DISCORD_BOT_API_URL: env.DISCORD_BOT_API_URL,
MISSED_UPDATES_ROLE_ID: MISSED_UPDATES_DEVELOPMENT_ROLE_ID,
},
};

return environment[env.CURRENT_ENVIRONMENT] || environment.default;
};
export default config;
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const NAMESPACE_NAME = 'CronJobsTimestamp';

export { NAMESPACE_NAME };
3 changes: 3 additions & 0 deletions src/constants/commons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const MISSED_UPDATES_PROD_ROLE_ID = '1183553844811153458';
export const MISSED_UPDATES_STAGING_ROLE_ID = '1184201657404362772';
export const MISSED_UPDATES_DEVELOPMENT_ROLE_ID = '1181214205081296896';
7 changes: 7 additions & 0 deletions src/constants/urls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const RDS_BASE_API_URL = 'https://api.realdevsquad.com';
export const RDS_BASE_STAGING_API_URL = 'https://staging-api.realdevsquad.com';
export const RDS_BASE_DEVELOPMENT_API_URL = 'http://localhost:3000'; // If needed, modify the URL to your local API server run through ngrok

export const DISCORD_BOT_API_URL = 'env';
export const DISCORD_BOT_STAGING_API_URL = '';
export const DISCORD_BOT_DEVELOPMENT_API_URL = '';
96 changes: 92 additions & 4 deletions src/handlers/scheduledEventHandler.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,96 @@
import { handleConfig } from '../config/config';
import { env } from '../types/global.types';
import { KVNamespace } from '@cloudflare/workers-types';

import config from '../config/config';
import { NAMESPACE_NAME } from '../constants';
import { updateUserRoles } from '../services/discordBotServices';
import { getMissedUpdatesUsers } from '../services/rdsBackendService';
import { DiscordUserRole, env, NicknameUpdateResponseType } from '../types/global.types';
import { chunks } from '../utils/arrayUtils';
import { generateJwt } from '../utils/generateJwt';

export async function ping(env: env) {
const url = handleConfig(env);
const response = await fetch(`${url.baseUrl}/healthcheck`);
const url = config(env).RDS_BASE_API_URL;
const response = await fetch(`${url}/healthcheck`);
return response;
}

export async function callDiscordNicknameBatchUpdate(env: env) {
const namespace = env[NAMESPACE_NAME] as unknown as KVNamespace;
let lastNicknameUpdate: string | null = '0';
try {
lastNicknameUpdate = await namespace.get('DISCORD_NICKNAME_UPDATED_TIME');
if (lastNicknameUpdate === null) {
throw new Error('Error while fetching KV "DISCORD_NICKNAME_UPDATED_TIME" timestamp');
}
if (!lastNicknameUpdate) {
lastNicknameUpdate = '0';
}
} catch (err) {
console.error(err, 'Error while fetching the timestamp for last nickname update');
throw err;
}

const url = config(env).RDS_BASE_API_URL;
let token;
try {
token = await generateJwt(env);
} catch (err) {
console.error(`Error while generating JWT token: ${err}`);
throw err;
}
const response = await fetch(`${url}/discord-actions/nickname/status`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
lastNicknameUpdate,
}),
});
if (!response.ok) {
throw new Error("Error while trying to update users' discord nickname");
}

const data: NicknameUpdateResponseType = await response.json();
if (data?.data.unsuccessfulNicknameUpdates === 0) {
try {
await namespace.put('DISCORD_NICKNAME_UPDATED_TIME', Date.now().toString());
} catch (err) {
console.error('Error while trying to update the last nickname change timestamp');
}
}
return data;
}

export const addMissedUpdatesRole = async (env: env) => {
const MAX_ROLE_UPDATE = 25;
try {
let cursor: string | undefined = undefined;
for (let index = MAX_ROLE_UPDATE; index > 0; index--) {
if (index < MAX_ROLE_UPDATE && !cursor) break;

const missedUpdatesUsers = await getMissedUpdatesUsers(env, cursor);

if (!!missedUpdatesUsers && missedUpdatesUsers.usersToAddRole?.length > 1) {
const discordUserIdRoleIdList: DiscordUserRole[] = missedUpdatesUsers.usersToAddRole.map((userId) => ({
userid: userId,
roleid: config(env).MISSED_UPDATES_ROLE_ID,
}));

const discordUserRoleChunks = chunks(discordUserIdRoleIdList, MAX_ROLE_UPDATE);
for (const discordUserRoleList of discordUserRoleChunks) {
try {
await updateUserRoles(env, discordUserRoleList);
} catch (error) {
console.error('Error occurred while updating discord users', error);
}
}
}
cursor = missedUpdatesUsers?.cursor;
}
// add logs for the results https://github.com/Real-Dev-Squad/website-backend/issues/1784
} catch (err) {
console.error('Error while adding missed updates roles');
}
};
27 changes: 27 additions & 0 deletions src/services/discordBotServices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import config from '../config/config';
import { DiscordRoleUpdatedList, DiscordUserRole, env } from '../types/global.types';
import { generateDiscordBotJwt } from '../utils/generateJwt';

export const updateUserRoles = async (env: env, payload: DiscordUserRole[]): Promise<DiscordRoleUpdatedList> => {
try {
const url = config(env).DISCORD_BOT_API_URL;
const token = await generateDiscordBotJwt(env);

const response = await env.DISCORD_BOT.fetch(`${url}/roles?action=add-role`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw Error(`Role Update failed with status: ${response.status}`);
}
const data: DiscordRoleUpdatedList = await response.json();
return data;
} catch (error) {
console.error('Error while updating discord user roles');
throw error;
}
};
32 changes: 32 additions & 0 deletions src/services/rdsBackendService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import config from '../config/config';
import { DiscordUsersResponse, env } from '../types/global.types';
import { generateJwt } from '../utils/generateJwt';

export const getMissedUpdatesUsers = async (env: env, cursor: string | undefined) => {
try {
const baseUrl = config(env).RDS_BASE_API_URL;

const url = new URL(`${baseUrl}/tasks/users/discord`);
url.searchParams.append('q', 'status:missed-updates');
if (cursor) {
url.searchParams.append('cursor', cursor);
}
const token = await generateJwt(env);
const response = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`Fetch call to get user discord details failed with status: ${response.status}`);
}

const responseData: DiscordUsersResponse = await response.json();
return responseData?.data;
} catch (error) {
console.error('Error occurred while fetching discord user details');
throw error;
}
};
Loading

0 comments on commit 8575b71

Please sign in to comment.