Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom management room messages #139

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mautrix_signal/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ def do_update(self, helper: ConfigUpdateHelper) -> None:
copy("bridge.contact_list_names")
copy("bridge.displayname_preference")

copy_dict("bridge.management_room_text")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The different messages should be copied individually because custom fields/messages aren't needed

copy("bridge.management_room_multiple_messages")

copy("bridge.autocreate_group_portal")
copy("bridge.autocreate_contact_portal")
copy("bridge.sync_with_custom_puppets")
Expand Down
24 changes: 24 additions & 0 deletions mautrix_signal/example-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,30 @@ bridge:
# The prefix for commands. Only required in non-management rooms.
command_prefix: "!signal"

# Messages to be sent to each user upon creating a management room.
# The defaults are listed below. If `plain` is not set, the text will
# not be used. If `html` is not set, `plain` will be used as HTML text.
management_room_text:
# Sent when joining a room.
welcome:
plain: "Hello, I'm a Signal bridge bot."
# html: ""
# Sent when joining a management room and the user is already logged in.
welcome_connected:
plain: "Use `help` for help"
html: "Use <code>help</code> for help"
# Sent when joining a management room and the user is not logged in.
welcome_unconnected:
plain: "Use `help` for help or `register` to log in."
html: "Use <code>help</code> for help or <code>register</code> to log in."
# Optional extra text sent when joining a management room.
# additional_help:
# plain: "This would be some additional text in case you need it."
# html: "This would be some additional <b>text</b> in case you need it."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate plaintext and HTML in the options doesn't seem particularly useful, it should just have a single string value for the markdown and render it at runtime (html = render(markdown) from mautrix.util.markdown). Alternatively it could have just the HTML field and un-render it (markdown = MatrixParser(html).text from mautrix.util.formatter)


# Send each message as a separate message (for readability in some clients)
management_room_multiple_messages: false

# Permissions for using the bridge.
# Permitted values:
# relay - Allowed to be relayed through the bridge, no access to commands.
Expand Down
72 changes: 65 additions & 7 deletions mautrix_signal/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import List, Union, TYPE_CHECKING
from typing import Dict, List, Optional, Tuple, Union, TYPE_CHECKING

from mautrix.bridge import BaseMatrixHandler
from mautrix.errors import MatrixError
from mautrix.types import (Event, ReactionEvent, MessageEvent, StateEvent, EncryptedEvent, RoomID,
EventID, UserID, ReactionEventContent, RelationType, EventType,
ReceiptEvent, TypingEvent, PresenceEvent, RedactionEvent,
Expand All @@ -30,13 +31,17 @@

class MatrixHandler(BaseMatrixHandler):
signal: 's.SignalHandler'
management_room_text: Dict[str, Dict[str, str]]
management_room_multiple_messages: bool

def __init__(self, bridge: 'SignalBridge') -> None:
prefix, suffix = bridge.config["bridge.username_template"].format(userid=":").split(":")
homeserver = bridge.config["homeserver.domain"]
self.user_id_prefix = f"@{prefix}"
self.user_id_suffix = f"{suffix}:{homeserver}"
self.signal = bridge.signal
self.management_room_text = bridge.config["bridge.management_room_text"]
self.management_room_multiple_messages = bridge.config["bridge.management_room_multiple_messages"]

super().__init__(bridge=bridge)

Expand All @@ -49,13 +54,66 @@ def filter_matrix_event(self, evt: Event) -> bool:
return (evt.sender == self.az.bot_mxid
or pu.Puppet.get_id_from_mxid(evt.sender) is not None)

def _get_welcome_message(self, statement_name: str, default_plain: str, default_html: Optional[str] = None) -> Tuple[str, str]:
plain = self.management_room_text.get(statement_name, {}).get("plain", None)
html = self.management_room_text.get(statement_name, {}).get("html", None)
return plain or default_plain, html or plain or default_html or default_plain

async def send_welcome_message(self, room_id: RoomID, inviter: 'u.User') -> None:
await super().send_welcome_message(room_id, inviter)
if not inviter.notice_room:
inviter.notice_room = room_id
await inviter.update()
await self.az.intent.send_notice(room_id, "This room has been marked as your "
"Signal bridge notice room.")
try:
is_management = len(await self.az.intent.get_room_members(room_id)) == 2
except MatrixError:
# The AS bot is not in the room.
return

welcome_messages: List[Tuple[str, str]] = []

welcome_messages.append(self._get_welcome_message(
"welcome",
"Hello, I'm a Signal bridge bot.",
))
if is_management:
if await inviter.is_logged_in():
welcome_messages.append(self._get_welcome_message(
"welcome_connected",
default_plain="Use `help` for help.",
default_html="Use <code>help</code> for help."
))
else:
welcome_messages.append(self._get_welcome_message(
"welcome_unconnected",
default_plain="Use `help` for help or `register` to log in.",
default_html="Use <code>help</code> for help or <code>register</code> to log in.",
))

additional_help_plain, additional_help_html = self._get_welcome_message(
"additional_help",
default_plain="",
)
if additional_help_plain:
welcome_messages.append((additional_help_plain, additional_help_html))

if not inviter.notice_room:
notice_plain = "This room has been marked as your Signal bridge notice room."
inviter.notice_room = room_id
await inviter.update()
welcome_messages.append((notice_plain, notice_plain))
else:
cmd_prefix = self.commands.command_prefix
plain = f"Use `{cmd_prefix} help` for help."
html = f"Use <code>{cmd_prefix} help</code> for help."
welcome_messages.append((plain, html))

if self.management_room_multiple_messages:
for plain, html in welcome_messages:
await self.az.intent.send_notice(room_id, text=plain, html=html)
else:
combined_plain = ""
combined_html = ""
for plain, html in welcome_messages:
combined_plain += plain + "\n"
combined_html += html + "<br/>"
Comment on lines +111 to +115
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"\n".join(...) would probably be nicer, I don't think it needs a trailing newline

await self.az.intent.send_notice(room_id, text=combined_plain, html=combined_html)

async def handle_leave(self, room_id: RoomID, user_id: UserID, event_id: EventID) -> None:
portal = await po.Portal.get_by_mxid(room_id)
Expand Down