Skip to content

Commit 0b72aaf

Browse files
committed
update
1 parent c6f8144 commit 0b72aaf

File tree

10 files changed

+137
-17
lines changed

10 files changed

+137
-17
lines changed

server/src/channels/messenger.channel.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Helper } from "@/utils/helper";
2+
import axios from "axios";
23
import { Request, Response } from "express";
34
import { BaseChannel } from "./base.channel";
45

@@ -35,7 +36,7 @@ export class MessengerChannel extends BaseChannel {
3536
console.log(`channel ${this.channelType} - ${this.contactName} ${this.contactId} webhook verified!`);
3637
return challenge;
3738
} else {
38-
console.error(`Verification channel ${this.channelType} - ${this.contactName} ${this.contactId} failed!`);
39+
console.error(`[MSG] Verification channel ${this.channelType} - ${this.contactName} ${this.contactId} failed!`);
3940
return;
4041
}
4142
}
@@ -72,4 +73,49 @@ export class MessengerChannel extends BaseChannel {
7273
sendAddressToBot({ userId, address }) {
7374
return this.postMessageToBot({ userId, message: 'ADDRESS', data: { USER_INFORMATION: Helper.arrayToObj(address) } });
7475
}
76+
77+
public async sendMessageToUser({ userId, text }) {
78+
if (!text) return;
79+
80+
try {
81+
await axios({
82+
method: 'POST',
83+
url: this.messengerPostURL + this.pageToken,
84+
data: {
85+
messaging_type: 'RESPONSE',
86+
recipient: {
87+
id: userId,
88+
},
89+
message: { text },
90+
},
91+
});
92+
console.log(`[MSG] Sent: ${text} to ${userId}`);
93+
} catch (e) {
94+
console.log(`[MSG] ${this.contactId} Can not send message to messenger ${e.message}`);
95+
}
96+
}
97+
98+
public async sendActionToUser({ userId, type }) {
99+
const types = {
100+
typing: 'TYPING_ON',
101+
};
102+
103+
if (!types[type]) return;
104+
105+
try {
106+
await axios({
107+
method: 'POST',
108+
url: this.messengerPostURL + this.pageToken,
109+
data: {
110+
messaging_type: 'RESPONSE',
111+
recipient: {
112+
id: userId,
113+
},
114+
sender_action: types[type],
115+
},
116+
});
117+
} catch (e) {
118+
console.log('[MSG] Messenger can not send action to user', e.message);
119+
}
120+
}
75121
}

server/src/constants/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ export const ENDPOINTS = {
4545
VERIFY: '/webhook/:contactId',
4646
INCOMING_MSG: '/webhook/:contactId',
4747
},
48+
CONVERSATION: {
49+
INDEX: '/v3/conversations'
50+
}
4851
};
4952

5053
export const LOCALE_KEY = 'lang';
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { LOCALE_KEY } from "@/constants";
2+
import { LocaleService } from "@/i18n/ctx";
3+
import { ConversationService } from "@/services/conversation.service";
4+
import { catchAsync } from "@/utils/catch-async";
5+
import { StatusCodes } from "http-status-codes";
6+
import Container from "typedi";
7+
8+
export class ConversationController {
9+
public conversationService = Container.get(ConversationService);
10+
public localeService = Container.get<LocaleService>(LOCALE_KEY);
11+
12+
public handleIncomingMessage = catchAsync(async (req, res) => {
13+
res.status(StatusCodes.OK).end();
14+
return await this.conversationService.handleIncomingMessage(req);
15+
});
16+
17+
}

server/src/controllers/webhook.controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ export class WebhookController {
1717
});
1818

1919
public handleIncomingMessage = catchAsync(async (req, res) => {
20-
res.status(StatusCodes.OK);
2120

22-
return await this.webhookService.handleIncomingMessage(req.params.contactId, req, res);
21+
await this.webhookService.handleIncomingMessage(req.params.contactId, req, res);
22+
res.status(StatusCodes.OK).end();
2323
});
2424
}

server/src/database/schema.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ export const channels = pgTable('channels', {
5959
credentials: text('credentials'),
6060
active: boolean('active'),
6161
deleted: boolean('deleted').default(false),
62-
channelTypeId: text('channel_type_id').notNull(),
63-
userId: text('user_id').notNull(),
62+
channelTypeId: text('channel_type_id').notNull().references(() => channelTypes.id),
63+
userId: text('user_id').notNull().references(() => users.id),
6464
createdAt: timestamp('created_at').defaultNow(),
6565
updatedAt: timestamp('updated_at'),
6666
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { ENDPOINTS } from '@/constants';
2+
import { ConversationController } from '@/controllers/conversation.controller';
3+
import { Routes } from '@/interfaces/routes.interface';
4+
import { Router } from 'express';
5+
6+
export class ConversationRoute implements Routes {
7+
router = Router();
8+
controller = new ConversationController();
9+
10+
constructor() {
11+
this.initializeRoutes();
12+
}
13+
14+
initializeRoutes() {
15+
this.router.post(
16+
`${ENDPOINTS.CONVERSATION.INDEX}/:conversationId/activities/:activity`,
17+
this.controller.handleIncomingMessage
18+
);
19+
}
20+
}

server/src/server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { App } from '@/app';
22
import { ValidateEnv } from '@/utils/validate-env';
33
import { AuthRoute } from '@routes/auth.route';
44
import { ChannelRoute } from './routes/channels.route';
5+
import { ConversationRoute } from './routes/conversation.route';
56
import { SettingRoute } from './routes/setting.route';
67
import { UploadRoute } from './routes/upload.route';
78
import { UserRoute } from './routes/users.route';
@@ -16,6 +17,7 @@ const app = new App([
1617
new ChannelRoute(),
1718
new SettingRoute(),
1819
new UserRoute(),
20+
new ConversationRoute(),
1921
]);
2022

2123
app.listen();

server/src/services/channels.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ export class ChannelService {
175175
id: channels.id,
176176
contactId: channels.contactId,
177177
contactName: channels.contactName,
178-
name: channels.contactName,
179178
channelType: channelTypes.description,
180179
credentials: channels.credentials,
181180
active: channels.active,
@@ -185,7 +184,7 @@ export class ChannelService {
185184
.from(channels)
186185
.where(
187186
and(
188-
like(channels.contactId, `%${paging.q}%`),
187+
like(channels.contactId, `%${paging.q || ''}%`),
189188
eq(channels.deleted, false),
190189
eq(channels.userId, userId)
191190
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { MessengerChannel } from "@/channels/messenger.channel";
2+
import { Request } from "express-serve-static-core";
3+
import { Service } from "typedi";
4+
import { ChannelService } from "./channels.service";
5+
6+
@Service()
7+
export class ConversationService {
8+
constructor(
9+
private readonly chanelService: ChannelService
10+
) { }
11+
12+
public async handleIncomingMessage(req: Request) {
13+
const { from, recipient, text, type, channelData } = req.body;
14+
15+
const expectedChannel = await this.chanelService.findOneByContactId(from.id);
16+
17+
if (!expectedChannel) console.log('Can not find channel to send to user!');
18+
19+
const { id, contactName, channelType, credentials } = expectedChannel;
20+
21+
switch (channelType) {
22+
case 'MSG':
23+
const messengerChannel = new MessengerChannel(id, from.id, contactName, channelType, credentials);
24+
25+
if (type == 'message') return await messengerChannel.sendMessageToUser({ userId: recipient.id, text })
26+
27+
if (['typing', 'stop-typing'].includes(type)) return await messengerChannel.sendActionToUser({ userId: recipient.id, type });
28+
29+
break;
30+
default:
31+
console.log(`Send message to Bot: Does not support channel type ${channelType}`);
32+
break;
33+
}
34+
}
35+
}

server/src/services/webhook.service.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,14 @@ export class WebhookService {
2626

2727
let verifyResult = null;
2828

29-
if (expectedChannel) {
30-
const { id, contactId, contactName, channelType, credentials } = expectedChannel;
31-
switch (channelType) {
32-
case 'MSG':
33-
const messengerChannel = new MessengerChannel(id, contactId, contactName, channelType, credentials);
34-
verifyResult = messengerChannel.verifyWebhook(req, res);
35-
break;
36-
default:
37-
break;
38-
}
29+
const { id, contactName, channelType, credentials } = expectedChannel;
30+
switch (channelType) {
31+
case 'MSG':
32+
const messengerChannel = new MessengerChannel(id, contactId, contactName, channelType, credentials);
33+
verifyResult = messengerChannel.verifyWebhook(req, res);
34+
break;
35+
default:
36+
break;
3937
}
4038

4139
if (!verifyResult) {

0 commit comments

Comments
 (0)