-
Notifications
You must be signed in to change notification settings - Fork 830
Expand file tree
/
Copy pathwhatsapp_web_backend.py
More file actions
executable file
·122 lines (98 loc) · 5.08 KB
/
whatsapp_web_backend.py
File metadata and controls
executable file
·122 lines (98 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function;
import sys;
sys.dont_write_bytecode = True;
import os;
import base64;
import time;
import json;
import uuid;
import traceback;
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket;
from whatsapp import WhatsAppWebClient;
from utilities import *;
reload(sys);
sys.setdefaultencoding("utf-8");
def eprint(*args, **kwargs): # from https://stackoverflow.com/a/14981125
print(*args, file=sys.stderr, **kwargs);
class WhatsAppWeb(WebSocket):
clientInstances = {};
def sendJSON(self, obj, tag=None):
if "from" not in obj:
obj["from"] = "backend";
eprint("sending " + json.dumps(obj));
if tag is None:
tag = str(getTimestampMs());
self.sendMessage(tag + "," + json.dumps(obj));
def sendError(self, reason, tag=None):
eprint("sending error: " + reason);
self.sendJSON({ "type": "error", "reason": reason }, tag);
def handleMessage(self):
try:
eprint(self.data);
tag = self.data.split(",", 1)[0];
obj = json.loads(self.data[len(tag)+1:]);
eprint(obj);
if "from" not in obj or obj["from"] != "api2backend" or "type" not in obj or not (("command" in obj and obj["command"] == "backend-connectWhatsApp") or "whatsapp_instance_id" in obj):
self.sendError("Invalid request");
return;
if obj["type"] == "call":
if "command" not in obj:
self.sendError("Invalid request");
return;
if obj["command"] == "backend-connectWhatsApp":
clientInstanceId = uuid.uuid4().hex;
onOpenCallback = {
"func": lambda cbSelf: self.sendJSON(mergeDicts({ "type": "resource_connected", "resource": "whatsapp" }, getAttr(cbSelf, "args")), getAttr(cbSelf, "tag")),
"tag": tag,
"args": { "resource_instance_id": clientInstanceId }
};
onMessageCallback = {
"func": lambda obj, cbSelf, moreArgs=None: self.sendJSON(mergeDicts(mergeDicts({ "type": "whatsapp_message_received", "message": obj, "timestamp": getTimestampMs() }, getAttr(cbSelf, "args")), moreArgs), getAttr(cbSelf, "tag")),
"args": { "resource_instance_id": clientInstanceId }
};
onCloseCallback = {
"func": lambda cbSelf: self.sendJSON(mergeDicts({ "type": "resource_gone", "resource": "whatsapp" }, getAttr(cbSelf, "args")), getAttr(cbSelf, "tag")),
"args": { "resource_instance_id": clientInstanceId }
};
self.clientInstances[clientInstanceId] = WhatsAppWebClient(onOpenCallback, onMessageCallback, onCloseCallback);
else:
currWhatsAppInstance = self.clientInstances[obj["whatsapp_instance_id"]];
def callback_function(obj_, cbSelf_):
self.sendJSON(mergeDicts(obj_, getAttr(cbSelf_, "args")), getAttr(cbSelf_, "tag"))
callback = {
"func": callback_function,
"tag": tag,
"args": {"resource_instance_id": obj["whatsapp_instance_id"]}
};
if currWhatsAppInstance.activeWs is None:
self.sendError("No WhatsApp server connected to backend.");
return;
cmd = obj["command"];
if cmd == "backend-generateQRCode":
currWhatsAppInstance.generateQRCode(callback);
elif cmd == "backend-getLoginInfo":
currWhatsAppInstance.getLoginInfo(callback);
elif cmd == "backend-getConnectionInfo":
currWhatsAppInstance.getConnectionInfo(callback);
elif cmd == "backend-getChatHistory":
currWhatsAppInstance.get_chat_history({
"func": callback_function,
"tag": tag,
"args": {"resource_instance_id": obj["whatsapp_instance_id"], "jid": obj["jid"]}
}, str(obj["jid"]));
elif cmd == "backend-disconnectWhatsApp":
currWhatsAppInstance.disconnect();
self.sendJSON({ "type": "resource_disconnected", "resource": "whatsapp", "resource_instance_id": obj["whatsapp_instance_id"] }, tag);
except:
eprint(traceback.format_exc());
def handleConnected(self):
self.sendJSON({ "from": "backend", "type": "connected" });
eprint(self.address, "connected to backend");
def handleClose(self):
whatsapp.disconnect();
eprint(self.address, "closed connection to backend");
server = SimpleWebSocketServer("", 2020, WhatsAppWeb);
eprint("whatsapp-web-backend listening on port 2020");
server.serveforever();