added direct chat support with bridge removing the need for seperate bot, issue #35

This commit is contained in:
Morgan McMillian 2020-03-24 22:39:09 -07:00
parent f10e8bb924
commit 9dc5e3eda9
2 changed files with 162 additions and 2 deletions

View file

@ -6,7 +6,7 @@ import pnutpy
from matrix_client.api import MatrixHttpApi from matrix_client.api import MatrixHttpApi
from matrix_client.api import MatrixError, MatrixRequestError from matrix_client.api import MatrixError, MatrixRequestError
from models import Avatars, Rooms, Events, Users from models import Avatars, Rooms, Events, Users, DirectRooms
from database import db_session from database import db_session
from sqlalchemy import and_ from sqlalchemy import and_
from flask import Flask, jsonify, request, abort from flask import Flask, jsonify, request, abort
@ -105,7 +105,17 @@ def on_receive_events(transaction):
delete_message(event, user) delete_message(event, user)
elif event['type'] == 'm.room.member': elif event['type'] == 'm.room.member':
logger.debug("-room member event") if 'is_direct' in event['content'] and 'membership' in event['content']:
if event['content']['membership'] == "invite" and event['content']['is_direct']:
return on_admin_invite(event)
if 'membership' in event['content']:
if event['content']['membership'] == "leave":
return on_leave_event(event)
logger.debug("----room member event----")
logger.debug(user)
logger.debug(event)
return jsonify({}) return jsonify({})
@ -115,6 +125,10 @@ def new_message(event, user):
logger.debug('-skipping dup event-') logger.debug('-skipping dup event-')
return return
direct = DirectRooms.query.filter(DirectRooms.room_id == event['room_id']).one_or_none()
if direct is not None:
return on_direct_message(event)
room = Rooms.query.filter(Rooms.room_id == event['room_id']).one_or_none() room = Rooms.query.filter(Rooms.room_id == event['room_id']).one_or_none()
if room is None: if room is None:
logger.debug('-room not mapped-') logger.debug('-room not mapped-')
@ -448,3 +462,144 @@ def cmd_admin_unlink(id):
errmsg = "- error while unlinking room -" errmsg = "- error while unlinking room -"
logger.exception(errmsg) logger.exception(errmsg)
return errmsg return errmsg
def on_admin_invite(event):
matrix_api = MatrixHttpApi(app.config['MATRIX_HOST'],
token=app.config['MATRIX_AS_TOKEN'])
matrix_api.join_room(event['room_id'])
direct = DirectRooms(room_id=event['room_id'])
db_session.add(direct)
db_session.commit()
return jsonify({})
def on_leave_event(event):
matrix_api = MatrixHttpApi(app.config['MATRIX_HOST'],
token=app.config['MATRIX_AS_TOKEN'])
direct = DirectRooms.query.filter(DirectRooms.room_id == event['room_id']).one_or_none()
if direct is not None:
db_session.delete(direct)
db_session.commit()
matrix_api.leave_room(event['room_id'])
return jsonify({})
def on_direct_message(event):
matrix_api = MatrixHttpApi(app.config['MATRIX_HOST'],
token=app.config['MATRIX_AS_TOKEN'])
logger.debug("- direct room event received -")
if event['type'] != 'm.room.message':
return jsonify({})
msg = event['content']['body'].split(' ')
if msg[0] == '!help' or msg[0] == 'help':
if len(msg) > 1:
matrix_api.send_message(event['room_id'], cmd_user_help(msg[1]))
else:
matrix_api.send_message(event['room_id'], cmd_user_help())
elif msg[0] == '!auth':
matrix_api.send_message(event['room_id'], cmd_user_auth())
elif msg[0] == '!save':
if len(msg) > 1:
matrix_api.send_message(event['room_id'], cmd_user_save(event['sender'], msg[1]))
else:
matrix_api.send_message(event['room_id'], cmd_user_save())
elif msg[0] == '!drop':
matrix_api.send_message(event['room_id'], cmd_user_drop(event['sender']))
elif msg[0] == '!status':
matrix_api.send_message(event['room_id'], cmd_user_status(event['sender']))
return jsonify({})
def cmd_user_help(cmd=None):
reply = "This is an admin room for controlling your connection to pnut.io\n"
reply += "The following commands are available.\n\n"
reply += "!auth\t\t\t- Authorize your account on pnut.io\n"
reply += "!save <token>\t- Save your pnut.io auth token\n"
reply += "!drop\t\t\t- Drop your pnut.io auth token\n"
reply += "!status\t\t\t- Status of your pnut.io auth token\n"
return reply
def cmd_user_auth():
reply = "Visit the following URL to authorize your account on pnut.io.\n\n"
reply += "https://pnut.io/oauth/authenticate"
reply += "?client_id=6SeCRCpCZkmZOKFLFGWbcdAeq2fX1M5t"
reply += "&redirect_uri=urn:ietf:wg:oauth:2.0:oob"
reply += "&scope=write_post,presence,messages&response_type=token\n\n"
reply += "You will be provided with a token that you store with the !save command.\n"
return reply
def cmd_user_save(sender=None, token=None):
if token is None:
reply = "You must provide a token with this command.\n"
reply += "!save <token>"
return reply
pnutpy.api.add_authorization_token(token)
try:
response, meta = pnutpy.api.get_user('me')
user = Users(
matrix_id=sender,
pnut_user_id=response.id,
pnut_user_token=token
)
db_session.add(user)
db_session.commit()
reply = "Success! You are now authorized as " + response['username']
except pnutpy.errors.PnutAuthAPIException as e:
reply = "Error! Unable to authorize your account."
except Exception as e:
logging.exception('!save')
reply = "Error! Problem saving your token."
return reply
def cmd_user_drop(sender=None):
try:
user = Users.query.filter(Users.matrix_id == sender).one_or_none()
if user is not None:
db_session.delete(user)
db_session.commit()
reply = "Success! Your auth token has been removed."
else:
reply = "You do not appear to be registered."
except Exception as e:
logging.exception('!drop')
reply = "Error! Problem removing your token."
return reply
def cmd_user_status(sender=None):
try:
user = Users.query.filter(Users.matrix_id == sender).one_or_none()
if user is None:
reply = "You are currently not authorized on pnut.io"
else:
pnutpy.api.add_authorization_token(user.pnut_user_token)
response, meta = pnutpy.api.get_user('me')
reply = "You are currently authorized as " + response.username
except pnutpy.errors.PnutAuthAPIException as e:
reply = "You are currently not authorized on pnut.io"
except Exception as e:
logging.exception('!status')
reply = "Error! There was a problem checking your account."
return reply

View file

@ -14,6 +14,11 @@ class Rooms(Base):
pnut_chan = Column(Integer, unique=True) pnut_chan = Column(Integer, unique=True)
portal = Column(Boolean) portal = Column(Boolean)
class DirectRooms(Base):
__tablename__ = 'direct'
id = Column(Integer, primary_key=True)
room_id = Column(String(250), unique=True)
class Events(Base): class Events(Base):
__tablename__ = 'events' __tablename__ = 'events'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)