Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a4ff6e81c8 | ||
|
cd1d66ffee | ||
|
2b186ad31c | ||
|
9e003f8ff9 | ||
|
e98b7312f6 | ||
|
3a21a819b9 | ||
|
828f92e37b | ||
|
2ee824f4ca | ||
|
8e422d683b | ||
|
d537cfb1b3 | ||
|
09945d75cc | ||
|
b0aeb11e8a | ||
|
fea8d89493 | ||
|
15e84f6861 | ||
|
fc65d5f0f5 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -152,5 +152,4 @@ Temporary Items
|
|||||||
|
|
||||||
# Config
|
# Config
|
||||||
config.json
|
config.json
|
||||||
asconfig.yaml
|
|
||||||
database.db
|
database.db
|
||||||
|
@ -42,8 +42,6 @@ First, copy config.json.example to config.json. Then fill in the fields:
|
|||||||
* `hosts.bare`: Just the (sub)domain of the server.
|
* `hosts.bare`: Just the (sub)domain of the server.
|
||||||
* `user_id_format`: A Python `str.format`-style string to format user IDs as
|
* `user_id_format`: A Python `str.format`-style string to format user IDs as
|
||||||
* `db_url`: A SQLAlchemy URL for the database. See the [SQLAlchemy docs](http://docs.sqlalchemy.org/en/latest/core/engines.html).
|
* `db_url`: A SQLAlchemy URL for the database. See the [SQLAlchemy docs](http://docs.sqlalchemy.org/en/latest/core/engines.html).
|
||||||
* `bot_owners`: A list of matrix users the bot won't use a `<username>` prefix for. Can be left blank to print a prefix for all matrix users. Useful if you would like the bridge to replace Telegram for yourself, but also want to allow others to use the Matrix room.
|
|
||||||
* `print_url_with_image`: Set to `false` to disable sending the Matrix url of an image to Telegram.
|
|
||||||
|
|
||||||
**Synapse configuration**
|
**Synapse configuration**
|
||||||
|
|
||||||
|
@ -12,16 +12,8 @@
|
|||||||
"bare": "DOMAIN.TLD"
|
"bare": "DOMAIN.TLD"
|
||||||
},
|
},
|
||||||
|
|
||||||
"bot_owners": [
|
|
||||||
"@youruser:DOMAIN.TLD",
|
|
||||||
"@youruser:matrix.org",
|
|
||||||
"@youruser:example.com"
|
|
||||||
],
|
|
||||||
|
|
||||||
"user_id_format": "@telegram_{}:DOMAIN.TLD",
|
"user_id_format": "@telegram_{}:DOMAIN.TLD",
|
||||||
"db_url": "sqlite:///database.db",
|
"db_url": "sqlite:///database.db",
|
||||||
|
|
||||||
"print_url_with_image": true,
|
|
||||||
|
|
||||||
"as_port": 5000
|
"as_port": 5000
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ from datetime import datetime
|
|||||||
from time import time
|
from time import time
|
||||||
from urllib.parse import unquote, quote, urlparse, parse_qs
|
from urllib.parse import unquote, quote, urlparse, parse_qs
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
import re
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from aiohttp import web, ClientSession
|
from aiohttp import web, ClientSession
|
||||||
@ -38,11 +39,6 @@ try:
|
|||||||
MATRIX_HOST_EXT = CONFIG['hosts']['external']
|
MATRIX_HOST_EXT = CONFIG['hosts']['external']
|
||||||
MATRIX_HOST_BARE = CONFIG['hosts']['bare']
|
MATRIX_HOST_BARE = CONFIG['hosts']['bare']
|
||||||
|
|
||||||
try:
|
|
||||||
MATRIX_BOT_OWNERS = CONFIG['bot_owners']
|
|
||||||
except KeyError:
|
|
||||||
MATRIX_BOT_OWNERS = {}
|
|
||||||
|
|
||||||
MATRIX_PREFIX = MATRIX_HOST + '_matrix/client/r0/'
|
MATRIX_PREFIX = MATRIX_HOST + '_matrix/client/r0/'
|
||||||
MATRIX_MEDIA_PREFIX = MATRIX_HOST + '_matrix/media/r0/'
|
MATRIX_MEDIA_PREFIX = MATRIX_HOST + '_matrix/media/r0/'
|
||||||
|
|
||||||
@ -50,8 +46,6 @@ try:
|
|||||||
DATABASE_URL = CONFIG['db_url']
|
DATABASE_URL = CONFIG['db_url']
|
||||||
|
|
||||||
AS_PORT = CONFIG['as_port'] if 'as_port' in CONFIG else 5000
|
AS_PORT = CONFIG['as_port'] if 'as_port' in CONFIG else 5000
|
||||||
|
|
||||||
PRINT_URL_WITH_IMAGE = CONFIG['print_url_with_image'] if 'print_url_with_image' in CONFIG else True
|
|
||||||
except (OSError, IOError) as exception:
|
except (OSError, IOError) as exception:
|
||||||
print('Error opening config file:')
|
print('Error opening config file:')
|
||||||
print(exception)
|
print(exception)
|
||||||
@ -89,26 +83,26 @@ def sanitize_html(string):
|
|||||||
soup = BeautifulSoup(string, 'html.parser')
|
soup = BeautifulSoup(string, 'html.parser')
|
||||||
for tag in soup.find_all(True):
|
for tag in soup.find_all(True):
|
||||||
if tag.name == 'blockquote':
|
if tag.name == 'blockquote':
|
||||||
tag.string = ('\n' + tag.text).replace('\n', '\n> ').rstrip('\n>')
|
tag.string = ('\n' + tag.text).replace('\n', '\n> ')[3:-3]
|
||||||
if tag.name not in VALID_TAGS:
|
if tag.name not in VALID_TAGS:
|
||||||
tag.hidden = True
|
tag.hidden = True
|
||||||
return soup.renderContents().decode('utf-8')
|
return soup.renderContents().decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
def format_matrix_msg(form, username, content):
|
def format_matrix_msg(form, content):
|
||||||
"""
|
"""
|
||||||
Formats a matrix message for sending to Telegram
|
Formats a matrix message for sending to Telegram
|
||||||
:param form: The format string of the message, where the first parameter
|
:param form: The format string of the message, where the first parameter
|
||||||
is the username and the second one the message.
|
is the username and the second one the message.
|
||||||
:param username: The username of the user.
|
|
||||||
:param content: The content to be sent.
|
:param content: The content to be sent.
|
||||||
:return: The formatted string.
|
:return: The formatted string.
|
||||||
"""
|
"""
|
||||||
if 'format' in content and content['format'] == 'org.matrix.custom.html':
|
if 'format' in content and content['format'] == 'org.matrix.custom.html':
|
||||||
sanitized = sanitize_html(content['formatted_body'])
|
sanitized = re.sub("<a href=\\\"https://matrix.to/#/@telegram_([0-9]+):{}\\\">(.+?) \(Telegram\)</a>".format(MATRIX_HOST_BARE), "<a href=\"tg://user?id=\\1\">\\2</a>", content['formatted_body'])
|
||||||
return html.escape(form).format(username, sanitized), 'HTML'
|
sanitized = sanitize_html(sanitized)
|
||||||
|
return html.escape(form).format(sanitized), 'HTML'
|
||||||
else:
|
else:
|
||||||
return form.format(username, content['body']), None
|
return form.format(html.escape(content['body'])), None
|
||||||
|
|
||||||
|
|
||||||
async def download_matrix_file(url, filename):
|
async def download_matrix_file(url, filename):
|
||||||
@ -190,7 +184,7 @@ async def matrix_transaction(request):
|
|||||||
for alias in aliases:
|
for alias in aliases:
|
||||||
print(alias)
|
print(alias)
|
||||||
if alias.split('_')[0] != '#telegram' \
|
if alias.split('_')[0] != '#telegram' \
|
||||||
or not alias.endswith(MATRIX_HOST_BARE):
|
or alias.split(':')[-1] != MATRIX_HOST_BARE:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
tg_id = alias.split('_')[1].split(':')[0]
|
tg_id = alias.split('_')[1].split(':')[0]
|
||||||
@ -212,9 +206,6 @@ async def matrix_transaction(request):
|
|||||||
|
|
||||||
if event['type'] == 'm.room.message':
|
if event['type'] == 'm.room.message':
|
||||||
user_id = event['user_id']
|
user_id = event['user_id']
|
||||||
if user_id in MATRIX_BOT_OWNERS:
|
|
||||||
displayname = ''
|
|
||||||
else:
|
|
||||||
if matrix_is_telegram(user_id):
|
if matrix_is_telegram(user_id):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -239,17 +230,14 @@ async def matrix_transaction(request):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if content['msgtype'] == 'm.text':
|
if content['msgtype'] == 'm.text':
|
||||||
prefix = '' if displayname == '' else '<' + displayname + '> '
|
msg, mode = format_matrix_msg('{}', content)
|
||||||
msg, mode = format_matrix_msg('{}{}', prefix, content)
|
response = await group.send_text("<b>{}:</b> {}".format(displayname, msg), parse_mode='HTML')
|
||||||
response = await group.send_text(msg, parse_mode=mode)
|
|
||||||
elif content['msgtype'] == 'm.notice':
|
elif content['msgtype'] == 'm.notice':
|
||||||
prefix = '' if displayname == '' else '[' + displayname + '] '
|
msg, mode = format_matrix_msg('{}', content)
|
||||||
msg, mode = format_matrix_msg('{}{}', prefix, content)
|
response = await group.send_text("[{}] {}".format(displayname, msg), parse_mode=mode)
|
||||||
response = await group.send_text(msg, parse_mode=mode)
|
|
||||||
elif content['msgtype'] == 'm.emote':
|
elif content['msgtype'] == 'm.emote':
|
||||||
prefix = '' if displayname == '' else '* ' + displayname + ' '
|
msg, mode = format_matrix_msg('{}', content)
|
||||||
msg, mode = format_matrix_msg('{}{}', prefix, content)
|
response = await group.send_text("* {} {}".format(displayname, 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'])
|
||||||
@ -262,18 +250,13 @@ async def matrix_transaction(request):
|
|||||||
# Download the file
|
# Download the file
|
||||||
await download_matrix_file(url, content['body'])
|
await download_matrix_file(url, content['body'])
|
||||||
with open('/tmp/{}'.format(content['body']), 'rb') as img_file:
|
with open('/tmp/{}'.format(content['body']), 'rb') as img_file:
|
||||||
url_str = ''
|
|
||||||
if PRINT_URL_WITH_IMAGE:
|
|
||||||
# Create the URL and shorten it
|
# Create the URL and shorten it
|
||||||
url_str = MATRIX_HOST_EXT + \
|
url_str = MATRIX_HOST_EXT + \
|
||||||
'_matrix/media/r0/download/{}{}' \
|
'_matrix/media/r0/download/{}{}' \
|
||||||
.format(url.netloc, quote(url.path))
|
.format(url.netloc, quote(url.path))
|
||||||
url_str = await shorten_url(url_str)
|
url_str = await shorten_url(url_str)
|
||||||
url_str = ' (' + url_str + ')'
|
|
||||||
|
|
||||||
prefix = '' if displayname == '' else '<' + displayname + '> '
|
caption = '{} sent an image'.format(displayname)
|
||||||
caption = '{}{}{}'.format(prefix,
|
|
||||||
content['body'], url_str)
|
|
||||||
response = await group.send_photo(img_file, caption=caption)
|
response = await group.send_photo(img_file, caption=caption)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@ -466,10 +449,7 @@ async def register_join_matrix(chat, room_id, user_id):
|
|||||||
|
|
||||||
await matrix_put('client', 'profile/{}/displayname'.format(user_id),
|
await matrix_put('client', 'profile/{}/displayname'.format(user_id),
|
||||||
user_id, {'displayname': name})
|
user_id, {'displayname': name})
|
||||||
j = await matrix_post('client', 'join/{}'.format(room_id), user_id, {})
|
await matrix_post('client', 'join/{}'.format(room_id), user_id, {})
|
||||||
if 'errcode' in j and j['errcode'] == 'M_FORBIDDEN':
|
|
||||||
print("Error with <{}> joining room <{}>. This is likely because guests are not allowed to join the room."
|
|
||||||
.format(user_id, room_id))
|
|
||||||
|
|
||||||
async def update_matrix_displayname_avatar(tg_user):
|
async def update_matrix_displayname_avatar(tg_user):
|
||||||
name = tg_user['first_name']
|
name = tg_user['first_name']
|
||||||
|
Loading…
x
Reference in New Issue
Block a user