Skip to content

added hook to send mail to moderators upon post creation #68

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions auth-server/src/controllers/eventsHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import Address from '../model/Address';
import Notification from '../model/Notification';
import PostSubscription from '../model/PostSubscription';
import User from '../model/User';
import { sendCommentMentionMail, sendNewProposalCreatedEmail, sendOwnProposalCreatedEmail, sendPostSubscriptionMail } from '../services/email';
import { CommentCreationHookDataType, HookResponseMessageType, MessageType, OnchainLinkType, PostTypeEnum } from '../types';
import { sendCommentMentionMail, sendNewPostCreatedEmail, sendNewProposalCreatedEmail, sendOwnProposalCreatedEmail, sendPostSubscriptionMail } from '../services/email';
import { CommentCreationHookDataType, HookResponseMessageType, MessageType, OnchainLinkType, PostCreateType, PostTypeEnum } from '../types';
import getMentions from '../utils/getMentions';
import getPostCommentLink from '../utils/getPostCommentLink';
import getPostId from '../utils/getPostId';
Expand Down Expand Up @@ -219,6 +219,31 @@ const sendNewProposalCreated = async (onchainLink: OnchainLinkType, responseMess
return { ...responseMessage, sendNewProposalCreatedMessage: messages.NEW_PROPOSAL_CREATED_MAIL_SENT };
};

const sendNewPostCreated = async (post: PostCreateType): Promise<HookResponseMessageType> => {
const { id, author_id, title, content } = post;

if (!id) {
return { sendNewPostCreatedMessage: messages.EVENT_POST_ID_NOT_FOUND };
}

if (!author_id) {
return { sendNewPostCreatedMessage: messages.EVENT_AUTHOR_ID_NOT_FOUND };
}

const user = await User
.query()
.findById(author_id);

if (!user) {
console.error('sendNewPostCreated - Unexpected empty user');
return { sendNewPostCreatedMessage: messages.USER_NOT_FOUND };
}

sendNewPostCreatedEmail(user, id, title, content);

return { sendNewPostCreatedMessage: messages.EVENT_POST_CREATED_MAIL_SENT };
};

export const commentCreateHook = async (req: Request, res: Response): Promise<void> => {
if (process.env.HASURA_EVENT_SECRET !== req.headers.hasura_event_secret) {
console.error("comment create hook failed, secrets don't match");
Expand Down Expand Up @@ -253,3 +278,23 @@ export const onchainLinksCreateHook = async (req: Request, res: Response): Promi
res.json(response);
}
};

export const postCreateHook = async (req: Request, res: Response): Promise<void> => {
if (process.env.HASURA_EVENT_SECRET !== req.headers.hasura_event_secret) {
console.error("post create hook failed, secrets don't match");
res.status(403).json({ message: messages.UNAUTHORISED });
return;
}

const post = req.body?.event?.data?.new || {};

// Doing this in background as several emails need to be sent
const response = await sendNewPostCreated(post);

// this response goes to hasura
if (response.sendNewPostCreatedMessage !== messages.EVENT_POST_CREATED_MAIL_SENT) {
res.status(400).json(response);
} else {
res.json(response);
}
};
3 changes: 2 additions & 1 deletion auth-server/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { Router } from 'express';

import { commentCreateHook, onchainLinksCreateHook } from './controllers/eventsHook';
import { commentCreateHook, onchainLinksCreateHook, postCreateHook } from './controllers/eventsHook';

const router = Router();

Expand All @@ -16,5 +16,6 @@ router.get('/healthcheck', (req, res) => {

router.post('/auth/event/comment/create', commentCreateHook);
router.post('/auth/event/onchain_link/create', onchainLinksCreateHook);
router.post('/auth/event/post/create', postCreateHook);

export default router;
27 changes: 27 additions & 0 deletions auth-server/src/services/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import User from '../model/User';
import { CommentCreationHookDataType, PostType, PostTypeEnum } from '../types';
import {
commentMentionEmailTemplate,
newPostCreatedEmailTemplate,
newProposalCreatedEmailTemplate,
ownProposalCreatedEmailTemplate,
postSubscriptionMailTemplate,
Expand Down Expand Up @@ -226,6 +227,32 @@ export const sendNewProposalCreatedEmail = (user: User, type: PostType, url: str
console.error('Proposal created email not sent', e));
};

export const sendNewPostCreatedEmail = (user: User, id: number | string, title: string | undefined, content: string | undefined): void => {
if (!apiKey) {
console.warn('New proposal created email not sent due to missing API key');
return;
}

const text = ejs.render(newPostCreatedEmailTemplate, {
content: content,
domain: DOMAIN,
id: id,
title: title,
username: user.username || ''
});

const msg = {
from: FROM,
html: text,
subject: 'New post created',
text,
to: process.env.MODERATOR_MAIL
};

sgMail.send(msg).catch(e =>
console.error('Post created email not sent', e));
};

export const sendReportContentEmail = (username: string, network: string, reportType: string, contentId: string, reason: string, comments: string): void => {
if (!apiKey) {
console.warn('Report Content Email not sent due to missing API key');
Expand Down
10 changes: 10 additions & 0 deletions auth-server/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export interface MessageType {
export interface HookResponseMessageType {
sendNewProposalCreatedMessage?: string;
sendOwnProposalCreatedMessage?: string;
sendNewPostCreatedMessage?: string;
}

export interface ChangeResponseType extends MessageType, TokenType {}
Expand Down Expand Up @@ -355,3 +356,12 @@ export interface EditPostArgs {
proposalType: string;
proposalId: string;
}

export interface PostCreateType {
id: number;
author_id: number;
content?: string;
title?: string;
topic_id?: number;
type_id?: number;
}
14 changes: 14 additions & 0 deletions auth-server/src/utils/emailTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ export const newProposalCreatedEmailTemplate = container(`
</p>
`);

export const newPostCreatedEmailTemplate = container(`
<p>
Created by <%= username %>!<br/><br/>

There is a new post.<br />

Title: <%= title %><br/><br/>

Content: <%= content %><br/><br/>

Polkassembly Team
</p>
`);

export const reportContentEmailTemplate = container(`
<p>
Content Reported.<br />
Expand Down
1 change: 1 addition & 0 deletions auth-server/src/utils/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default {
EVENT_ADDRESS_NOT_VERIFIED: 'Address not verified.',
EVENT_AUTHOR_ID_NOT_FOUND: 'Author id not found',
EVENT_AUTHOR_NOT_FOUND: 'Author not found',
EVENT_POST_CREATED_MAIL_SENT: 'Post created mail sent.',
EVENT_POST_ID_NOT_FOUND: 'Post id not found in event.',
EVENT_POST_SUBSCRIPTION_MAIL_SENT: 'Post subscription mail sent.',
EVENT_PROPOSAL_CREATED_MAIL_SENT: 'Proposal created mail sent.',
Expand Down
2 changes: 0 additions & 2 deletions hasura/hasura-migrations/metadata/actions.graphql
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@


14 changes: 14 additions & 0 deletions hasura/hasura-migrations/metadata/tables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -880,3 +880,17 @@
proposer_address:
_in: X-Hasura-Polkadot
check: null
event_triggers:
- name: post_create
definition:
enable_manual: false
insert:
columns: '*'
retry_conf:
num_retries: 0
interval_sec: 10
timeout_sec: 60
webhook_from_env: HASURA_POST_CREATE_EVENT_HOOK
headers:
- value: HASURA_EVENT_SECRET
name: HASURA_EVENT_SECRET