diff --git a/Dockerfile b/Dockerfile index 37bf4d3..f9e32c5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,7 @@ RUN apk add --no-cache \ COPY . /opt/mautrix-twilio WORKDIR /opt/mautrix-twilio -RUN pip3 install . +RUN pip3 install .[phonenumbers] VOLUME /data diff --git a/example-config.yaml b/example-config.yaml index c15fa99..76e36dc 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -50,11 +50,11 @@ appservice: # Bridge config bridge: # Localpart template of MXIDs for remote users. - # {userid} is replaced with the phone number of the user (international format without +). + # {userid} is replaced with the phone number of the user (plain/E.164 international format). username_template: "twilio_whatsapp_{userid}" # Displayname template for remote users. - # {displayname} is replaced with the phone number of the user (international format without +). - displayname_template: "+{displayname} (WhatsApp)" + # {displayname} is replaced with the phone number of the user (human-readable international format). + displayname_template: "{displayname} (WhatsApp)" # The prefix for commands. Only required in non-management rooms. command_prefix: "!tw" diff --git a/mautrix_twilio/portal.py b/mautrix_twilio/portal.py index faffa44..370c899 100644 --- a/mautrix_twilio/portal.py +++ b/mautrix_twilio/portal.py @@ -130,7 +130,8 @@ async def _create_matrix_room(self) -> RoomID: return self.mxid async def handle_twilio_message(self, message: TwilioMessageEvent) -> None: - await self.create_matrix_room() + if not await self.create_matrix_room(): + return mxid = None if message.media: diff --git a/mautrix_twilio/puppet.py b/mautrix_twilio/puppet.py index f4ecf2f..57f90fb 100644 --- a/mautrix_twilio/puppet.py +++ b/mautrix_twilio/puppet.py @@ -26,6 +26,11 @@ if TYPE_CHECKING: from .context import Context +try: + import phonenumbers +except ImportError: + phonenumbers = None + config: Config @@ -38,6 +43,7 @@ class Puppet(BasePuppet): by_twid: Dict[TwilioUserID, 'Puppet'] = {} twid: TwilioUserID + _formatted_number: Optional[str] _db_instance: Optional[DBPuppet] @@ -46,6 +52,7 @@ def __init__(self, twid: TwilioUserID, is_registered: bool = False, super().__init__() self.twid = twid self.is_registered = is_registered + self._formatted_number = None self._db_instance = db_instance self.intent = self.az.intent.user(self.mxid) self.log = self.log.getChild(self.twid) @@ -55,13 +62,21 @@ def __init__(self, twid: TwilioUserID, is_registered: bool = False, def phone_number(self) -> int: return self.twid_template.parse(self.twid) + @property + def formatted_phone_number(self) -> str: + if not self._formatted_number: + parsed = phonenumbers.parse(f"+{self.phone_number}") + fmt = phonenumbers.PhoneNumberFormat.INTERNATIONAL + self._formatted_number = phonenumbers.format_number(parsed, fmt) + return self._formatted_number + @property def mxid(self) -> UserID: return UserID(self.mxid_template.format_full(str(self.phone_number))) @property def displayname(self) -> str: - return self.displayname_template.format_full(str(self.phone_number)) + return self.displayname_template.format_full(self.formatted_phone_number) @property def db_instance(self) -> DBPuppet: diff --git a/optional-requirements.txt b/optional-requirements.txt new file mode 100644 index 0000000..7813b15 --- /dev/null +++ b/optional-requirements.txt @@ -0,0 +1 @@ +phonenumbers diff --git a/setup.py b/setup.py index a8832f8..ebc3720 100644 --- a/setup.py +++ b/setup.py @@ -30,6 +30,9 @@ "SQLAlchemy>=1.2,<2", "alembic>=1,<2", ], + extras_require={ + "phonenumbers": ["phonenumbers>=8,<9"], + }, classifiers=[ "Development Status :: 2 - Pre-Alpha",