warnect 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- warnect-0.1.0/PKG-INFO +66 -0
- warnect-0.1.0/README.md +53 -0
- warnect-0.1.0/pyproject.toml +27 -0
- warnect-0.1.0/setup.cfg +4 -0
- warnect-0.1.0/warnect/__init__.py +6 -0
- warnect-0.1.0/warnect/bridge/package.json +9 -0
- warnect-0.1.0/warnect/bridge/server.js +55 -0
- warnect-0.1.0/warnect/client.py +94 -0
- warnect-0.1.0/warnect.egg-info/PKG-INFO +66 -0
- warnect-0.1.0/warnect.egg-info/SOURCES.txt +10 -0
- warnect-0.1.0/warnect.egg-info/dependency_links.txt +1 -0
- warnect-0.1.0/warnect.egg-info/top_level.txt +1 -0
warnect-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: warnect
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python interface to arsya-baileys-open (WhatsApp Web) via a Node.js bridge
|
|
5
|
+
Author: Arsya
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ziole-visa/warnect
|
|
8
|
+
Keywords: whatsapp,baileys,warnect,automation
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# warnect (Python)
|
|
15
|
+
|
|
16
|
+
Python interface to **arsya-baileys-open** (WhatsApp Web multi-device) through a
|
|
17
|
+
small Node.js bridge. It keeps the heavy WhatsApp protocol implementation in
|
|
18
|
+
Node and exposes an easy Python API.
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- Python >= 3.10
|
|
23
|
+
- Node.js >= 20
|
|
24
|
+
- npm
|
|
25
|
+
|
|
26
|
+
Node dependencies are installed automatically on first run. To install manually:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd warnect/bridge
|
|
30
|
+
npm install
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Python install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install -e .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick start
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from warnect import BaileysClient
|
|
43
|
+
|
|
44
|
+
client = BaileysClient(auth_dir="auth")
|
|
45
|
+
|
|
46
|
+
def on_qr(qr):
|
|
47
|
+
print("QR:", qr)
|
|
48
|
+
|
|
49
|
+
def on_message(msg):
|
|
50
|
+
print("Pesan:", msg.get("text"))
|
|
51
|
+
if msg.get("text") == "ping":
|
|
52
|
+
client.send_text(msg["key"]["remoteJid"], "pong")
|
|
53
|
+
|
|
54
|
+
client.on("qr", on_qr)
|
|
55
|
+
client.on("message", on_message)
|
|
56
|
+
client.start()
|
|
57
|
+
|
|
58
|
+
input("Press Enter to stop...\n")
|
|
59
|
+
client.stop()
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Notes
|
|
63
|
+
|
|
64
|
+
- This is an early alpha. Only text send/receive and QR login are supported.
|
|
65
|
+
- Media, groups, and advanced features will be added incrementally.
|
|
66
|
+
- Bridge runs `arsya-baileys-open` under the hood.
|
warnect-0.1.0/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# warnect (Python)
|
|
2
|
+
|
|
3
|
+
Python interface to **arsya-baileys-open** (WhatsApp Web multi-device) through a
|
|
4
|
+
small Node.js bridge. It keeps the heavy WhatsApp protocol implementation in
|
|
5
|
+
Node and exposes an easy Python API.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Python >= 3.10
|
|
10
|
+
- Node.js >= 20
|
|
11
|
+
- npm
|
|
12
|
+
|
|
13
|
+
Node dependencies are installed automatically on first run. To install manually:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cd warnect/bridge
|
|
17
|
+
npm install
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Python install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install -e .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick start
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from warnect import BaileysClient
|
|
30
|
+
|
|
31
|
+
client = BaileysClient(auth_dir="auth")
|
|
32
|
+
|
|
33
|
+
def on_qr(qr):
|
|
34
|
+
print("QR:", qr)
|
|
35
|
+
|
|
36
|
+
def on_message(msg):
|
|
37
|
+
print("Pesan:", msg.get("text"))
|
|
38
|
+
if msg.get("text") == "ping":
|
|
39
|
+
client.send_text(msg["key"]["remoteJid"], "pong")
|
|
40
|
+
|
|
41
|
+
client.on("qr", on_qr)
|
|
42
|
+
client.on("message", on_message)
|
|
43
|
+
client.start()
|
|
44
|
+
|
|
45
|
+
input("Press Enter to stop...\n")
|
|
46
|
+
client.stop()
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Notes
|
|
50
|
+
|
|
51
|
+
- This is an early alpha. Only text send/receive and QR login are supported.
|
|
52
|
+
- Media, groups, and advanced features will be added incrementally.
|
|
53
|
+
- Bridge runs `arsya-baileys-open` under the hood.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "warnect"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python interface to arsya-baileys-open (WhatsApp Web) via a Node.js bridge"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Arsya" }]
|
|
13
|
+
keywords = ["whatsapp", "baileys", "warnect", "automation"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://github.com/ziole-visa/warnect"
|
|
21
|
+
|
|
22
|
+
[tool.setuptools]
|
|
23
|
+
packages = ["warnect"]
|
|
24
|
+
include-package-data = false
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.package-data]
|
|
27
|
+
warnect = ["bridge/server.js", "bridge/package.json"]
|
warnect-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { makeWASocket, useMultiFileAuthState, DisconnectReason } from 'arsya-baileys-open';
|
|
2
|
+
import readline from 'node:readline';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
|
|
5
|
+
const authDir = process.argv[2] || './auth';
|
|
6
|
+
let sock = null;
|
|
7
|
+
|
|
8
|
+
function send(obj) {
|
|
9
|
+
process.stdout.write(JSON.stringify(obj) + '\n');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const rl = readline.createInterface({ input: process.stdin });
|
|
13
|
+
rl.on('line', async (line) => {
|
|
14
|
+
let cmd;
|
|
15
|
+
try { cmd = JSON.parse(line); } catch { return; }
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
if (cmd.cmd === 'start') {
|
|
19
|
+
const { state, saveCreds } = await useMultiFileAuthState(authDir);
|
|
20
|
+
sock = makeWASocket({ auth: state, printQRInTerminal: false });
|
|
21
|
+
sock.ev.on('creds.update', saveCreds);
|
|
22
|
+
sock.ev.on('connection.update', (u) => {
|
|
23
|
+
if (u.qr) send({ event: 'qr', data: u.qr });
|
|
24
|
+
if (u.connection) send({ event: 'connection', data: u.connection });
|
|
25
|
+
if (u.lastDisconnect?.error) {
|
|
26
|
+
send({ event: 'error', data: String(u.lastDisconnect.error) });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
sock.ev.on('messages.upsert', (m) => {
|
|
30
|
+
for (const msg of m.messages || []) {
|
|
31
|
+
if (!msg.message) continue;
|
|
32
|
+
const text = msg.message.conversation
|
|
33
|
+
|| msg.message.extendedTextMessage?.text
|
|
34
|
+
|| null;
|
|
35
|
+
send({ event: 'message', data: { key: msg.key, text, message: msg.message } });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
send({ event: 'started' });
|
|
39
|
+
} else if (cmd.cmd === 'sendText') {
|
|
40
|
+
if (!sock) throw new Error('socket not started');
|
|
41
|
+
await sock.sendMessage(cmd.jid, { text: cmd.text });
|
|
42
|
+
send({ event: 'sent', data: { jid: cmd.jid } });
|
|
43
|
+
} else if (cmd.cmd === 'stop') {
|
|
44
|
+
try { sock?.end(); } catch {}
|
|
45
|
+
process.exit(0);
|
|
46
|
+
} else {
|
|
47
|
+
send({ event: 'error', data: 'unknown command: ' + cmd.cmd });
|
|
48
|
+
}
|
|
49
|
+
} catch (e) {
|
|
50
|
+
send({ event: 'error', data: String(e?.message || e) });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
process.on('SIGTERM', () => { try { sock?.end(); } catch {} process.exit(0); });
|
|
55
|
+
process.on('SIGINT', () => { try { sock?.end(); } catch {} process.exit(0); });
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
import threading
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Callable, Dict, List
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaileysClient:
|
|
10
|
+
"""Minimal Python client that talks to the Node bridge (arsya-baileys-open)."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, auth_dir: str = "auth", bridge_script: str | None = None):
|
|
13
|
+
if bridge_script is None:
|
|
14
|
+
bridge_script = str(Path(__file__).resolve().parent / "bridge" / "server.js")
|
|
15
|
+
self.auth_dir = auth_dir
|
|
16
|
+
self.bridge_script = bridge_script
|
|
17
|
+
self.proc = None
|
|
18
|
+
self._handlers: Dict[str, List[Callable]] = {}
|
|
19
|
+
self._reader_thread = None
|
|
20
|
+
|
|
21
|
+
def on(self, event: str, callback: Callable) -> None:
|
|
22
|
+
self._handlers.setdefault(event, []).append(callback)
|
|
23
|
+
|
|
24
|
+
def _emit(self, event: str, data=None) -> None:
|
|
25
|
+
for cb in self._handlers.get(event, []):
|
|
26
|
+
try:
|
|
27
|
+
cb(data)
|
|
28
|
+
except Exception as exc: # pragma: no cover - user callback
|
|
29
|
+
print(f"[arsya-baileys] callback error: {exc}")
|
|
30
|
+
|
|
31
|
+
def _read_loop(self) -> None:
|
|
32
|
+
assert self.proc and self.proc.stdout
|
|
33
|
+
for line in self.proc.stdout:
|
|
34
|
+
line = line.strip()
|
|
35
|
+
if not line:
|
|
36
|
+
continue
|
|
37
|
+
try:
|
|
38
|
+
obj = json.loads(line)
|
|
39
|
+
except json.JSONDecodeError:
|
|
40
|
+
continue
|
|
41
|
+
if "event" in obj:
|
|
42
|
+
self._emit(obj["event"], obj.get("data"))
|
|
43
|
+
elif "error" in obj:
|
|
44
|
+
self._emit("error", obj["error"])
|
|
45
|
+
|
|
46
|
+
def _send(self, obj: dict) -> None:
|
|
47
|
+
if not self.proc or not self.proc.stdin:
|
|
48
|
+
raise RuntimeError("bridge is not running")
|
|
49
|
+
self.proc.stdin.write(json.dumps(obj) + "\n")
|
|
50
|
+
self.proc.stdin.flush()
|
|
51
|
+
|
|
52
|
+
def _ensure_node_deps(self) -> None:
|
|
53
|
+
bridge_dir = Path(self.bridge_script).resolve().parent
|
|
54
|
+
marker = bridge_dir / "node_modules" / "arsya-baileys-open" / "package.json"
|
|
55
|
+
if marker.exists():
|
|
56
|
+
return
|
|
57
|
+
print("[arsya-baileys] Installing Node dependencies (first run)...")
|
|
58
|
+
try:
|
|
59
|
+
subprocess.run(
|
|
60
|
+
["npm", "install", "--no-audit", "--no-fund"],
|
|
61
|
+
cwd=str(bridge_dir),
|
|
62
|
+
check=True,
|
|
63
|
+
timeout=300,
|
|
64
|
+
)
|
|
65
|
+
except FileNotFoundError as exc:
|
|
66
|
+
raise RuntimeError("Node.js/npm is required but was not found in PATH") from exc
|
|
67
|
+
|
|
68
|
+
def start(self) -> None:
|
|
69
|
+
if self.proc is not None:
|
|
70
|
+
return
|
|
71
|
+
self._ensure_node_deps()
|
|
72
|
+
self.proc = subprocess.Popen(
|
|
73
|
+
["node", self.bridge_script, self.auth_dir],
|
|
74
|
+
stdin=subprocess.PIPE,
|
|
75
|
+
stdout=subprocess.PIPE,
|
|
76
|
+
stderr=subprocess.PIPE,
|
|
77
|
+
text=True,
|
|
78
|
+
bufsize=1,
|
|
79
|
+
)
|
|
80
|
+
self._reader_thread = threading.Thread(target=self._read_loop, daemon=True)
|
|
81
|
+
self._reader_thread.start()
|
|
82
|
+
self._send({"cmd": "start"})
|
|
83
|
+
|
|
84
|
+
def send_text(self, jid: str, text: str) -> None:
|
|
85
|
+
self._send({"cmd": "sendText", "jid": jid, "text": text})
|
|
86
|
+
|
|
87
|
+
def stop(self) -> None:
|
|
88
|
+
try:
|
|
89
|
+
self._send({"cmd": "stop"})
|
|
90
|
+
except Exception:
|
|
91
|
+
pass
|
|
92
|
+
if self.proc:
|
|
93
|
+
self.proc.terminate()
|
|
94
|
+
self.proc = None
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: warnect
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python interface to arsya-baileys-open (WhatsApp Web) via a Node.js bridge
|
|
5
|
+
Author: Arsya
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ziole-visa/warnect
|
|
8
|
+
Keywords: whatsapp,baileys,warnect,automation
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# warnect (Python)
|
|
15
|
+
|
|
16
|
+
Python interface to **arsya-baileys-open** (WhatsApp Web multi-device) through a
|
|
17
|
+
small Node.js bridge. It keeps the heavy WhatsApp protocol implementation in
|
|
18
|
+
Node and exposes an easy Python API.
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- Python >= 3.10
|
|
23
|
+
- Node.js >= 20
|
|
24
|
+
- npm
|
|
25
|
+
|
|
26
|
+
Node dependencies are installed automatically on first run. To install manually:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd warnect/bridge
|
|
30
|
+
npm install
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Python install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install -e .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick start
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from warnect import BaileysClient
|
|
43
|
+
|
|
44
|
+
client = BaileysClient(auth_dir="auth")
|
|
45
|
+
|
|
46
|
+
def on_qr(qr):
|
|
47
|
+
print("QR:", qr)
|
|
48
|
+
|
|
49
|
+
def on_message(msg):
|
|
50
|
+
print("Pesan:", msg.get("text"))
|
|
51
|
+
if msg.get("text") == "ping":
|
|
52
|
+
client.send_text(msg["key"]["remoteJid"], "pong")
|
|
53
|
+
|
|
54
|
+
client.on("qr", on_qr)
|
|
55
|
+
client.on("message", on_message)
|
|
56
|
+
client.start()
|
|
57
|
+
|
|
58
|
+
input("Press Enter to stop...\n")
|
|
59
|
+
client.stop()
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Notes
|
|
63
|
+
|
|
64
|
+
- This is an early alpha. Only text send/receive and QR login are supported.
|
|
65
|
+
- Media, groups, and advanced features will be added incrementally.
|
|
66
|
+
- Bridge runs `arsya-baileys-open` under the hood.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
warnect
|