azmailauto.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. from azwmail import send_email2,imap_session,get_credentials,return_email_session
  2. import email
  3. import os
  4. from pathlib import Path
  5. import json
  6. import time
  7. from email.utils import parseaddr
  8. from email.mime.multipart import MIMEMultipart
  9. from email.mime.text import MIMEText
  10. from email.mime.message import MIMEMessage
  11. import subprocess
  12. from subprocess import check_output,PIPE,CREATE_NEW_CONSOLE
  13. from signal import signal,SIGINT
  14. import sys
  15. username,_ = get_credentials()
  16. server = None
  17. def signal_handler(signal_received,frame):
  18. print('\n')
  19. print('closing connection')
  20. try:
  21. server.close()
  22. server.logout()
  23. sys.exit(0)
  24. except Exception:
  25. print('error while closing connection')
  26. sys.exit(1)
  27. def config_file():
  28. config_file_path = os.path.join(Path.home(),'config.json')
  29. if os.path.exists(config_file_path):
  30. jobj = dict()
  31. with open(config_file_path,'r',encoding='utf-8') as f:
  32. jobj = json.load(f)
  33. try:
  34. trigger_subject = jobj['trigger_subject']
  35. except KeyError:
  36. jobj['trigger_subjecr'] = input('Enter trigger subject : ')
  37. with open(config_file_path,'w',encoding='utf-8') as fp:
  38. json.dump(jobj,fp)
  39. return jobj
  40. else:
  41. dict_config_data = dict()
  42. num_instances = int(input('number of instances you are running : '))
  43. db_table_name = input('table name from database :')
  44. s3_bucket_name = input('s3 bucket name to upload :')
  45. s3_folder = input('s3 folder for upload :')
  46. notifier_name = input('emails delimiated by ; :')
  47. dict_config_data['num_instances'] = num_instances
  48. dict_config_data['db_table_name'] = db_table_name
  49. dict_config_data['s3_bucket_name'] = s3_bucket_name
  50. dict_config_data['s3_folder'] = s3_folder
  51. dict_config_data['notification_addr'] = notifier_name
  52. with open(config_file_path,'w',encoding='utf-8') as fp:
  53. json.dump(dict_config_data,fp)
  54. return dict_config_data
  55. #https://stackoverflow.com/a/2189630/3025905
  56. def create_reply_message(originalemail,mailcontent):
  57. #removing attachment
  58. for part in originalemail.walk():
  59. if(part.get('Content-Disposition') and part.get('Content-Disposition').startswih('attachment')):
  60. part.set_type('text/plain')
  61. part.set_payload("Attachment removed : %s (%s,%d,bytes)"%(part.get_filename(),
  62. part.get_content_type(),
  63. len(part.get_payload(decode=True))))
  64. del part['Content-Disposition']
  65. del part["Content-Transfer-Encoding"]
  66. #create reply email
  67. mailbody = f'your request executed through pid : {mailcontent}'
  68. new = MIMEMultipart('mixed')
  69. body = MIMEMultipart('alternative')
  70. body.attach(MIMEText(f'{mailbody}','plain'))
  71. body.attach(MIMEText(f'<html>{mailbody}</html>','html'))
  72. new.attach(body)
  73. new['Messasge-ID'] = email.utils.make_msgid()
  74. new['In-Reply-To'] = originalemail['Message-ID']
  75. new['Reference'] = originalemail['Message-ID']
  76. new['Subject'] = 'Re: '+originalemail['Subject']
  77. new['to']= originalemail['Reply-To'] or originalemail["From"]
  78. new['from'] = username
  79. #attach original email
  80. new.attach(MIMEMessage(originalemail))
  81. smtp_session = return_email_session()
  82. #sendemail
  83. #input(new['to'])
  84. smtp_session.sendmail(username,[new['to']],new.as_string())
  85. smtp_session.quit()
  86. def read_message():
  87. #Will read email, and take action
  88. global server
  89. server = imap_session()
  90. server.select('INBOX')
  91. for _ in range(100):
  92. signal(SIGINT, signal_handler)
  93. server.noop()
  94. _,response = server.search(None,'(UNSEEN)')
  95. new_messages = response[0].split()
  96. count_messages = len(new_messages)
  97. print(f'{count_messages} unread messages')
  98. for m_id in new_messages:
  99. #m_status, m_data = server.fetch(m_id, '(RFC822)')
  100. m_status, m_data = server.fetch(m_id, 'BODY.PEEK[]')
  101. if m_status =='OK':
  102. email_content = m_data[0][1]
  103. msg = email.message_from_bytes(email_content)
  104. subject = msg['SUBJECT']
  105. if 'TRIGGER:' in subject:
  106. m_status, m_data = server.fetch(m_id, '(RFC822)') #set it seen by actually fetching
  107. #this step is redundent but needs to be done
  108. command_name = subject.split(':')[1].strip()
  109. invoke_cmd = command_name
  110. handle_pid = None
  111. handle = None
  112. try:
  113. handle = subprocess.Popen(invoke_cmd,creationflags=CREATE_NEW_CONSOLE)
  114. handle_pid = handle.pid
  115. except Exception as e:
  116. handle_pid = e
  117. create_reply_message(msg,mailcontent=str(handle_pid))
  118. else:
  119. print('no trigger found')
  120. time.sleep(10)
  121. server.close()
  122. server.logout()
  123. def read_message2(server,trigger_subject):
  124. #Will read email and return subject and body
  125. server = imap_session()
  126. server.select('INBOX')
  127. signal(SIGINT, signal_handler)
  128. server.noop()
  129. _,response = server.search(None,'(UNSEEN)')
  130. new_messages = response[0].split()
  131. count_messages = len(new_messages)
  132. print(f'{count_messages} unread messages')
  133. for m_id in new_messages:
  134. #m_status, m_data = server.fetch(m_id, '(RFC822)')
  135. m_status, m_data = server.fetch(m_id, 'BODY.PEEK[]')
  136. input(m_status)
  137. if m_status =='OK':
  138. email_content = m_data[0][1]
  139. msg = email.message_from_bytes(email_content)
  140. subject = msg['SUBJECT']
  141. body = msg['BODY']
  142. input(trigger_subject)
  143. input(subject)
  144. if trigger_subject in subject:
  145. m_status, m_data = server.fetch(m_id, '(RFC822)') #set it seen by actually fetching,this step is redundent but needs to be done
  146. return 'TRIGGER',subject,body,msg
  147. else:
  148. return 'NOTRIGGER',subject,body,msg
  149. return 'NOEMAIL','NOEMAIL','NOEMAIL','NOEMAIL'
  150. if __name__ == "__main__":
  151. server = imap_session()
  152. server.select('INBOX')
  153. t,_,_,_ = read_message2(server,'TRIGGER')
  154. #print(t)
  155. #config_file()
  156. server.close()
  157. server.logout()