Encryption when pdf is attached to Outlook Mail - vba

I want to encrypt whenever an attachment with PDF extension is added to mail with Outlook vba.
Is there a way to write such a macro?
Thanky you?

You can handle the MailItem.AttachmentAdd event which is fired when an attachment has been added to an Outlook item. So, you could check the attached file - the Attachment that was added to the item is passed as a parameter and encrypt it if required. For example:
Public WithEvents newItem As Outlook.MailItem
Private Sub newItem_AttachmentAdd(ByVal newAttachment As Attachment)
If newAttachment.Type = olByValue Then
newItem.Save
If newItem.Size > 500000 Then
MsgBox "Warning: Item size is now " & newItem.Size & " bytes."
End If
End If
End Sub
Public Sub TestAttachAdd()
Dim atts As Outlook.Attachments
Dim newAttachment As Outlook.Attachment
Set newItem = Application.CreateItem(olMailItem)
newItem.Subject = "Test attachment"
Set atts = newItem.Attachments
Set newAttachment = atts.Add("C:\Test.txt", olByValue)
End Sub
Note, you can find the cached file on disk. You can find the actual path in the windows registry:

Related

Create a rule that deletes attachments before forwarding

I have been tasked to create an automated report system where an report from Google Data Studios are uploaded to specific projects (On a site called Basecamp). The reports always include both a report within the body of the e-mail and an attached PDF file. The are sent to a Gmail account (data studios refuse to schedule towards a non-Google account). The filters within Gmail doesnt really work well with the Basecamp system so I use filters to re-route them towards a Outlook account. There I use rules to send each e-mail towards the correct client within Basecamp.
Here comes the problem, Basecamp shows both the body of the e-mail AND the attached PDF version which makes us show duplicates.
Is there a way to create a macro that first deletes all attachments (or body of an e-mail) and THEN forward the e-mail.
It cant be done manually it have to be a rule that does it automaticaly. Keep in mind that I am not a coder and have never done anything like this so please keep it simple for my dumb brain!
Thank you in advance!
Marcus
PS: I found a code that seems to be what I am after.
Public WithEvents ReceivedItems As Outlook.Items
Private Sub Application_Startup()
Set ReceivedItems = Outlook.Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub ReceivedItems_ItemAdd(ByVal Item As Object)
Dim xForwardMail As Outlook.MailItem
Dim xEmail As MailItem
On Error Resume Next
If Item.Class <> olMail Then Exit Sub
Set xEmail = Item
If InStrRev(UCase(xEmail.Subject), UCase("kto feature")) = 0 Then Exit Sub 'change subject text to your need
If xEmail.Attachments.Count = 0 Then Exit Sub
Set xForwardMail = xEmail.Forward
With xForwardMail
.HTMLBody = ""
With .Recipients
.Add "skyyang#addin88.com" 'change address to your own
.ResolveAll
End With
.Send
End With
End Sub
I am trying to get that code to work, and changes the subject to a specific word and then route it to a final e-mail account that then filters out to correct clients. However the code doesnt seem to work, it DOES forward the e-mail but the attachment is still there. The code was found at https://www.extendoffice.com/documents/outlook/5359-outlook-forward-attachment-only.html#a1
It seems you need to modify the code slightly:
Public WithEvents ReceivedItems As Outlook.Items
Private Sub Application_Startup()
Set ReceivedItems = Outlook.Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub ReceivedItems_ItemAdd(ByVal Item As Object)
Dim xForwardMail As Outlook.MailItem
Dim xEmail As MailItem
Dim myattachments as Outlook.Attachments
On Error Resume Next
If Item.Class <> olMail Then Exit Sub
Set xEmail = Item
If InStrRev(UCase(xEmail.Subject), UCase("kto feature")) = 0 Then Exit Sub 'change subject text to your need
If xEmail.Attachments.Count = 0 Then Exit Sub
Set xForwardMail = xEmail.Forward
Set myattachments = xForwardMail.Attachments
While myattachments.Count > 0
myattachments.Remove 1
Wend
With xForwardMail
.HTMLBody = ""
With .Recipients
.Add "skyyang#addin88.com" 'change address to your own
.ResolveAll
End With
.Send
End With
End Sub
The Remove method of the Attachments class removes an object from the collection.

How to save Sent Items to folder of SentOnBehalfName mailbox in Office 365?

At work we send emails from Shared Inboxes. The emails would go into the user's own Sent Items instead of that of the Shared Inbox.
I wrote some VBA code which sorted this issue. We are moving to Outlook 365 & the code is not working there.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If TypeName(Item) = "MailItem" Then 'If Item is a MailItem
If Item.SentOnBehalfOfName <> "" Then 'And if Item is Sent on Behalf of an inbox
'Save the sent email in the Sent Items folder for the inbox in question
Item.SaveSentMessageFolder GetNamespace("MAPI").Folders(Item.SentOnBehalfOfName).Folders("Sent Items")
End If
End If
End Sub
I tried
msgbox GetNamespace("MAPI").Folders(Item.SentOnBehalfOfName).Folders("Sent Items").Name
It gives the name of the folder but the Sent Item does not go there.
I created a "Test" folder & saved to the folder ignoring Item.SentOnBehalfOfName & this works if the "Test" folder is in my own inbox but not if it is in a Shared Inbox.
I tried changing the code to use Set & to include Application as per below.
Set Item.SaveSentMessageFolder = Application.GetNamespace("MAPI").Folders(Item.SentOnBehalfOfName).Folders("Sent Items")
You can set a folder from a single store, there is no way to set a folder from another store/account. If you want to get items saved to another store, you must save them first and then move them programmatically to another folder/store.
Also, I'd suggest setting the MailItem.SaveSentMessageFolder property before an item is submitted:
Sub SetSentFolder()
Dim myItem As Outlook.MailITem
Dim myResponse As Outlook.MailITem
Dim mpfInbox As Outlook.Folder
Dim mpf As Outlook.Folder
Set mpfInbox = Application.Session.GetDefaultFolder(olFolderInbox)
Set mpf = mpfInbox.Folders.Add("SaveMyPersonalItems")
Set myItem = Application.ActiveInspector.CurrentItem
Set myResponse = myItem.Reply
myResponse.Display
myResponse.To = "Eugene Astafiev"
Set myResponse.SaveSentMessageFolder = mpf
myResponse.Send
End Sub
In the ThisOutlookSession module add the following variable declaration:
Private WithEvents Items As Outlook.Items
If you don't already have an Application_Startup event procedure create it by selecting Application in the left dropdown over the code area & Startup in the right dropdown over the code area.
The code to add to this procedure:
Set Items = Session.GetDefaultFolder(olFolderSentMail).Items
Then in the left dropdown over the code area you need to select Items & in the right dropdown over the code area select ItemSend.
Below is what this procedure should look like:
Private Sub Items_ItemAdd(ByVal Item As Object)
If TypeName(Item) = "MailItem" Then 'If Item is a MailItem
If Item.SentOnBehalfOfName <> Session.Accounts.Item(1).CurrentUser Then 'And if Item is Sent on Behalf of the users own inbox
'Move the email into the Sent Items folder for the inbox in question
Item.Move GetNamespace("MAPI").Folders(Item.SentOnBehalfOfName).Folders("Sent Items")
End If
End If
End Sub

Outlook Email created in VBA using a template converts to plain text when saved

Below is the code that I am running in ThisOutlookSession. The code is meant to check all incoming emails and if the email is from a certain email address and contains a specific string in the subject then a new email is created from a template and the triggering email is attached and the email is then sent out to a different email address. This portion all works fine.
Also to note I am using windows 10 and office 2016.
The problem that I am having is the email is converted to plain text unless it is displayed first. The template that I have created is saved as a HTML formatted message. I have tried adding lines such as
NewMsg.BodyFormat = olFormatHTML
NewMsg.save
But this doesn't seem to work as the email that is sent was still in the plain text format. If I add the following to that the message it basically works.
NewMsg.BodyFormat = olFormatRichText
NewMsg.save
NewMsg.BodyFormat = olFormatHTML
NewMsg.save
However the above block of code removes a lot of the formatting that was saved in my template such as different fonts/ font sizes.
Am I missing something about working with templates in VBA?
Also The problem that I am having with displaying the message first is two things. The obvious one is the flash that this causes because the message is briefly displayed. The second is my default signature is also added to the displayed message but I wanted to use a custom signature that I built into my template.
Here is my full code with sensitive information removed.
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
' default local Inbox
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
Dim Msg As Outlook.MailItem
Dim NewMsg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
If Msg.SenderEmailAddress <> "example#example.com" Then GoTo Skip
If InStr(1, Msg.Subject, "Specific String") > 0 Then 'checks if subject contains the proper string
Set NewMsg = Application.CreateItemFromTemplate("Template Path")
Msg.Subject = Replace(Msg.Subject, "Old Subject", "New subject")
Msg.Save
NewMsg.HTMLBody = NewMsg.HTMLBody
NewMsg.Attachments.Add Msg
NewMsg.Recipients.Add("Example#Example.com")
NewMsg.Subject = Msg.Subject
NewMsg.Save
NewMsg.Send
End If
End If
Skip:
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
End Sub
Reset the HTMLBody property - that will force HTML format:
Msg.HTMLBody = Msg.HTMLBody

Saving Attachments by Sender address

I want to append the sender address to my attachment filenames.
For example, I get an email from johnsmith#fakeemail.com with the attachment somespreadsheet.xls.
I'd like to automatically save that file as somespreadsheet.johnsmith.xls (or any variation of that filename will work).
I receive about 200 of these spreadsheets a day, but they are all named the same, somespreadsheet.xls, and I am looking for a faster/easier way to get them all pulled from my emails while maintaining who sent them to me.
The Attachment class from the Outlook object model provides the SaveAsFile method which allows to specify the filename.
Sub SaveAttachment()
Dim myInspector As Outlook.Inspector
Dim myItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
Set myInspector = Application.ActiveInspector
If Not TypeName(myInspector) = "Nothing" Then
If TypeName(myInspector.CurrentItem) = "MailItem" Then
Set myItem = myInspector.CurrentItem
Set myAttachments = myItem.Attachments
'Prompt the user for confirmation
Dim strPrompt As String
strPrompt = "Are you sure you want to save the first attachment in the current item to the Documents folder? If a file with the same name already exists in the destination folder, it will be overwritten with this copy of the file."
If MsgBox(strPrompt, vbYesNo + vbQuestion) = vbYes Then
myAttachments.Item(1).SaveAsFile Environ("HOMEPATH") & "\My Documents\" & _
myAttachments.Item(1).DisplayName
End If
Else
MsgBox "The item is of the wrong type."
End If
End If
End Sub
As you may see the DisplayName property of the Attachment class is used for specifying the file name. So you may combine it with the Sender* related properties of the MailItem class - see SenderName and SenderEmailAddress properties.

Read body of email with attachment using VBA in Outlook

I have some VBA that checks the subject of every message as soon as it hits my inbox, and submits certain emails' contents over http to a server for processing.
This works great for messages with no attachments, but fails if there is an attachment on the email. I am using a http GET to submit the text.
What is the effect of the presence of an attachment on the body property of the message, and how can I ignore the attachment and submit only the email body text?
The VBA (trimmed for clarity but complete and functional):
Declarations:
Option Explicit
Private WithEvents olInboxItems As Items
On startup:
Private Sub Application_Startup()
Set olInboxItems = Session.GetDefaultFolder(olFolderInbox).Items
End Sub
On item added to inbox:
Private Sub olInboxItems_ItemAdd(ByVal Item As Object)
On Error Resume Next
Dim olMailItem As MailItem
Dim strAttachmentName As String
Dim submitResult As String
If TypeOf Item Is MailItem Then
Set olMailItem = Item
If ((InStr(olMailItem.subject, "test subject") > 0)
Dim subject As String
subject = olMailItem.subject
Dim contents As Variant
contents = olMailItem.body
Dim submitURL As String
submitURL = "http:// ... " & subject & "..." & contents & "..."
XMLHttpSynchronous submitURL
End If
End If
Set Item = Nothing
Set olMailItem = Nothing
End Sub
Http submit:
Sub XMLHttpSynchronous(ByVal URL As String)
Dim XMLHttpRequest As XMLHTTP
Set XMLHttpRequest = New MSXML2.XMLHTTP
XMLHttpRequest.Open "GET", URL, False
XMLHttpRequest.Send
End Sub
edit: I am now stripping attachments with the below code (tested and working) but the url still isn't submitting correctly.
Set myattachments = olMailItem.Attachments
While myattachments.Count > 0
myattachments.Remove 1
Wend
edit 2: I set contents=subject and the url submitted correctly, still no luck with the email's body, even after the message has been stripped of attachments
In order to get this working I stripped the attachments with the code in my first edit, than split the string of the body's text around the first and last character. I'm not sure why this works