33
33
UpdateNewMessage , InputMediaUploadedDocument ,
34
34
InputMediaUploadedPhoto )
35
35
36
- from mautrix .types import (EventID , RoomID , UserID , ContentURI , MessageType , MessageEventContent ,
37
- TextMessageEventContent , MediaMessageEventContent , Format ,
38
- LocationMessageEventContent , ImageInfo , VideoInfo )
36
+ from mautrix .types import (EventID , EventType , RoomID , UserID , ContentURI , MessageType ,
37
+ MessageEventContent , TextMessageEventContent , MediaMessageEventContent ,
38
+ Format , LocationMessageEventContent , ImageInfo , VideoInfo )
39
+ from mautrix .util .message_send_checkpoint import MessageSendCheckpointStatus
39
40
40
41
from ..types import TelegramID
41
42
from ..db import Message as DBMessage
@@ -225,11 +226,13 @@ async def _pre_process_matrix_message(self, sender: 'u.User', use_relaybot: bool
225
226
elif content .msgtype == MessageType .EMOTE :
226
227
await self ._apply_emote_format (sender , content )
227
228
228
- async def _handle_matrix_text (self , sender_id : TelegramID , event_id : EventID ,
229
+ async def _handle_matrix_text (self , sender : 'u.User' , logged_in : bool , event_id : EventID ,
229
230
space : TelegramID , client : 'MautrixTelegramClient' ,
230
- content : TextMessageEventContent , reply_to : TelegramID ) -> None :
231
+ content : TextMessageEventContent , reply_to : Optional [TelegramID ]
232
+ ) -> None :
231
233
message , entities = await formatter .matrix_to_telegram (client , text = content .body ,
232
234
html = content .formatted (Format .HTML ))
235
+ sender_id = sender .tgid if logged_in else self .bot .tgid
233
236
async with self .send_lock (sender_id ):
234
237
lp = self .get_config ("telegram_link_preview" )
235
238
if content .get_edit ():
@@ -240,16 +243,28 @@ async def _handle_matrix_text(self, sender_id: TelegramID, event_id: EventID,
240
243
link_preview = lp )
241
244
self ._add_telegram_message_to_db (event_id , space , - 1 , response )
242
245
return
243
- response = await client .send_message (self .peer , message , reply_to = reply_to ,
244
- formatting_entities = entities ,
245
- link_preview = lp )
246
- self ._add_telegram_message_to_db (event_id , space , 0 , response )
247
- await self ._send_delivery_receipt (event_id )
246
+ try :
247
+ response = await client .send_message (self .peer , message , reply_to = reply_to ,
248
+ formatting_entities = entities ,
249
+ link_preview = lp )
250
+ except Exception :
251
+ raise
252
+ else :
253
+ sender .send_remote_checkpoint (
254
+ MessageSendCheckpointStatus .SUCCESS ,
255
+ event_id ,
256
+ self .mxid ,
257
+ EventType .ROOM_MESSAGE ,
258
+ message_type = content .msgtype ,
259
+ )
260
+ self ._add_telegram_message_to_db (event_id , space , 0 , response )
261
+ await self ._send_delivery_receipt (event_id )
248
262
249
- async def _handle_matrix_file (self , sender_id : TelegramID , event_id : EventID ,
263
+ async def _handle_matrix_file (self , sender : 'u.User' , logged_in : bool , event_id : EventID ,
250
264
space : TelegramID , client : 'MautrixTelegramClient' ,
251
265
content : MediaMessageEventContent , reply_to : TelegramID ,
252
266
caption : TextMessageEventContent = None ) -> None :
267
+ sender_id = sender .tgid if logged_in else self .bot .tgid
253
268
mime = content .info .mimetype
254
269
if isinstance (content .info , (ImageInfo , VideoInfo )):
255
270
w , h = content .info .width , content .info .height
@@ -264,9 +279,8 @@ async def _handle_matrix_file(self, sender_id: TelegramID, event_id: EventID,
264
279
else :
265
280
if content .file :
266
281
if not decrypt_attachment :
267
- self .log .warning (f"Can't bridge encrypted media event { event_id } :"
268
- " matrix-nio not installed" )
269
- return
282
+ raise Exception (f"Can't bridge encrypted media event { event_id } : matrix-nio "
283
+ "is not installed" )
270
284
file = await self .main_intent .download_media (content .file .url )
271
285
file = decrypt_attachment (file , content .file .key .key ,
272
286
content .file .hashes .get ("sha256" ), content .file .iv )
@@ -304,15 +318,26 @@ async def _handle_matrix_file(self, sender_id: TelegramID, event_id: EventID,
304
318
if await self ._matrix_document_edit (client , content , space , capt , media , event_id ):
305
319
return
306
320
try :
307
- response = await client .send_media (self .peer , media , reply_to = reply_to ,
308
- caption = capt , entities = entities )
309
- except (PhotoInvalidDimensionsError , PhotoSaveFileInvalidError , PhotoExtInvalidError ):
310
- media = InputMediaUploadedDocument (file = media .file , mime_type = mime ,
311
- attributes = attributes )
312
- response = await client .send_media (self .peer , media , reply_to = reply_to ,
313
- caption = capt , entities = entities )
314
- self ._add_telegram_message_to_db (event_id , space , 0 , response )
315
- await self ._send_delivery_receipt (event_id )
321
+ try :
322
+ response = await client .send_media (self .peer , media , reply_to = reply_to ,
323
+ caption = capt , entities = entities )
324
+ except (PhotoInvalidDimensionsError , PhotoSaveFileInvalidError , PhotoExtInvalidError ):
325
+ media = InputMediaUploadedDocument (file = media .file , mime_type = mime ,
326
+ attributes = attributes )
327
+ response = await client .send_media (self .peer , media , reply_to = reply_to ,
328
+ caption = capt , entities = entities )
329
+ except Exception :
330
+ raise
331
+ else :
332
+ sender .send_remote_checkpoint (
333
+ MessageSendCheckpointStatus .SUCCESS ,
334
+ event_id ,
335
+ self .mxid ,
336
+ EventType .ROOM_MESSAGE ,
337
+ message_type = content .msgtype ,
338
+ )
339
+ self ._add_telegram_message_to_db (event_id , space , 0 , response )
340
+ await self ._send_delivery_receipt (event_id )
316
341
317
342
async def _matrix_document_edit (self , client : 'MautrixTelegramClient' ,
318
343
content : MessageEventContent , space : TelegramID ,
@@ -327,10 +352,11 @@ async def _matrix_document_edit(self, client: 'MautrixTelegramClient',
327
352
return True
328
353
return False
329
354
330
- async def _handle_matrix_location (self , sender_id : TelegramID , event_id : EventID ,
355
+ async def _handle_matrix_location (self , sender : 'u.User' , logged_in : bool , event_id : EventID ,
331
356
space : TelegramID , client : 'MautrixTelegramClient' ,
332
357
content : LocationMessageEventContent , reply_to : TelegramID
333
358
) -> None :
359
+ sender_id = sender .tgid if logged_in else self .bot .tgid
334
360
try :
335
361
lat , long = content .geo_uri [len ("geo:" ):].split (";" )[0 ].split ("," )
336
362
lat , long = float (lat ), float (long )
@@ -343,10 +369,21 @@ async def _handle_matrix_location(self, sender_id: TelegramID, event_id: EventID
343
369
async with self .send_lock (sender_id ):
344
370
if await self ._matrix_document_edit (client , content , space , caption , media , event_id ):
345
371
return
346
- response = await client .send_media (self .peer , media , reply_to = reply_to ,
347
- caption = caption , entities = entities )
348
- self ._add_telegram_message_to_db (event_id , space , 0 , response )
349
- await self ._send_delivery_receipt (event_id )
372
+ try :
373
+ response = await client .send_media (self .peer , media , reply_to = reply_to ,
374
+ caption = caption , entities = entities )
375
+ except Exception :
376
+ raise
377
+ else :
378
+ self ._add_telegram_message_to_db (event_id , space , 0 , response )
379
+ sender .send_remote_checkpoint (
380
+ MessageSendCheckpointStatus .SUCCESS ,
381
+ event_id ,
382
+ self .mxid ,
383
+ EventType .ROOM_MESSAGE ,
384
+ message_type = content .msgtype ,
385
+ )
386
+ await self ._send_delivery_receipt (event_id )
350
387
351
388
def _add_telegram_message_to_db (self , event_id : EventID , space : TelegramID ,
352
389
edit_index : int , response : TypeMessage ) -> None :
@@ -362,7 +399,19 @@ def _add_telegram_message_to_db(self, event_id: EventID, space: TelegramID,
362
399
mxid = event_id ,
363
400
edit_index = edit_index ).insert ()
364
401
365
- async def _send_bridge_error (self , msg : str ) -> None :
402
+ async def _send_bridge_error (self , sender : 'u.User' , err : Exception , event_id : EventID ,
403
+ event_type : EventType ,
404
+ message_type : Optional [MessageType ] = None ,
405
+ msg : Optional [str ] = None , confirmed : bool = False ) -> None :
406
+ sender .send_remote_checkpoint (
407
+ MessageSendCheckpointStatus .PERM_FAILURE ,
408
+ event_id ,
409
+ self .mxid ,
410
+ event_type ,
411
+ message_type = message_type ,
412
+ error = err ,
413
+ )
414
+
366
415
if config ["bridge.delivery_error_reports" ]:
367
416
await self ._send_message (self .main_intent ,
368
417
TextMessageEventContent (msgtype = MessageType .NOTICE , body = msg ))
@@ -372,10 +421,25 @@ async def handle_matrix_message(self, sender: 'u.User', content: MessageEventCon
372
421
try :
373
422
await self ._handle_matrix_message (sender , content , event_id )
374
423
except RPCError as e :
375
- if config ["bridge.delivery_error_reports" ]:
376
- await self ._send_bridge_error (
377
- f"\u26a0 Your message may not have been bridged: { e } " )
424
+ self .log .exception (f"RPCError while bridging { event_id } : { e } " )
425
+ await self ._send_bridge_error (
426
+ sender ,
427
+ e ,
428
+ event_id ,
429
+ EventType .ROOM_MESSAGE ,
430
+ message_type = content .msgtype ,
431
+ msg = f"\u26a0 Your message may not have been bridged: { e } " ,
432
+ )
378
433
raise
434
+ except Exception as e :
435
+ self .log .exception (f"Failed to bridge { event_id } : { e } " )
436
+ await self ._send_bridge_error (
437
+ sender ,
438
+ e ,
439
+ event_id ,
440
+ EventType .ROOM_MESSAGE ,
441
+ message_type = content .msgtype ,
442
+ )
379
443
380
444
async def _handle_matrix_message (self , sender : 'u.User' , content : MessageEventContent ,
381
445
event_id : EventID ) -> None :
@@ -385,7 +449,6 @@ async def _handle_matrix_message(self, sender: 'u.User', content: MessageEventCo
385
449
386
450
logged_in = not await sender .needs_relaybot (self )
387
451
client = sender .client if logged_in else self .bot .client
388
- sender_id = sender .tgid if logged_in else self .bot .tgid
389
452
space = (self .tgid if self .peer_type == "channel" # Channels have their own ID space
390
453
else (sender .tgid if logged_in else self .bot .tgid ))
391
454
reply_to = formatter .matrix_reply_to_telegram (content , space , room_id = self .mxid )
@@ -397,14 +460,15 @@ async def _handle_matrix_message(self, sender: 'u.User', content: MessageEventCo
397
460
bridge_notices = self .get_config ("bridge_notices.default" )
398
461
excepted = sender .mxid in self .get_config ("bridge_notices.exceptions" )
399
462
if not bridge_notices and not excepted :
400
- return
463
+ raise Exception ( "Notices are not configured to be bridged." )
401
464
402
465
if content .msgtype in (MessageType .TEXT , MessageType .EMOTE , MessageType .NOTICE ):
403
466
await self ._pre_process_matrix_message (sender , not logged_in , content )
404
- await self ._handle_matrix_text (sender_id , event_id , space , client , content , reply_to )
467
+ await self ._handle_matrix_text (sender , logged_in , event_id , space , client , content ,
468
+ reply_to )
405
469
elif content .msgtype == MessageType .LOCATION :
406
470
await self ._pre_process_matrix_message (sender , not logged_in , content )
407
- await self ._handle_matrix_location (sender_id , event_id , space , client , content ,
471
+ await self ._handle_matrix_location (sender , logged_in , event_id , space , client , content ,
408
472
reply_to )
409
473
elif content .msgtype in media :
410
474
content ["net.maunium.telegram.internal.filename" ] = content .body
@@ -418,11 +482,12 @@ async def _handle_matrix_message(self, sender: 'u.User', content: MessageEventCo
418
482
if caption_content :
419
483
caption_content .msgtype = content .msgtype
420
484
await self ._pre_process_matrix_message (sender , not logged_in , caption_content )
421
- await self ._handle_matrix_file (sender_id , event_id , space , client , content , reply_to ,
422
- caption_content )
485
+ await self ._handle_matrix_file (sender , logged_in , event_id , space , client , content ,
486
+ reply_to , caption_content )
423
487
else :
424
- self .log .debug ("Didn't handle Matrix event {event_id} due to unknown msgtype {content.msgtype}" )
488
+ self .log .debug (f "Didn't handle Matrix event { event_id } due to unknown msgtype { content .msgtype } " )
425
489
self .log .trace ("Unhandled Matrix event content: %s" , content )
490
+ raise Exception (f"Unhandled msgtype { content .msgtype } " )
426
491
427
492
async def handle_matrix_unpin_all (self , sender : 'u.User' , pin_event_id : EventID ) -> None :
428
493
await sender .client (UnpinAllMessagesRequest (peer = self .peer ))
@@ -444,22 +509,36 @@ async def handle_matrix_pin(self, sender: 'u.User', changes: Dict[EventID, bool]
444
509
445
510
async def handle_matrix_deletion (self , deleter : 'u.User' , event_id : EventID ,
446
511
redaction_event_id : EventID ) -> None :
512
+ try :
513
+ await self ._handle_matrix_deletion (deleter , event_id , redaction_event_id )
514
+ except Exception as e :
515
+ await self ._send_bridge_error (deleter , e , event_id , EventType .ROOM_REDACTION )
516
+ else :
517
+ deleter .send_remote_checkpoint (
518
+ MessageSendCheckpointStatus .SUCCESS ,
519
+ event_id ,
520
+ self .mxid ,
521
+ EventType .ROOM_REDACTION ,
522
+ )
523
+ await self ._send_delivery_receipt (redaction_event_id )
524
+
525
+ async def _handle_matrix_deletion (self , deleter : 'u.User' , event_id : EventID ,
526
+ redaction_event_id : EventID ) -> None :
447
527
real_deleter = deleter if not await deleter .needs_relaybot (self ) else self .bot
448
528
space = self .tgid if self .peer_type == "channel" else real_deleter .tgid
449
529
message = DBMessage .get_by_mxid (event_id , self .mxid , space )
450
530
if not message :
451
- self . log . trace (f"Ignoring Matrix redaction of unknown event { event_id } " )
531
+ raise Exception (f"Ignoring Matrix redaction of unknown event { event_id } " )
452
532
elif message .redacted :
453
- self . log . debug ("Ignoring Matrix redaction of already redacted event "
454
- f"{ message .mxid } in { message .mx_room } " )
533
+ raise Exception ("Ignoring Matrix redaction of already redacted event "
534
+ f"{ message .mxid } in { message .mx_room } " )
455
535
elif message .edit_index != 0 :
456
536
message .edit (redacted = True )
457
- self . log . debug ("Ignoring Matrix redaction of edit event "
458
- f"{ message .mxid } in { message .mx_room } " )
537
+ raise Exception ("Ignoring Matrix redaction of edit event "
538
+ f"{ message .mxid } in { message .mx_room } " )
459
539
else :
460
540
message .edit (redacted = True )
461
541
await real_deleter .client .delete_messages (self .peer , [message .tgid ])
462
- await self ._send_delivery_receipt (redaction_event_id )
463
542
464
543
async def _update_telegram_power_level (self , sender : 'u.User' , user_id : TelegramID ,
465
544
level : int ) -> None :
0 commit comments