COM Outlook Events

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

COM Outlook Events

09 Nov 2017, 17:37

Hello,

I'm trying to get started with events but I'm having a rough time figuring out. I want to create a code such that, anytime the autohotkey script is running, I am able to retrieve the contents of an email that I have just sent and perform actions once the email is sent.

This is what I have so far, though I am sure it's quite incorrect, especially as it isn't working:

Code: Select all

#Persistent
Outlook := ComObjActive("Outlook.Application")
Email := Outlook.Application.ActiveInspector.CurrentItem
ComObjConnect(Email, "Email_")

Email_Send()
{
	Email_To := Email.To
	Email_Subject := Email.Subject
	MsgBox, %Email_To%`n%Email_Subject%
}
Another question that I have is that I want to retrieve the full email address when using the .cc, .SenderName, and .to via COM. I believe that if I have a contact saved into my outlook, it will only retrieve the full name instead of the email address. Please advise how I can still retrieve the "@somedomain.com" with each individual.

Thanks so much for any help you can provide!
User avatar
Jovannb
Posts: 268
Joined: 17 Jun 2014, 02:44
Location: Austria

Re: COM Outlook Events

10 Nov 2017, 04:37

Hi,

I saw an interesting post (many thanks to FanaticGuru) and tried it with that small example below

Code: Select all

/*
Source: https://autohotkey.com/boards/viewtopic.php?f=5&t=35111&start=20
*/
#singleinstance force
#persistent

olApp := ComObjActive("Outlook.Application")
ComObjConnect(olApp, "EventApp_")

EventApp_NewMail()
{
	MsgBox % NEW MAIL
}

return
1.) start that AHK example
2.) wait until a new email arrives at Outlook (tested with OL2010)

J.B.
AHK: 1.1.37.01 Ansi, 32-Bit; Win10 22H2 64 bit, german
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

10 Nov 2017, 12:29

Hey there, JB. Thanks a lot for your help! However, I noticed this is for when emails are received. How do I modify this for when emails are sent, while keeping the contents of the email such as to, from, cc, and subject line?

In addition, would you be able to assist on my other question: I want to retrieve the full email address when using the .cc, .SenderName, and .to via COM. I believe that if I have a contact saved into my outlook, it will only retrieve the full name instead of the email address. Please advise how I can still retrieve the "@somedomain.com" with each individual.

Thanks again!!
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: COM Outlook Events

10 Nov 2017, 13:41

Below is a link to a post about using the Application Event ItemSend as opposed to Send which is a MailItem Event.
https://autohotkey.com/boards/viewtopic ... 04#p134704

It depends on whether you want this event to trigger on all sends or just the send of a specific email.

The problem in you code is probably that in the function Email_Send() the variable Email is a local variable in the function and has no value. The Email variable outside the function and the Email variable inside the function are basically not the same variable reference.

global Email := Outlook.Application.ActiveInspector.CurrentItem should fix this.

Also this is a little shorter: Outlook.ActiveWindow.CurrentItem

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

10 Nov 2017, 14:26

Hey, FG,

I read that link before but I remain a little puzzled.

Overall, I now want the following altogether:

1. In the event that an email is received at anytime, I am able to perform actions based on this exact email's contents such as to, from, subject, and cc.

2. In the event that an email is sent at anytime, I am able to perform actions based on this exact emails contents as well. I see that your link has an example of something like this but it seems like it's based off a new email that is created via autohotkey. I simply want to use outlook and when it sends, the event occurs and I perform actions using this email's contents.

3. Retrieve the full email address on .to, SenderName and .cc. When I try to retrieve these from an email, it often returns the full name when I want the full email address instead.

If you are able to assist on the three above, I would greatly appreciate it!
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: COM Outlook Events

10 Nov 2017, 14:27

ShubhamM wrote:In addition, would you be able to assist on my other question: I want to retrieve the full email address when using the .cc, .SenderName, and .to via COM. I believe that if I have a contact saved into my outlook, it will only retrieve the full name instead of the email address. Please advise how I can still retrieve the "@somedomain.com" with each individual.
The Properties you listed show only the display name as you discovered. This is basically just a string of text of what is displayed in the email field. To get the addresses you need to access the Recipients collection which is the nitty gritty of everyone getting the email.

This will display the email address of all recipients of an email.

Code: Select all

F12::
	olApp := ComObjActive("Outlook.Application")
	olEmail := olApp.ActiveWindow.CurrentItem	; Expects an Email to be open
	for olRecipient in olEmail.Recipients
		MsgBox % olRecipient.Address
return
FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: COM Outlook Events

10 Nov 2017, 14:42

ShubhamM wrote:Hey, FG,

I read that link before but I remain a little puzzled.

Overall, I now want the following altogether:

1. In the event that an email is received at anytime, I am able to perform actions based on this exact email's contents such as to, from, subject, and cc.

2. In the event that an email is sent at anytime, I am able to perform actions based on this exact emails contents as well. I see that your link has an example of something like this but it seems like it's based off a new email that is created via autohotkey. I simply want to use outlook and when it sends, the event occurs and I perform actions using this email's contents.

3. Retrieve the full email address on .to, SenderName and .cc. When I try to retrieve these from an email, it often returns the full name when I want the full email address instead.

If you are able to assist on the three above, I would greatly appreciate it!
Here is a link to receive event for 1.
https://autohotkey.com/boards/viewtopic ... 69#p162869

Here is an example of 2.

Code: Select all

#Persistent
olApp := ComObjActive("Outlook.Application")
ComObjConnect(olApp, "EventApp_")

EventApp_ItemSend(olItem, Cancel)
{
	if InStr(olItem.Body, "stupid")
	{
		MsgBox The new company policy is to NOT call our customers "stupid".`nPlease rephrase your email.
		return ComObject(0xB,0) ; VT_Bool False = Cancels Send with Email staying open
	}
}
Anytime an email is sent with the word "stupid" in the body of the email a warning is displayed and the send is canceled.

If nothing is after the return then the email would be sent after the message was displayed.

Gave example of 3. in previous post above.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

10 Nov 2017, 14:59

You, sir, are brilliant. I appreciate this so much! I'll give it a go once I'm back at the computer and post again if I run into more problems.

Thanks again!!
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

10 Nov 2017, 17:32

Hey, There,

So most things worked without a hitch but I have encountered the following few problems;
For the new received/sent emails, I need to use another value(string) from another function that I've been using. That value is passed through function to function and I need to use that variable. How can I pass through this variable into the event-based code, "NewVariable" in this case.

Code: Select all

global olApp := ComObjActive("Outlook.Application")
ComObjConnect(olApp, "EventApp_")

EventApp_NewMailEx(IDs, NewVariable)
{
	MsgBox, %NewVariable%
	IDs := StrSplit(IDs, ",")
	for index, ID in IDs
		MsgBox % olApp.Session.GetItemFromID(ID).Subject
}
The second is that the following code you provided didn't work; it returned a random program value and not the email addresses. I literally just copied and pasted this one direct and it gave me the attached image for basically every recipient.
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

10 Nov 2017, 17:34

Sorry, I was referring to this code:

Code: Select all

F12::
	olApp := ComObjActive("Outlook.Application")
	olEmail := olApp.ActiveWindow.CurrentItem	; Expects an Email to be open
	for olRecipient in olEmail.Recipients
		MsgBox % olRecipient.Address
return
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: COM Outlook Events

10 Nov 2017, 19:03

ShubhamM wrote:For the new received/sent emails, I need to use another value(string) from another function that I've been using. That value is passed through function to function and I need to use that variable. How can I pass through this variable into the event-based code, "NewVariable" in this case.

EventApp_NewMailEx(IDs, NewVariable)
There is no adding of parameters to these Event functions. Windows calls these functions and only passes the parameters that are built into Windows to pass. To that Event function Windows always and only passes a list of IDs.

If you want to get additional information into the function, you need to do it with global variables.

Put global NewVariable near the top of your script and all functions in the script will be able to access that variable.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: COM Outlook Events

10 Nov 2017, 19:21

ShubhamM wrote:

Code: Select all

F12::
	olApp := ComObjActive("Outlook.Application")
	olEmail := olApp.ActiveWindow.CurrentItem	; Expects an Email to be open
	for olRecipient in olEmail.Recipients
		MsgBox % olRecipient.Address
return
The second is that the following code you provided didn't work; it returned a random program value and not the email addresses. I literally just copied and pasted this one direct and it gave me the attached image for basically every recipient.
I cannot explain this behavior. The script works as expected for me.

I don't really know what this means, "attached image for basically every recipient".

Possibly, you have another script running, especially another script with the same trigger hotkey.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

10 Nov 2017, 20:02

Hey,

Damn, I gotta say, I was really going that it would allow me to do that. The problem that I'm already setting these variables as global originally but manipulating them by calling them through functions and a subsequent subroutine. Any way to retrieve these variables as global and then enter the event to use them?

No, I actually was using the single script and I have force instance on anyways. I noticed the image didn't show but is there any other way to translate the recipients into their address names only?
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

10 Nov 2017, 20:08

I'll try resending the image when I'm home (on the phone atm)
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

10 Nov 2017, 20:29

lol, tbh, I'm a complete noob at this form as I just joined a couple days ago, so I'm not entirely sure how to add the image, even with "" (don't know how to properly give the address in this case) but this is exactly what the string returns when I try to run the code on an active email on outlook; this is with outlook 2016:

/o=ExchangeLabs/ou=Exchange Administrative Group
(FYDIBOHF23SPDLT)/cn=Recipients/cn=...

Where "..." is just a bunch of random alphanumeric characters.

Either way, is there another way to retrieve the raw email addresses?

Thanks!
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: COM Outlook Events

13 Nov 2017, 12:47

ShubhamM wrote:lol, tbh, I'm a complete noob at this form as I just joined a couple days ago, so I'm not entirely sure how to add the image, even with "" (don't know how to properly give the address in this case) but this is exactly what the string returns when I try to run the code on an active email on outlook; this is with outlook 2016:

/o=ExchangeLabs/ou=Exchange Administrative Group
(FYDIBOHF23SPDLT)/cn=Recipients/cn=...

Where "..." is just a bunch of random alphanumeric characters.

Either way, is there another way to retrieve the raw email addresses?

Thanks!
That is the address that you get when going through an Exchange server.

You might try:

Code: Select all

#F11::
	olApp := ComObjActive("Outlook.Application")
	olEmail := olApp.ActiveWindow.CurrentItem	; Expects an Email to be open
	for Recipient in olEmail.Recipients
	{
		if !(SMTP := Recipient.AddressEntry.GetExchangeUser.PrimarySmtpAddress)
			SMTP := Recipient.AddressEntry.Address 
		MsgBox % SMTP 
	}
return
I have no ability to test the code so cannot say for certain that will work.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

13 Nov 2017, 13:59

This worked!! Thank so much!

One small follow-up as this only covers the recipients, how do I obtain the same for the sender (who the email is from)?

Also, for the EventApp_ItemSend(Outlook_Item) [Item Send outlook event], I tried to save the email via Outlook_Item.SaveAs(Email_To_Save) but the email saves as if it hasn't been sent. It has everything filled out, but it looks like an email before you click send. How can I save this email as if it has already been sent? Is there also a way to retrieve the creation time for when this same email was generated? When I use .creationtime, it returns "1/1/1401" for this new item. I am using current date time for when it sends, but it doesn't reflect the time that the email was generated, which I prefer to have. Please advise on these if you can. Thanks a lot!
User avatar
FanaticGuru
Posts: 1908
Joined: 30 Sep 2013, 22:25

Re: COM Outlook Events

13 Nov 2017, 20:24

ShubhamM wrote:This worked!! Thank so much!

One small follow-up as this only covers the recipients, how do I obtain the same for the sender (who the email is from)?

Also, for the EventApp_ItemSend(Outlook_Item) [Item Send outlook event], I tried to save the email via Outlook_Item.SaveAs(Email_To_Save) but the email saves as if it hasn't been sent. It has everything filled out, but it looks like an email before you click send. How can I save this email as if it has already been sent? Is there also a way to retrieve the creation time for when this same email was generated? When I use .creationtime, it returns "1/1/1401" for this new item. I am using current date time for when it sends, but it doesn't reflect the time that the email was generated, which I prefer to have. Please advise on these if you can. Thanks a lot!
The Sender of an email can be obtained by:

Code: Select all

#F10::
	olApp := ComObjActive("Outlook.Application")
	olEmail := olApp.ActiveWindow.CurrentItem	; Expects an Email to be open
	MsgBox % olEmail.SenderEmailAddress
return
It is important to realize that an email does not have a sender until it is actually sent.

Also after an email is sent, a new email object is created so the handle that was used to access the before sending email will not work to access the after sending email.

Here is a post that talks about that some:
https://autohotkey.com/boards/viewtopic ... 13#p168213

There is no easy way that I know of to go from the before send email handle to the after send email handle.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
ShubhamM
Posts: 38
Joined: 08 Nov 2017, 21:38

Re: COM Outlook Events

13 Nov 2017, 21:00

Hey, FG,

I used .SenderEmailAddress but it still returns the exchange server string. How do I modify this to retrieve the email address itself, without the Exchange Server address?

Also, this question above is not for sent emails but rather the ones I receive.

In any case, I tried to use the following code (that you provided on another thread) to save sent items but the operation kept failing as "an object could not be found". I replaced "Important Stuff" with "Sent Items" and event just tried to remove the second .Folders("Important Stuff") and replaced "Inbox" with "Sent Items" to no avail. Any idea how I would save emails from my "Sent Items" folder?

Code: Select all

olApp := ComObjActive("Outlook.Application")
olNameSpace := olApp.GetNamespace("MAPI")
olFolderItems := olNameSpace.Folders("Account Display Name").Folders("Inbox").Folders("Important Stuff").Items

ComObjConnect(olFolderItems, "EventFolderItems_")

EventFolderItems_ItemAdd(olItem)
{
	MsgBox % olItem.Subject
}
Thanks as always!!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: bobstoner289, peter_ahk, Spawnova and 357 guests