working with attachments in outlook
working with attachments in outlook
Hi All Gurus!
I have been banging my head against the wall with this problem...maybe someone can help.
Lets say i receive an email with 4 pdf attachments. my issue is that i need to select one of the attachments and forward it to a specific address and then select the other 3 and forward them to a different address.
what i want to do is to have an ahk script to select one of the attachments, hit a hotkey and have it automatically forward to a specific address (the forwarding addresses do not change, they are always the same)
And then, select the other attachment/s hit a different hotkey and have them forwarded to a different address.
i am able to do this if the user saves the attachments to a folder on the desktop, but not from within outlook.
Alternately, i can drag the attachments only (not the entire email) to an outlook folder, and have an ahk script monitor the folder and forward whatever is dragged there to a specific address.
Can anyone help me with this? is this even possible?
Thanks!
I have been banging my head against the wall with this problem...maybe someone can help.
Lets say i receive an email with 4 pdf attachments. my issue is that i need to select one of the attachments and forward it to a specific address and then select the other 3 and forward them to a different address.
what i want to do is to have an ahk script to select one of the attachments, hit a hotkey and have it automatically forward to a specific address (the forwarding addresses do not change, they are always the same)
And then, select the other attachment/s hit a different hotkey and have them forwarded to a different address.
i am able to do this if the user saves the attachments to a folder on the desktop, but not from within outlook.
Alternately, i can drag the attachments only (not the entire email) to an outlook folder, and have an ahk script monitor the folder and forward whatever is dragged there to a specific address.
Can anyone help me with this? is this even possible?
Thanks!
- flyingDman
- Posts: 2848
- Joined: 29 Sep 2013, 19:01
Re: working with attachments in outlook
This is an example how that could work. It is basic as it assumes that the first file goes to recipient 1 (^F1), the second to recipient 2(^F2), etc. But you can customize this to your liking. The email is assumed to be open when launching the script. The files are saved to disk (I do not think they can be sent without first being saved; someone could prove me wrong on that). You obviously can delete the files when done.
Code: Select all
lst := []
tos := ["rcpnt1@gmail.com","rcpnt2@gmail.com","rcpnt3@gmail.com","rcpnt4@gmail.com"]
olApp := ComObjActive("Outlook.Application")
For olAttachment in olApp.ActiveWindow.CurrentItem.Attachments
{
olAttachment.SaveAsFile("e:\" olAttachment.FileName)
lst.push("e:\" olAttachment.FileName)
}
^F1::
^F2::
^F3::
^F4::
{
item := substr(A_ThisHotkey,3)
ol := olApp.CreateItem(0)
ol.To := tos[item]
ol.Subject := "This is the subject"
ol.Body := "Please see attached"
ol.attachments.add(lst[item])
ol.display
}
14.3 & 1.3.7
Re: working with attachments in outlook
ok, this is neat but i have some questions...
1. its not always 4 attachments, it can be 2 or 10
2. it doesn't seem to find the files after they are saved
3. it may be that one attachment needs to go to the first recipient, but the remaining attachments need to go the the second recipient, is there a way to handle this?
thanks so much for the help!
1. its not always 4 attachments, it can be 2 or 10
2. it doesn't seem to find the files after they are saved
3. it may be that one attachment needs to go to the first recipient, but the remaining attachments need to go the the second recipient, is there a way to handle this?
thanks so much for the help!
- flyingDman
- Posts: 2848
- Joined: 29 Sep 2013, 19:01
Re: working with attachments in outlook
re 1:The script handles any number of attachments.
re 2:Make sure the path is accessible (I used e:\; chose your own)
re 3:The following will send the first attachment to rcpnt1 (^F1) and all the others to rcpnt2 (^F2). This assumes obviously that the order of the attachments remains the same every time a new email is received).
re 2:Make sure the path is accessible (I used e:\; chose your own)
re 3:The following will send the first attachment to rcpnt1 (^F1) and all the others to rcpnt2 (^F2). This assumes obviously that the order of the attachments remains the same every time a new email is received).
Code: Select all
lst := []
olApp := ComObjActive("Outlook.Application")
For olAttachment in olApp.ActiveWindow.CurrentItem.Attachments
{
olAttachment.SaveAsFile("e:\" olAttachment.FileName)
lst.push("e:\" olAttachment.filename)
}
^F1::
{
ol := olApp.CreateItem(0)
ol.To := "rcpnt1@gmail.com"
ol.Subject := "This is the subject"
ol.Body := "Please see attached"
ol.attachments.add(lst[1])
ol.display
}
^F2::
{
ol := olApp.CreateItem(0)
ol.To := "rcpnt2@gmail.com"
ol.Subject := "This is the subject"
ol.Body := "Please see attached"
for x,y in lst
if x > 1
ol.Attachments.Add(lst[x])
ol.display
}
14.3 & 1.3.7
Re: working with attachments in outlook
I may have gone a bit off-topic here. I added a GUI to pick which attachments go where.
To avoid having to save the attachments to disk it forwards the original email twice. Once to each recipient. It removes any attachments that were not selected. It also removes the original body and subject of the email.
The hotkey is Ctrl+F1.
Change the emails at the top of the script. Also, to send the emails instead of displaying them comment out the .Display lines and un-comment the .Send ones:
To avoid having to save the attachments to disk it forwards the original email twice. Once to each recipient. It removes any attachments that were not selected. It also removes the original body and subject of the email.
The hotkey is Ctrl+F1.
Code: Select all
#Requires AutoHotkey v2
#SingleInstance Force
email1 := "someperson@xyz.com"
email2 := "anotherperson@xyz.com"
^F1::OutlookForwardAttachments()
OutlookForwardAttachments() {
if !oItem := OutlookGetMailItem() {
MsgBox "MailItem not selected.", "OutlookForwardAttachments", 0x40
return
}
if !oItem.Sent {
MsgBox "MailItem has not been sent.", "OutlookForwardAttachments", 0x40
return
}
if !oItem.Attachments.Count {
MsgBox "MailItem does not have attachments.", "OutlookForwardAttachments", 0x40
return
}
; Get a list of attachments.
attList := []
for oAtt in oItem.Attachments
attList.Push(oAtt.FileName)
; Make the Gui.
g := Gui()
g.OnEvent("Close", GuiClose)
g.AddText("x10 y10", email1)
g.AddListBox("x10 y+10 r10 w250 vLBEmail1", attList)
g.AddButton("x+10 y50 w50 vButton1", "-->").OnEvent("Click", Button1Click)
g.AddButton("y+10 w50 vButton2", "<--").OnEvent("Click", Button2Click)
g.AddText("x+10 y10", email2)
g.AddListBox("y+10 r10 w250 vLBEmail2")
g.AddButton("x10 y+10 vSend", "Send").OnEvent("Click", SendEmails.Bind(oItem))
g.Show()
}
SendEmails(oItem, GuiCtrlObj, Info) {
g := GuiCtrlObj.Gui
LB1 := g["LBEmail1"], LB2 := g["LBEmail2"]
oNewMail1 := oItem.Forward()
oNewMail1.Subject := "", oNewMail1.Body := ""
oRecip := oNewMail1.Recipients.Add(email1), oRecip.Resolve
oNewMail2 := oItem.Forward()
oNewMail2.Subject := "", oNewMail2.Body := ""
oRecip := oNewMail2.Recipients.Add(email2), oRecip.Resolve
; Remove LB2 attachments from oNewMail1
for i, attName in ControlGetItems(LB2.Hwnd) {
for oAtt in oNewMail1.Attachments
if oAtt.FileName = attName {
oAtt.Delete()
break
}
}
; Remove LB1 attachments from oNewMail2
for i, attName in ControlGetItems(LB1.Hwnd) {
for oAtt in oNewMail2.Attachments
if oAtt.FileName = attName {
oAtt.Delete()
break
}
}
g.Destroy()
oNewMail1.Display
oNewMail2.Display
;oNewMail1.Send
;oNewMail2.Send
}
Button1Click(GuiCtrlObj, Info) {
g := GuiCtrlObj.Gui
LB1 := g["LBEmail1"], LB2 := g["LBEmail2"]
if !LB1.Text
return
LB2.Add([LB1.Text]), LB1.Delete(LB1.Value)
}
Button2Click(GuiCtrlObj, Info) {
g := GuiCtrlObj.Gui
LB1 := g["LBEmail1"], LB2 := g["LBEmail2"]
if !LB2.Text
return
LB1.Add([LB2.Text]), LB2.Delete(LB2.Value)
}
GuiClose(g) {
g.Destroy()
}
; Returns a MailItem object selected in an Explorer or displayed in an Inspector.
; Returns 0 if a MailItem is not found.
OutlookGetMailItem() {
static olExplorer := 34
static olInspector := 35
static olMail := 43
oWin := ComObjActive("Outlook.Application").ActiveWindow
if oWin.Class = olExplorer {
if oWin.ActiveInlineResponse
return oWin.ActiveInlineResponse
oSel := oWin.Selection
if oSel.Count > 0
if oSel.Item(1).Class = olMail
return oSel.Item(1)
}
else if oWin.Class = olInspector
&& oWin.CurrentItem.Class = olMail
return oWin.CurrentItem
return 0
}
Code: Select all
email1 := "someperson@xyz.com"
email2 := "anotherperson@xyz.com"
...
oNewMail1.Display
oNewMail2.Display
;oNewMail1.Send
;oNewMail2.Send
- FanaticGuru
- Posts: 1908
- Joined: 30 Sep 2013, 22:25
Re: working with attachments in outlook
flyingDman wrote: ↑25 Jan 2024, 22:24The files are saved to disk (I do not think they can be sent without first being saved; someone could prove me wrong on that).
One option for copying attachments to a new email without saving the attachments to a file first is to forward the email.
Code: Select all
olApp := ComObjActive("Outlook.Application")
olEmail := olApp.ActiveExplorer.Selection[1] ; get selected email
olEmail := olEmail.Forward ; forward email
olEmail.Body := '' ; remove body
olEmail.Subject := SubStr(olEmail.Subject, 5) ; remove 'FW: ' from beginning of Subject
X := olEmail.Attachments.Count + 1
While --X ; remove embedded attachments
If olEmail.Attachments[X].PropertyAccessor.GetProperty('http://schemas.microsoft.com/mapi/proptag/0x3712001F') ~= '@'
olEmail.Attachments.Remove(X)
while olEmail.Attachments.Count > 1 ; remove all Attachments after first
olEmail.Attachments.Remove(2)
olEmail.Display
This forwards a selected email, then cleans up its subject, deletes the body, deletes all embedded attachments, and deletes all attachments except for the first.
The detecting of embedded attachments is useful for other purposes where you want to save all the attachments in the list without getting all the embedded images that might be in the body of the email.
FG
Edit: Realized since I am removing attachments I need to loop through them backwards to not mess up the index. Also, I am not 100% about the method of detecting if embedded in all environments. All embedded attachments I have tested have a '@' in that property.
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
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
Re: working with attachments in outlook
OMG, you guys are incredible!
Re: working with attachments in outlook
@Datapoint
You rock so hard!!!
this is incredible...is there a way to limit this to pdf attachments only (or attachments over a certain size) because its picking up the signature images and there is no way to remove them.
thanks soooooo much!!!
You rock so hard!!!
this is incredible...is there a way to limit this to pdf attachments only (or attachments over a certain size) because its picking up the signature images and there is no way to remove them.
thanks soooooo much!!!
Re: working with attachments in outlook
Try this. It will only send PDF attachments.
FanaticGuru's suggestion for how to remove embedded attachments would probably work for deleting the signature images too. However, the code below just looks for files that end in "pdf".
FanaticGuru's suggestion for how to remove embedded attachments would probably work for deleting the signature images too. However, the code below just looks for files that end in "pdf".
Code: Select all
#Requires AutoHotkey v2
#SingleInstance Force
email1 := "someperson@xyz.com"
email2 := "anotherperson@xyz.com"
^F1::OutlookForwardAttachments()
OutlookForwardAttachments() {
if !oItem := OutlookGetMailItem() {
MsgBox "MailItem not selected.", "OutlookForwardAttachments", 0x40
return
}
if !oItem.Sent {
MsgBox "MailItem has not been sent.", "OutlookForwardAttachments", 0x40
return
}
if !oItem.Attachments.Count {
MsgBox "MailItem does not have attachments.", "OutlookForwardAttachments", 0x40
return
}
; Get a list of attachments.
attList := []
for oAtt in oItem.Attachments {
; Only add PDF attachments to the list
if SubStr(oAtt.FileName, -3) = "pdf"
attList.Push(oAtt.FileName)
}
; Make the Gui.
g := Gui()
g.OnEvent("Close", GuiClose)
g.AddText("x10 y10", email1)
g.AddListBox("x10 y+10 r10 w250 vLBEmail1", attList)
g.AddButton("x+10 y50 w50 vButton1", "-->").OnEvent("Click", Button1Click)
g.AddButton("y+10 w50 vButton2", "<--").OnEvent("Click", Button2Click)
g.AddText("x+10 y10", email2)
g.AddListBox("y+10 r10 w250 vLBEmail2")
g.AddButton("x10 y+10 vSend", "Send").OnEvent("Click", SendEmails.Bind(oItem))
g.Show()
}
SendEmails(oItem, GuiCtrlObj, Info) {
g := GuiCtrlObj.Gui
LB1 := g["LBEmail1"], LB2 := g["LBEmail2"]
oNewMail1 := oItem.Forward()
oNewMail1.Subject := "", oNewMail1.Body := ""
oRecip := oNewMail1.Recipients.Add(email1), oRecip.Resolve
oNewMail2 := oItem.Forward()
oNewMail2.Subject := "", oNewMail2.Body := ""
oRecip := oNewMail2.Recipients.Add(email2), oRecip.Resolve
; Remove files that are not PDF from the new mail items
for i, oNewMail in [oNewMail1, oNewMail2] {
x := oNewMail.Attachments.Count + 1
while --x
if SubStr(oNewMail.Attachments[x].FileName, -3) != "pdf"
oNewMail.Attachments.Remove(x)
}
; Remove LB2 attachments from oNewMail1
for i, attName in ControlGetItems(LB2.Hwnd) {
for oAtt in oNewMail1.Attachments
if oAtt.FileName = attName {
oAtt.Delete()
break
}
}
; Remove LB1 attachments from oNewMail2
for i, attName in ControlGetItems(LB1.Hwnd) {
for oAtt in oNewMail2.Attachments
if oAtt.FileName = attName {
oAtt.Delete()
break
}
}
g.Destroy()
oNewMail1.Display
oNewMail2.Display
;oNewMail1.Send
;oNewMail2.Send
}
Button1Click(GuiCtrlObj, Info) {
g := GuiCtrlObj.Gui
LB1 := g["LBEmail1"], LB2 := g["LBEmail2"]
if !LB1.Text
return
LB2.Add([LB1.Text]), LB1.Delete(LB1.Value)
}
Button2Click(GuiCtrlObj, Info) {
g := GuiCtrlObj.Gui
LB1 := g["LBEmail1"], LB2 := g["LBEmail2"]
if !LB2.Text
return
LB1.Add([LB2.Text]), LB2.Delete(LB2.Value)
}
GuiClose(g) {
g.Destroy()
}
; Returns a MailItem object selected in an Explorer or displayed in an Inspector.
; Returns 0 if a MailItem is not found.
OutlookGetMailItem() {
static olExplorer := 34
static olInspector := 35
static olMail := 43
oWin := ComObjActive("Outlook.Application").ActiveWindow
if oWin.Class = olExplorer {
if oWin.ActiveInlineResponse
return oWin.ActiveInlineResponse
oSel := oWin.Selection
if oSel.Count > 0
if oSel.Item(1).Class = olMail
return oSel.Item(1)
}
else if oWin.Class = olInspector
&& oWin.CurrentItem.Class = olMail
return oWin.CurrentItem
return 0
}
Last edited by Datapoint on 31 Jan 2024, 18:25, edited 3 times in total.
- FanaticGuru
- Posts: 1908
- Joined: 30 Sep 2013, 22:25
Re: working with attachments in outlook
If you need to work with image files that cannot be separated from embedded images by their extension, here is a AttachmentEmbedded function.
Code: Select all
olApp := ComObjActive("Outlook.Application")
olEmail := olApp.ActiveExplorer.Selection[1] ; get selected email
List := ''
For olAttachment in olEmail.Attachments
If AttachmentEmbedded(olAttachment)
List .= 'Body`t' olAttachment.DisplayName '`n'
else
List .= 'List`t' olAttachment.DisplayName '`n'
MsgBox List
AttachmentEmbedded(olAttachment)
{
If olAttachment.PropertyAccessor.GetProperty('http://schemas.microsoft.com/mapi/proptag/0x3712001F') ~= '@'
Return true
}
It is only one if-statement. I have read that possibly more things need to be checked to be sure but, in my usage, this seems to do the job.
Embedded images are very common in signature blocks, which are actually attachments but typically these want to be ignored in most cases.
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
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
Re: working with attachments in outlook
I just realized I made the exact same mistake, even after I had read FanaticGuru's post. I corrected my script above. Specifically, this part:FanaticGuru wrote: ↑26 Jan 2024, 21:10Realized since I am removing attachments I need to loop through them backwards to not mess up the index.
Code: Select all
; Remove files that are not PDF from the new mail items
for i, oNewMail in [oNewMail1, oNewMail2] {
x := oNewMail.Attachments.Count + 1
while --x
if SubStr(oNewMail.Attachments[x].FileName, -3) != "pdf"
oNewMail.Attachments.Remove(x)
}
...