#!/usr/bin/env python3 import sys import json import hashlib import gevent import fbchat # ---- MESSAGE TYPES ---- # ezbr -> external CONFIGURE = "configure" GET_USER = "get_user" SET_USER_INFO = "set_user_info" SET_ROOM_INFO = "set_room_info" JOIN = "join" INVITE = "invite" LEAVE = "leave" SEND = "send" CLOSE = "close" # external -> ezbr JOINED = "joined" LEFT = "left" USER_INFO_UPDATED = "user_info_updated" ROOM_INFO_UPDATED = "room_info_updated" EVENT = "event" CACHE_PUT = "cache_put" CACHE_GET = "cache_get" # reply messages # ezbr -> external: all must wait for a reply! # external -> ezbr: only CACHE_GET produces a reply REP_OK = "rep_ok" REP_ERROR = "rep_error" # ---- MESSENGER CLIENT CLASS THAT HANDLES EVENTS ---- class MessengerBridgeClient(fbchat.Client): def __init__(self, bridge, *args, **kwargs): self.bridge = bridge super(MessengerBridgeClient, self).__init__(*args, **kwargs) # TODO: handle events # ---- MAIN LOOP THAT HANDLES REQUESTS FROM BRIDGE ---- class MessengerBridge: def run(self): self.client = None self.keep_running = True while self.keep_running: line = sys.stdin.readline() sys.stderr.write("(python) reading {}\n".format(line.strip())) cmd = json.loads(line) try: rep = self.handle_cmd(cmd) if rep is None: rep = {} if "_type" not in rep: rep["_type"] = REP_OK except Exception as e: rep = { "_type": REP_ERROR, "error": "{}".format(e) } rep["_id"] = cmd["_id"] self.write(rep) def write(self, msg): msgstr = json.dumps(msg) sys.stderr.write("(python) writing {}\n".format(msgstr)) sys.stdout.write(msgstr + "\n") sys.stdout.flush() def handle_cmd(self, cmd): ty = cmd["_type"] if ty == CONFIGURE: cookies_file = "/tmp/cookies_" + hashlib.sha224(cmd["data"]["email"].encode("utf-8")).hexdigest() try: f = open(cookies_file, "r") cookies = json.load(f) f.close() sys.stderr.write("(python messenger) using previous cookies: {}\n".format(cookies)) except: cookies = None self.client = MessengerBridgeClient(self, cmd["data"]["email"], cmd["data"]["password"], session_cookies=cookies) if self.client.isLoggedIn(): cookies = self.client.getSession() try: f = open(cookies_file, "w") json.dump(cookies, f) f.close() except: pass elif ty == CLOSE: self.client.logout() self.keep_running = False else: return {"_type": REP_ERROR, "error": "Not implemented"} if __name__ == "__main__": bridge = MessengerBridge() bridge.run()