├── api └── index.js ├── static └── whatsapp-sessions.json ├── nodemon.json ├── .gitignore ├── utils └── formatter.js ├── README.md ├── package.json ├── LICENSE ├── app.js └── index.html /api/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/whatsapp-sessions.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore":["./static/*.json"] 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | package-lock.json 3 | static/./static/whatsapp-session-*.json -------------------------------------------------------------------------------- /utils/formatter.js: -------------------------------------------------------------------------------- 1 | const phoneNumberFormatter = (number) => { 2 | let formatted = number.replace(/\D/g, '') 3 | 4 | if(formatted.startsWith('0')){ 5 | formatted = '62' + formatted.substr(1); 6 | } 7 | 8 | if (!formatted.endsWith('@c.us')) { 9 | formatted += '@c.us'; 10 | } 11 | 12 | return formatted; 13 | } 14 | 15 | module.exports = { 16 | phoneNumberFormatter 17 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Whapi 2 | 3 | Whapi Adalah open source WhatsApp Api Gateaway Multi Device yang di kembangkan oleh : [Muhammad Zakir Ramadhan](https://github.com/muhammadzakirramadhan/) yang dapat di pakai dan kembangkan oleh siapa aja. Jangan jadikan open source ini untuk jadi brand tanpa seizin Pengembang. 4 | 5 | ## Instalasi 6 | 7 | Clone Project 8 | 9 | git clone https://github.com/muhammadzakirramadhan/whapi 10 | 11 | Instalasi Depedency 12 | 13 | npm install 14 | 15 | Command Development 16 | 17 | npm run dev 18 | 19 | ## Todo 20 | 21 | - [x] Frontend 22 | - [ ] Rest Api 23 | - [ ] Dokumentasi Api 24 | 25 | 26 | > Untuk Api masih di develop karena ada beberapa kendala saat save device baru 27 | 28 | ## Untuk Contribute 29 | 30 | Silahkan Commit dengan branch : 31 | 32 | username-commit-(pembaruan yang di lakukan) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "whapi", 3 | "version": "1.0.0", 4 | "description": "WhatsApp Api Gateaway", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "node app.js", 8 | "dev": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/muhammadzakirramadhan/whapi.git" 14 | }, 15 | "keywords": [ 16 | "whatsapp-api", 17 | "whatsapp", 18 | "whapi" 19 | ], 20 | "author": "Muhammad Zakir Ramadhan", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/muhammadzakirramadhan/whapi/issues" 24 | }, 25 | "homepage": "https://github.com/muhammadzakirramadhan/whapi#readme", 26 | "dependencies": { 27 | "express": "^4.17.1", 28 | "http": "0.0.1-security", 29 | "qrcode": "^1.4.4", 30 | "socket.io": "^3.1.1", 31 | "whatsapp-web.js": "^1.12.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Muhammad Zakir Ramadhan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const { Client } = require('whatsapp-web.js') 2 | const express = require('express') 3 | const socketIO = require('socket.io'); 4 | const qrcode = require('qrcode'); 5 | const http = require('http'); 6 | const fs = require('fs') 7 | 8 | const port = process.env.PORT || 8000; 9 | const app = express(); 10 | const server = http.createServer(app) 11 | const io = socketIO(server); 12 | 13 | app.use(express.json()) 14 | app.use(express.urlencoded({ 15 | extended:true 16 | })) 17 | 18 | // WhatsApp Api Core 19 | const sessions = []; 20 | const SESSIONS_FILE = './static/whatsapp-sessions.json'; 21 | 22 | const createSessionsFileIfNotExists = () =>{ 23 | if (!fs.existsSync(SESSIONS_FILE)) { 24 | try { 25 | fs.writeFileSync(SESSIONS_FILE, JSON.stringify([])); 26 | console.log('Sessions file created successfully.'); 27 | } catch(err) { 28 | console.log('Failed to create sessions file: ', err); 29 | } 30 | } 31 | } 32 | 33 | createSessionsFileIfNotExists(); 34 | 35 | const setSessionsFile = (sessions) => { 36 | fs.writeFile(SESSIONS_FILE, JSON.stringify(sessions), (err) => { 37 | if(err){ 38 | console.log(err) 39 | } 40 | }) 41 | } 42 | 43 | const getSessionsFile = () => { 44 | return JSON.parse(fs.readFileSync(SESSIONS_FILE)) 45 | } 46 | 47 | const createSession = async (id) => { 48 | console.log('Create sessions : ' + id); 49 | const SESSION_FILE_PATH = `./static/whatsapp-session-${id}.json`; 50 | 51 | let sessionCfg; 52 | if (fs.existsSync(SESSION_FILE_PATH)) { 53 | sessionCfg = require(SESSION_FILE_PATH); 54 | } 55 | 56 | const client = new Client({ 57 | restartOnAuthFail: true, 58 | puppeteer: { 59 | headless: true, 60 | args: [ 61 | '--no-sandbox', 62 | '--disable-setuid-sandbox', 63 | '--disable-dev-shm-usage', 64 | '--disable-accelerated-2d-canvas', 65 | '--no-first-run', 66 | '--no-zygote', 67 | '--single-process', // <- this one doesn't works in Windows 68 | '--disable-gpu' 69 | ], 70 | }, 71 | session: sessionCfg 72 | }); 73 | 74 | client.initialize(); 75 | 76 | client.on('qr', (qr) => { 77 | // Generate and scan this code with your phone 78 | // console.log('QR RECEIVED', qr); 79 | qrcode.toDataURL(qr, (err, url) => { 80 | // console.log('QR RECEIVED', url); 81 | 82 | io.emit('qr', { 83 | id: id, 84 | src: url 85 | }); 86 | 87 | io.emit('message', { 88 | id: id, 89 | text: 'QR Code received, scan please!' 90 | }); 91 | }) 92 | }); 93 | 94 | client.on('ready', () => { 95 | io.emit('ready', { 96 | id:id 97 | }); 98 | 99 | io.emit('message', { 100 | id:id, 101 | text:'WhatsApp Ready!' 102 | }); 103 | 104 | const savedSessions = getSessionsFile(); 105 | const sessionIndex = savedSessions.findIndex(sess => sess.id = id); 106 | savedSessions[sessionIndex].ready = true; 107 | setSessionsFile(savedSessions); 108 | }); 109 | 110 | client.on('authenticated', (session) => { 111 | io.emit('authenticated', { 112 | id:id 113 | }); 114 | 115 | io.emit('message', { 116 | id:id, 117 | text:'Client is authenticated!' 118 | }); 119 | 120 | console.log('AUTHENTICATED', session); 121 | sessionCfg=session; 122 | fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), function (err) { 123 | if (err) { 124 | console.error(err); 125 | } 126 | }); 127 | }); 128 | 129 | client.on('auth_failure', (session) =>{ 130 | io.emit('message', { 131 | id: id, 132 | text: 'Auth failure, restarting...' 133 | }); 134 | }); 135 | 136 | client.on('disconnected', (reason) => { 137 | io.emit('message', { id: id, text: 'Whatsapp is disconnected!' }); 138 | fs.unlinkSync(SESSION_FILE_PATH, function(err) { 139 | if(err) return console.log(err); 140 | console.log('Session file deleted!'); 141 | }); 142 | 143 | client.destroy(); 144 | client.initialize(); 145 | 146 | // Menghapus pada file sessions 147 | const savedSessions = getSessionsFile(); 148 | const sessionIndex = savedSessions.findIndex(sess => sess.id == id); 149 | savedSessions.splice(sessionIndex, 1); 150 | setSessionsFile(savedSessions); 151 | 152 | io.emit('remove-session', id); 153 | }); 154 | 155 | sessions.push({ 156 | id:id, 157 | client:client 158 | }); 159 | 160 | console.log(sessions) 161 | 162 | const savedSessions = getSessionsFile() 163 | const sessionsIndex = savedSessions.findIndex(sess => sess.id = id) 164 | console.log(sessionsIndex) 165 | if(sessionsIndex == -1){ 166 | savedSessions.push({ 167 | id:id, 168 | ready:false 169 | }); 170 | 171 | setSessionsFile(savedSessions); 172 | } 173 | } 174 | 175 | const init = (socket) => { 176 | const savedSessions = getSessionsFile(); 177 | 178 | if(savedSessions.length > 0){ 179 | if(socket){ 180 | socket.emit('init', savedSessions); 181 | } else { 182 | savedSessions.forEach(sess => { 183 | createSession(sess.id) 184 | }); 185 | } 186 | } 187 | } 188 | 189 | init(); 190 | // socket.io 191 | 192 | io.on('connection', (socket) => { 193 | init(socket) 194 | socket.on('create-session', (data) => { 195 | // console.log(data) 196 | createSession(data.id); 197 | }) 198 | }) 199 | 200 | // Application Core 201 | app.get('/', (req, res) => { 202 | res.status(200).sendFile('index.html', { 203 | root: __dirname 204 | }); 205 | }) 206 | 207 | 208 | server.listen(port, () => { 209 | console.log(`Running Server On Port ${port}`); 210 | }) -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Whapi - WhatsApp Api Gateaway 7 | 8 | 13 | 14 | 15 | 28 |
29 |

Selamat Datang Di Whapi!

30 |

Whapi adalah Whatsapp Api Gateaway yang di kembangkan oleh Muhammad Zakir Ramadhan.

31 |
32 |

Whapi adalah Open Source yang dapat di kembangkan oleh siapa saja, Fork.

33 | Mulai 34 |
35 |
36 |
37 |
38 |
39 | 49 |
50 |
51 |
52 |

Logs

53 | 54 |
55 |
56 |
    57 |
    58 |
    59 |
    60 |
    61 |
    62 |
    63 |

    Token

    64 | 65 |
    66 |
    67 |
    68 | 69 | 70 |
    71 | 72 |
    73 |
    74 |
    75 |
    76 |
    77 |
    78 |
    79 | 80 | 81 | 82 | 173 | 174 | --------------------------------------------------------------------------------