Skip to content

Commit

Permalink
add more routes
Browse files Browse the repository at this point in the history
  • Loading branch information
ookamiiixd committed Dec 11, 2022
1 parent 3fb430b commit 03eff28
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 10 deletions.
20 changes: 20 additions & 0 deletions src/controllers/chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { RequestHandler } from 'express';
import { logger, prisma } from '../shared';

export const list: RequestHandler = async (req, res) => {
try {
const { sessionId } = req.params;
const { cursor = undefined, limit = 25 } = req.query;
const chats = await prisma.chat.findMany({
cursor: cursor ? { sessionId_id: { id: cursor as string, sessionId } } : undefined,
take: Number(limit),
skip: cursor ? 1 : 0,
});

res.status(200).json({ data: chats, cursor: chats.length ? chats[chats.length - 1].id : null });
} catch (e) {
const message = 'An error occured during chat list';
logger.error(e, message);
res.status(500).json({ error: message });
}
};
22 changes: 22 additions & 0 deletions src/controllers/group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { RequestHandler } from 'express';
import { logger, prisma } from '../shared';

export const list: RequestHandler = async (req, res) => {
try {
const { sessionId } = req.params;
const { cursor = undefined, limit = 25 } = req.query;
const groups = await prisma.groupMetadata.findMany({
cursor: cursor ? { sessionId_id: { id: cursor as string, sessionId } } : undefined,
take: Number(limit),
skip: cursor ? 1 : 0,
});

res
.status(200)
.json({ data: groups, cursor: groups.length ? groups[groups.length - 1].id : null });
} catch (e) {
const message = 'An error occured during group list';
logger.error(e, message);
res.status(500).json({ error: message });
}
};
98 changes: 98 additions & 0 deletions src/controllers/message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import type { RequestHandler } from 'express';
import { delay as delayMs } from '@adiwajshing/baileys';
import { logger, prisma } from '../shared';
import { getSession, jidExists } from '../wa';

export const send: RequestHandler = async (req, res) => {
try {
const { sessionId } = req.params;
const { jid, type = 'number', message, options } = req.body;
const session = getSession(sessionId)!;

const exists = await jidExists(session, jid, type);
if (!exists) return res.status(400).json({ error: 'JID does not exist' });

const result = await session.sendMessage(jid, message, options);
res.status(200).json(result);
} catch (e) {
const message = 'An error occured during message send';
logger.error(e, message);
res.status(500).json({ error: message });
}
};

export const sendBulk: RequestHandler = async (req, res) => {
const { sessionId } = req.params;
const session = getSession(sessionId)!;
const results: { index: number; result: any }[] = [];
const errors: { index: number; error: string }[] = [];

for (const [
index,
{ jid, type = 'number', delay = 2500, message, options },
] of req.body.entries()) {
try {
const exists = await jidExists(session, jid, type);
if (!exists) {
errors.push({ index, error: 'JID does not exist' });
continue;
}

if (index > 0) await delayMs(delay);
const result = await session.sendMessage(jid, message, options);
results.push({ index, result });
} catch (e) {
const message = 'An error occured during message send';
logger.error(e, message);
errors.push({ index, error: message });
}
}

res
.status(req.body.length !== 0 && errors.length === req.body.length ? 500 : 200)
.json({ results, errors });
};

export const list: RequestHandler = async (req, res) => {
try {
const { sessionId } = req.params;
const { cursor = undefined, limit = 25 } = req.query;
const messages = await prisma.message.findMany({
cursor: cursor ? { pkId: Number(cursor) } : undefined,
take: Number(limit),
skip: cursor ? 1 : 0,
where: { sessionId },
});

res
.status(200)
.json({ data: messages, cursor: messages.length ? messages[messages.length - 1].id : null });
} catch (e) {
const message = 'An error occured during message list';
logger.error(e, message);
res.status(500).json({ error: message });
}
};

export const find: RequestHandler = async (req, res) => {
try {
const { sessionId, jid } = req.params;
const { cursor = undefined, limit = 25 } = req.query;
const messages = await prisma.message.findMany({
cursor: cursor
? { sessionId_remoteJid_id: { id: cursor as string, remoteJid: jid, sessionId } }
: undefined,
take: Number(limit),
skip: cursor ? 1 : 0,
orderBy: { messageTimestamp: 'desc' },
});

res
.status(200)
.json({ data: messages, cursor: messages.length ? messages[messages.length - 1].id : null });
} catch (e) {
const message = 'An error occured during message find';
logger.error(e, message);
res.status(500).json({ error: message });
}
};
17 changes: 17 additions & 0 deletions src/controllers/misc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { RequestHandler } from 'express';
import { logger } from '../shared';
import { getSession, jidExists } from '../wa';

export const checkJid: RequestHandler = async (req, res) => {
try {
const { sessionId, jid } = req.params;
const { type = 'number' } = req.query;
const session = getSession(sessionId)!;
const exists = await jidExists(session, jid, type as any);
res.status(200).json({ exists });
} catch (e) {
const message = 'An error occured during jid check';
logger.error(e, message);
res.status(500).json({ error: message });
}
};
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const app = express();
app.use(cors());
app.use(express.json());
app.use('/', routes);
app.all('*', (req, res) => res.status(404).json({ error: 'URL not found' }));

const host = process.env.HOST || '0.0.0.0';
const port = Number(process.env.PORT || 3000);
Expand Down
26 changes: 26 additions & 0 deletions src/routes/chats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Router } from 'express';
import { list } from '../controllers/chat';
import { find } from '../controllers/message';
import sessionValidator from '../middlewares/session-validator';
import requestValidator from '../middlewares/request-validator';
import { query } from 'express-validator';

const router = Router();
router.get(
'/',
sessionValidator,
query('cursor').isString(),
query('limit').isNumeric(),
requestValidator,
list
);
router.get(
'/:jid',
sessionValidator,
query('cursor').isString(),
query('limit').isNumeric(),
requestValidator,
find
);

export default router;
26 changes: 26 additions & 0 deletions src/routes/groups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Router } from 'express';
import { list } from '../controllers/group';
import { find } from '../controllers/message';
import sessionValidator from '../middlewares/session-validator';
import requestValidator from '../middlewares/request-validator';
import { query } from 'express-validator';

const router = Router();
router.get(
'/',
sessionValidator,
query('cursor').isString(),
query('limit').isNumeric(),
requestValidator,
list
);
router.get(
'/:jid',
sessionValidator,
query('cursor').isString(),
query('limit').isNumeric(),
requestValidator,
find
);

export default router;
9 changes: 8 additions & 1 deletion src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { Router } from 'express';
import sessionRoutes from './sessions';
import chatRoutes from './chats';
import groupRoutes from './groups';
import messageRoutes from './messages';
import miscRoutes from './misc';

const router = Router();
router.use('/sessions', sessionRoutes);
router.all('*', (req, res) => res.status(404).json({ error: 'URL not found' }));
router.use('/:sessionId/chats', chatRoutes);
router.use('/:sessionId/groups', groupRoutes);
router.use('/:sessionId/messages', messageRoutes);
router.use('/:sessionId/misc', miscRoutes);

export default router;
34 changes: 34 additions & 0 deletions src/routes/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Router } from 'express';
import { body, query } from 'express-validator';
import * as controller from '../controllers/message';
import requestValidator from '../middlewares/request-validator';
import sessionValidator from '../middlewares/session-validator';

const router = Router();
router.get(
'/',
sessionValidator,
query('cursor').isString(),
query('limit').isNumeric(),
requestValidator,
controller.list
);
router.post(
'/send',
sessionValidator,
body('jid').isString().notEmpty(),
body('type').isString().isIn(['group', 'number']),
body('message').isObject().notEmpty(),
body('options').isObject(),
requestValidator,
controller.send
);
router.post(
'/send-bulk',
sessionValidator,
body().isArray().notEmpty(),
requestValidator,
controller.sendBulk
);

export default router;
16 changes: 16 additions & 0 deletions src/routes/misc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Router } from 'express';
import * as controller from '../controllers/misc';
import sessionValidator from '../middlewares/session-validator';
import requestValidator from '../middlewares/request-validator';
import { query } from 'express-validator';

const router = Router();
router.get(
'/check-jid/:jid',
sessionValidator,
query('type').isString().isIn(['group', 'number']),
requestValidator,
controller.checkJid
);

export default router;
2 changes: 1 addition & 1 deletion src/routes/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import sessionValidator from '../middlewares/session-validator';
const router = Router();
router.get('/:sessionId', sessionValidator, controller.find);
router.get('/:sessionId/status', sessionValidator, controller.status);
router.post('/add', body('sessionId').notEmpty(), requestValidator, controller.add);
router.post('/add', body('sessionId').isString().notEmpty(), requestValidator, controller.add);
router.get('/:sessionId/add-sse', controller.addSSE);
router.delete('/:sessionId', sessionValidator, controller.del);

Expand Down
39 changes: 31 additions & 8 deletions src/wa.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import type { ConnectionState, proto, SocketConfig, WASocket } from '@adiwajshing/baileys';
import type { ConnectionState, SocketConfig, WASocket } from '@adiwajshing/baileys';
import makeWASocket, { DisconnectReason, Browsers } from '@adiwajshing/baileys';
import type { Response } from 'express';
import { useSession, Store, initStore } from 'baileys-store';
import type { Boom } from '@hapi/boom';
import { toDataURL } from 'qrcode';
import { prisma, logger } from './shared';

const sessions = new Map<string, WASocket & { destroy: () => Promise<void>; store: Store }>();
type Session = WASocket & {
destroy: () => Promise<void>;
store: Store;
};

const sessions = new Map<string, Session>();
const retries = new Map<string, number>();
const SSEQRGenerations = new Map<string, number>();

Expand All @@ -19,7 +24,7 @@ export async function init() {
initStore({ prisma, logger });
const sessions = await prisma.session.findMany({
select: { sessionId: true, data: true },
where: { id: { contains: SESSION_CONFIG_ID } },
where: { id: { startsWith: SESSION_CONFIG_ID } },
});

for (const { sessionId, data } of sessions) {
Expand All @@ -42,14 +47,14 @@ function shouldReconnect(sessionId: string) {
return false;
}

type WASessionOptions = {
type createSessionOptions = {
sessionId: string;
res?: Response;
SSE?: boolean;
socketConfig?: SocketConfig;
};

export async function createSession(options: WASessionOptions) {
export async function createSession(options: createSessionOptions) {
const { sessionId, res, SSE, socketConfig } = options;
let connectionState: Partial<ConnectionState> = { connection: 'close' };

Expand Down Expand Up @@ -101,16 +106,16 @@ export async function createSession(options: WASessionOptions) {

const { state, saveCreds } = await useSession(sessionId);
const socket = makeWASocket({
auth: state,
logger,
printQRInTerminal: true,
browser: Browsers.ubuntu('Chrome'),
...socketConfig,
auth: state,
logger,
getMessage: async (key) => {
const data = await prisma.message.findFirst({
where: { remoteJid: key.remoteJid!, id: key.id!, sessionId },
});
return (data || undefined) as proto.IMessage | undefined;
return (data || undefined) as any;
},
});

Expand Down Expand Up @@ -150,3 +155,21 @@ export async function deleteSession(sessionId: string) {
export function sessionExists(sessionId: string) {
return sessions.has(sessionId);
}

export async function jidExists(
session: Session,
jid: string,
type: 'group' | 'number' = 'number'
) {
try {
if (type === 'number') {
const [result] = await session.onWhatsApp(jid);
return result.exists;
}

const groupMeta = await session.groupMetadata(jid);
return !!groupMeta.id;
} catch (e) {
return Promise.reject(e);
}
}

0 comments on commit 03eff28

Please sign in to comment.