Receive your emails via SMS with the Free Mobile API.

emails_sms_free.py 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #!/usr/bin/env python3
  2. # -*- coding:utf-8-*-
  3. import email
  4. import hashlib
  5. import imaplib
  6. import json
  7. import os.path
  8. import requests
  9. import sys
  10. import time
  11. msg_ids = {}
  12. def get_subject(subject_header):
  13. tmp = email.header.decode_header(subject_header)[0]
  14. if tmp[1] is None:
  15. return str(tmp[0])
  16. else:
  17. try:
  18. return tmp[0].decode(tmp[1])
  19. except LookupError:
  20. return "--Unable to fetch subject--"
  21. def send(url, user, password, msg, i=0):
  22. try:
  23. r = requests.get(url, params={'user': user, 'pass': password, 'msg': msg}, verify=False)
  24. if r.status_code == 200:
  25. return True
  26. elif r.status_code == 400:
  27. print('Un paramètre obligatoire est manquant.')
  28. return False
  29. elif r.status_code == 402:
  30. if i < 3:
  31. print('Trop de SMS ont été envoyés en trop peu de temps, ' +
  32. 'le script réessayera dans 30 secondes.')
  33. time.sleep(30)
  34. send(url, user, password, msg, i+1)
  35. else:
  36. print('Impossible d\'envoyer le message dans la dernière minute ' +
  37. 'et demie.')
  38. return False
  39. elif r.status_code == 403:
  40. print('Identifiants incorrects ou service non activé.')
  41. return False
  42. elif r.status_code == 500:
  43. print('Erreur côté serveur.')
  44. return False
  45. except requests.exceptions.RequestException:
  46. return False
  47. def get_emails(imap_server, imap_user, imap_password, inbox, uid):
  48. global msg_ids
  49. print('Connecting to '+imap_server+'… ', end=' ')
  50. conn = imaplib.IMAP4_SSL(imap_server)
  51. print('Connected')
  52. to_send = []
  53. try:
  54. print('Logging as '+imap_user+'… ', end='')
  55. retcode, capabilities = conn.login(imap_user, imap_password)
  56. except:
  57. print('Failed')
  58. print(sys.exc_info()[1])
  59. sys.exit(1)
  60. print('Logged in')
  61. try:
  62. conn.select(inbox, readonly=True)
  63. typ, tmp_msg_ids = conn.uid('search', None, 'ALL')
  64. tmp_msg_ids = [i.decode('utf-8')
  65. for i in tmp_msg_ids[0].split()]
  66. if uid in msg_ids:
  67. diff_msg_ids = [i
  68. for i in tmp_msg_ids
  69. if i not in msg_ids[uid]]
  70. else:
  71. diff_msg_ids = tmp_msg_ids
  72. msg_ids[uid] = tmp_msg_ids
  73. if len(diff_msg_ids) == 0:
  74. print("\tNo new emails")
  75. else:
  76. for i in diff_msg_ids:
  77. typ, msg_data = conn.uid('fetch', i, '(RFC822)')
  78. msg_parsed = email.message_from_bytes(msg_data[0][1])
  79. text = ""
  80. for part in msg_parsed.walk():
  81. if part.get_content_charset() is None:
  82. # We cannot know the character set, so return decoded "something"
  83. text = part.get_payload(decode=True)
  84. continue
  85. charset = part.get_content_charset()
  86. if part.get_content_type() == 'text/plain':
  87. text = part.get_payload(decode=True).decode(str(charset))
  88. break
  89. subject = get_subject(msg_parsed['Subject'])
  90. print("\tNew email from "+msg_parsed['From'] +
  91. " : "+subject)
  92. to_send.append({'server_uid': uid,
  93. 'id': i,
  94. 'from': msg_parsed['From'],
  95. 'subject': subject,
  96. 'content': text})
  97. return to_send
  98. finally:
  99. try:
  100. conn.close()
  101. except:
  102. pass
  103. conn.logout()
  104. if __name__ == '__main__':
  105. # EDIT BELOW ACCORDING TO YOUR NEEDS
  106. imap_servers = [{'server': 'SERVER',
  107. 'login': 'LOGIN',
  108. 'password': 'PASS',
  109. 'inbox': 'INBOX'}]
  110. save_path = os.path.expanduser('~/.emails_sms_free.json')
  111. debug = False
  112. url = "https://smsapi.free-mobile.fr/sendmsg"
  113. user = 'IDENT'
  114. password = 'PASS'
  115. # YOU SHOULD NOT HAVE TO EDIT BELOW
  116. url = url.replace('{$user}', user)
  117. url = url.replace('{$pass}', password)
  118. if os.path.isfile(save_path):
  119. with open(save_path, 'r') as fh:
  120. msg_ids = json.load(fh)
  121. to_send = []
  122. for imap_server in imap_servers:
  123. to_send.extend(get_emails(imap_server['server'],
  124. imap_server['login'],
  125. imap_server['password'],
  126. imap_server['inbox'],
  127. hashlib.md5((imap_server['server']+imap_server['login']).encode('utf-8')).hexdigest()))
  128. if debug:
  129. print("\nNew emails to send via SMS:")
  130. print("\t", to_send)
  131. i = 1
  132. for data in to_send:
  133. msg = ('New email from '+data['from']+'\n' +
  134. data['subject']+'\n' +
  135. str(data['content'][:700])+'...')
  136. if send(url, user, password, msg):
  137. print('Sent '+str(i)+'/'+str(len(to_send)))
  138. else:
  139. msg_ids[data['server_uid']].remove(data['id'])
  140. print('Email '+str(i)+'/'+str(len(to_send))+' : Unable to send the text ' +
  141. 'message, remove this email from parsed list.')
  142. i += 1
  143. with open(save_path, 'w') as fh:
  144. json.dump(msg_ids, fh)