...
 
Commits (2)
......@@ -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
......
......@@ -50,15 +50,18 @@ 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"
# List of users to always invite to newly created portal rooms.
invite_users: []
# Whether or not created rooms should have federation enabled.
# If false, created portal rooms will never be federated.
federate_rooms: true
......
......@@ -32,6 +32,8 @@ class Config(BaseBridgeConfig):
copy("bridge.username_template")
copy("bridge.command_prefix")
copy("bridge.invite_users")
copy("bridge.federate_rooms")
copy("bridge.initial_state")
......
......@@ -118,7 +118,7 @@ class Portal(BasePortal):
initial_state[EventType.ROOM_POWER_LEVELS].content.users[self.az.bot_mxid] = 100
self.mxid = await self.az.intent.create_room(name=puppet.displayname,
invitees=[self.main_intent.mxid,
"@tulir:pc.mau.dev"],
*config["bridge.invite_users"]],
creation_content=creation_content,
initial_state=list(initial_state.values()))
if not self.mxid:
......@@ -130,7 +130,8 @@ class Portal(BasePortal):
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:
......
......@@ -26,6 +26,11 @@ from .twilio import TwilioUserID
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 @@ class Puppet(BasePuppet):
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 @@ class Puppet(BasePuppet):
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:
......
......@@ -30,6 +30,9 @@ setuptools.setup(
"SQLAlchemy>=1.2,<2",
"alembic>=1,<2",
],
extras_require={
"phonenumbers": ["phonenumbers>=8,<9"],
},
classifiers=[
"Development Status :: 2 - Pre-Alpha",
......