Skip to content

Commit

Permalink
Merge pull request #58 from DevNode-Dev/dev
Browse files Browse the repository at this point in the history
MVP2 - Version 2
  • Loading branch information
ap-atul authored Apr 10, 2023
2 parents a4ca231 + 329bb85 commit cff8081
Show file tree
Hide file tree
Showing 182 changed files with 4,197 additions and 806 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/github-acitons.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: devnode

on:
push:
branches: [ dev ]
pull_request:
branches: [ dev ]

jobs:
build-and-test:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Use Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: '16.x'

- name: Install dependencies
run: yarn install

- name: Build apps
run: yarn run build

- name: Run tests
run: yarn run test

8 changes: 4 additions & 4 deletions apps/discord-bot/.nycrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"src/**/types.ts"
],
"loader": "ts-node/esm",
"branches": 65,
"lines": 65,
"functions": 65,
"statements": 65
"branches": 75,
"lines": 75,
"functions": 75,
"statements": 75
}
3 changes: 2 additions & 1 deletion apps/discord-bot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"dev": "tsup && node dist/index.js",
"dev:bot": "tsup && node dist/index.js",
"test:bot": "mocha tests/**/*.spec.ts tests/**/**/*.spec.ts -- --silent",
"test:bot-coverage": "c8 --reporter=html --reporter=text mocha tests/**/*.spec.ts tests/unit/**/*.spec.ts"
"test:bot-coverage": "c8 --reporter=html --reporter=text mocha tests/**/*.spec.ts tests/unit/**/*.spec.ts",
"test": "c8 --reporter=html --reporter=text mocha tests/**/*.spec.ts tests/unit/**/*.spec.ts"
},
"dependencies": {
"@composedb/client": "^0.4.3",
Expand Down
29 changes: 16 additions & 13 deletions apps/discord-bot/src/bots/discord/comments/handler.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {ChannelType, Client, Message, MessageType, ThreadChannel} from "discord.js";
import {PostCommentToSocialPayload} from "../../../core/types";
import {Clients, PostCommentToSocialPayload} from "../../../core/types";
import {buildMessage} from "../utils";
import {config, constants, getBotDid} from "../../../config";
import {composeMutationHandler, composeQueryHandler} from "@devnode/composedb";
import {ComposeClient} from "@composedb/client";
import {composeMutationHandler} from "@devnode/composedb";
import {logger} from "../../../core/utils/logger";

export const handleNewComment = async (compose: ComposeClient, message: Message<boolean>) => {
export const handleNewComment = async (clients: Clients, message: Message<boolean>) => {
if (message.author.bot) return; // ignoring bots

switch (message.channel.type) {
Expand Down Expand Up @@ -36,27 +35,30 @@ export const handleNewComment = async (compose: ComposeClient, message: Message<
return;
}

const user = await composeQueryHandler().fetchUserByPlatformDetails(constants.PLATFORM_DISCORD_NAME, message.author.id);
const queryHandler = clients.composeQuery();
const user = await queryHandler.fetchUserByPlatformDetails(constants.PLATFORM_DISCORD_NAME, message.author.id);
if (!user) {
await deleteMessage(message);
await message.author.send(constants.replies.userUnknown);
return;
}

const thread = await composeQueryHandler().fetchThreadBySocialThreadId(message.channel.id);
const thread = await queryHandler.fetchThreadBySocialThreadId(message.channel.id);
if (!thread) return;

const comment = {
clients.compose.setDID(await getBotDid());
const mutation = await composeMutationHandler(clients.compose);
const result = await mutation.createComment({
threadId: thread.node.id,
userId: user.node.id,
comment: message.content,
socialCommentIds: [{
platformName: constants.PLATFORM_DISCORD_NAME,
commentId: message.id,
}],
createdFrom: constants.PLATFORM_DISCORD_NAME,
createdAt: message.createdAt.toISOString(),
};

compose.setDID(await getBotDid());
const mutation = await composeMutationHandler(compose);
const result = await mutation.createComment(comment);
});
if(result.errors && result.errors.length > 0) {
logger.error('discord', {e: result.errors});
await message.delete().catch((e) => logger.error('discord', {e}));
Expand All @@ -77,5 +79,6 @@ export const postComment = async (client: Client, payload: PostCommentToSocialPa
throw new Error("unknown server or thread!");
}

return await thread.send(buildMessage({...payload, body: payload.text}));
const message = await thread.send(buildMessage({...payload, body: payload.text}));
return message.id;
};
4 changes: 2 additions & 2 deletions apps/discord-bot/src/bots/discord/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export {commentHandler, threadHandler};
export const attachListeners = (clients: Clients) => {
const discord = clients.discord;

discord.on(Events.MessageCreate, (message) => commentHandler.handleNewComment(clients.compose, message));
discord.on(Events.ThreadCreate, (thread) => threadHandler.handleNewThread(clients.compose, thread));
discord.on(Events.MessageCreate, (message) => commentHandler.handleNewComment(clients, message));
discord.on(Events.ThreadCreate, (thread) => threadHandler.handleNewThread(clients, thread));
discord.on(Events.GuildCreate, channelHandler.handleServerJoin);
};
21 changes: 11 additions & 10 deletions apps/discord-bot/src/bots/discord/threads/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,45 @@ import {AnyThreadChannel, ChannelType, TextChannel} from "discord.js";
import {Clients, Node, PostThreadToSocialPayload, User} from "../../../core/types";
import {config, constants, getBotDid} from "../../../config";
import {buildMessage, buildThread} from "../utils";
import {composeMutationHandler, composeQueryHandler} from "@devnode/composedb";
import {composeMutationHandler} from "@devnode/composedb";
import {logger} from "../../../core/utils/logger";
import {ComposeClient} from "@composedb/client";

export const handleNewThread = async (compose: ComposeClient, thread: AnyThreadChannel<boolean>) => {
export const handleNewThread = async (clients: Clients, thread: AnyThreadChannel<boolean>) => {
const threadOwner = await thread.fetchOwner();
if (!threadOwner || !threadOwner.user || threadOwner.user.bot) return; //We ignore bots
if (thread.type !== ChannelType.PublicThread) return;//We only care about public threads
if (thread.parent?.name !== config.discord.channel) return;//We only care about threads in our channel

const queryHandler = composeQueryHandler();
const queryHandler = clients.composeQuery();
const user: Node<User> = await queryHandler.fetchUserByPlatformDetails(constants.PLATFORM_DISCORD_NAME, threadOwner.user.id);
if (!user) {
await thread.delete().catch((e) => logger.error('discord', {e}));
await threadOwner.user.send(constants.replies.userUnknown);
return;
}

compose.setDID(await getBotDid());
const mutation = await composeMutationHandler(compose);
clients.compose.setDID(await getBotDid());
const mutation = await composeMutationHandler(clients.compose);
const community = await queryHandler.fetchCommunityUsingPlatformId(thread.guildId);
if (!community) {
await thread.delete().catch((e) => logger.error('discord', {e}));
await threadOwner.user.send("No such community exists!");
return;
}

const threadPayload = {
const result = await mutation.createThread({
communityId: community.node.id,
userId: user.node.id,
threadId: thread.id,
socialThreadIds: [{
threadId: thread.id,
platformName: constants.PLATFORM_DISCORD_NAME,
}],
title: thread.name,
body: thread.lastMessage?.content || " ",
createdFrom: constants.PLATFORM_DISCORD_NAME,
createdAt: thread.createdAt?.toISOString() || new Date().toISOString(),
}
});

const result = await mutation.createThread(threadPayload);
if(result.errors && result.errors.length > 0) {
logger.error('discord', {e: result.errors});
await thread.delete().catch((e) => logger.error('discord', {e}));
Expand Down
1 change: 0 additions & 1 deletion apps/discord-bot/src/bots/discord/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ export interface DiscordMessage {
userName: string;
userAvatar: string;
userProfileLink: string;
redirectLink: string;
body: string;
}
5 changes: 1 addition & 4 deletions apps/discord-bot/src/bots/discord/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
ActionRowBuilder,
ButtonBuilder,
EmbedBuilder,
GuildTextThreadCreateOptions, MessageCreateOptions,
Expand All @@ -16,11 +15,9 @@ export const buildThread = (title: string): GuildTextThreadCreateOptions<any> =>
}

export const buildMessage = (message: DiscordMessage): MessageCreateOptions => {
const {body, userName, userAvatar, userProfileLink, redirectLink} = message;
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(buildLinkButton(redirectLink));
const {body, userName, userAvatar, userProfileLink} = message;
return {
embeds: [buildUserEmbed(userName, body, userAvatar, userProfileLink)],
components: [row],
}
}

Expand Down
42 changes: 26 additions & 16 deletions apps/discord-bot/src/core/comments/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,45 @@ import {Resp} from "../utils/response";
import {Client} from "discord.js";
import {commentHandler as discordCommentHandler} from "../../bots/discord";
import {logger} from "../utils/logger";
import {communityHasSocial, getSocialCommunityId} from "../utils/data";
import {communityHasSocial, getSocialCommunityId, getSocialThreadId} from "../utils/data";

export const postComment = async (clients: Clients, req: Request, res: Response) => {
const {commentId} = req.body;
logger.info('core', {body: req.body});
const comment: Node<Comment> = await clients.composeQuery().fetchCommentDetails(commentId);
const socials = _.get(comment, "node.thread.community.socialPlatforms.edges");
try {
logger.info('core', {body: req.body});
const {commentId} = req.body;
const comment: Node<Comment> = await clients.composeQuery().fetchCommentDetails(commentId);
const socials = _.get(comment, "node.thread.community.socialPlatforms.edges");

if (communityHasSocial(socials, constants.PLATFORM_DISCORD_NAME)) {
postCommentToDiscord(clients.discord, comment);
} else {
return Resp.notOk(res, "No discord for this community, bailing out!");
if (communityHasSocial(socials, constants.PLATFORM_DISCORD_NAME)) {
const commentId = await postCommentToDiscord(clients.discord, comment);
const response = [{
platformName: constants.PLATFORM_DISCORD_NAME,
commentId: commentId,
}];
return Resp.okD(res, response, "Created comment on socials");
} else {
return Resp.notOk(res, "No discord for this community, bailing out!");
}
} catch (e) {
logger.error('core', {e, body: req.body});
return Resp.error(res, "Server error occurred");
}
return Resp.ok(res, "Posted to socials!");
};

export const postCommentToDiscord = (discordClient: Client, comment: Node<Comment>) => {
export const postCommentToDiscord = async (discordClient: Client, comment: Node<Comment>) => {
const text = _.get(comment, "node.text");
const socials = _.get(comment, "node.thread.community.socialPlatforms.edges");
const threadStreamId = _.get(comment, "node.threadId");
const userName = _.get(comment, "node.user.userPlatforms[0].platformUsername");
const userId = _.get(comment, "node.user.walletAddress");
const userAvatar = _.get(comment, "node.user.userPlatforms[0].platformAvatar");
const userProfileLink = config.devnodeWebsite.concat(`/${userId}/profile`);
const redirectLink = config.devnodeWebsite.concat(`/${threadStreamId}`);
const serverId = getSocialCommunityId(socials, constants.PLATFORM_DISCORD_NAME);
const threadId = _.get(comment, "node.thread.threadId");
const threadId = getSocialThreadId(
_.get(comment, "node.thread.socialThreadIds"),
constants.PLATFORM_DISCORD_NAME
);

const payload = {text, userName, serverId, threadId, threadStreamId, userAvatar, userProfileLink, redirectLink};
discordCommentHandler.postComment(discordClient, payload)
.catch((e) => logger.error('core', {payload, e}));
const payload = {text, userName, serverId, threadId, threadStreamId, userAvatar, userProfileLink};
return await discordCommentHandler.postComment(discordClient, payload)
}
9 changes: 6 additions & 3 deletions apps/discord-bot/src/core/threads/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ export const postThread = async (clients: Clients, req: Request, res: Response)

if (communityHasSocial(socials, constants.PLATFORM_DISCORD_NAME)) {
const threadId = await postThreadToDiscord(clients, thread);
return Resp.okD(res, {threadId}, "Created thread on socials");
const response = [{
platformName: constants.PLATFORM_DISCORD_NAME,
threadId: threadId,
}];
return Resp.okD(res, response, "Created thread on socials");
} else {
return Resp.notOk(res, "No discord for this community, bailing out!");
}
Expand All @@ -35,8 +39,7 @@ export const postThreadToDiscord = async (clients: Clients, thread: Node<Thread>
const userId = _.get(thread, "node.user.walletAddress");
const userAvatar = _.get(thread, "node.user.userPlatforms[0].platformAvatar");
const userProfileLink = config.devnodeWebsite.concat(`/${userId}/profile`);
const redirectLink = config.devnodeWebsite.concat(`/${threadStreamId}`);
const serverId = getSocialCommunityId(socials, constants.PLATFORM_DISCORD_NAME);
const payload = {title, body, userName, serverId, threadStreamId, userAvatar, userProfileLink, redirectLink};
const payload = {title, body, userName, serverId, threadStreamId, userAvatar, userProfileLink};
return await discordThreadHandler.postThread(clients, payload);
}
9 changes: 6 additions & 3 deletions apps/discord-bot/src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export interface Thread {
title: string;
body: string;
userId: string;
threadId: string;
socialThreadIds: SocialThreadId[];
createdAt: string;
community: Community;
communityId: string;
Expand Down Expand Up @@ -77,7 +77,6 @@ export interface PostCommentToSocialPayload {
userName: string;
userAvatar: string;
userProfileLink: string;
redirectLink: string;
serverId: string;
threadId: string;
}
Expand All @@ -88,7 +87,11 @@ export interface PostThreadToSocialPayload {
userName: string;
userAvatar: string;
userProfileLink: string;
redirectLink: string;
threadStreamId: string;
serverId: string;
}

export interface SocialThreadId {
platformName: string;
threadId: string;
}
8 changes: 7 additions & 1 deletion apps/discord-bot/src/core/utils/data.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Node, SocialPlatform} from "../types";
import _ from "lodash";
import {Node, SocialPlatform, SocialThreadId} from "../types";

export const communityHasSocial = (socials: Node<SocialPlatform>[], platform: string) => {
const social = socials.filter((d) => d.node.platform === platform);
Expand All @@ -9,3 +10,8 @@ export const getSocialCommunityId = (socials: Node<SocialPlatform>[], platform:
const social = socials.filter((d) => d.node.platform === platform);
return social[0].node.platformId;
}

export const getSocialThreadId = (socials: SocialThreadId[], platformName: string) => {
const id = socials.find((s) => s.platformName === platformName);
return _.get(id,"threadId", "");
}
14 changes: 12 additions & 2 deletions apps/discord-bot/tests/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ export const sampleComment = {
"id": "kjzl6kcym7w8y772zht4omem25y3plfp929wsgumb158oi8uca2fnlhcdri2jqx",
"title": "Is storing secrets in redux store secure?",
"userId": "k2t6wzhkhabz2wixqd45q1wxpoy9fg7wd2dbfp2vzgq0wd2dq9sh5fkzywjxye",
"threadId": "na",
"socialThreadIds": [
{
"platformName": "discord",
"threadId": "1092795497066020864"
}
],
"createdAt": "2023-03-15T09:22:45.468Z",
"community": {
"socialPlatforms": {
Expand Down Expand Up @@ -86,7 +91,12 @@ export const sampleThread = {
"title": "Is storing secrets in redux store secure?",
"body": "From the docs, I understand that Redux store variables in memory so it should be readable to the browser, but is it secure enough to store sensitive information?",
"userId": "k2t6wzhkhabz2wixqd45q1wxpoy9fg7wd2dbfp2vzgq0wd2dq9sh5fkzywjxye",
"threadId": "na",
"socialThreadIds": [
{
"platformName": "discord",
"threadId": "1092795497066020864"
}
],
"createdAt": "2023-03-15T09:22:45.468Z",
"communityId": "kjzl6kcym7w8y8dgfi093n3o6gby2gwq4fs3nltxjl8gutwvr2ol1sf9vpdmn09",
"createdFrom": "devnode",
Expand Down
Loading

0 comments on commit cff8081

Please sign in to comment.