Added reply bridging (#26)
Messages sent from Telegram that are replies to previous messages are now formatted better on Matrix: The message contains a link to the replied-to message on Matrix, so clicking on it works just like it does on Telegram Also, the reply quotes the original message.
This commit is contained in:
parent
b67d0733d9
commit
89779b4da7
@ -227,13 +227,13 @@ async def matrix_transaction(request):
|
|||||||
|
|
||||||
if content['msgtype'] == 'm.text':
|
if content['msgtype'] == 'm.text':
|
||||||
msg, mode = format_matrix_msg('<{}> {}', displayname, content)
|
msg, mode = format_matrix_msg('<{}> {}', displayname, content)
|
||||||
await group.send_text(msg, parse_mode=mode)
|
response = await group.send_text(msg, parse_mode=mode)
|
||||||
elif content['msgtype'] == 'm.notice':
|
elif content['msgtype'] == 'm.notice':
|
||||||
msg, mode = format_matrix_msg('[{}] {}', displayname, content)
|
msg, mode = format_matrix_msg('[{}] {}', displayname, content)
|
||||||
await group.send_text(msg, parse_mode=mode)
|
response = await group.send_text(msg, parse_mode=mode)
|
||||||
elif content['msgtype'] == 'm.emote':
|
elif content['msgtype'] == 'm.emote':
|
||||||
msg, mode = format_matrix_msg('* {} {}', displayname, content)
|
msg, mode = format_matrix_msg('* {} {}', displayname, content)
|
||||||
await group.send_text(msg, parse_mode=mode)
|
response = await group.send_text(msg, parse_mode=mode)
|
||||||
elif content['msgtype'] == 'm.image':
|
elif content['msgtype'] == 'm.image':
|
||||||
try:
|
try:
|
||||||
url = urlparse(content['url'])
|
url = urlparse(content['url'])
|
||||||
@ -254,12 +254,13 @@ async def matrix_transaction(request):
|
|||||||
|
|
||||||
caption = '<{}> {} ({})'.format(displayname,
|
caption = '<{}> {} ({})'.format(displayname,
|
||||||
content['body'], url_str)
|
content['body'], url_str)
|
||||||
await group.send_photo(img_file, caption=caption)
|
response = await group.send_photo(img_file, caption=caption)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
print('Unsupported message type {}'.format(content['msgtype']))
|
print('Unsupported message type {}'.format(content['msgtype']))
|
||||||
print(json.dumps(content, indent=4))
|
print(json.dumps(content, indent=4))
|
||||||
|
|
||||||
elif event['type'] == 'm.room.member':
|
elif event['type'] == 'm.room.member':
|
||||||
if matrix_is_telegram(event['state_key']):
|
if matrix_is_telegram(event['state_key']):
|
||||||
continue
|
continue
|
||||||
@ -300,13 +301,22 @@ async def matrix_transaction(request):
|
|||||||
msg = '> {} has joined the room'.format(displayname)
|
msg = '> {} has joined the room'.format(displayname)
|
||||||
|
|
||||||
if msg:
|
if msg:
|
||||||
await group.send_text(msg)
|
response = await group.send_text(msg)
|
||||||
elif content['membership'] == 'leave':
|
elif content['membership'] == 'leave':
|
||||||
msg = '< {} has left the room'.format(displayname)
|
msg = '< {} has left the room'.format(displayname)
|
||||||
await group.send_text(msg)
|
response = await group.send_text(msg)
|
||||||
elif content['membership'] == 'ban':
|
elif content['membership'] == 'ban':
|
||||||
msg = '<! {} was banned from the room'.format(displayname)
|
msg = '<! {} was banned from the room'.format(displayname)
|
||||||
await group.send_text(msg)
|
response = await group.send_text(msg)
|
||||||
|
|
||||||
|
if response:
|
||||||
|
message = db.Message(
|
||||||
|
response['result']['chat']['id'],
|
||||||
|
response['result']['message_id'],
|
||||||
|
event['room_id'],
|
||||||
|
event['event_id'],
|
||||||
|
displayname)
|
||||||
|
db.session.add(message)
|
||||||
|
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
print('Got a runtime error:', e)
|
print('Got a runtime error:', e)
|
||||||
@ -470,6 +480,19 @@ async def aiotg_sticker(chat, sticker):
|
|||||||
await send_matrix_message(room_id, user_id, txn_id + 'caption',
|
await send_matrix_message(room_id, user_id, txn_id + 'caption',
|
||||||
body=chat.message['caption'],
|
body=chat.message['caption'],
|
||||||
msgtype='m.text')
|
msgtype='m.text')
|
||||||
|
if 'event_id' in j:
|
||||||
|
name = chat.sender['first_name']
|
||||||
|
if 'last_name' in chat.sender:
|
||||||
|
name += " " + chat.sender['last_name']
|
||||||
|
name += " (Telegram)"
|
||||||
|
message = db.Message(
|
||||||
|
chat.message['chat']['id'],
|
||||||
|
chat.message['message_id'],
|
||||||
|
room_id,
|
||||||
|
j['event_id'],
|
||||||
|
name)
|
||||||
|
db.session.add(message)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
@TG_BOT.handle('photo')
|
@TG_BOT.handle('photo')
|
||||||
async def aiotg_photo(chat, photo):
|
async def aiotg_photo(chat, photo):
|
||||||
@ -503,6 +526,19 @@ async def aiotg_photo(chat, photo):
|
|||||||
body=chat.message['caption'],
|
body=chat.message['caption'],
|
||||||
msgtype='m.text')
|
msgtype='m.text')
|
||||||
|
|
||||||
|
if 'event_id' in j:
|
||||||
|
name = chat.sender['first_name']
|
||||||
|
if 'last_name' in chat.sender:
|
||||||
|
name += " " + chat.sender['last_name']
|
||||||
|
name += " (Telegram)"
|
||||||
|
message = db.Message(
|
||||||
|
chat.message['chat']['id'],
|
||||||
|
chat.message['message_id'],
|
||||||
|
room_id,
|
||||||
|
j['event_id'],
|
||||||
|
name)
|
||||||
|
db.session.add(message)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
@TG_BOT.command(r'/alias')
|
@TG_BOT.command(r'/alias')
|
||||||
async def aiotg_alias(chat, match):
|
async def aiotg_alias(chat, match):
|
||||||
@ -548,7 +584,7 @@ async def aiotg_message(chat, match):
|
|||||||
|
|
||||||
elif 'reply_to_message' in chat.message:
|
elif 'reply_to_message' in chat.message:
|
||||||
re_msg = chat.message['reply_to_message']
|
re_msg = chat.message['reply_to_message']
|
||||||
if not 'text' in re_msg and not 'photo' in re_msg:
|
if not 'text' in re_msg and not 'photo' in re_msg and not 'sticker' in re_msg:
|
||||||
return
|
return
|
||||||
if 'last_name' in re_msg['from']:
|
if 'last_name' in re_msg['from']:
|
||||||
msg_from = '{} {} (Telegram)'.format(re_msg['from']['first_name'],
|
msg_from = '{} {} (Telegram)'.format(re_msg['from']['first_name'],
|
||||||
@ -558,26 +594,32 @@ async def aiotg_message(chat, match):
|
|||||||
date = datetime.fromtimestamp(re_msg['date']) \
|
date = datetime.fromtimestamp(re_msg['date']) \
|
||||||
.strftime('%Y-%m-%d %H:%M:%S')
|
.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
reply_mx_id = db.session.query(db.Message)\
|
||||||
|
.filter_by(tg_group_id=chat.message['chat']['id'], tg_message_id=chat.message['reply_to_message']['message_id']).first()
|
||||||
|
|
||||||
html_message = html.escape(message).replace('\n', '<br />')
|
html_message = html.escape(message).replace('\n', '<br />')
|
||||||
if 'text' in re_msg['from']:
|
if 'text' in re_msg:
|
||||||
quoted_msg = '\n'.join(['>{}'.format(x)
|
quoted_msg = '\n'.join(['>{}'.format(x)
|
||||||
for x in re_msg['text'].split('\n')])
|
for x in re_msg['text'].split('\n')])
|
||||||
quoted_msg = 'Reply to {} ({}):\n{}\n\n{}' \
|
|
||||||
.format(msg_from, date, quoted_msg, message)
|
|
||||||
|
|
||||||
quoted_html = '<blockquote>{}</blockquote>' \
|
quoted_html = '<blockquote>{}</blockquote>' \
|
||||||
.format(html.escape(re_msg['text'])
|
.format(html.escape(re_msg['text'])
|
||||||
.replace('\n', '<br />'))
|
.replace('\n', '<br />'))
|
||||||
quoted_html = '<i>Reply to {} ({}):</i><br />{}<p>{}</p>' \
|
else:
|
||||||
.format(html.escape(msg_from), html.escape(str(date)),
|
quoted_msg = ''
|
||||||
|
quoted_html = ''
|
||||||
|
|
||||||
|
if reply_mx_id:
|
||||||
|
quoted_msg = 'Reply to {}:\n{}\n\n{}' \
|
||||||
|
.format(reply_mx_id.displayname, quoted_msg, message)
|
||||||
|
quoted_html = '<i><a href="https://matrix.to/#/{}/{}">Reply to {}</a>:</i><br />{}<p>{}</p>' \
|
||||||
|
.format(html.escape(room_id), html.escape(reply_mx_id.matrix_event_id), html.escape(reply_mx_id.displayname),
|
||||||
quoted_html, html_message)
|
quoted_html, html_message)
|
||||||
else:
|
else:
|
||||||
quoted_msg = 'Reply to {} ({})\n\n{}' \
|
quoted_msg = 'Reply to {}:\n{}\n\n{}' \
|
||||||
.format(msg_from, date, message)
|
.format(msg_from, quoted_msg, message)
|
||||||
quoted_html = '<i>Reply to {} ({})</i><br /><p>{}</p>' \
|
quoted_html = '<i>Reply to {}:</i><br />{}<p>{}</p>' \
|
||||||
.format(html.escape(msg_from), html.escape(str(date)),
|
.format(html.escape(msg_from),
|
||||||
html_message)
|
quoted_html, html_message)
|
||||||
|
|
||||||
|
|
||||||
j = await send_matrix_message(room_id, user_id, txn_id,
|
j = await send_matrix_message(room_id, user_id, txn_id,
|
||||||
body=quoted_msg,
|
body=quoted_msg,
|
||||||
@ -593,6 +635,19 @@ async def aiotg_message(chat, match):
|
|||||||
await asyncio.sleep(0.5)
|
await asyncio.sleep(0.5)
|
||||||
j = await send_matrix_message(room_id, user_id, txn_id + 'join',
|
j = await send_matrix_message(room_id, user_id, txn_id + 'join',
|
||||||
body=message, msgtype='m.text')
|
body=message, msgtype='m.text')
|
||||||
|
elif 'event_id' in j:
|
||||||
|
name = chat.sender['first_name']
|
||||||
|
if 'last_name' in chat.sender:
|
||||||
|
name += " " + chat.sender['last_name']
|
||||||
|
name += " (Telegram)"
|
||||||
|
message = db.Message(
|
||||||
|
chat.message['chat']['id'],
|
||||||
|
chat.message['message_id'],
|
||||||
|
room_id,
|
||||||
|
j['event_id'],
|
||||||
|
name)
|
||||||
|
db.session.add(message)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -52,6 +52,27 @@ class MatrixUser(Base):
|
|||||||
self.matrix_id = matrix_id
|
self.matrix_id = matrix_id
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
class Message(Base):
|
||||||
|
"""Describes a message in a room bridged between Telegram and Matrix"""
|
||||||
|
__tablename__ = "message"
|
||||||
|
|
||||||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
tg_group_id = sa.Column(sa.BigInteger)
|
||||||
|
tg_message_id = sa.Column(sa.BigInteger)
|
||||||
|
|
||||||
|
matrix_room_id = sa.Column(sa.String)
|
||||||
|
matrix_event_id = sa.Column(sa.String)
|
||||||
|
|
||||||
|
displayname = sa.Column(sa.String)
|
||||||
|
|
||||||
|
def __init__(self, tg_group_id, tg_message_id, matrix_room_id, matrix_event_id, displayname):
|
||||||
|
self.tg_group_id = tg_group_id
|
||||||
|
self.tg_message_id = tg_message_id
|
||||||
|
|
||||||
|
self.matrix_room_id = matrix_room_id
|
||||||
|
self.matrix_event_id = matrix_event_id
|
||||||
|
|
||||||
|
self.displayname = displayname
|
||||||
|
|
||||||
def initialize(*args, **kwargs):
|
def initialize(*args, **kwargs):
|
||||||
"""Initializes the database and creates tables if necessary."""
|
"""Initializes the database and creates tables if necessary."""
|
||||||
|
Loading…
Reference in New Issue
Block a user