Skip to content

Commit

Permalink
Fix notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
peterpolman committed May 28, 2024
1 parent fc31951 commit 6ede0c0
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 130 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Request, Response } from 'express';
import { param, query } from 'express-validator';
import PoolService from '@thxnetwork/api/services/PoolService';
import AnalyticsService from '@thxnetwork/api/services/AnalyticsService';
import AccountProxy from '@thxnetwork/api/proxies/AccountProxy';

const validation = [
param('id').isMongoId(),
Expand All @@ -23,19 +21,7 @@ const controller = async (req: Request, res: Response) => {
options['limit'] = Number(limit);
}

const leaderboard = await AnalyticsService.createLeaderboard(pool, options);
const topTen = leaderboard.slice(0, 10);
const subs = topTen.map((p) => p.sub);
const accounts = await AccountProxy.find({ subs });
const result = topTen.map((p, index) => {
const { username, profileImg } = accounts.find((a) => a.sub === p.sub);
return {
rank: Number(index) + 1,
account: { username, profileImg },
score: p.score,
questEntryCount: p.questEntryCount,
};
});
const result = await PoolService.getLeaderboard(pool, options);

res.json(result);
};
Expand Down
110 changes: 0 additions & 110 deletions apps/api/src/app/jobs/sendPoolAnalyticsReport.ts

This file was deleted.

4 changes: 2 additions & 2 deletions apps/api/src/app/services/AnalyticsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,11 @@ async function getPoolMetrics(pool: PoolDocument, dateRange?: { startDate: Date;
},
]);

const query = { poolId: String(pool._id) };
const query = { poolId: pool.id };
if (dateRange) {
query['createdAt'] = { $gte: dateRange.startDate, $lte: dateRange.endDate };
}
const totalCreated = await Model.countDocuments(query as any);
const totalCreated = await Model.countDocuments(query);

return {
totalCompleted: result && result.totalCompleted ? result.totalCompleted : 0,
Expand Down
96 changes: 95 additions & 1 deletion apps/api/src/app/services/NotificationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ import { DiscordButtonVariant } from '../events/InteractionCreated';
import { ButtonStyle } from 'discord.js';
import { WIDGET_URL } from '../config/secrets';
import { celebratoryWords } from '../util/dictionaries';
import { Pool } from '@thxnetwork/api/models';
import { DASHBOARD_URL } from '../config/secrets';
import AccountProxy from '../proxies/AccountProxy';
import MailService from './MailService';
import PoolService from './PoolService';
import BrandService from './BrandService';
import DiscordDataProxy from '../proxies/DiscordDataProxy';
import AnalyticsService from '../services/AnalyticsService';
import { subDays } from 'date-fns';

const MAIL_CHUNK_SIZE = 600;
const emojiMap = ['🥇', '🥈', '🥉'];
const oneDay = 86400000; // one day in milliseconds

async function send(
pool: PoolDocument,
Expand Down Expand Up @@ -146,4 +152,92 @@ async function sendQuestEntryNotification(pool: PoolDocument, quest: TQuest, acc
);
}

export default { send, notify, sendQuestEntryNotification };
export async function sendWeeklyDigestJob() {
const endDate = new Date();
endDate.setHours(0, 0, 0, 0);

const startDate = new Date(new Date(endDate).getTime() - oneDay * 7);
const dateRange = { startDate, endDate };

let account: TAccount;

for await (const pool of Pool.find({ 'settings.isWeeklyDigestEnabled': true })) {
try {
if (!account || account.sub != pool.sub) account = await AccountProxy.findById(pool.sub);
if (!account.email) continue;

const {
dailyQuest,
socialQuest,
inviteQuest,
customQuest,
web3Quest,
gitcoinQuest,
coinReward,
nftReward,
customReward,
couponReward,
discordRoleReward,
galachainReward,
} = await AnalyticsService.getPoolMetrics(pool, dateRange);

const endDate = new Date();
const startDate = subDays(endDate, 7);
startDate.setHours(0, 0, 0, 0);
const leaderboard = await PoolService.getLeaderboard(pool, {
startDate,
endDate,
limit: 5,
});

const entryCount = [dailyQuest, socialQuest, inviteQuest, customQuest, web3Quest, gitcoinQuest].reduce(
(acc, entry) => acc + entry.totalCreated,
0,
);

const paymentCount = [
coinReward,
nftReward,
customReward,
couponReward,
discordRoleReward,
galachainReward,
].reduce((acc, payment) => acc + payment.totalCreated, 0);

// Skip if nothing happened.
if (!entryCount && !paymentCount) continue;
console.log(leaderboard);
let html = `<p style="font-size: 18px">Hi there!👋</p>`;
html += `<p>We're pleased to bring you the <strong>Weekly Digest</strong> for "${pool.settings.title}".</p>`;
html += `<hr />`;

html += `<p><strong>🏆 Quests: </strong> ${entryCount} completed</p>`;
html += `<hr />`;

html += `<p><strong>🎁 Rewards: </strong> ${paymentCount} purchased</p>`;
html += `<hr />`;

html += `<p style="font-size:16px"><strong>Top 5</strong></p>`;
html += `<table role="presentation" border="0" cellpadding="0" cellspacing="0">`;

for (const index in leaderboard) {
const entry = leaderboard[index];

html += `<tr>
<td width="5%">${emojiMap[index]}</td>
<td><strong>${entry.account.username || 'Unknown'}</strong></td>
<td align="right" width="25%"><strong>${entry.questEntryCount} quests</strong></td>
<td align="right" width="25%"><strong>${entry.score} points</strong></td>
</tr>`;
}
html += '</table>';
html += `<a href="${DASHBOARD_URL}/pool/${pool.id}/participants">All participants</a>`;

await MailService.send(account.email, `🎁 Weekly Digest: "${pool.settings.title}"`, html);
} catch (error) {
logger.error(error);
}
}
}

export default { send, notify, sendQuestEntryNotification, sendWeeklyDigestJob };
18 changes: 18 additions & 0 deletions apps/api/src/app/services/PoolService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import SafeService from './SafeService';
import ParticipantService from './ParticipantService';
import DiscordService from './DiscordService';
import ContractService from './ContractService';
import AnalyticsService from './AnalyticsService';

export const ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000';

Expand Down Expand Up @@ -63,6 +64,22 @@ function getByAddress(address: string) {
return Pool.findOne({ address });
}

async function getLeaderboard(pool: PoolDocument, options: { startDate: Date; endDate: Date; limit: number }) {
const leaderboard = await AnalyticsService.createLeaderboard(pool, options);
const topTen = leaderboard.slice(0, options.limit);
const subs = topTen.map((p) => p.sub);
const accounts = await AccountProxy.find({ subs });
return topTen.map((p, index) => {
const { username, profileImg } = accounts.find((a) => a.sub === p.sub);
return {
rank: Number(index) + 1,
account: { username, profileImg },
score: p.score,
questEntryCount: p.questEntryCount,
};
});
}

async function deploy(sub: string, title: string): Promise<PoolDocument> {
const pool = await Pool.create({
sub,
Expand Down Expand Up @@ -417,4 +434,5 @@ export default {
findCollaborators,
findCouponCodes,
inviteCollaborator,
getLeaderboard,
};
4 changes: 2 additions & 2 deletions apps/api/src/app/util/agenda.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import db from './database';
import { Agenda, Job } from '@hokify/agenda';
import { updatePendingTransactions } from '@thxnetwork/api/jobs/updatePendingTransactions';
import { sendPoolAnalyticsReport } from '@thxnetwork/api/jobs/sendPoolAnalyticsReport';
import { updateCampaignRanks } from '@thxnetwork/api/jobs/updateCampaignRanks';
import { logger } from './logger';
import { MONGODB_URI } from '../config/secrets';
Expand All @@ -17,6 +16,7 @@ import PaymentService from '../services/PaymentService';
import TwitterQueryService from '../services/TwitterQueryService';
import VoteEscrowService from '../services/VoteEscrowService';
import ParticipantService from '../services/ParticipantService';
import NotificationService from '../services/NotificationService';

const agenda = new Agenda({
db: {
Expand All @@ -35,7 +35,7 @@ agenda.define(JobType.CreateTwitterQuests, () => TwitterQueryService.searchJob()
agenda.define(JobType.CreateQuestEntry, (job: Job) => QuestService.createEntryJob(job));
agenda.define(JobType.CreateRewardPayment, (job: Job) => RewardService.createPaymentJob(job));
agenda.define(JobType.DeploySafe, (job: Job) => SafeService.createJob(job));
agenda.define(JobType.SendCampaignReport, sendPoolAnalyticsReport);
agenda.define(JobType.SendCampaignReport, () => NotificationService.sendWeeklyDigestJob());
agenda.define(JobType.RequestAttemp, (job: Job) => WebhookService.requestAttemptJob(job));
agenda.define(JobType.UpdateTwitterLikeCache, (job: Job) => TwitterCacheService.updateLikeCacheJob(job));
agenda.define(JobType.UpdateTwitterRepostCache, (job: Job) => TwitterCacheService.updateRepostCacheJob(job));
Expand Down

0 comments on commit 6ede0c0

Please sign in to comment.