main.py 3.0 KB

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