From cf2920f284bdc52272febc9c8059d6993b07d97d Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Sun, 6 Sep 2020 12:05:42 +0200 Subject: [PATCH] bundles/mautrix-telegram: introduce --- bundles/mautrix-telegram/files/config.yaml | 179 ++++++++++++++++++ .../files/mautrix-telegram.service | 15 ++ bundles/mautrix-telegram/items.py | 70 +++++++ bundles/mautrix-telegram/metadata.py | 33 ++++ nodes/htz/ex42-1048908.py | 25 ++- 5 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 bundles/mautrix-telegram/files/config.yaml create mode 100644 bundles/mautrix-telegram/files/mautrix-telegram.service create mode 100644 bundles/mautrix-telegram/items.py create mode 100644 bundles/mautrix-telegram/metadata.py diff --git a/bundles/mautrix-telegram/files/config.yaml b/bundles/mautrix-telegram/files/config.yaml new file mode 100644 index 0000000..ddb6f77 --- /dev/null +++ b/bundles/mautrix-telegram/files/config.yaml @@ -0,0 +1,179 @@ +homeserver: + address: ${node.metadata['mautrix-telegram']['homeserver']['url']} + domain: ${node.metadata['mautrix-telegram']['homeserver']['domain']} + verify_ssl: true + +appservice: + address: http://${node.metadata['mautrix-telegram'].get('listen-addr', '127.0.0.1')}:${node.metadata['mautrix-telegram'].get('port', 21000)} + tls_cert: false + tls_key: false + hostname: ${node.metadata['mautrix-telegram'].get('listen-addr', '127.0.0.1')} + port: ${node.metadata['mautrix-telegram'].get('port', 21000)} + max_body_size: ${node.metadata['mautrix-telegram'].get('max-body-size', 1)} + database: postgres://${node.metadata['mautrix-telegram']['database']['user']}:${node.metadata['mautrix-telegram']['database']['password']}@${node.metadata['mautrix-telegram']['database'].get('host', 'localhost')}/${node.metadata['mautrix-telegram']['database']['database']} + public: + enabled: false + prefix: /public + external: https://example.com/public + provisioning: + enabled: ${str(node.metadata['mautrix-telegram']['provisioning']['enabled']).lower()} + prefix: /_matrix/provision/v1 + shared_secret: ${node.metadata['mautrix-telegram']['provisioning']['shared_secret']} + id: telegram + bot_username: telegrambot + bot_displayname: Telegram bridge bot + bot_avatar: mxc://maunium.net/tJCRmUyJDsgRNgqhOgoiHWbX + community_id: false + as_token: ${node.metadata['mautrix-telegram']['as_token']} + hs_token: ${node.metadata['mautrix-telegram']['hs_token']} + +metrics: + enabled: false + listen_port: 8000 + +manhole: + enabled: false + path: /var/tmp/mautrix-telegram.manhole + whitelist: + - 0 + +bridge: + username_template: telegram_{userid} + alias_template: telegram_{groupname} + displayname_template: '{displayname} (Telegram)' + displayname_preference: + - full name + - username + - phone number + displayname_max_length: 100 + allow_avatar_remove: false + max_initial_member_sync: -1 + sync_channel_members: true + skip_deleted_members: true + startup_sync: true + sync_dialog_limit: 30 + sync_direct_chats: true + max_telegram_delete: 100 + sync_matrix_state: true + allow_matrix_login: true + plaintext_highlights: false + public_portals: true + sync_with_custom_puppets: true + login_shared_secret: + telegram_link_preview: true + inline_images: false + image_as_file_size: 10 + max_document_size: 500 + parallel_file_transfer: true + federate_rooms: true + animated_sticker: + target: gif + args: + width: 256 + height: 256 + background: '020202' # only for gif + fps: 30 # only for webm + encryption: + allow: true + default: false + private_chat_portal_meta: false + delivery_receipts: true + delivery_error_reports: true + initial_power_level_overrides: + user: {} + group: {} + bot_messages_as_notices: true + bridge_notices: + default: false + exceptions: + - '@importantbot:example.com' + deduplication: + pre_db_check: false + cache_queue_length: 20 + message_formats: + m.text: '$sender_displayname: $message' + m.notice: '$sender_displayname: $message' + m.emote: '* $sender_displayname $message' + m.file: '$sender_displayname sent a file: $message' + m.image: '$sender_displayname sent an image: $message' + m.audio: '$sender_displayname sent an audio file: $message' + m.video: '$sender_displayname sent a video: $message' + m.location: '$sender_displayname sent a location: $message' + emote_format: '* $mention $formatted_body' + state_event_formats: + join: $displayname joined the room. + leave: $displayname left the room. + name_change: $prev_displayname changed their name to $displayname + filter: + mode: blacklist + list: [] + command_prefix: '!tg' + permissions: +% for user, permission in node.metadata['mautrix-telegram']['permissions'].items(): + ${user}: ${permission} +% endfor + relaybot: + private_chat: + invite: +% for user, permission in node.metadata['mautrix-telegram']['permissions'].items(): +% if permission == 'admin': + - ${user} +% endif +% endfor + state_changes: true + message: This is a Matrix bridge relaybot and does not support direct chats + group_chat_invite: [] + ignore_unbridged_group_chat: true + authless_portals: true + whitelist_group_admins: true + ignore_own_incoming_events: true + whitelist: [] + +telegram: + api_id: ${node.metadata['mautrix-telegram']['telegram']['api_id']} + api_hash: ${node.metadata['mautrix-telegram']['telegram']['api_token']} + bot_token: ${node.metadata['mautrix-telegram']['telegram']['bot_token']} + connection: + timeout: 60 + retries: 5 + retry_delay: 3 + flood_sleep_threshold: 60 + request_retries: 5 + device_info: + device_model: auto + system_version: auto + app_version: auto + lang_code: en + system_lang_code: en + server: + enabled: false + dc: 2 + ip: 149.154.167.40 + port: 80 + proxy: + type: disabled + address: 127.0.0.1 + port: 1080 + rdns: true + username: '' + password: '' + +logging: + version: 1 + formatters: + precise: + format: '[%(asctime)s] [%(levelname)s@%(name)s] %(message)s' + handlers: + console: + class: logging.StreamHandler + formatter: precise + loggers: + mau: + level: INFO + telethon: + level: INFO + aiohttp: + level: INFO + root: + level: INFO + handlers: [console] diff --git a/bundles/mautrix-telegram/files/mautrix-telegram.service b/bundles/mautrix-telegram/files/mautrix-telegram.service new file mode 100644 index 0000000..e25680f --- /dev/null +++ b/bundles/mautrix-telegram/files/mautrix-telegram.service @@ -0,0 +1,15 @@ +[Unit] +Description=Matrix Telegram Bridge +After=network.target + +[Service] +User=mautrix-telegram +Group=mautrix-telegram +Environment="VIRTUAL_ENV=/opt/mautrix-telegram/venv" +Environment="PATH=/opt/mautrix-telegram/venv/bin:/usr/local/bin:/usr/bin:/bin" +ExecStart=/opt/mautrix-telegram/venv/bin/python -m mautrix_telegram -c /opt/mautrix-telegram/config.yaml +WorkingDirectory=/opt/mautrix-telegram +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/bundles/mautrix-telegram/items.py b/bundles/mautrix-telegram/items.py new file mode 100644 index 0000000..535a24f --- /dev/null +++ b/bundles/mautrix-telegram/items.py @@ -0,0 +1,70 @@ +actions = { + 'mautrix-telegram_create_virtualenv': { + 'command': '/usr/bin/python3 -m virtualenv -p python3 /opt/mautrix-telegram/venv/', + 'unless': 'test -d /opt/mautrix-telegram/venv/', + 'needs': { + 'directory:/opt/mautrix-telegram', # provided by bundle:users + }, + }, + 'mautrix-telegram_install_bridge': { + # TODO find out how we can check if *this package* requires an update + 'command': '/opt/mautrix-telegram/venv/bin/pip install --upgrade mautrix-telegram[all]', + 'needs': { + 'action:mautrix-telegram_create_virtualenv', + }, + 'triggers': { + 'action:mautrix-telegram_generate_registration', + 'action:mautrix-telegram_upgrade_database', + }, + }, + 'mautrix-telegram_generate_registration': { + 'command': '/opt/mautrix-telegram/venv/bin/python3 -m mautrix_telegram -c /opt/mautrix-telegram/config.yaml -r /opt/mautrix-telegram/registration.yaml -g', + 'needs': { + 'file:/opt/mautrix-telegram/config.yaml', + }, + 'triggers': { + 'svc_systemd:mautrix-telegram:restart', + }, + 'triggered': True, + }, + 'mautrix-telegram_upgrade_database': { + 'command': '/opt/mautrix-telegram/venv/bin/alembic -x /opt/mautrix-telegram/config.yaml upgrade head', + 'needs': { + # Actually, the dependency is 'mautrix-telegram has run + # atleast once, but we can't check that. + 'action:mautrix-telegram_generate_registration', + 'postgres_db:mautrix-telegram', + 'postgres_role:mautrix-telegram', + }, + 'triggered': True, + }, +} + +svc_systemd = { + 'mautrix-telegram': { + 'needs': { + 'action:mautrix-telegram_generate_registration', + 'action:mautrix-telegram_upgrade_database', + 'file:/etc/systemd/system/mautrix-telegram.service', + 'postgres_db:mautrix-telegram', + 'postgres_role:mautrix-telegram', + }, + }, +} + +files = { + '/opt/mautrix-telegram/config.yaml': { + 'content_type': 'mako', + 'triggers': { + 'svc_systemd:mautrix-telegram:restart', + }, + }, + '/etc/systemd/system/mautrix-telegram.service': { + 'triggers': { + 'svc_systemd:mautrix-telegram:restart', + }, + } +} + +if node.has_bundle('matrix-synapse'): + actions['mautrix-telegram_generate_registration']['triggers'].add('svc_systemd:matrix-synapse:restart') diff --git a/bundles/mautrix-telegram/metadata.py b/bundles/mautrix-telegram/metadata.py new file mode 100644 index 0000000..5f8e423 --- /dev/null +++ b/bundles/mautrix-telegram/metadata.py @@ -0,0 +1,33 @@ +defaults = { + 'users': { + 'mautrix-telegram': { + 'home': '/opt/mautrix-telegram', + 'home-mode': '0755', + }, + }, + 'matrix-synapse': { + 'appservice_configs': { + '/opt/mautrix-telegram/registration.yaml', + }, + }, + 'mautrix-telegram': { + 'database': { + 'user': 'mautrix-telegram', + 'password': repo.vault.password_for('{} postgresql mautrix-telegram'.format(node.name)), + 'database': 'mautrix-telegram', + }, + }, + 'postgresql': { + 'users': { + 'mautrix-telegram': { + 'password': repo.vault.password_for('{} postgresql mautrix-telegram'.format(node.name)), + }, + }, + 'databases': { + 'mautrix-telegram': { + 'owner': 'mautrix-telegram', + }, + }, + }, +} + diff --git a/nodes/htz/ex42-1048908.py b/nodes/htz/ex42-1048908.py index 8cf1e6d..08a431f 100644 --- a/nodes/htz/ex42-1048908.py +++ b/nodes/htz/ex42-1048908.py @@ -3,6 +3,7 @@ nodes['htz.ex42-1048908'] = { 'gitea', 'jenkins-ci', 'matrix-synapse', + 'mautrix-telegram', 'mx-puppet-discord', 'nodejs', 'riot-web', @@ -110,7 +111,6 @@ nodes['htz.ex42-1048908'] = { 'appservice_configs': { # TODO move to bundles '/opt/matrix-bridges/mautrix-whatsapp/registration.yaml', - '/opt/matrix-bridges/mautrix-telegram/registration.yaml', }, 'trusted_key_servers': { 'matrix.org', @@ -118,6 +118,29 @@ nodes['htz.ex42-1048908'] = { 'nyantec.com', }, }, + 'mautrix-telegram': { + 'homeserver': { + 'domain': 'franzi.business', + 'url': 'https://matrix.franzi.business', + }, + 'provisioning': { + 'enabled': True, + 'shared_secret': vault.decrypt('encrypt$gAAAAABfVKflEMAi07C_QGP8cy97hF-4gGPym0oF6p4WSMdAveTpx-hFsZd2s7v9ubw99yIsyKx0dHOJI0UND7hV1rKZdvjy4Qa642abZ2wwW7SWTqvuP_qVtrf6-klc2QKTzeD9c_LVsyZ2dqz_JxRPq3MRXgkubZuWOZ6FmFlAlteTffoGfWE='), + }, + 'as_token': vault.decrypt('encrypt$gAAAAABfVK4eOskBMde8BgmLmMpgr5O1562Ln3qLwCGrW85j57aVkm33-ySWv12ByUoS4U6zU_aTstX1aiRaNgPa76FewNv-Yq9WxNsyxjbpeMdfhX2O9Q5T5RFL4Uple4kJCbOvqDn92U1gAKv2K-RioEGb41iv3Z7usXeyfkny5wa-s8gjICg='), + 'hs_token': vault.decrypt('encrypt$gAAAAABfVK461ryXf-ka8P7x0GQ64O5bBG5-U2mvCzrlS02VGDsLPgNY-_QKd2-GhBtMaYb-OG1KZO_CtCHs54KWQsSDfxJbId4GVpncNDCoDQRnpIvXb0ebdj10-dC3zcANMb9Q2un1psnmgFYawSl4YJLf0_pkQaT13Y1OwWTmHdILUKyAzQU='), + 'permissions': { + "'*'": 'relaybot', + 'nyantec.com': 'full', + 'franzi.business': 'full', + "'@kunsi:franzi.business'": 'admin', + }, + 'telegram': { + 'api_id': vault.decrypt('encrypt$gAAAAABfVK5SmDDru-UQxitkE5VhPArnUBhaRbAqQPvAW2Fh3fd1XDrWxa3Qn4BSnJAPNWglH5wil_SXUMcIm95FMhPe8dVeMQ=='), + 'api_token': vault.decrypt('encrypt$gAAAAABfVK5jHuUly1xr9Iku362k7oF4ZYRhLGzNJh3aJpiNrLfAy_DJpTwucx4FV_g45dyQF5boqG2rgdDfwsJN_Ab95es6T4SPGiXIxJOBlvIln1Torwh16pXKchhUTn_PQ077Ll1W'), + 'bot_token': vault.decrypt('encrypt$gAAAAABfVK51ErJ6gfsOOkbRxSHDnVYmf7EihAQf7Uwj9og3TlAw64WRsA6ZVEgTSvOdLB3SMKZ-cTEhwkCOpbymq-_WLhes-hZALhN-H_oXHaxTQErJ0lARynKmjM-4ZhoGlUWlfh4Q'), + }, + }, 'mx-puppet-discord': { 'homeserver': { 'domain': 'franzi.business',