Skip to content

Commit

Permalink
Merge pull request #50 from Zain-ul-din/baileys
Browse files Browse the repository at this point in the history
Baileys
  • Loading branch information
Zain-ul-din authored Aug 26, 2024
2 parents be08119 + 7da889b commit efbea55
Show file tree
Hide file tree
Showing 21 changed files with 1,092 additions and 1,575 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
npm-debug.log
Dockerfile
.dockerignore
auth_info_baileys
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@

# local session
/session
/auth_info_baileys
3 changes: 1 addition & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"semi": true,
"tabWidth": 4,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "none"
}

20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM node:20

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json (if available)
COPY package*.json ./
COPY yarn*.lock ./

# Install dependencies
RUN npx yarn

# Copy the rest of the application code
COPY . .

# Expose the port the app runs on
EXPOSE 3000

# Define the command to run the application
CMD ["npx", "yarn", "dev"]
63 changes: 63 additions & 0 deletions baileys/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Code for learning @whiskeysockets/baileys library
*/

import makeWASocket, { DisconnectReason, useMultiFileAuthState } from '@whiskeysockets/baileys';
import { Boom } from '@hapi/boom';
import * as fs from 'fs';

const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys');

async function connectToWhatsApp() {
const sock = makeWASocket({
// can provide additional config here
printQRInTerminal: true,
auth: state
});

sock.ev.on('connection.update', (update) => {
const { connection, lastDisconnect } = update;
try {
if (connection === 'close' && lastDisconnect) {
const shouldReconnect =
(lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut;

console.log(
'connection closed due to ',
lastDisconnect.error,
', reconnecting ',
shouldReconnect
);
// reconnect if not logged out
if (shouldReconnect) {
connectToWhatsApp();
} else {
// clear credentials
if (lastDisconnect.error)
fs.rmSync('./auth_info_baileys', { force: true, recursive: true });
}
} else if (connection === 'open') {
console.log('opened connection');
}
} catch (err) {
console.log(err);
}
});

sock.ev.on('messages.upsert', async (m) => {
console.log(JSON.stringify(m, undefined, 2));

console.log('replying to', m.messages[0].key.remoteJid);
// don't reply to self
if (m.messages[0].key.fromMe) {
console.log('returning this message is from me');
return;
}
await sock.sendMessage(m.messages[0].key.remoteJid!, { text: 'Hello there!' });
});

sock.ev.on('creds.update', saveCreds);
}

// run in main file
connectToWhatsApp();
11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"start": "vite-node ./src/index.ts",
"format": "prettier --write ./src",
"test": "vite-node ./test/index.test.ts",
"test:baileys": "vite-node ./baileys/index.ts",
"build": "npx yarn"
},
"devDependencies": {
Expand All @@ -18,15 +19,13 @@
"vite-node": "^0.28.5"
},
"dependencies": {
"@google/generative-ai": "^0.1.2",
"@google/generative-ai": "^0.17.1",
"@types/qrcode-terminal": "^0.12.0",
"chatgpt": "^5.2.2",
"@whiskeysockets/baileys": "^6.7.7",
"dotenv": "^16.0.3",
"openai": "^4.52.1",
"openai": "^4.56.0",
"ora": "3.2.0",
"puppeteer": "^22.1.0",
"qrcode-terminal": "^0.12.0",
"stability-client": "^1.8.0",
"whatsapp-web.js": "^1.23.0"
"stability-client": "^1.8.0"
}
}
68 changes: 50 additions & 18 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@

<br>
```diff
+ We are switching to the @whiskeysockets/baileys library for our bot because it's lightweight and easy to deploy.

<div align="center">
- This branch is still under construction 🚧. Currently, we only support the models listed below, but support for new models will be added soon.
```

<h1>
<img src="https://github.com/Zain-ul-din/whatsapp-ai-bot/assets/78583049/d31339cf-b4ae-450e-95b9-53d21e4641a0" width="35" height="35"/>
WhatsApp AI Bot 🚀</h1>
</div>
**Supported Models:**

The WhatsApp AI Bot is a chatbot that uses AI models APIs to generate responses to user input. The bot supports several AI models, including **`Gemini`**, **`Gemini-Vision`**, **`CHAT-GPT`**, **`DALL-E`**, and **`Stability AI`**, and users can also create their **`own models`** to customize the bot's behavior.
<table>
<thead>
<tr>
<th align="center">Model</th>
<th align="center">Provider</th>
<th align="center">Type</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">Chat GPT</td>
<td align="center">Open AI</td>
<td align="center">text to text</td>
</tr>
<tr>
<td align="center">Gemini</td>
<td align="center">Google</td>
<td align="center">text to text</td>
</tr>
<tr>
<td align="center">Gemini Vision</td>
<td align="center">Google</td>
<td align="center">image to text</td>
</tr>
</tbody>
</table>

**Useful links:**

<table align="center">
<table>
<thead>
<tr>
<th>♥ Sponsor</th>
Expand Down Expand Up @@ -44,6 +69,20 @@ The WhatsApp AI Bot is a chatbot that uses AI models APIs to generate responses
</tbody>
</table>

---
=======

<br>


<div align="center">

<h1>
<img src="https://github.com/Zain-ul-din/whatsapp-ai-bot/assets/78583049/d31339cf-b4ae-450e-95b9-53d21e4641a0" width="35" height="35"/>
WhatsApp AI Bot 🚀</h1>
</div>

The WhatsApp AI Bot is a chatbot that uses AI models APIs to generate responses to user input. The bot supports several AI models, including **`Gemini`**, **`Gemini-Vision`**, **`CHAT-GPT`**, **`DALL-E`**, and **`Stability AI`**, and users can also create their **`own models`** to customize the bot's behavior.

# Table of Content

Expand All @@ -56,23 +95,20 @@ The WhatsApp AI Bot is a chatbot that uses AI models APIs to generate responses
- [Sponsors.](#Sponsors)
- [About.](#about-us)


# Demo

**Gemini**

[![Screenshot (1186)](https://github.com/Zain-ul-din/whatsapp-ai-bot/assets/78583049/b6f256de-c792-4947-bf65-401a60a0b1f4)](https://www.youtube.com/watch?v=dXDxTQQqeq8)


**Stability AI + Chat-GPT**

![image](https://user-images.githubusercontent.com/78583049/222071673-ef0f2021-a8b4-4263-9304-a77ecd76c0a1.png)

**Dalle + Custom Model**
**Dalle + Custom Model**

![image](https://user-images.githubusercontent.com/78583049/222074174-55792d13-5137-4c1c-b708-3ad188ca8d8d.png)


# Usage

**1. Download Source Code**
Expand All @@ -86,7 +122,6 @@ The WhatsApp AI Bot is a chatbot that uses AI models APIs to generate responses
- [Download Zip File](https://github.com/Zain-ul-din/WhatsApp-Ai-bot/archive/refs/heads/master.zip)


**2. Get API Keys**

- [Gemini API Key](https://makersuite.google.com/app/apikey)
Expand All @@ -98,6 +133,7 @@ The WhatsApp AI Bot is a chatbot that uses AI models APIs to generate responses
- create `.env` in the root of the project.

- set following fields in `.env` file

```.env
OPENAI_API_KEY=YOUR_OPEN_AI_API_KEY
DREAMSTUDIO_API_KEY=YOUR_STABILITY_AI_API_KEY
Expand Down Expand Up @@ -128,17 +164,14 @@ The WhatsApp AI Bot is a chatbot that uses AI models APIs to generate responses
- **[Setup bot on cloud using Github code-spaces](https://www.youtube.com/watch?v=QahJSi6Ygj4)**
- **[setup bot on a local machine](https://www.youtube.com/watch?v=fyPD3ILFPck)**


### FQA

- [How to create custom model](https://github.com/Zain-ul-din/whatsapp-ai-bot/issues/3)


# Disclaimer

This bot utilizes Puppeteer to operate an actual instance of Whatsapp Web to prevent blocking. However, it is essential to note that these operations come at a cost charged by OpenAI and Stability AI for every request made. Please be aware that WhatsApp does not support bots or unofficial clients on its platform, so using this method is not entirely secure and could lead to getting blocked.


## Contributors

<a href="https://github.com/Zain-ul-din/WhatsApp-Ai-bot/graphs/contributors">
Expand All @@ -152,7 +185,7 @@ This bot utilizes Puppeteer to operate an actual instance of Whatsapp Web to pre

<!-- about -->

## Sponsors
## Sponsors

A big thank you to these people for supporting this project.

Expand Down Expand Up @@ -187,7 +220,6 @@ A big thank you to these people for supporting this project.
<p> Show some ❤️ by starring this awesome repository! </p>
</div>


<div align="center">
<a href="https://www.buymeacoffee.com/zainuldin" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

Expand Down
3 changes: 0 additions & 3 deletions setup.cpp

This file was deleted.

Binary file removed setup.exe
Binary file not shown.
15 changes: 9 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { WhatsAppClient } from './lib/WhatsAppClient';
import welcomeUser from './services/welcomeUser';
// import { WhatsAppClient } from './lib/WhatsAppClient';
// import welcomeUser from './services/welcomeUser';

console.log('🤖 starting client...');
const whatsappClient = new WhatsAppClient();
whatsappClient.initializeClient();
// console.log('🤖 starting client...');
// const whatsappClient = new WhatsAppClient();
// whatsappClient.initializeClient();

whatsappClient.messageEvent.on('self', welcomeUser);
// whatsappClient.messageEvent.on('self', welcomeUser);

import { connectToWhatsApp } from './lib/baileys';
connectToWhatsApp();
62 changes: 62 additions & 0 deletions src/lib/baileys/handlers/message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { downloadMediaMessage } from '@whiskeysockets/baileys';
import { ChatGptModel } from '../../../models/ChatGptModel';
import { GeminiModel } from '../../../models/GeminiModel';
import { GeminiVisionModel } from '../../../models/GeminiVisionModel';
import { AiModels } from '../../../types/AiModels';
import { Util } from '../../../util/Util';
import MessageHandlerParams from '../types';

const gptModel = new ChatGptModel();
const geminiModel = new GeminiModel();
const geminiVisionModel = new GeminiVisionModel();

// handles message
export async function handleMessage({ client, msg, metadata }: MessageHandlerParams) {
const modelToUse = Util.getModelByPrefix(metadata.text) as AiModels;

if (!modelToUse) return;

const prompt = metadata.text.split(' ').slice(1).join(' ');

if (modelToUse === 'ChatGPT' && metadata.msgType === 'text') {
await gptModel.sendMessage({ sender: metadata.sender, prompt }, async (res, err) => {
client.sendMessage(metadata.remoteJid, { text: err || res }, { quoted: msg });
});
return;
}

if (modelToUse === 'Gemini' && metadata.msgType === 'text') {
await geminiModel.sendMessage({ sender: metadata.sender, prompt }, async (res, err) => {
client.sendMessage(metadata.remoteJid, { text: err || res }, { quoted: msg });
});
return;
}

// Generative Models
if (
modelToUse === 'GeminiVision' &&
metadata.msgType === 'image' &&
metadata.imgMetaData.caption
) {
const { mimeType, url } = metadata.imgMetaData;
if (mimeType === 'image/jpeg') {
const buffer = await downloadMediaMessage(msg, 'buffer', {});
await geminiVisionModel.sendMessage(
{ sender: metadata.sender, prompt: { prompt, buffer, mimeType } },
async (res, err) => {
client.sendMessage(metadata.remoteJid, { text: err || res }, { quoted: msg });
}
);
return;
}
}

client.sendMessage(metadata.remoteJid, { text: `Hi It's WAAI BOT here 🤖` }, { quoted: msg });
}

// handles message from self
export async function handlerMessageFromMe({ metadata, client, msg, type }: MessageHandlerParams) {
if (metadata.fromMe && metadata.isQuoted) return;
if (metadata.isQuoted && Util.getModelByPrefix(metadata.text)) return;
await handleMessage({ metadata, client, msg, type });
}
Loading

0 comments on commit efbea55

Please sign in to comment.