How can I automatically send email from Thunderbird with Excel VBA? - vba

What I want to do is send an email from a Thunderbird account automatically. The user shouldn't even have to hit the Send button of the email.
I've tried using CDO, but the problem with it is that you have to input the username and password of the account you are sending from. This macro will be used from several different accounts, so inputting each username and password isn't feasible. I could use CDO if there was someway of retrieving the username, password, and smtp server from Thunderbird, but I feel like the code I already have should be able to accomplish this without CDO (hopefully).
Here is really the only code I see (and it's everywhere) in regards to accomplishing this.
Sub Thunderbird()
Dim thund As String
Dim email As String
Dim cc As String
Dim bcc As String
Dim subj As String
Dim body As String
email = "email#test.com"
cc = "cc#test.com"
bcc = "bcc#test.com"
subj = "Subject"
body = "body text"
thund = "C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe"
thund = thund & " -compose " & Chr$(34) & "mailto:" & email & "?"
thund = thund & "cc=" & Chr$(34) & cc & "?"
thund = thund & "bcc=" & Chr$(34) & bcc & "?"
thund = thund & "subject=" & Chr$(34) & subj & Chr$(34)
thund = thund & "body=" & Chr$(34) & body
Call Shell(thund, vbNormalFocus)
SendKeys "^+{ENTER}", True
End Sub
As of right now, the fields cc, bcc, subj, and body are all recognized correctly. The problem is they all get added to the end of the first field. For instance, with the way the code is right now, cc will get put in the cc field, but bcc, subj, and body all get appended to cc in the cc field of Thunderbird.
If I comment cc out, then bcc is put in the correct field, but subj and body get appended to bcc in the bcc field of Thunderbird.
If I comment cc and bcc out, then subj gets put in the correct field, but body gets appended to subj in the subject field of Thunderbird.
So basically I need to add the correct code at the end of each of these lines. I've tried both "?" and Chr$(34) to no avail.
Lastly, SendKeys "^+{ENTER}", True isn't working at all. This might be because of all the parameters not being put in the correct field of Thunderbird, but not sure since I can't get that working. Email from Thunderbird displays, but this code isn't sending the email like it's supposed to.
SOLUTION (as provided by #zedfoxus)
Sub Thunderbird()
Dim thund As String
Dim email As String
Dim cc As String
Dim bcc As String
Dim subj As String
Dim body As String
email = "email#test.com"
cc = "cc#test.com"
bcc = "bcc#test.com"
subj = "Subject"
body = "body text"
thund = "C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe" & _
" -compose " & """" & _
"to='" & email & "'," & _
"cc='" & cc & "'," & _
"bcc='" & bcc & "'," & _
"subject='" & subj & "'," & _
"body='" & body & "'" & """"
Call Shell(thund, vbNormalFocus)
Application.Wait (Now + TimeValue("0:00:03"))
SendKeys "^{ENTER}", True
End Sub

You were pretty close. Try this:
Public Sub SendEmail()
Dim thund As String
Dim email As String
Dim cc As String
Dim bcc As String
Dim subj As String
Dim body As String
email = "test#test.com"
cc = "test#test.com"
bcc = "test#test.com"
subj = "Testing"
body = "Testing"
thund = "C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe " & _
"-compose " & """" & _
"to='" & email & "'," & _
"cc='" & cc & "'," & _
"bcc='" & bcc & "'," & _
"subject='" & subj & "'," & _
"body='" & body & "'" & """"
Call Shell(thund, vbNormalFocus)
SendKeys "^+{ENTER}", True
End Sub
Notice the example from http://kb.mozillazine.org/Command_line_arguments_(Thunderbird).
thunderbird -compose "to='john#example.com,kathy#example.com',cc='britney#example.com',subject='dinner',body='How about dinner tonight?',attachment='C:\temp\info.doc,C:\temp\food.doc'"
The example indicates that after -compose we should use type our information in double-quotes. Each parameter is separated by comma. Nomenclature is parameter='value[,value]' [,parameter='value[,value]]....

Related

Generate email body with values from MS Access userform

I created a form and would like to send an email using a button capturing data from the sub-form (based on a query).
I am using this YouTube video as a guide and get stuck (starting from msg =....
Private Sub cmd_EmailContact_Click()
Dim Msg As String
msg = "Dear " & First name & ",<P>" & _
Student First name & "has been successfully been loaded on the platform" & ",<P>" & _
"Student login details on the platform are:" & ",<P>" & _
"Username:" & Username & ",<P>" & _
"Password:" & Password**
Dim O As Outlook.Application
Dim M As Outlook.MailItem
Set O = New Outlook.Application
Set M = O.CreateItem(olMailItem)
With M
.BodyFormat = olFormatHTML
.HTMLBody = Msg
.To = Email
.Subject = "Student available on OARS"
.Display
End With
Set M = Nothing
Set O = Nothing
End Sub
Variables are populated on a query on the form.
First name (Name of teacher)
Student First name
Username
Password
To send the email as HTML, you will need to format the body with HTML tags and set the HTMLBody property of the olMailItem (email) as shown below.
The example uses late binding (no reference to Outlook needed) which means it can run with different versions of outlook installed.
Private Sub cmd_EmailContact_Click()
Dim firstName As String, _
studentFirstName As String, _
userName As String, _
password As String, _
email As String, _
body_ As String
'provide values
firstName = "ABC"
studentFirstName = "XYZ"
userName = "User"
password = "Pass"
email = "foo#bar.com"
'build body
body_ = "<p> Dear" & firstName & ", </p>" _
& "<p>" & studentFirstName & " has been successfully been loaded on the platform. </p>" _
& "<p> Student login details on the platform are: </p>" _
& "<p> Username: " & userName & "</p>" _
& "<p> Password: " & password & "</p>"
'send email
With CreateObject("Outlook.Application")
With .CreateItem(0) 'olMailItem
.BodyFormat = 2 'olFormatHTML
.To = email
.Subject = "Student available on OARS"
.HTMLBody = "<html><head></head><body>" & body_ & "</body></html>"
.Display
End With
End With
End Sub
You will need to provide values for the following variables:
FirstName
StudentFirstName
UserName
Password
Email

Sending meeting requests using ical through outlook

Here is my dilemma. I have a vb.net application for requesting time using an asset. The user submits a request (can contain required and optional users), then an approver has to approve it. When it is approved, I want to send a meeting request. I can't do it using outlook code since it won't let me change the organizer. If I try to send it using outlook.application > outlook.olitemtype.olappointmentitem or whatever it is, it will default the organizer to the person sending the meeting request, which in this case is the approver, which I don't want. So I think I am left with trying to send an ical. This is where I am having issues. I can't use smtpclient to create the email and send it using the proper content-type, etc. I have to send it using outlook. So I create an ics file and add it as an attachment. I am not sure the difference between METHOD:PUBLISH and METHOD:REQUEST. All the searches I've have done say I should use method:request, but when i open the ICS file, it doesn't give me the options to accept, etc. It doesn't add to my calendar. I want the ability to be able to update and cancel the meeting as well, which I think I know how to do with uid, sequence, etc. I've done searches and just can't get to where I need to be. It looks like the best option is to use smtpclient to create the mail message where you add the headers and ical stuff, but I can't do that, is there a way to it using outlook?
If someone can help point me in the right direction, I would greatly appreciate it.
Here is my current code:
Dim msg As MailMessage = New MailMessage
msg.From = New MailAddress(br.requesting_user_email)
msg.To.Add(New MailAddress(br.requesting_user_email))
msg.Subject = variables.UserInfo.last_name & ", " + variables.UserInfo.first_name & " has approved your request through the Bench Scheduler."
Dim bodytxt As String = "User: " & variables.UserInfo.last_name & ", " + variables.UserInfo.first_name & vbLf & "5+2: " + variables.UserInfo.username & vbLf & vbLf
bodytxt += "Has approved your bench request for " & br.program_name & " - " & br.project_name & "." & vbLf & vbLf
bodytxt += "Start: " & br.start_time & vbLf & "End: " & br.end_time & vbLf
bodytxt += "Bench: " & br.bench_name & vbLf & "Priority: " & br.priority & vbLf & "Purpose: " & br.objective & vbLf & vbLf
bodytxt += "Request Notes: " & br.notes & vbLf & vbLf
bodytxt += vbLf & vbLf & vbLf & "This email was automatically generated by Bench Scheduler. You may respond to this email."
msg.Body = bodytxt
Dim str As StringBuilder = New StringBuilder
str.AppendLine("BEGIN:VCALENDAR")
str.AppendLine("PRODID:-//Microsoft Corporation//Outlook 15.0 MIMEDIR//EN")
str.AppendLine("VERSION:2.0")
If cancel Then
str.AppendLine("METHOD:CANCEL")
Else
str.AppendLine("METHOD:REQUEST")
End If
str.AppendLine("BEGIN:VEVENT")
str.AppendLine("X-MS-OLK-FORCEINSPECTOROPEN:TRUE")
str.AppendLine("BEGIN:VTIMEZONE")
str.AppendLine("TZID:Eastern Standard Time")
str.AppendLine("BEGIN:STANDARD")
str.AppendLine("DTSTART:16011104T020000")
str.AppendLine("RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11")
str.AppendLine("TZOFFSETFROM:-0400")
str.AppendLine("TZOFFSETTO:-0500")
str.AppendLine("END:STANDARD")
str.AppendLine("BEGIN:DAYLIGHT")
str.AppendLine("DTSTART:16010311T020000")
str.AppendLine("RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3")
str.AppendLine("TZOFFSETFROM:-0500")
str.AppendLine("TZOFFSETTO:-0400")
str.AppendLine("END:DAYLIGHT")
str.AppendLine("END:VTIMEZONE")
Dim dt As New DataTable
Dim ta As New BSDataSetTableAdapters.getUserRequestTableAdapter
dt = ta.GetData(br.request_id, "T")
For Each row As DataRow In dt.Rows
If row("type") = "Required" Then
str.AppendLine(String.Format("ATTENDEE;CN='{0}';RSVP=TRUE:mailto:{1}", row("username"), row("email")))
ElseIf row("type") = "Optional" Then
str.AppendLine(String.Format("ATTENDEE;CN='{0}';ROLE=OPT-PARTICIPANT;RSVP=TRUE:mailto:{1}", row("username"), row("email")))
End If
Next
str.AppendLine("CLASS:PUBLIC")
str.AppendLine("CREATED:" & Format(Date.Now, "yyyyMMddTHHmmssZ"))
str.AppendLine(String.Format("DESCRIPTION:{0}", br.objective))
str.AppendLine("DTEND;TZID=" & """" & "Eastern Standard Time" & """" & ":" & Format(CDate(br.end_time), "yyyyMMddTHHmmss"))
str.AppendLine("DTSTAMP:" & Format(Date.Now, "yyyyMMddTHHmmssZ"))
str.AppendLine("DTSTART;TZID=" & """" & "Eastern Standard Time" & """" & ":" & Format(CDate(br.start_time), "yyyyMMddTHHmmss"))
str.AppendLine(String.Format("LOCATION:{0}", br.bench_name))
str.AppendLine(String.Format("ORGANIZER;CN='" & br.requesting_username & "':mailto:" & br.requesting_user_email))
str.AppendLine("PRIORITY:5")
str.AppendLine("SEQUENCE:0")
str.AppendLine(String.Format("SUMMARY;LANGUAGE=en-us:{0}", "Approved Bench Request (ID-" & br.request_id & "): " & br.program_name & "-" & br.project_name & "-" & br.activity))
str.AppendLine("TRANSP:OPAQUE")
str.AppendLine(String.Format("UID:{0}", br.uid))
str.AppendLine(String.Format("X-ALT-DESC;FMTTYPE=text/html:{0}", br.objective))
str.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:BUSY")
str.AppendLine("X-MICROSOFT-CDO-IMPORTANCE:1")
str.AppendLine("X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY")
str.AppendLine("X-MICROSOFT-DISALLOW-COUNTER:FALSE")
str.AppendLine("X-MS-OLK-AUTOFILLLOCATION:FALSE")
str.AppendLine("X-MS-OLK-CONFTYPE:0")
str.AppendLine("BEGIN:VALARM")
str.AppendLine("TRIGGER:-PT30M")
str.AppendLine("ACTION:DISPLAY")
str.AppendLine("DESCRIPTION:Reminder")
str.AppendLine("END:VALARM")
str.AppendLine("END:VEVENT")
str.AppendLine("END:VCALENDAR")
Dim smtpclient As SmtpClient = New SmtpClient
smtpclient.Host = "replaced for privacy"
smtpclient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials
Dim contype As System.Net.Mime.ContentType = New System.Net.Mime.ContentType("text/calendar")
contype.Parameters.Add("method", "REQUEST")
contype.Parameters.Add("name", "Meeting.ics")
Dim avcal As AlternateView = AlternateView.CreateAlternateViewFromString(str.ToString, contype)
msg.AlternateViews.Add(avcal)
smtpclient.Send(msg)

How to improve this VBA code to add Carbon Copy into it

I am trying to improve my code my from previous post Predetermine the cells with the data to send emails to put some Carbon Copy (CC) on the line code. What I am trying to figure out is that there are some companies that might be my CC's, that depends of the type of email I want to send.
Example: I created 2 lists of CC emails That I might wanna send emails.
In front of the company's name I Concatenate all the emails from the list to only one cell.
How can I put this into the code that I can choose the name of the company and all the emails from that company goes to the CC list?
Thank you one more time for all the helping you guys are giving me.
I am going to copy the code from the previous post just to be easier to read:
Sub SendEMail()
'update by Extendoffice 20160506
Dim xEmail As String
Dim xSubj As String
Dim xMsg As String
Dim xURL As String
Dim i As Integer
Dim k As Double
Dim xCell As Range
Dim xRg As Range
Dim xTxt As String
On Error Resume Next
xTxt = ActiveWindow.RangeSelection.Address
Set xRg = Range("A2:C6")
If xRg Is Nothing Then Exit Sub
For i = 1 To xRg.Rows.Count
' Get the email address
xEmail = xRg.Cells(i, 2)
' Message subject
xSubj = "Your Registration Code"
' Compose the message
xMsg = ""
xMsg = xMsg & "Dear " & xRg.Cells(i, 1) & "," & vbCrLf & vbCrLf
xMsg = xMsg & " This is your Registration Code "
xMsg = xMsg & xRg.Cells(i, 3).Text & "." & vbCrLf & vbCrLf
xMsg = xMsg & " please try it, and glad to get your feedback! " & vbCrLf
xMsg = xMsg & "Skyyang"
' Replace spaces with %20 (hex)
xSubj = Application.WorksheetFunction.Substitute(xSubj, " ", "%20")
xMsg = Application.WorksheetFunction.Substitute(xMsg, " ", "%20")
' Replace carriage returns with %0D%0A (hex)
xMsg = Application.WorksheetFunction.Substitute(xMsg, vbCrLf, "%0D%0A")
' Create the URL
xURL = "mailto:" & xEmail & "?subject=" & xSubj & "&body=" & xMsg
' Execute the URL (start the email client)
ShellExecute 0&, vbNullString, xURL, vbNullString, vbNullString, vbNormalFocus
' Wait two seconds before sending keystrokes
Application.DisplayKeys "%s"
Next
End Sub
1-In your code after:
If xRg Is Nothing Then Exit Sub
insert:
Dim CCCompany As Integer
Dim ccstr As String
ccstr = FindMyCompany()
If ccstr = vbNullString Then
CCCompany = MsgBox("No cc email selected. Are you sure you want to proceed?", vbYesNo + vbQuestion, "To be or not to be")
If CCCompany = vbYes Then
xCC = ""
Else
Exit Sub
End If
Else
xCC = "&cc=" & ccstr
End If
2-Then replace:
xURL = "mailto:" & xEmail & "?subject=" & xSubj & "&body=" & xMsg
with:
xURL = "mailto:" & xEmail & "?subject=" & xSubj & xCC & "&body=" & xMsg
3-Finally add below function after your sub:
Function FindMyCompany() As String
Dim rng As Range
Dim i As Long
Dim xCC As String
Application.DisplayAlerts = False
Set rng = Application.InputBox("Select desired Company column or any cell in that column", _
"Get Company Column", Type:=8)
Application.DisplayAlerts = True
i = 1
Do Until IsEmpty(Cells(i, rng.Column))
Set crng = Cells(i, rng.Column)
If InStr(crng.Value, "#") Then
xCC = xCC & crng.Value & ";"
End If
i = i + 1
Loop
FindMyCompany = Left(xCC, Len(xCC) - 1)
End Function
4-Allocate your Companies along with email addresses to different columns as shown below. You can set as many company as you need this way.
5-When you run your code, simply select your desired company cell and click ok.
Important note: You can select the whole column, a range of cells from desired column or a single cell in the desired column. Your code will still work since it extracts only column number from your selection.
Edit: If you want to repeat this process for selecting bcc emails, right after selecting ccs, you can use the same function with different assignment like this:
Dim CCCompany As Integer
Dim ccstr As String
Dim bccstr As String
ccstr = FindMyCompany()
bccstr = FindMyCompany()
If ccstr = vbNullString Then
CCCompany = MsgBox("No cc email selected. Are you sure you want to proceed?", vbYesNo + vbQuestion, "To be or not to be")
If CCCompany = vbYes Then
xCC = ""
Else
Exit Sub
End If
Else
xCC = "&cc=" & ccstr
End If
If bccstr = vbNullString Then
BCCCompany = MsgBox("No cc email selected. Are you sure you want to proceed?", vbYesNo + vbQuestion, "To be or not to be")
If BCCCompany = vbYes Then
xBCC = ""
Else
Exit Sub
End If
Else
xBCC = "&bcc=" & bccstr
End If
and amend your xURL like this
xURL = "mailto:" & xEmail & "?subject=" & xSubj & xCC & xBCC & "&body=" & xMsg
The short answer (albeit somewhat janky) might be to:
Make Column D you "cc" column which will point to the concatenated value of the cc's (C10)
make an xCC = xRg.Cells(i, 4)
make xURL = "mailto:" & xEmail & "?subject=" & xSubj & "&body=" & xMsg & "&cc=" & xCC
I do want to point out that this is prone to becoming a mess, but it should solve your immediate need.
I would recommend the solution below for a better approach:
Create 2 new columns (let's say J and K). J will hold the Name of the companies, (like XCCompany) and K will hold a single email address corresponding to the company. In your example you would do this three times for each company (since they both have three cc's and end up with six records) -- the company name will be the same for three but the email addresses will be different. We want the company names to be the same so that we can search on them.
ADDITIONALLY, in column D you can store the name of the company to CC (XCCompany) and when you press the button the macro will lookup email addresses that correspond to the company name (using the info in J and K), concatenate them, and put them as cc's. I found a nifty little UDF function that does this http://www.excelfox.com/forum/showthread.php/345-LookUp-Value-and-Concatenate-All-Found-Results.
If you wanted to take this approach, declare the function in a module (maybe under your SendEmail function) and instead of setting xCC as indicated above, set it as indicated below (make sure to keep the changes to xURL):
xCC = LookUpConcat(xRg.Cells(i, 4), Range("J2:J100"), Range("K2:K100"), ";")
(Note I only went up to K100 and J100 for performance issues, your list could grow longer and if so, you would want to adjust accordingly.)
Good Luck!

Run Script to Append Subject and Body of Email

I am [attempting to] learn how to write a script in Outlook that when a certain category is set on an email:
Append the Subject with " PROJ=5"
Append the Body with about 10 lines of text
Send email.
My goal is to mark an email with a category and forward the email to our ticketing system.
I'm not really having any luck with the samples I have found.
Samples (URL) I have tried (Copied code and updated relevant fields):
slipstick.com
social.technet.microsoft.com
Append the Subject with " PROJ=5"
MailItem.Subject Property Returns a String indicating Outlook item. Read/write.
Example
Item.Subject = "PROJ=5" & Item.Subject
Append the Body with about 10 lines of text
Example
Dim olBody As String
olBody = "<HTML><BODY><P>Append the Body with about 10 lines of text</P>" & vbNewLine & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P></HTML></BODY>" & vbNewLine
olForward.HTMLBody = olBody & vbCrLf & olForward.HTMLBody
Send / Forward Email
Example
'//
Set olForward = Item.Forward
'// add Recipent
olForward.Recipients.Add "email#domain.com"
'// Send or your use .Dispaly
olForward.Send
Run a Script Rule
To use Rule Wizard, your macro has to have the expected parameter:
Example
Public Sub ItemForward(Item As Outlook.MailItem)
End Sub
Helpful article in MSDN Outlook 2010 VBA
Complete Code Test on Outlook 2010 VBA
Please make sure your References are set to run action script (Tools > References)
Option Explicit
'// Run Action Script
Public Sub ItemForward(Item As Outlook.MailItem)
Dim olApp As Outlook.Application
Dim olForward As MailItem
Dim olBody As String
Set olApp = CreateObject("Outlook.Application")
'// Append the Subject
Item.Subject = "PROJ=5 " & Item.Subject
Item.Save
Set olForward = Item.Forward
'// add Recipent
olForward.Recipients.Add "Test#mail.com"
olBody = "<HTML><BODY><P>Append the Body with about 10 lines of text</P>" & vbNewLine & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P></HTML></BODY>" & vbNewLine
'// Forward Email
olForward.HTMLBody = olBody & vbCrLf & olForward.HTMLBody
'// Send or your use .Dispaly
olForward.Send
Set olApp = Nothing
Set olForward = Nothing
End Sub

My outlook VBA code drops the odd email

I put together some VBA code for Outlook 2007 which has been working predominantly fine.
Its basically designed to check incoming messages and store the subject, body etc into a database and the attachment into a folder. In general, it works fine, but out of 100 messages or so, it drops the odd email.
I previously had a problem where some emails were not being processed and stored in the database, but then discovered there was an issue with illegal characters, which i have solved now, so that cant be it. I've compared the emails being dropped to the one's that arent, in terms of message header, content to and from fields and i cant see any difference between the two emails at all, so am completely perplexed as to why they're being dropped. When i copy the content of the email and forward it back to the system again, the VBA code processes it fine.
I am pasting the code below (the code links to some modules which are used for checking illegal characters or concatenating strings)
Sub SaveIncomingEmails(Items As Outlook.MailItem) ' enable this to run macro inbound emails
Dim cnn As ADODB.Connection
Set cnn = New ADODB.Connection
' ================================================================
' Open a Connection using an ODBC DSN named "Delphi".
' ================================================================
cnn.Open "MyDB", "MyUsername", "MyPassword"
' ================================================================
' Constants declaration
' ================================================================
Const olFolderInbox = 6
Const olTxt = 0
' ================================================================
' variable declaration
' ================================================================
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim SenderName As String
Dim i As Integer
Dim strSQLquery As String
Dim strSQLquery1 As String
Dim strSQLGTDResourceQuery As String
Dim MessageHeader As String
Dim strCommandQuery As String
Dim strGTDIdQuery As String
Dim AttachmentStr As String
Dim strFailedRcp As String
Dim strSubject As String
Dim hasattachment As String
Dim AttachmentType As String
Dim SenderAuthorised As String
Dim strToEmail As String
Dim strFromEmail As String
Dim strBody As String
Dim strSentDate As String
Dim strReceivedDate As String
Dim StrUniqueID As String
Dim strCommandDate As String
Dim strDomain As String
Dim strBodyStripped As String
Dim strSubjectStripped As String
Dim rs As Object
Dim strGoalId As String
Dim strFile As String
Dim strSenderAccountDescription As String
Dim strContentType As String
Dim strMimeVersion As String
Dim strReceived As String
' ================================================================
' Intializing variables
' ================================================================
i = 0
Set objItem = Items
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
Set colMailItems = objFolder.Items
Set Item = objItem
strToEmail = Items.To
strFromEmail = Items.SenderEmailAddress
strSubject = Items.Subject
strBody = Items.Body
strSentDate = Items.SentOn
strReceivedDate = Items.ReceivedTime
'Initialize variables in a given format
StrUniqueID = Format(Items.ReceivedTime, "ddmmyyyyhhnnss") & Items.SenderEmailAddress
strCommandDate = Format(Items.ReceivedTime, "mm/dd/yyyy_hh:nn:ss")
' Grab the sender domain by stripping the last portion of the email address using the getdomain function
strDomain = Module2.GetDomain(Items.SenderEmailAddress)
' Strip the body of illegal characters and replace with legal characters for insertion into SQL
strBodyStripped = Module3.RemoveIllegalCharacters(Items.Body)
strSubjectStripped = Module4.RemoveIllegalCharacters(Items.Subject)
AttachmentStr = "images/no_attachment.png"
' ================================================================
' ================================================================
' ================================================================
' =====================================================
' Check list of authorised senders for xsCRM commands.
' Populate email addresses here
' =====================================================
If (InStr(strFromEmail, "AuthorisedSender1#email.com") > 0) Or (InStr(strFromEmail, "AuthorisedSender2#email.com") > 0) Or (InStr(strFromEmail, "AuthorisedSender3#email.com") > 0) Then
SenderAuthorised = "true"
End If
' ======================================================
' ======================================================
' ======================================================
' ================================================================
' check if subject holds a command
' ================================================================
'check to see if email sender is authorised
If SenderAuthorised = "true" Then
' Check if the subject line contains the string xs4crm is true
If InStr(strSubject, "xs4crm") > 0 Then
'If its true then do this
strCommandQuery = "INSERT INTO XSCRMEMAILCOMMAND (" & vbCrLf & _
"FromEmail," & vbCrLf & _
"command," & vbCrLf & _
"date," & vbCrLf & _
"Body" & vbCrLf & _
") VALUES ('" & strFromEmail & "','" & strSubject & "',GETDATE(),'" & strBody & "')"
Set rs = cnn.Execute(strCommandQuery)
'Look for a GTDID string so that we can save data to resources table
If InStr(strSubject, "gtdid=") > 0 Then
'Set the hasattachment variable to zero since we only want to run this loop if there are no attachments
hasattachment = "0"
'Set the variable to 1 so that we that our next if statement can only run if there are no attachments
For Each Atmt In Item.Attachments
hasattachment = "1"
Next Atmt
If hasattachment = "0" Then
'Grab the GTDId so we know which goal this resource belongs too.
strGoalId = Module5.GetHeaderProperty(strSubject, "gtdid=", ";", 5)
'Save data to table
strGTDIdQuery = "INSERT INTO XSCRMGTDRESOURCES (" & vbCrLf & _
"GoalId," & vbCrLf & _
"insertdatetime" & vbCrLf & _
") VALUES ('" & strGoalId & "',GETDATE())"
Set rs = cnn.Execute(strGTDIdQuery)
End If
End If
End If
End If
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' Create folders for atttachments
' ================================================================
' Save any attachments found
For Each Atmt In Item.Attachments
AttachmentStr = "images/attachment.png" 'because it has gone into attachment loop the icon is now required.
'Create the subfolder for the attachment if it doesnt exist based on sender domain
Dim fso
Dim fol As String
fol = "c:\OLAttachments\" & strDomain
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(fol) Then
fso.CreateFolder (fol)
End If
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' save attachments
' ================================================================
FileName = "C:\OLAttachments\" & strDomain & "\" & _
Format(Item.CreationTime, "ddmmyyyy-") & Items.SenderEmailAddress & "-" & Atmt.FileName
Atmt.SaveAsFile FileName
i = i + 1
strFile = Atmt.FileName
strSQLquery1 = "INSERT INTO XSCRMEMAILSATTACHMENTS (" & vbCrLf & _
"FileSavedIn," & vbCrLf & _
"ActualFileName," & vbCrLf & _
"UniqueIdentifier," & vbCrLf & _
"SendersEmail" & vbCrLf & _
") VALUES ('" & FileName & "','" & StrUniqueID & "','" & strFile & "','" & strFromEmail & "')"
Set rs = cnn.Execute(strSQLquery1)
'If there is a GTDCommand, then grab the GTDId so we know which goal this resource belongs too.
If InStr(strSubject, "gtdid=") > 0 Then
strGoalId = Module5.GetHeaderProperty(strSubject, "gtdid=", ";", 5)
End If
AttachmentType = ""
'If the attachment is png or jpg set attachment type string to image
If (InStr(Atmt.FileName, ".png") > 0) Or (InStr(Atmt.FileName, ".jpg") > 0) Then
AttachmentType = "image"
End If
'If attachment is .mov set attachment type string to video
If InStr(Atmt.FileName, ".mov") > 0 Then
AttachmentType = "video"
End If
'If the attachment is mp3 or m4a set attachment type string to audio
If (InStr(Atmt.FileName, ".mp3") > 0) Or (InStr(Atmt.FileName, ".m4a") > 0) Then
AttachmentType = "audio"
End If
'check to see if email sender is authorised
If SenderAuthorised = "true" Then
'If attachment type is an image, audio or video as per extensions above then populate the xscrmgtdresource table with following fields
If (InStr(Atmt.FileName, ".png") > 0) Or (InStr(Atmt.FileName, ".jpg") > 0) Or (InStr(Atmt.FileName, ".mov") > 0) Or (InStr(Atmt.FileName, ".m4a") > 0) Or (InStr(Atmt.FileName, ".mp3") > 0) Then
strSQLGTDResourceQuery = "INSERT INTO XSCRMGTDRESOURCES (" & vbCrLf & _
"GoalId," & vbCrLf & _
"Title," & vbCrLf & _
"Type," & vbCrLf & _
"insertdatetime," & vbCrLf & _
"ResourcePath," & vbCrLf & _
"UniqueIdentifier" & vbCrLf & _
") VALUES ('" & strGoalId & "','" & Atmt.FileName & "','" & AttachmentType & "',GETDATE(),'" & FileName & "','" & StrUniqueID & "')"
End If
Set rs = cnn.Execute(strSQLGTDResourceQuery)
End If
Next Atmt
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' Setting up to work with the Email Message Header
' ================================================================
'This accesses the message header property and sets the variable MessageHeader
Const PR_TRANSPORT_MESSAGE_HEADERS = "http://schemas.microsoft.com/mapi/proptag/0x007D001E"
MessageHeader = objItem.PropertyAccessor.GetProperty(PR_TRANSPORT_MESSAGE_HEADERS)
If MessageHeader <> "" Then
End If
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' Accessing the message header and collecting specific info for database tables
' ================================================================
strSenderAccountDescription = Module5.GetHeaderProperty(MessageHeader, "From:", "<", 5)
strContentType = Module5.GetHeaderProperty(MessageHeader, "Content-Type:", ";", 13)
strMimeVersion = Module5.GetHeaderProperty(MessageHeader, "MIME-Version:", vbNewLine, 13)
strReceived = Module5.GetHeaderProperty(MessageHeader, "Received:", "(", 9)
'As the x-failed-recipients property does not appear in ALL messageheaders, we have to first check if it is present
If InStr(MessageHeader, "X-Failed-Recipients:") > 0 Then
'Get the MessageHeader Property value
strFailedRcp = Module5.GetHeaderProperty(MessageHeader, "X-Failed-Recipients:", vbNewLine, 20)
'Else set the variable value to blank so that we still have something to supply to the SQL query
Else
strFailedRcp = ""
End If
' ================================================================
' ================================================================
' ================================================================
' ================================================================
' Save Email into the database DeplphiDude and table xsCRMEmails for attachment based emails and without attachments
' ================================================================
If InStr(strSubject, "xs4crm") = 0 Then 'only insert if the emails is not a command
strSQLquery = "INSERT INTO XSCRMEMAILS (" & vbCrLf & _
"XFailedRecipients," & vbCrLf & _
"Received," & vbCrLf & _
"MimeVersion," & vbCrLf & _
"ContentType," & vbCrLf & _
"SendersAccountDescription," & vbCrLf & _
"FromEmail," & vbCrLf & _
"ToEmail," & vbCrLf & _
"Subject," & vbCrLf & _
"Body," & vbCrLf & _
"SentDate," & vbCrLf & _
"ReceivedDate," & vbCrLf & _
"UniqueIdentifier," & vbCrLf & _
"Status," & vbCrLf & _
"AttachmentIcon," & vbCrLf & _
"AssignedToUser," & vbCrLf & _
"EmailHeader" & vbCrLf & _
") VALUES ('" & strFailedRcp & "','" & strReceived & "','" & strMimeVersion & "','" & strContentType & "','" & strSenderAccountDescription & "', '" & strFromEmail & "','" & strToEmail & "','" & strSubjectStripped & "','" & strBodyStripped & "','" & strSentDate & "','" & strReceivedDate & "','" & StrUniqueID & "','EmailStatus_New','" & AttachmentStr & "','','" & Module4.RemoveIllegalCharacters(MessageHeader) & "')"
Set rs = cnn.Execute(strSQLquery)
End If
' ================================================================
' final steps
' ================================================================
'Delete email
objItem.Delete
Set objItem = Nothing
Set Atmt = Nothing
' ================================================================
' close connection to the sql server and end the program
' ================================================================
cnn.Close
End Sub
You should add some logging to help track down the problem.
I haven't used this personally, but maybe give it a go: Log4VBA
Also, you should add error handling:
Error Handling and Debugging Tips for Access 2007, VB, and VBA
Error Handling In VBA
First you do not say which part of your process is not working. You have showed a routine that does not fire by itself, it must be called by something else. This something else must have some conditions attached to it to call your routine. What are they? Can you show the workings of this.
If you are using a rule then could you show the conditions of the rule. Further what about if instead of a rule we code for the event in the VBEditor so that you can maybe see this event happening as well? Here is what I am talking about and there is example code there on how to do it MSDN Application_New_MAIL
Next I agree with everyone else that you need some logging, there is so much going on and it is impossible to tell where you cod is falling over. If I were you I would get an email that does not work and send it to yourself and have a break point right at the beginning of your code so that you can see a. That your code is actually being called and then where it is failing.