From 0a22899d9f5057d2c65fdcdc3a92a5001542bd48 Mon Sep 17 00:00:00 2001 From: Sebastian Hugentobler Date: Thu, 6 Apr 2023 14:33:25 +0200 Subject: [PATCH] initial commit --- .gitignore | 3 + .woodpecker.yml | 11 + Dockerfile | 42 +++ README.md | 27 ++ rootfs/etc/confd/conf.d/config.yaml.toml | 6 + rootfs/etc/confd/templates/config.yaml.tmpl | 264 ++++++++++++++++++ .../s6-rc.d/discord-bridge/dependencies | 1 + .../etc/s6-overlay/s6-rc.d/discord-bridge/run | 3 + .../s6-overlay/s6-rc.d/discord-bridge/type | 1 + .../s6-rc.d/user/contents.d/discord-bridge | 0 10 files changed, 358 insertions(+) create mode 100755 .gitignore create mode 100644 .woodpecker.yml create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 rootfs/etc/confd/conf.d/config.yaml.toml create mode 100644 rootfs/etc/confd/templates/config.yaml.tmpl create mode 100644 rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/dependencies create mode 100644 rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/run create mode 100644 rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/type create mode 100644 rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/discord-bridge diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..af0faab --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*~ +.DS_Store +*.swp diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100644 index 0000000..763b5ae --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1,11 @@ +pipeline: + publish-docker-image: + image: plugins/kaniko + settings: + repo: docker.io/thallian/matrix-appservice-discord + tags: latest,${CI_COMMIT_SHA:0:8},${CI_COMMIT_TAG=pre} + dockerfile: Dockerfile + username: + from_secret: DOCKER_USER + password: + from_secret: DOCKER_PW diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0528411 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +FROM docker.io/golang:1.19.3-alpine3.17 as builder + +ENV VERSION=v0.2.0 + +RUN apk --no-cache add \ + git \ + gcc \ + olm-dev \ + libc-dev \ + musl-dev + +RUN ln -s /usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so + +WORKDIR /build +RUN git clone https://github.com/mautrix/discord.git +WORKDIR /build/discord +RUN git checkout $VERSION + +RUN go build -o /build/bin/mautrix-discord + +FROM docker.io/thallian/confd-env:3.17-3.1.3.0 + +RUN addgroup -g 2222 matrix-bridge +RUN adduser -h /var/lib/matrix-bridge -u 2222 -D -G matrix-bridge matrix-bridge + +COPY --from=builder /build/bin/mautrix-discord /bin/mautrix-discord + +RUN apk --no-cache add \ + ca-certificates \ + libstdc++ \ + olm + +WORKDIR /var/lib/matrix-bridge + +RUN mkdir /var/lib/matrix-bridge/data + +ADD /rootfs / + +RUN chown -R matrix-bridge:matrix-bridge /var/lib/matrix-bridge +ENV HOME /var/lib/matrix-bridge + +EXPOSE 8080 diff --git a/README.md b/README.md new file mode 100644 index 0000000..ebf5363 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +[discord bridge](https://github.com/mautrix/discord.git) +for the [matrix](http://matrix.org/) network. + +# Volumes +- `/var/lib/matrix-bridge/data` + +# Environment Variables +## SERVER_DOMAIN +Domain of the synapse server. + +## SERVER_URL +Full url to the synapse server. + +## AS_TOKEN +Appservice token (from the generated registration) + +## HS_TOKEN +Homeserver token (from the generated registration) + +## ADMIN_USER +Matrix id of the admin user. + +## DATABASE_DATASOURCE +Postgre datasource url + +# Ports +- 8080 diff --git a/rootfs/etc/confd/conf.d/config.yaml.toml b/rootfs/etc/confd/conf.d/config.yaml.toml new file mode 100644 index 0000000..214f61d --- /dev/null +++ b/rootfs/etc/confd/conf.d/config.yaml.toml @@ -0,0 +1,6 @@ +[template] +src = "config.yaml.tmpl" +dest = "/var/lib/matrix-bridge/config.yaml" +uid = 2222 +gid = 2222 +mode = "0640" diff --git a/rootfs/etc/confd/templates/config.yaml.tmpl b/rootfs/etc/confd/templates/config.yaml.tmpl new file mode 100644 index 0000000..b8f68b5 --- /dev/null +++ b/rootfs/etc/confd/templates/config.yaml.tmpl @@ -0,0 +1,264 @@ +# Homeserver details. +homeserver: + # The address that this appservice can use to connect to the homeserver. + address: "{{ getenv "SERVER_URL" }}" + # Publicly accessible base URL for media, used for avatars in relay mode. + # If not set, the connection address above will be used. + public_address: null + # The domain of the homeserver (also known as server_name, used for MXIDs, etc). + domain: "{{ getenv "SERVER_DOMAIN" }}" + + # What software is the homeserver running? + # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. + software: standard + # The URL to push real-time bridge status to. + # If set, the bridge will make POST requests to this URL whenever a user's discord connection state changes. + # The bridge will use the appservice as_token to authorize requests. + status_endpoint: null + # Endpoint for reporting per-message status. + message_send_checkpoint_endpoint: null + # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? + async_media: false + +# Application service host/registration related details. +# Changing these values requires regeneration of the registration. +appservice: + # The address that the homeserver can use to connect to this appservice. + address: http://{{getenv "HOSTNAME"}}:29334 + + # The hostname and port where this appservice should listen. + hostname: "[::]" + port: 29334 + + # Database config. + database: + # The database type. "sqlite3-fk-wal" and "postgres" are supported. + type: postgres + # The database URI. + # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. + # https://github.com/mattn/go-sqlite3#connection-string + # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable + # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql + uri: {{ getenv "DATABASE_DATASOURCE" }} + # Maximum number of connections. Mostly relevant for Postgres. + max_open_conns: 20 + max_idle_conns: 2 + # Maximum connection idle time and lifetime before they're closed. Disabled if null. + # Parsed with https://pkg.go.dev/time#ParseDuration + max_conn_idle_time: null + max_conn_lifetime: null + + # The unique ID of this appservice. + id: discord + # Appservice bot details. + bot: + # Username of the appservice bot. + username: discordbot + # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty + # to leave display name/avatar as-is. + displayname: Discord bridge bot + avatar: mxc://maunium.net/nIdEykemnwdisvHbpxflpDlC + + # Whether or not to receive ephemeral events via appservice transactions. + # Requires MSC2409 support (i.e. Synapse 1.22+). + ephemeral_events: true + + # Should incoming events be handled asynchronously? + # This may be necessary for large public instances with lots of messages going through. + # However, messages will not be guaranteed to be bridged in the same order they were sent in. + async_transactions: false + + # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. + as_token: "{{ getenv "AS_TOKEN" -}}" + hs_token: "{{ getenv "HS_TOKEN" -}}" + +# Bridge config +bridge: + # Localpart template of MXIDs for Discord users. + username_template: discord_{{"{{"}}.{{"}}"}} + # Displayname template for Discord users. This is also used as the room name in DMs if private_chat_portal_meta is enabled. + # Available variables: + # .ID - Internal user ID + # .Username - User's displayname on Discord + # .Discriminator - The 4 numbers after the name on Discord + # .Bot - Whether the user is a bot + # .System - Whether the user is an official system user + displayname_template: '{{"{{"}}.Username{{"}}"}}#{{"{{"}}.Discriminator{{"}}"}}{{"{{"}}if .Bot{{"}}"}} (bot){{"{{"end{{"}}"}}' + # Displayname template for Discord channels (bridged as rooms, or spaces when type=4). + # Available variables: + # .Name - Channel name, or user displayname (pre-formatted with displayname_template) in DMs. + # .ParentName - Parent channel name (used for categories). + # .GuildName - Guild name. + # .NSFW - Whether the channel is marked as NSFW. + # .Type - Channel type (see values at https://github.com/bwmarrin/discordgo/blob/v0.25.0/structs.go#L251-L267) + channel_name_template: '{{"{{"}}if or (eq .Type 3) (eq .Type 4){{"}}"}}{{"{{"}}.Name{{"}}"}}{{"{{"}}else{{"}}"}}#{{"{{"}}.Name{{"}}"}}{{"{{"}}end{{"}}"}}' + # Displayname template for Discord guilds (bridged as spaces). + # Available variables: + # .Name - Guild name + guild_name_template: '{{"{{"}}.Name{{"}}"}}' + # Should the bridge explicitly set the avatar and room name for DM portal rooms? + # This is implicitly enabled in encrypted rooms. + private_chat_portal_meta: false + + portal_message_buffer: 128 + + # Number of private channel portals to create on bridge startup. + # Other portals will be created when receiving messages. + startup_private_channel_create_limit: 5 + # Should the bridge send a read receipt from the bridge bot when a message has been sent to Discord? + delivery_receipts: false + # Whether the bridge should send the message status as a custom com.beeper.message_send_status event. + message_status_events: false + # Whether the bridge should send error notices via m.notice events when a message fails to bridge. + message_error_notices: true + # Should the bridge use space-restricted join rules instead of invite-only for guild rooms? + # This can avoid unnecessary invite events in guild rooms when members are synced in. + restricted_rooms: true + # Should the bridge automatically join the user to threads on Discord when the thread is opened on Matrix? + # This only works with clients that support thread read receipts (MSC3771 added in Matrix v1.4). + autojoin_thread_on_open: true + # Should inline fields in Discord embeds be bridged as HTML tables to Matrix? + # Tables aren't supported in all clients, but are the only way to emulate the Discord inline field UI. + embed_fields_as_tables: true + # Should guild channels be muted when the portal is created? This only meant for single-user instances, + # it won't mute it for all users if there are multiple Matrix users in the same Discord guild. + mute_channels_on_create: false + # Should the bridge update the m.direct account data event when double puppeting is enabled. + # Note that updating the m.direct event is not atomic (except with mautrix-asmux) + # and is therefore prone to race conditions. + sync_direct_chat_list: false + # Set this to true to tell the bridge to re-send m.bridge events to all rooms on the next run. + # This field will automatically be changed back to false after it, except if the config file is not writable. + resend_bridge_info: false + # Should incoming custom emoji reactions be bridged as mxc:// URIs? + # If set to false, custom emoji reactions will be bridged as the shortcode instead, and the image won't be available. + custom_emoji_reactions: true + # Should the bridge attempt to completely delete portal rooms when a channel is deleted on Discord? + # If true, the bridge will try to kick Matrix users from the room. Otherwise, the bridge only makes ghosts leave. + delete_portal_on_channel_delete: false + # Should the bridge delete all portal rooms when you leave a guild on Discord? + # This only applies if the guild has no other Matrix users on this bridge instance. + delete_guild_on_leave: true + # Whether or not created rooms should have federation enabled. + # If false, created portal rooms will never be federated. + federate_rooms: true + # Settings for converting animated stickers. + animated_sticker: + # Format to which animated stickers should be converted. + # disable - No conversion, send as-is (lottie JSON) + # png - converts to non-animated png (fastest) + # gif - converts to animated gif + # webm - converts to webm video, requires ffmpeg executable with vp9 codec and webm container support + # webp - converts to animated webp, requires ffmpeg executable with webp codec/container support + target: webp + # Arguments for converter. All converters take width and height. + args: + width: 320 + height: 320 + fps: 25 # only for webm, webp and gif (2, 5, 10, 20 or 25 recommended) + # Servers to always allow double puppeting from + double_puppet_server_map: + example.com: https://example.com + # Allow using double puppeting from any server with a valid client .well-known file. + double_puppet_allow_discovery: false + # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth + # + # If set, double puppeting will be enabled automatically for local users + # instead of users having to find an access token and run `login-matrix` + # manually. + login_shared_secret_map: + example.com: foobar + + # The prefix for commands. Only required in non-management rooms. + command_prefix: '!discord' + # Messages sent upon joining a management room. + # Markdown is supported. The defaults are listed below. + management_room_text: + # Sent when joining a room. + welcome: "Hello, I'm a Discord bridge bot." + # Sent when joining a management room and the user is already logged in. + welcome_connected: "Use `help` for help." + # Sent when joining a management room and the user is not logged in. + welcome_unconnected: "Use `help` for help or `login` to log in." + # Optional extra text sent when joining a management room. + additional_help: "" + + # End-to-bridge encryption support options. + # + # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. + encryption: + # Allow encryption, work in group chat rooms with e2ee enabled + allow: true + # Default to encryption, force-enable encryption in all portals the bridge creates + # This will cause the bridge bot to be in private chats for the encryption to work properly. + default: true + # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. + appservice: false + # Require encryption, drop any unencrypted messages. + require: false + # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. + # You must use a client that supports requesting keys from other users to use this feature. + allow_key_sharing: true + # What level of device verification should be required from users? + # + # Valid levels: + # unverified - Send keys to all device in the room. + # cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys. + # cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes). + # cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot. + # Note that creating user signatures from the bridge bot is not currently possible. + # verified - Require manual per-device verification + # (currently only possible by modifying the `trust` column in the `crypto_device` database table). + verification_levels: + # Minimum level for which the bridge should send keys to when bridging messages from WhatsApp to Matrix. + receive: unverified + # Minimum level that the bridge should accept for incoming Matrix messages. + send: unverified + # Minimum level that the bridge should require for accepting key requests. + share: cross-signed-tofu + # Options for Megolm room key rotation. These options allow you to + # configure the m.room.encryption event content. See: + # https://spec.matrix.org/v1.3/client-server-api/#mroomencryption for + # more information about that event. + rotation: + # Enable custom Megolm room key rotation settings. Note that these + # settings will only apply to rooms created after this option is + # set. + enable_custom: false + # The maximum number of milliseconds a session should be used + # before changing it. The Matrix spec recommends 604800000 (a week) + # as the default. + milliseconds: 604800000 + # The maximum number of messages that should be sent with a given a + # session before changing it. The Matrix spec recommends 100 as the + # default. + messages: 100 + + # Settings for provisioning API + provisioning: + # Prefix for the provisioning API paths. + prefix: /_matrix/provision + # Shared secret for authentication. If set to "generate", a random secret will be generated, + # or if set to "disable", the provisioning API will be disabled. + shared_secret: generate + + # Permissions for using the bridge. + # Permitted values: + # relay - Talk through the relaybot (if enabled), no access otherwise + # user - Access to use the bridge to chat with a Discord account. + # admin - User level and some additional administration tools + # Permitted keys: + # * - All Matrix users + # domain - All users on that homeserver + # mxid - Specific user + permissions: + "*": relay + "{{ getenv "SERVER_DOMAIN" }}": user + "{{ getenv "ADMIN_USER" }}": admin + +# Logging config. See https://github.com/tulir/zeroconfig for details. +logging: + min_level: debug + writers: + - type: stdout + format: pretty-colored diff --git a/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/dependencies b/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/dependencies new file mode 100644 index 0000000..7ba7514 --- /dev/null +++ b/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/dependencies @@ -0,0 +1 @@ +confd diff --git a/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/run b/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/run new file mode 100644 index 0000000..d4a5646 --- /dev/null +++ b/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/run @@ -0,0 +1,3 @@ +#!/bin/sh + +s6-setuidgid matrix-bridge mautrix-discord -c /var/lib/matrix-bridge/config.yaml -r /var/lib/matrix-bridge/discord-registration.yaml diff --git a/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/type b/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/rootfs/etc/s6-overlay/s6-rc.d/discord-bridge/type @@ -0,0 +1 @@ +longrun diff --git a/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/discord-bridge b/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/discord-bridge new file mode 100644 index 0000000..e69de29