I composed a new email. Before sending this email, I would like (using VBA) to get the senders email address.
I wrote the following example code. When I run this code, the first message box displays the email subject correctly, however the second message box shows nothing (the message box is empty).
Sub email_test()
Dim eSubject As String
Dim eSender As String
eSubject = Application.ActiveInspector.currentItem.subject
MsgBox eSubject
eSubject = Application.ActiveInspector.currentItem.SenderEmailAddress
MsgBox eSender
End Sub
A new mail item doesn't have the Sender* related properties set. They are set right after the message is processed by the transport provider and can be get, for example, from the Sent Items folder. You can handle the ItemAdd event of the Items class which comes from the Sent Items folder. Be aware, the SaveSentMessageFolder property of the MailItem class can be used to set a Folder object that represents the folder in which a copy of the e-mail message will be saved after being sent. Also the DeleteAfterSubmit property can be set, in that case a copy of the mail message is not saved after being sent.
You may be interested in the SendUsingAccount property which allows to get or set set an Account object that represents the account under which the MailItem is to be sent.
Use MailItem.SendUsingAccount.SmtpAddress. If MailItem.SendUsingAccount is null, you can asssume the default account will be used - the address can be accessed from Application.Session.CurrentUser.Address. In case of an Exchange mailbox, use Application.Session.CurrentUser.AdderssEntry.GetExchangeUser.PrimarySmtpAddress
Related
I have an Exchange mailbox with a bunch of Outlook ReportItem Undelivered messages. I am attempting to reprocess the undelivered messages via an Outlook VBA script by invoking the "SendAgain" operation on the ReportItem messages. My issue is that the ReportItem does not have a send method, so I have no way of actually sending the reprocessed messages. I am using the following code to go through the messages:
Dim objApp As Outlook.Application
Dim objNameSpace As NameSpace
Dim journalAlertInbox As Folder
Dim objInspector As Inspector
Dim resendItem As ReportItem
Set objApp = CreateObject("Outlook.Application")
Set objNameSpace = objApp.GetNamespace("MAPI")
Set journalAlertInbox = objNameSpace.Stores.Item("thestore").GetDefaultFolder(olFolderInbox)
For Each folderItem In journalAlertInbox.Items
If TypeOf folderItem Is ReportItem Then
folderItem.Display
Set objInspector = folderItem.GetInspector
objInspector.CommandBars.ExecuteMso "SendAgain"
Set resendItem = Application.ActiveInspector.CurrentItem
Set objInspector = resendItem.GetInspector
''how do I send the item that is now displayed?
''resendItem.Close olSave
folderItem.Close olDiscard
End If
Next folderItem
I thought I might be able to save the displayed message as a draft, however If I uncomment the resendItem.close olSave line this results in a message in my Outlook Drafts folder of type ReportItem. I can open up the saved draft message it the Outlook GUI and click the send button, but I do not see a way to actually invoke the send operation programmatically. Examining the message in drafts shows it to be of type ReportItem, which does not have a .Send method.
How can I invoke the "Send" operation on the Report Item? I can clearly see the "Send" button, but there seems to be no programmatic way of actually clicking it.
OOM does not expose any functionality that allows to link a ReportItem object to the original MailItem, and, generally, there might not be any kind of link between the two. The best you can do is to retrieve PR_ORIGINAL_SEARCH_KEY MAPI property (or PR_REPORT_TAG, which includes both the search key and the store/Sent Items folder entry id) using ReportItem.PropertyAccess.GetProperty and try to find a matching message in the Sent Items folder. You can see these properties in OutlookSpy (I am its author).
Keep in mind that OOM does not allow to search on the binary (PT_BINARY) properties in Items.Find/Restrict.
If using Redemption is an option (I am also its author), it exposes RDOReportItem.FindOriginalItem method.
Once you have the original item, you can make a copy and try to send it again.
The ReportItem doesn't represent the original item which is failed to be sent. Also it doesn't contain any relationship with the original mail item, so you will not find any property or method available in the Outlook object model. Your existing solution looks good.
You may also try using the ReportItem.GetConversation method which obtains a Conversation object that represents the conversation to which this item belongs. So, you may try getting the previous item from the conversation, it could be the original item which has been submitted.
I tried isolating the body of a received Outlook email in a macro, using the following code:
Dim inspector As Outlook.inspector, email As Outlook.MailItem, body As String
Set inspector = Application.ActiveInspector
Set email = email.subject
body = email.Body
The problem is, when I print out the contents of this variable in a MsgBox, it has the person's signature included. Is there a different attribute other than Body to use for this? Some way to isolate the body of the mail item without the sender's signature, if they added one?
For bonus points: if email is an email that was forwarded to me, Body also includes information (header details/metadata, the body itself, and a signature if present) from all the previous emails in the forwarding chain. Is there a way to isolate just the body of the current mail item rather than all the associated ones?
Outlook places the new signature inside the "_MailAutoSig" bookmark, which can be accessed through Document.Bookmarks.Item("_MailAutoSig"), where Document can be retrieved from Inspector.WordEditor.
I currently have two Lotus Notes databases, each with their own email addresses associated with them. As expected, when I send an email through the first database to my gmail account, it shows up as "From: notesAccount1#db1.com" and when I send using the second database, the message shows up as "From: notesAccount2#db2.com" in my gmail.
I have working code that opens up the second database, searches the inbox for an email containing a certain keyword, and extracts an email address from that email. It then creates a new document in that second database, inserts the recipients name, subject, body, etc., sends the email, and saves it to my sent folder. Everything works smoothly up to this point.
However, when I send an email from the second database to my gmail account using this VBA method, the email shows up in my gmail as "From: notesAccount1#db1.com" - the email associated with the first database.
I can't figure out why this is happening. Pretty limited knowledge of the interactions between VBA and Lotus Notes, and Lotus Notes servers/databases in general. The first database is technically my default one that only I have access to and the second database was added later and multiple people have access to it. I don't know if that's relevant.
Would appreciate any help! Thanks.
Note: This code was copied and adapted from several sources, including some on SO, IBM and other Notes sources, and anything else Google threw my way, including
http://www.fabalou.com/vbandvba/lotusnotesmail.asp
http://www-01.ibm.com/support/docview.wss?uid=swg21178583
Code: (This will have to be adapted as I have taken out server names and mail file names)
Sub ReadNotesEmail()
Dim sess As Object
Dim db As Object
Dim folder As Object
Dim docNext As Object
Dim memoSenders As Variant
Dim newEmail As Object
Dim view As Object
Dim entry As Object
Dim entries As Object
Dim templateEmail As Object
Dim mailServer As String
Dim mailFile As String
Dim folderName As String
Dim todayDate As String
Dim memoBody As String
Dim senderEmail As String
Dim emailStartPos As Integer
Dim emailEndPos As Integer
'This program will search a particular folder in a Notes database that I designate.
'It will search that folder for emails that contain certain key words. Once it finds
'an email that fits, it will grab the sender's email address (written in the body, not
'in the 'from') and send them an email.
'Name of folder to search for emails
folderName = "($Inbox)"
'Create a Lotus Notes session and open it (will require password)
Set sess = CreateObject("Lotus.NotesSession")
sess.Initialize ("")
'Set the mail server, mail file, and database. This will be the tricky part as I need this to
'look at the second mail server as opposed to the default mail server of jdyagoda
Set db = sess.GETDATABASE("***name of second Notes server***", "***name of second mail file***")
'Open the mail database in notes
If Not db.IsOpen = True Then
Call db.Open
End If
Set folder = db.GetView(folderName)
'Now look through the emails one at a time with a loop that ends when no emails are left.
'If an email contains the key word, look for the email address of the person who submitted
'the contact-us form. It follows the string "Email:" and preceeds
'the string "Phone:".
Set doc = folder.GetFirstDocument
Do Until doc Is Nothing
Set docNext = folder.GETNEXTDOCUMENT(doc)
memoBody = LCase(doc.GetItemValue("body")(0))
If (memoBody Like "*") Then 'This is where you designate the keyword
'Here's where you extract the email address - taken out for the purpose of this SO question
'senderEmail = testName#test.com
'Now create a new email to the intended recipient
Set newEmail = db.CREATEDOCUMENT
Call newEmail.ReplaceItemValue("Form", "Memo")
Call newEmail.ReplaceItemValue("SendTo", senderEmail)
Call newEmail.ReplaceItemValue("Subject", "Thank you for your email")
Call newEmail.ReplaceItemValue("body", "Test Body 1. This is a test.")
newEmail.SAVEMESSAGEONSEND = True
'Send the new email
Call newEmail.ReplaceItemValue("PostedDate", Now()) 'Gets the mail to appeaer in the sent items folder
Call newEmail.SEND(False)
End If
Set doc = docNext
Loop
End Sub
Notes will normally send the mail using the email address for the ID you use to login. So if you login using notesAccount1/Domain, then all emails will be coming from notesAccount1#example.com.
If you want to fake the sender, you need to use an undocumented method: inject the email directly into mail.box.
You should not attempt to do this unless you really know what you are doing.
I have posted code on my blog for a mail notification class, it supports this work-around to set the sender on outgoing emails. You can find the latest code at http://blog.texasswede.com/updated-mailnotification-class-now-with-html-email-support-and-web-links/
I need to create a mail via VBA, send it, and then export a .msg file of the sent mail to be archived (I know, it's weird, but that's what the boss asked for).
Creating the mail is straightforward:
Set OLK = Outlook.Session
Set ML = OLK.Createitem olMailItem
With ML
.Recipients.add "somebody#somedomain.com"
.Subject = "Great mail you have there"
.Body = "It would be a shame if somebody couldn't archive it"
End with
ML.Send
Problem is, after sending the mail is moved in the sent folder and the ML object points to nothing.
I could use the .saveas method before sending, but then the saved file is the unsent version, which can be edited and sent again.
How can I trace the mail in the sent folder?
The "brute force" way I found out implies saving the ConversationIndex before sending
IDX= ML.ConversationIndex
and then scan all the items in the sent folder for it:
For each ML in OLK.Session.GetDefaultFolder(olFolderSentMail).Items
If ML.ConversationIndex = IDX Then ML.SaveAs HomeDir & "\" & OutFileName: Exit For
Next
but it isn't exactly a smooth work.... (and may fail if some smartass replies to the automatic mail, even if nobody should)
Max,
You can handle the ItemAdd event of the Items class which belongs to the Sent Items folder. It is fired when one or more items are added to the specified collection.
In the ItemAdd event handler you can check out whether a particular item should be saved or not. For example, you can add a user property before calling the Send method. See the UserProperties class for more information.
Set myProp = myItem.UserProperties.Add("MyPropName", olText)
Be aware, the MailItem class provides the SaveSentMessageFolder property which allows to set a Folder object that represents the folder in which a copy of the e-mail message will be saved after being sent. So, you can assign a custom folder to save them.
You can add a user property (MailItem.UserProperties.Add), but that would cause the message to be sent in the TNEF format unless the UseTnef property (DASL name http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8582000B) is explicitly set to false.
You can set a named MAPI property using PropertyAccessor.SetProperty - just pick your custom GUID and property name. E.g.
ML.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/string/{3ADE3813-37A9-49C9-AD84-D49C8FF5D660}/MyOwnProp", "SomeValue")
I have VBA code to forward email to a specific account. It works except email being forwarded has the forwarder's email address.
How can I keep the original sender email address as the replyto after an email is forwarded?
Sub AutoForwardAllSentItems(Item As Outlook.MailItem)
Dim strMsg As String
Dim autoFwd As Outlook.MailItem
Set autoFwd = Item.Forward
autoFwd.Recipients.Add "my_email#domain.com"
autoFwd.Send
Set autoFwd = Nothing
End Sub
so there is no way? really? – Mike 7 hours ago
Riking is correct when he mentioned that Outlook will not let you modify the headers included in the email. I am guessing that he is refering to .SenderEmailAddress property. You cannot modify the .SenderEmailAddressas this property is readonly.
Having said that there is another property that you may like to use. .SentOnBehalfOfName More details here
Topic: SentOnBehalfOfName Property
Link: http://msdn.microsoft.com/en-us/library/aa171998%28v=office.11%29.aspx
Quote from the above link
Returns a String indicating the display name for the intended sender of the mail message. This property corresponds to the MAPI property PR_SENT_REPRESENTING_NAME. Read/write.
expression.SentOnBehalfOfName
expression Required. An expression that returns a MailItem object.
Also see this link
Topic: Automatically setting the ‘From’ address of a new Outlook message
Link: http://benchristian.wordpress.com/2005/12/18/automatically-setting-the-from-address-of-a-new-outlook-message/
Quote from the above link
Setting an alternate reply address is particularly useful if you are using a mail enabled public folder or distribution list for a group of users and would like the replies to messages that they send to go to the group smtp address instead of the sender’s mailbox.
HTH
Everything I've seen so far supports the conclusion that Outlook will not
let you modify the headers included in the email.
Sorry. I'd suggest managing the forwards at the email provider, if that is an option for you.