diff --git a/appservice.py b/appservice.py new file mode 100644 index 0000000..1949dbb --- /dev/null +++ b/appservice.py @@ -0,0 +1,143 @@ +import json +import requests +import logging + +from flask import Flask, jsonify, request, abort +from models import * + +app = Flask(__name__) +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +db.init_app(app) + +txId = 0 + +@app.route("/testme/") +def on_testme(hello): + logging.debug(hello) + user = MatrixUser.query.filter_by(matrix_id=hello).first() + logging.debug(user) + logging.debug(app.config['MATRIX_PNUT_PREFIX']) + return jsonify({}) + +@app.route("/transactions/", methods=["PUT"]) +def on_receive_events(transaction): + global txId + + events = request.get_json()["events"] + for event in events: + logging.debug(event) + user = MatrixUser.query.filter_by(matrix_id=event["user_id"]) + + if (event['type'] == 'm.room.message' + and not app.config['MATRIX_PNUT_PREFIX'] in event["user_id"] + and not 'pnut-bridge' in event["user_id"]): + + if (event['content']['msgtype'] == 'm.text' + or event['content']['msgtype'] == 'm.notice'): + if user: + token = user.pnut_token + text = event['content']['body'] + else: + token = app.config['MATRIX_PNUT_TOKEN'] + text = "<" + event["user_id"] + "> " + event['content']['body'] + elif event['content']['msgtype'] == 'm.emote': + if user: + token = user.pnut_token + text = "* " + user.pnut_id + " " + event['content']['body'] + else: + token = app.config['MATRIX_PNUT_TOKEN'] + text = "* " + event["user_id"] + " " + event['content']['body'] + else: + text = None + + chan = MatrixRoom.query.filter_by(room_id=event['room_id']).first() + if chan: + chan_id = chan.pnut_chan + else: + return jsonify({}) + + if user == None and not chan.pnut_write: + txId += 1 + url = app.config['MATRIXBOT_HOST'] + url += '/_matrix/client/r0/rooms/{0}/redact/{1}/{2}'.format( + event['room_id'], event['event_id'], txId) + url += "?access_token=" + app.config['MATRIX_AS_TOKEN'] + requests.put(url, headers={"Content-Type": "application/json"}, data=json.dumps({})) + else: + if text: + r = Pnut(token).channel_post(chan_id, text) + if r.status_code == 201: + msgid = json.loads(r.text)['data']['id'] + if token == app.config['MATRIX_PNUT_TOKEN']: + puser = app.config['MATRIX_PNUT_USER'] + else: + puser = user.pnut_id + + el = MatrixMsgEvents(event['event_id'], event['room_id'], msgid, puser, chan_id) + db.session.add(el) + db.session.commit() + + elif event['type'] == 'm.room.redaction': + r_event = MatrixMsgEvents.query.filter_by(event_id=event['redacts'],room_id=event['room_id']).first() + if r_event: + if r_event.pnut_user == app.config['MATRIX_PNUT_USER']: + token = token == app.config['MATRIX_PNUT_TOKEN'] + else: + r_user = MatrixUser.query.filter_by(pnut_id=r_event.pnut_user).first() + if r_user: + token = r_user.pnut_token + else: + return jsonify({}) + + r = Pnut(token).delete_channel_post(r_event.pnut_chan, r_event.pnut_msgid) + + return jsonify({}) + +@app.route("/rooms/") +def query_alias(alias): + alias_localpart = alias.split(":")[0][1:] + try: + channel_id = int(alias_localpart.split('_')[1]) + r = requests.get('https://api.pnut.io/v0/channels/' + str(channel_id) + '?include_raw=1') + if r.status_code == 200: + cdata = json.loads(r.text)['data'] + if cdata['type'] != 'io.pnut.core.chat': + abort(404) + raw = cdata['raw'] + for item in raw: + if item['type'] == 'io.pnut.core.chat-settings': + chan_settings = item['value'] + else: + abort(404) + except: + raise + abort(404) + + mroom = {'room_alias_name': alias_localpart} + if 'name' in chan_settings: + mroom['name'] = chan_settings['name'] + if 'description' in chan_settings: + mroom['topic'] = chan_settings['description'] + if cdata['acl']['read']['any_user']: + mroom['preset'] = 'public_chat' + mroom['visibility'] = 'public' + + resp = requests.post( + # NB: "TOKEN" is the as_token referred to in registration.yaml + "http://localhost:8008/_matrix/client/api/v1/createRoom?access_token=" + app.config['MATRIX_AS_TOKEN'], + json.dumps(mroom), + headers={"Content-Type":"application/json"} + ) + + if resp.status_code == 200: + room_id = json.loads(resp.text)['room_id'] + mro = MatrixRoom(room_id, channel_id, cdata['acl']['write']['any_user']) + db.session.add(mro) + db.session.commit() + + return jsonify({}) + +@app.errorhandler(404) +def not_found(error): + return jsonify({'errcode':'COM.MONKEYSTEW.PNUT_NOT_FOUND'}), 404 +