mapisend.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/env python
  2. """module to send mail with Extended MAPI using the pywin32 mapi wrappers..."""
  3. # this was based on Jason Hattingh's C++ code at http://www.codeproject.com/internet/mapadmin.asp
  4. # written by David Fraser <davidf at sjsoft.com> and Stephen Emslie <stephene at sjsoft.com>
  5. # you can test this by changing the variables at the bottom and running from the command line
  6. from win32com.mapi import mapi
  7. from win32com.mapi import mapitags
  8. def SendEMAPIMail(Subject="", Message="", SendTo=None, SendCC=None, SendBCC=None, MAPIProfile=None):
  9. """Sends an email to the recipient using the extended MAPI interface
  10. Subject and Message are strings
  11. Send{To,CC,BCC} are comma-separated address lists
  12. MAPIProfile is the name of the MAPI profile"""
  13. # initialize and log on
  14. mapi.MAPIInitialize(None)
  15. session = mapi.MAPILogonEx(0, MAPIProfile, None, mapi.MAPI_EXTENDED | mapi.MAPI_USE_DEFAULT)
  16. messagestorestable = session.GetMsgStoresTable(0)
  17. messagestorestable.SetColumns((mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME_A, mapitags.PR_DEFAULT_STORE),0)
  18. while True:
  19. rows = messagestorestable.QueryRows(1, 0)
  20. #if this is the last row then stop
  21. if len(rows) != 1:
  22. break
  23. row = rows[0]
  24. #if this is the default store then stop
  25. if ((mapitags.PR_DEFAULT_STORE,True) in row):
  26. break
  27. # unpack the row and open the message store
  28. (eid_tag, eid), (name_tag, name), (def_store_tag, def_store) = row
  29. msgstore = session.OpenMsgStore(0,eid,None,mapi.MDB_NO_DIALOG | mapi.MAPI_BEST_ACCESS)
  30. # get the outbox
  31. hr, props = msgstore.GetProps((mapitags.PR_IPM_OUTBOX_ENTRYID), 0)
  32. (tag, eid) = props[0]
  33. #check for errors
  34. if mapitags.PROP_TYPE(tag) == mapitags.PT_ERROR:
  35. raise TypeError('got PT_ERROR instead of PT_BINARY: %s'%eid)
  36. outboxfolder = msgstore.OpenEntry(eid,None,mapi.MAPI_BEST_ACCESS)
  37. # create the message and the addrlist
  38. message = outboxfolder.CreateMessage(None,0)
  39. # note: you can use the resolveaddress functions for this. but you may get headaches
  40. pal = []
  41. def makeentry(recipient, recipienttype):
  42. return ((mapitags.PR_RECIPIENT_TYPE, recipienttype),
  43. (mapitags.PR_SEND_RICH_INFO, False),
  44. (mapitags.PR_DISPLAY_TYPE, 0),
  45. (mapitags.PR_OBJECT_TYPE, 6),
  46. (mapitags.PR_EMAIL_ADDRESS_A, recipient),
  47. (mapitags.PR_ADDRTYPE_A, 'SMTP'),
  48. (mapitags.PR_DISPLAY_NAME_A, recipient))
  49. if SendTo:
  50. pal.extend([makeentry(recipient, mapi.MAPI_TO) for recipient in SendTo.split(",")])
  51. if SendCC:
  52. pal.extend([makeentry(recipient, mapi.MAPI_CC) for recipient in SendCC.split(",")])
  53. if SendBCC:
  54. pal.extend([makeentry(recipient, mapi.MAPI_BCC) for recipient in SendBCC.split(",")])
  55. # add the resolved recipients to the message
  56. message.ModifyRecipients(mapi.MODRECIP_ADD,pal)
  57. message.SetProps([(mapitags.PR_BODY_A,Message),
  58. (mapitags.PR_SUBJECT_A,Subject)])
  59. # save changes and submit
  60. outboxfolder.SaveChanges(0)
  61. message.SubmitMessage(0)
  62. if __name__ == '__main__':
  63. MAPIProfile = ""
  64. # Change this to a valid email address to test
  65. SendTo = "an.invalid at address"
  66. SendMessage = "testing one two three"
  67. SendSubject = "Testing Extended MAPI!!"
  68. SendEMAPIMail(SendSubject, SendMessage, SendTo, MAPIProfile=MAPIProfile)