main.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #!/usr/bin/env python3
  2. from urllib.parse import urlparse
  3. import os
  4. import time
  5. import traceback
  6. import asyncio
  7. import simplematrixbotlib as botlib
  8. import nio
  9. from speech_recognition import ASR
  10. creds = botlib.Creds(
  11. homeserver=os.environ['HOMESERVER'],
  12. username=os.environ['USERNAME'],
  13. password=os.getenv('PASSWORD', None),
  14. login_token=os.getenv('LOGIN_TOKEN', None),
  15. access_token=os.getenv('ACCESS_TOKEN', None),
  16. session_stored_file="/data/session.txt"
  17. )
  18. config = botlib.Config()
  19. config.encryption_enabled = True
  20. config.emoji_verify = False
  21. config.ignore_unverified_devices = True
  22. config.store_path = '/data/crypto_store/'
  23. if 'ALLOWLIST' in os.environ:
  24. config.allowlist = os.environ['ALLOWLIST'].split(',')
  25. bot = botlib.Bot(creds, config)
  26. asr = ASR(os.getenv('ASR_MODEL', os.getenv('PRELOAD_MODEL', 'tiny')), os.getenv('ASR_LANGUAGE', 'en'))
  27. @bot.listener.on_custom_event(nio.RoomMessage)
  28. async def on_message(room, event):
  29. if not isinstance(event, (nio.RoomMessageAudio,
  30. nio.RoomEncryptedAudio,
  31. nio.RoomMessageVideo,
  32. nio.RoomEncryptedVideo)):
  33. return
  34. encrypted = isinstance(event, (nio.RoomEncryptedAudio, nio.RoomEncryptedVideo))
  35. print(room.machine_name, event.sender, event.body, event.url)
  36. match = botlib.MessageMatch(room, event, bot)
  37. if match.is_not_from_this_bot():
  38. await bot.async_client.room_typing(room.machine_name, True, timeout=120000)
  39. url = urlparse(event.url)
  40. response = await bot.async_client.download(server_name=url.netloc, media_id=url.path[1:])
  41. if encrypted:
  42. print("decrypting...")
  43. data = nio.crypto.attachments.decrypt_attachment(
  44. response.body,
  45. event.source["content"]["file"]["key"]["k"],
  46. event.source["content"]["file"]["hashes"]["sha256"],
  47. event.source["content"]["file"]["iv"],
  48. )
  49. else:
  50. data = response.body
  51. print(response)
  52. result = await asr.transcribe(data)
  53. await bot.async_client.room_typing(room.machine_name, False)
  54. if not result:
  55. print("No result")
  56. return
  57. filename = response.filename or event.body
  58. if filename:
  59. reply = f"Transcription of {filename}: {result}"
  60. else:
  61. reply = f"Transcription: {result}"
  62. await bot.api._send_room(
  63. room_id=room.room_id,
  64. content={
  65. "msgtype": "m.notice",
  66. "body": reply,
  67. "m.relates_to": {
  68. "m.in_reply_to": {
  69. "event_id": event.event_id
  70. }
  71. }
  72. })
  73. async def main():
  74. asr.load_model()
  75. while True:
  76. try:
  77. await bot.run()
  78. except (asyncio.exceptions.TimeoutError, aiohttp.ClientError) as e:
  79. print(f"Network issue: {e}")
  80. traceback.print_exc()
  81. print("Network issue, restarting...")
  82. await asyncio.sleep(5)
  83. except Exception as e:
  84. print(f"Unexpected error: {e}")
  85. traceback.print_exc()
  86. print("Unexpected error, restarting...")
  87. await asyncio.sleep(5)
  88. if __name__ == "__main__":
  89. asyncio.run(main())