Skip to content

Commit fc5a60e

Browse files
committed
add verify
1 parent 068330a commit fc5a60e

File tree

17 files changed

+1158
-5325
lines changed

17 files changed

+1158
-5325
lines changed

server/package-lock.json

Lines changed: 839 additions & 5272 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@paralleldrive/cuid2": "^2.2.2",
3232
"@react-email/components": "^0.0.15",
3333
"@react-email/render": "0.0.7",
34+
"axios": "^1.6.7",
3435
"bcrypt": "^5.0.1",
3536
"bullmq": "^5.1.5",
3637
"class-transformer": "^0.5.1",

server/src/app.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import 'reflect-metadata';
1+
import { CREDENTIALS, LOG_FORMAT, NODE_ENV, PORT } from '@config';
2+
import type { Routes } from '@interfaces/routes.interface';
3+
import { ErrorMiddleware } from '@middlewares/error.middleware';
4+
import { logger, stream } from '@utils/logger';
25
import compression from 'compression';
36
import cookieParser from 'cookie-parser';
47
import cors from 'cors';
58
import express from 'express';
69
import helmet from 'helmet';
710
import hpp from 'hpp';
811
import morgan from 'morgan';
12+
import 'reflect-metadata';
913
import swaggerJSDoc from 'swagger-jsdoc';
1014
import swaggerUi from 'swagger-ui-express';
11-
import { NODE_ENV, PORT, LOG_FORMAT, ORIGIN, CREDENTIALS } from '@config';
12-
import type { Routes } from '@interfaces/routes.interface';
13-
import { ErrorMiddleware } from '@middlewares/error.middleware';
14-
import { logger, stream } from '@utils/logger';
15-
import { loadAllLocales } from './i18n/i18n-util.sync';
16-
import { getPreferredLocale } from './i18n/get-preferred-locale';
1715
import Container from 'typedi';
1816
import { LOCALE_KEY } from './constants';
1917
import { LocaleService } from './i18n/ctx';
18+
import { getPreferredLocale } from './i18n/get-preferred-locale';
19+
import { loadAllLocales } from './i18n/i18n-util.sync';
2020

2121
Container.set(LOCALE_KEY, new LocaleService('en'));
2222

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { BOT_URL } from "@/config";
2+
import axios from "axios";
3+
import { Service } from "typedi";
4+
5+
@Service()
6+
export class BaseChannel {
7+
id: string;
8+
contactId: string;
9+
contactName: string;
10+
channelType: string;
11+
12+
constructor(id: string, contactId: string, contactName: string, channelType: string,) {
13+
this.id = id;
14+
this.contactId = contactId;
15+
this.contactName = contactName;
16+
this.channelType = channelType;
17+
18+
if (channelType && contactName && contactId) {
19+
console.log(`Init channel ${channelType} - ${contactName} ${contactId}`);
20+
}
21+
}
22+
23+
public async postMessageToBot({ userId, data }) {
24+
try {
25+
const uId = this.initConversationId(userId);
26+
await axios({
27+
method: 'POST',
28+
url: BOT_URL,
29+
data: {
30+
conversation: {
31+
id: uId,
32+
},
33+
from: {
34+
id: userId,
35+
},
36+
recipient: {
37+
id: this.contactId,
38+
},
39+
type: 'event',
40+
name: 'payload',
41+
data,
42+
id: uId,
43+
channelId: this.channelType,
44+
serviceUrl: 'http://localhost:3000/api',
45+
},
46+
})
47+
} catch (error) {
48+
console.log(`Can not send data to bot!`, userId);
49+
console.log(error.message);
50+
}
51+
}
52+
53+
initConversationId(useId: string) {
54+
return this.contactId + '-' + useId
55+
}
56+
57+
// public async verifyWebhook(req: Request, res: Response) {
58+
// };
59+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Request, Response } from "express";
2+
import { BaseChannel } from "./base.channel";
3+
4+
export class MessengerChannel extends BaseChannel {
5+
channelType: string;
6+
pageToken: string;
7+
webhookSecret: string;
8+
messengerPostURL: string;
9+
credentials: string;
10+
11+
12+
constructor(id: string, contactId: string, contactName: string, channelType: string, credentials: string) {
13+
super(id, contactId, contactName, channelType);
14+
15+
let parseCredentials: MessengerChannel;
16+
17+
this.credentials = credentials;
18+
19+
if (typeof credentials == 'string') parseCredentials = JSON.parse(credentials);
20+
21+
if (parseCredentials) {
22+
this.pageToken = parseCredentials.pageToken;
23+
this.webhookSecret = parseCredentials.webhookSecret;
24+
}
25+
26+
this.channelType = channelType;
27+
this.messengerPostURL = `https://graph.facebook.com/v18.0/me/messages?access_token=`;
28+
}
29+
30+
public verifyWebhook(req: Request, res: Response) {
31+
let mode = req.query['hub.mode'];
32+
let token = req.query['hub.verify_token'];
33+
let challenge = req.query['hub.challenge'];
34+
35+
if (mode === 'subscribe' && this.webhookSecret == token) {
36+
console.log(`channel ${this.channelType} - ${this.contactName} ${this.contactId} webhook verified!`);
37+
return challenge;
38+
} else {
39+
console.error(`Verification channel ${this.channelType} - ${this.contactName} ${this.contactId} failed!`);
40+
return null;
41+
}
42+
}
43+
}

server/src/config/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ export const {
2727
FIREBASE_CLIENT_X509_CERT_URL,
2828
FIREBASE_UNIVERSE_DOMAIN,
2929
FIREBASE_DATABASE_URL,
30+
PUBLIC_DOMAIN,
31+
BOT_URL,
3032
} = process.env;

server/src/constants/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ export const ENDPOINTS = {
3030
INDEX: '/channel',
3131
DELETE: '/channel/delete',
3232
DELETES: '/channel/deletes',
33+
},
34+
WEBHOOK: {
35+
INDEX: '/webhook',
36+
VERIFY: '/webhook/:contactId',
3337
}
3438
};
3539

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { LOCALE_KEY } from "@/constants";
2+
import { LocaleService } from "@/i18n/ctx";
3+
import { WebhookService } from "@/services/webhook.service";
4+
import { catchAsync } from "@/utils/catch-async";
5+
import { StatusCodes } from "http-status-codes";
6+
import Container from "typedi";
7+
8+
export class WebhookController {
9+
public webhookService = Container.get(WebhookService);
10+
public localeService = Container.get<LocaleService>(LOCALE_KEY);
11+
12+
13+
public verifyWebhook = catchAsync(async (req, res) => {
14+
const data = await this.webhookService.verifyWebhook(req.params.contactId as string, req, res);
15+
16+
res.status(StatusCodes.OK).send(data);
17+
});
18+
}

server/src/database/seed.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ async function seedChannelTypes() {
1919
async function seedDefaultAccount() {
2020
try {
2121
const hashedPassword = await bcrypt.hash("Hello@123", 10);
22-
await db.insert(users).values({email: "[email protected]", password: hashedPassword, name: "admin",});
22+
await db.insert(users).values({ email: "[email protected]", password: hashedPassword, name: "admin", });
2323
} catch (error) {
2424
console.error(`Can't create default account`);
2525
}

server/src/dtos/channels.dto.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getCurrentLocale } from '@/i18n/get-current';
22
import { Transform } from "class-transformer";
3-
import { IsArray, IsBoolean, IsNotEmpty, IsString } from "class-validator";
3+
import { IsArray, IsBoolean, IsNotEmpty, IsOptional, IsString } from "class-validator";
44

55
export class ChannelDTO {
66
@IsString()
@@ -23,8 +23,8 @@ export class ChannelDTO {
2323
})
2424
channelTypeId: string;
2525

26-
@IsString()
27-
credentials: string;
26+
@IsOptional()
27+
credentials: any;
2828

2929
@IsBoolean()
3030
active: boolean | false;
@@ -34,4 +34,9 @@ export class DeleteChannelDTO {
3434
@IsArray()
3535
@Transform(({ value }) => value ?? [])
3636
id: string[];
37+
}
38+
39+
export class MessengerDTO {
40+
pageToken: string;
41+
webhookSecret: string;
3742
}

0 commit comments

Comments
 (0)