Skip to content
This repository has been archived by the owner on Apr 20, 2023. It is now read-only.

Dev #162

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft

Dev #162

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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ PORT="3000"
DATABASE_URL="mysql://root:12345@localhost:3306/baileys_api"
RECONNECT_INTERVAL="5000"
MAX_RECONNECT_RETRIES="5"
SSE_MAX_QR_GENERATION="10"
MAX_QR_GENERATION="10"
LOG_LEVEL="warn"
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ module.exports = {
'@typescript-eslint/consistent-type-imports': 'error',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ An implementation of [@adiwajshing/Baileys](https://github.com/adiwajshing/Baile

## Requirements

- **NodeJS** version **14.5.0** or higher
- **Prisma** [supported databases](https://www.prisma.io/docs/reference/database-reference/supported-databases). Tested on MySQL and PostgreSQL
- **NodeJS** version **14.7.0** or higher
- **Prisma** [supported databases](https://github.com/ookamiiixd/baileys-store#supported-databases). Tested on MySQL and PostgreSQL

## Installation

Expand All @@ -17,7 +17,9 @@ An implementation of [@adiwajshing/Baileys](https://github.com/adiwajshing/Baile
npm install
```

4. Build the project using the `build` script
4. Follow guide in the `Setup` section to setup your database first

5. Build the project using the `build` script

```sh
npm run build
Expand Down Expand Up @@ -61,27 +63,27 @@ RECONNECT_INTERVAL="5000"
# Maximum Reconnect Attempts
MAX_RECONNECT_RETRIES="5"

# Maximum SSE QR Generation Attempts
SSE_MAX_QR_GENERATION="10"
# Maximum QR Generation Attempts
MAX_QR_GENERATION="10"

# Pino Logger Level
LOG_LEVEL="warn"
```

## Usage

1. Make sure you have completed the **Installation** and **Setup** step
1. Make sure you have completed all of the step in the **Installation** and **Setup** section
1. You can then start the app using the `start` script

```sh
npm run start
```

1. Now the endpoint should be available according to your environment variables configuration. Default is at `http://localhost:3000`
Now the endpoint should be available according to your environment variables configuration. Default is at `http://localhost:3000`

## API Docs

The API documentation is available online [here](https://documenter.getpostman.com/view/18988925/2s8Z73zWbg). You can also import the **Postman Collection File** `(postman_collection.json)` into your Postman App alternatively
The API documentation is available online [here](https://documenter.getpostman.com/view/18988925/2s8Z73zWbg). You can also import the **Postman Collection File** `(postman_collection.json)` into your Postman App alternatively. The online version is always up-to-date with current development version, so make sure you read the right documentation version

## Notes

Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "baileys-api",
"description": "Simple RESTful WhatsApp API",
"version": "1.0.0-beta.0",
"version": "1.0.0-beta.1",
"private": true,
"main": "dist/index.js",
"repository": "github:ookamiiixd/baileys-api",
Expand All @@ -15,19 +15,22 @@
"start": "node .",
"build": "tsc",
"lint": "eslint .",
"typecheck": "tsc --noEmit",
"format": "prettier . --write"
},
"dependencies": {
"@adiwajshing/baileys": "^5.0.0",
"@hapi/boom": "^10.0.0",
"@ookamiiixd/baileys-store": "^1.0.0-beta.0",
"@prisma/client": "^4.7.1",
"@ookamiiixd/baileys-store": "file:debug/ookamiiixd-baileys-store-v1.0.0-beta.1.tgz",
"axios": "^1.3.3",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"express-validator": "^6.14.2",
"link-preview-js": "^3.0.0",
"pino": "^8.7.0",
"proxy-agent": "^5.0.0",
"qrcode": "^1.5.1",
"qrcode-terminal": "^0.12.0",
"sharp": "^0.30.5"
Expand Down
95 changes: 36 additions & 59 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,38 @@ datasource db {
}

model Chat {
pkId Int @id @default(autoincrement())
sessionId String @db.VarChar(128)
pkId BigInt @id @default(autoincrement())
sessionId String
archived Boolean?
contactPrimaryIdentityKey Bytes?
conversationTimestamp BigInt?
createdAt BigInt?
createdBy String? @db.VarChar(128)
description String? @db.VarChar(255)
createdBy String?
description String?
disappearingMode Json?
displayName String? @db.VarChar(128)
displayName String?
endOfHistoryTransfer Boolean?
endOfHistoryTransferType Int?
ephemeralExpiration Int?
ephemeralSettingTimestamp BigInt?
id String @db.VarChar(128)
id String
isDefaultSubgroup Boolean?
isParentGroup Boolean?
lastMsgTimestamp BigInt?
lidJid String? @db.VarChar(128)
lidJid String?
markedAsUnread Boolean?
mediaVisibility Int?
messages Json?
muteEndTime BigInt?
name String? @db.VarChar(128)
newJid String? @db.VarChar(128)
name String?
newJid String?
notSpam Boolean?
oldJid String? @db.VarChar(128)
pHash String? @db.VarChar(128)
parentGroupId String? @db.VarChar(128)
oldJid String?
pHash String?
parentGroupId String?
participant Json?
pinned Int?
pnJid String? @db.VarChar(128)
pnJid String?
pnhDuplicateLidThread Boolean?
readOnly Boolean?
shareOwnPn Boolean?
Expand All @@ -57,53 +57,30 @@ model Chat {
wallpaper Json?
lastMessageRecvTimestamp Int?

@@unique([sessionId, id], map: "unique_id_per_session_id")
@@unique([sessionId, id], map: "unique_id_per_session_id_chat")
@@index([sessionId])
}

model Contact {
pkId Int @id @default(autoincrement())
sessionId String @db.VarChar(128)
id String @db.VarChar(128)
name String? @db.VarChar(128)
notify String? @db.VarChar(128)
verifiedName String? @db.VarChar(128)
imgUrl String? @db.VarChar(255)
status String? @db.VarChar(128)
pkId BigInt @id @default(autoincrement())
sessionId String
id String
name String?
notify String?
verifiedName String?
imgUrl String?
status String?

@@unique([sessionId, id], map: "unique_id_per_session_id")
@@index([sessionId])
}

model GroupMetadata {
pkId Int @id @default(autoincrement())
sessionId String @db.VarChar(128)
id String @db.VarChar(128)
owner String? @db.VarChar(128)
subject String @db.VarChar(128)
subjectOwner String? @db.VarChar(128)
subjectTime Int?
creation Int?
desc String? @db.VarChar(255)
descOwner String? @db.VarChar(128)
descId String? @db.VarChar(128)
restrict Boolean?
announce Boolean?
size Int?
participants Json
ephemeralDuration Int?
inviteCode String? @db.VarChar(255)

@@unique([sessionId, id], map: "unique_id_per_session_id")
@@unique([sessionId, id], map: "unique_id_per_session_id_contact")
@@index([sessionId])
}

model Message {
pkId Int @id @default(autoincrement())
sessionId String @db.VarChar(128)
remoteJid String @db.VarChar(128)
id String @db.VarChar(128)
agentId String? @db.VarChar(128)
pkId BigInt @id @default(autoincrement())
sessionId String
remoteJid String
id String
agentId String?
bizPrivacyStatus Int?
broadcast Boolean?
clearMedia Boolean?
Expand All @@ -127,13 +104,13 @@ model Message {
messageStubType Int?
messageTimestamp BigInt?
multicast Boolean?
originalSelfAuthorUserJidString String? @db.VarChar(128)
participant String? @db.VarChar(128)
originalSelfAuthorUserJidString String?
participant String?
paymentInfo Json?
photoChange Json?
pollAdditionalMetadata Json?
pollUpdates Json?
pushName String? @db.VarChar(128)
pushName String?
quotedPaymentInfo Json?
quotedStickerData Json?
reactions Json?
Expand All @@ -145,18 +122,18 @@ model Message {
urlNumber Boolean?
urlText Boolean?
userReceipt Json?
verifiedBizName String? @db.VarChar(128)
verifiedBizName String?

@@unique([sessionId, remoteJid, id], map: "unique_message_key_per_session_id")
@@index([sessionId])
}

model Session {
pkId Int @id @default(autoincrement())
sessionId String @db.VarChar(128)
id String @db.VarChar(255)
pkId BigInt @id @default(autoincrement())
sessionId String
id String
data String @db.Text

@@unique([sessionId, id], map: "unique_id_per_session_id")
@@unique([sessionId, id], map: "unique_id_per_session_id_session")
@@index([sessionId])
}
33 changes: 18 additions & 15 deletions src/controllers/contact.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { serializePrisma } from '@ookamiiixd/baileys-store';
import type { RequestHandler } from 'express';
import { logger, prisma } from '../shared';
import { getSession, jidExists } from '../wa';
import { Session } from '../wa';
import { makePhotoURLHandler } from './misc';

export const list: RequestHandler = async (req, res) => {
try {
const { sessionId } = req.params;
const { cursor = undefined, limit = 25 } = req.query;
const contacts = await prisma.contact.findMany({
cursor: cursor ? { pkId: Number(cursor) } : undefined,
take: Number(limit),
skip: cursor ? 1 : 0,
where: { id: { endsWith: 's.whatsapp.net' }, sessionId },
});
const contacts = (
await prisma.contact.findMany({
cursor: cursor ? { pkId: Number(cursor) } : undefined,
take: Number(limit),
skip: cursor ? 1 : 0,
where: { id: { endsWith: 's.whatsapp.net' }, sessionId },
})
).map((m) => serializePrisma(m));

res.status(200).json({
data: contacts,
Expand All @@ -30,8 +33,8 @@ export const list: RequestHandler = async (req, res) => {

export const listBlocked: RequestHandler = async (req, res) => {
try {
const session = getSession(req.params.sessionId)!;
const data = await session.fetchBlocklist();
const session = Session.get(req.params.sessionId)!;
const data = await session.socket.fetchBlocklist();
res.status(200).json(data);
} catch (e) {
const message = 'An error occured during blocklist fetch';
Expand All @@ -42,13 +45,13 @@ export const listBlocked: RequestHandler = async (req, res) => {

export const updateBlock: RequestHandler = async (req, res) => {
try {
const session = getSession(req.params.sessionId)!;
const { jid, action = 'block' } = req.body;
const session = Session.get(req.params.sessionId)!;
const { jid, action } = req.body;

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

await session.updateBlockStatus(jid, action);
await session.socket.updateBlockStatus(jid, action);
res.status(200).json({ message: `Contact ${action}ed` });
} catch (e) {
const message = 'An error occured during blocklist update';
Expand All @@ -60,9 +63,9 @@ export const updateBlock: RequestHandler = async (req, res) => {
export const check: RequestHandler = async (req, res) => {
try {
const { sessionId, jid } = req.params;
const session = getSession(sessionId)!;
const session = Session.get(sessionId)!;

const exists = await jidExists(session, jid);
const exists = await session.jidExists(jid);
res.status(200).json({ exists });
} catch (e) {
const message = 'An error occured during jid check';
Expand Down
Loading