I've inherited an office network.
My goal is to send all (incoming and outgoing) emails for mydomain.com to an external address some_email#external_domain.com
Scenario:
Mail server for mydomain.com is hosted outside (No exchange server). Clients use Outlook 2010 to POP and send emails.
-Each email address has a forward to some_email#external_domain.com on server-side
-Each Outlook 2010 client has been configured with:
Dim strBcc As String
On Error Resume Next
' #### USER OPTIONS ####
' address for Bcc -- must be SMTP address
' or resolvable to a name in the address book
strBcc = "some_email#external_domain.com"
Set objRecip = Item.Recipients.Add(strBcc)
objRecip.Type = olBCC
If Not objRecip.Resolve Then
strMsg = "Could not resolve the Bcc recipient. " & _
"Do you want to send the message?"
res = MsgBox(strMsg, vbYesNo + vbDefaultButton1, _
"Could Not Resolve Bcc")
If res = vbNo Then
Cancel = True
End If
End If
Now everything works fine....except when user sends an email from mydomain.com to mydomain.com. Naturally, some_email#external_domain.com gets two emails (from auto BCC and a server-side forward)
My question: Is it possible to exclude *#mydomain.com from auto BCC?
After some trial and error, I've achieved this with following:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim objRecip As Recipient
Dim strMsg As String
Dim res As Integer
Dim strBcc As String
On Error Resume Next
If Item.To Like "*#mydomain.com" Or Item.CC Like "*#mydomain.com" Then
'Do nothing
Else
strBcc = "some_email#external_domain.com"
Set objRecip = Item.Recipients.Add(strBcc)
objRecip.Type = olBCC
If Not objRecip.Resolve Then
strMsg = "Could not resolve the Bcc recipient. " & _
"Do you want still to send the message?"
res = MsgBox(strMsg, vbYesNo + vbDefaultButton1, _
"Could Not Resolve Bcc Recipient")
If res = vbNo Then
Cancel = True
End If
End If
End If
Set objRecip = Nothing
End Sub
This will auto BCC all email except if "To" or "CC" contains "#mydomain.com". So far works fine with my tests.
This is my first time tinkering with VBA, would be grateful to see any comments/suggestions.
Related
I have code that upon click, opens up a pre-defined Outlook Message.
My problem is, when the Outlook message window opens, my VB.Net app freezes until, the Outlook message window is either closed or the mail is sent.
How can I release the object from vb.net so the my app is normal to use and not frozen in time?
My Code:
Dim EmailImgPath, strMsg As String
If CustID = vbEmpty Then
MsgBox("No Client selected. Please select a client first before clicking on the Notifications Email button.", vbExclamation + vbOKOnly, "No Client Selected")
Else
If cmbOrdStatus.Text = "Ready" Then
Try
Dim Outl As Object
Outl = CreateObject("Outlook.Application")
If Outl IsNot Nothing Then
Dim omsg As Object
omsg = Outl.CreateItem(0) '=Outlook.OlItemType.olMailItem'
omsg.To = txtEmail1.Text
omsg.cc = txtEmail2.Text
omsg.bcc = EmailBcc
omsg.subject = "Order Update from EyeStyle Opticians"
strMsg = strMsg & "<p>Dear " & txtFname.Text & ",<br><br>"
strMsg = strMsg & "<p>Great News!"
strMsg = strMsg & "<p>Your order is ready for collection"
strMsg = strMsg & "<p>For any enquiries please call 0734 544376 / 0726 936136 / 0707 908838"
strMsg = strMsg & "<p>Thank you for your patronage and assuring you of our very best services at all times."
strMsg = strMsg & "<p>Karibu."
strMsg = strMsg & "<p>Eyestyle Opticians Ltd.<br><br>"
strMsg = strMsg & "<p><img src=" & EmailImgPath & "></p>"
omsg.HTMLBody = strMsg
omsg.Display(True) 'will display message to user
End If
Outl = Nothing
Catch ex As Exception
MessageBox.Show("ERROR: Failed to send mail: " & ex.Message)
End Try
End If
The following shows how to use Microsoft.Office.Interop.Outlook to send an e-mail. It's been tested.
Pre-requisite: Outlook installed.
Add Reference:
Note: The instructions below are for VS 2019.
In VS menu, click Project
Select Add Reference...
Click COM
Check Microsoft Outlook xx.x Object Library (ex: Microsoft Outlook 16.0 Object Library)
Click OK
Add Imports statement
Imports Outlook = Microsoft.Office.Interop.Outlook
CreateMsg:
Private Sub CreateMsg(toAddress As String)
Dim oApp As Outlook.Application = Nothing
Dim oNS As Outlook.NameSpace = Nothing
Try
'create new instance
oApp = New Outlook.Application()
'get MAPI namepsace
oNS = oApp.GetNamespace("mapi")
'log on using default profile
oNS.Logon()
'logon using specified profile
'oNS.Logon("profileName", System.Reflection.Missing.Value, False, true)
'create MailItem
Dim oMsg As Outlook.MailItem = DirectCast(oApp.CreateItem(Outlook.OlItemType.olMailItem), Outlook.MailItem)
'ToDo: change the message properties as desired (ie: subject, body, etc...)
oMsg.To = toAddress
oMsg.Subject = "this is the subject"
oMsg.Body = "This is a test " & DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff")
'send message
For Each account As Outlook.Account In oApp.Session.Accounts
Debug.WriteLine($"account SMTP address: {account.SmtpAddress}")
If account.SmtpAddress = "desiredFromAddress#outlook.com" OrElse oApp.Session.Accounts.Count = 1 Then
Debug.WriteLine($"Sending from {account.SmtpAddress}...")
oMsg.SendUsingAccount = account
oMsg.Send()
Exit For
End If
Next
'sleep to allow send to complete
System.Threading.Thread.Sleep(150)
'send and receive
oNS.SendAndReceive(False)
'log off
oNS.Logoff()
'oMsg.Display(True)
'oMsg.Display(False)
Finally
If oApp IsNot Nothing Then
oApp.Quit()
End If
End Try
End Sub
Resources:
Microsoft.Office.Interop.Outlook
Work with mail items
How to: Programmatically create an email item
Outlook Automatic Send Receive not Working (Solved)
COM Interop & Outlook - Make Outlook Visible?
How to use the Microsoft Outlook Object Library to retrieve a message from the Inbox by using Visual C#
How to send a mail using Microsoft.Office.Interop.Outlook.MailItem by specifying the From Address
How To: Perform Send/Receive in Outlook programmatically
Outlook error when sending more than one mail: "The item has been moved or deleted"
Outlook Interop: MailItem stuck in Outbox
Outlook Integration in C#
I'm adding an email sender in my app, so i used this:
Try
Dim oMail As New SmtpMail("TryIt")
Dim oSmtp As New SmtpClient()
oMail.From = "app-NHK#hotmail.com" ' From
oMail.To = "NHKomaiha#hotmail.com" ' To
oMail.Subject = Title.Text 'Title
oMail.TextBody = MsgTxt.Text 'Body
Dim oServer As New SmtpServer("smtp.live.com") ' SMTP server address
oServer.User = "app-NHK#hotmail.com" 'here i have written my app's email address made for sending the email from this form
oServer.Password = "thepassword" 'here i have put my app email password
oServer.ConnectType = SmtpConnectType.ConnectSSLAuto ' if SSL connection required
UseWaitCursor = True
Here done setting the main needed info
oSmtp.SendMail(oServer, oMail)
Sending...
UseWaitCursor = False
MessageBox.Show("E-Mail Sent Successfully", "Contact by E-Mail", MessageBoxButtons.OK, MessageBoxIcon.Information)
Main.BringToFront()
Main.Enabled = True
Close()
Error catching...
Catch ep As Exception
UseWaitCursor = False
MessageBox.Show("Error while sending E-Mail." & vbCrLf & vbCrLf & ep.Message, "Contact by E-Mail", MessageBoxButtons.OK, MessageBoxIcon.Error)
Dim closeerror = MessageBox.Show("Do you want to close?", "Contact by E-Mail", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If closeerror = DialogResult.Yes Then
Main.BringToFront()
Main.Enabled = True
Close()
End If
End Try
Is this code wrong? i used a lot of ways to send email but none worked
This time i got error: 550 5.3.4 Requested action not taken; To continue sending messages, please sign in to your account.
Modify and try this working example:
Imports System.Net.Mail
...
Try
Dim Email As New MailMessage()
Email.From = New MailAddress("abcdef#gmail.com")
Email.To.Add("other#provider.com")
Email.Subject = "Subject"
Email.IsBodyHtml = False 'or true if you want html
Email.Body = TextBox1.Text
Dim EmailClient As New SmtpClient("smtp.gmail.com", 587)
EmailClient.EnableSsl = True
EmailClient.Credentials = New Net.NetworkCredential("abcdef#gmail.com", "password")
EmailClient.Timeout = 7000
EmailClient.Send(Email)
Catch ex As SmtpException
MsgBox(ex.StatusCode & vbCrLf & ex.Message, vbCritical, "SMTP Error!")
End Try
Usually you need to specify port and authentication type in order to connect to an smtp server. It seems that smtp.live.com use SSL and port 465 (please verify this data).
So you can use SmtpClient.Port property to sets the port used for SMTP transactions and SmtpClient.EnableSSL to specify that SmtpClient uses Secure Sockets Layer (SSL) to encrypt the connection.
I'm trying to run this a block of code that exports the file I am working on to a PDF and emailing it to a 'client' using gmail.
I keep getting the message "Failure Sending Message", if you could help shed some light on this that would be appreciated.
I also purposely "*****" my emails credentials for obvious reasons.
<MiCode(ControlScriptEventType.AfterInkAdded, "Email")> _
Public Sub Ctl_Email_AfterInkAdded(ByVal e As AfterInkAddedEventArgs)
MsgBox("1")
Dim EmailTo As String = _EmailAddress.Value
Dim EmailToName As String = "Client"
Dim EmailFrom As String = "******"
Dim EmailFromName As String = "WHSD"
Dim fileName As String = String.Empty
Dim erl As New System.Collections.Generic.List(Of ExportResult)
For Each er As ExportResult In _form.Validator.ExportResults
erl.Add(er)
fileName = System.IO.Path.GetFileNameWithoutExtension(er.ExpandedFilePath)
Next
Try
Dim fromAddress As New MailAddress(EmailFrom, EmailFromName)
Dim toAddress As New MailAddress(EmailTo, EmailToName)
Using msg As New MailMessage(fromAddress, toAddress)
msg.Body = "This will be the body of the message you are sending." & VbCrLf & "Thank you for your purchase."
msg.Subject = (Me._form.Name & " (" & fileName & ")")
' Add the mail body - an HTML file attached to this form.
For Each attData As AttachmentData In _form.Attachments
If String.Compare(attData.Name, "Lead Generation.html") = 0 Then
msg.Body = System.Text.UTF8Encoding.UTF8.GetChars(attData.BinaryData())
msg.Body = msg.Body.Replace("[filename]", fileName)
End If
Next
' Add pdf/csv file attachments to mail - they are datapaths of the form.
For Each er As ExportResult In erl
If er.Success And ( er.DataPathName = "PDF" Or er.DataPathName = "CSV" ) Then
msg.Attachments.Add(New Attachment(er.ExpandedFilePath))
End If
Next
Dim client As New SmtpClient("aspmx.l.google.com", 25)
'client.EnableSsl = True
'client.Timeout = 10000
client.DeliveryMethod = SmtpDeliveryMethod.Network
client.UseDefaultCredentials = False
client.Credentials = New NetworkCredential("********", "******")
client.Send(msg)
Me.RecordExportResult("Email", True, "Sent email", "Sent email to " & EmailToName & "(" & EmailTo & ")", "")
MsgBox("Sent!")
End Using
Catch ex As Exception
Me.RecordExportResult("Email", False, ex.Message, ex.Message, ex.Message)
MsgBox(ex.Message)
End Try
End Sub
Looks like you are trying to use gmail as your mail server in which case you will definately need to use SSL/TLS and make sure your credentials are as follows;
Google's SMTP server requires authentication, so here's how to set it up:
SMTP server (i.e., outgoing mail): smtp.gmail.com
SMTP username: Your
full Gmail or Google Apps email address (e.g. example#gmail.com or
example#yourdomain.com)
SMTP password: Your Gmail or Google Apps
email password
SMTP port: 465
SMTP TLS/SSL required: yes
In order to store a copy of outgoing emails in your Gmail or Google Apps Sent folder, log into your Gmail or Google Apps email Settings and:
Click on the Forwarding/IMAP tab and scroll down to the IMAP Access section: IMAP must be enabled in order for emails to be properly copied to your sent folder.
NOTE: Google automatically rewrites the From line of any email you send via its SMTP server to the default Send mail as email address in your Gmail or Google Apps email account Settings. You need to be aware of this nuance because it affects the presentation of your email, from the point of view of the recepient, and it may also affect the Reply-To setting of some programs.
Workaround: In your Google email Settings, go to the Accounts tab/section and make "default" an account other than your Gmail/Google Apps account. This will cause Google's SMTP server to re-write the From field with whatever address you enabled as the default Send mail as address.
I have the following code:
Public Function VerstuurMail(ByVal strFrom As String, ByVal strTo As String, ByVal strSubject As String, ByVal strBody As String, ByVal strMailSMTP As String, ByVal MailUser As String, ByVal MailPassword As String, ByVal MailPort As Integer, Optional ByVal AttachmentFiles As String = "") As String
Try
'create the mail message
Dim mail As New MailMessage()
Dim basicCredential As New NetworkCredential(MailUser, MailPassword)
'set the addresses
mail.From = New MailAddress(strFrom)
mail.To.Add(strTo)
'set the content
mail.Subject = strSubject
If File.Exists(strBody) = True Then
Dim objReader As New System.IO.StreamReader(strBody, System.Text.Encoding.GetEncoding(1252))
mail.Body = objReader.ReadToEnd
objReader.Close()
End If
mail.IsBodyHtml = False
'send the message
Dim smtp As New SmtpClient(strMailSMTP)
smtp.DeliveryMethod = SmtpDeliveryMethod.Network
smtp.EnableSsl = True
'smtp.UseDefaultCredentials = True
smtp.Credentials = basicCredential
smtp.Port = MailPort
Dim AttachmentFile As String() = AttachmentFiles.Split("*")
For Each bestand In AttachmentFile
If System.IO.File.Exists(bestand) Then
mail.Attachments.Add(New Attachment(bestand))
Else
Call MessageBox.Show("File can't be found")
End If
Next
'Dim userState As Object = mail
'smtp.SendAsync(mail, userState)
'AddHandler smtp.SendCompleted, AddressOf SendCompletedCallback
smtp.Send(mail)
mailSent = True
smtp.Dispose()
Catch ex As Exception
mailSent = False
Call MessageBox.Show(ex.Message & vbCrLf & "Didn't sent to: " & strTo & vbCrLf & " with extra error message:" & vbCrLf & ex.ToString)
Finally
End Try
Return mailSent
End Function
This function is used in a program which reads a text file, with the parameters on one line, and is called as many lines there are. (in a loop)
This is working fine.
Now when the text file has a wrong email adress the function doesn't trow a error it just sent the email to nobody.
example: sent an mail to joe#gmail.com works, send an email to joe#hmail.com doesn't sent but doesn't give an error either.
I have googled but the examples said that I should use 'smtp.SendAsync(mail, userState)'
But then the program doesn't follow the loop anymore and no mails are being sent. I can't use the debugger and step through the code. It just jumps from one place to the other.
This is the other function:
Private Sub SendCompletedCallback(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
Dim mail As MailMessage = CType(e.UserState, MailMessage)
'write out the subject
Dim subject As String = mail.Subject
'If e.Cancelled Then
' Call MessageBox.Show("Send canceled: " & Now & " token " & subject)
' MailLog &= "Send canceled" & vbCrLf
'End If
If Not e.Error Is Nothing Then
Call MessageBox.Show("Foutmelding op: " & Now & " onderwerp " & subject & " met error: " & e.Error.ToString())
MailLog = MailLog & "Niet verstuurd met als fout melding: " & e.Error.ToString() & vbCrLf
Else
'Call MessageBox.Show("Message sent at: " & Now)
MailLog = MailLog & "Bericht verstuurd op: " & Now & vbCrLf
End If
mailSent = True
End Sub
Thanks in advance. I hope somebody can put me in the right direction.
Brian
This is a data issue, not an issue with the actual mechanism to send email. The best you can do is to use a regular expression to make sure the email address is valid per the rules of RFC 2822, like this:
string email = txtemail.Text;
Regex regex = new Regex(#"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$");
Match match = regex.Match(email);
if (match.Success)
{
Response.Write(email + " is valid.");
}
else
{
Response.Write(email + " is invalid.");
}
Unfortunately for you, joe#hmail.com is a valid email address by the above logic, but is is not the intended joe#gmail.com address so it ends up in the wrong place. When it is discovered that it is the wrong email address, then changing the data to the right value is the only correct course of action.
Note: Generally, you verify someone's email address when they register for a website, thus the system "knows" the email address is legitimate/correct because they successfully received an email and entered a verification code or clicked on a link that verified with the website that they did get the email. This solves most data issues (misspellings, incorrectly entered values, etc.).
After two full days of testing and searching I have found that when using:
Dim userState As Object = mail
smtp.SendAsync(mail, userState)
AddHandler smtp.SendCompleted, AddressOf SendCompletedCallback
you should not close the smtpClient with smtp.Dispose()
The callback function kept getting the cancel error.
Also I used the backgroundworker for sending the many mails but the async is, in a way, a backgroundworker. So I had two backgroundworkers and that didn't work at all.
It took me two days.....
Brian
I use SmtpMail for users to forward site content. The user fills out a form which includes first name and email.
The email sent has the full email address as the "From address" in the recipients inbox (they see From: Joe#Gmail.com while I want them to see From: Joe).
How can I format the "From address" to be the users inputted first name?
Thanks!
The MailAddress class has an optional parameter where you can specify a display name. I assume it will be used when present.
Dim from As MailAddress = New MailAddress("ben#contoso.com", "Ben Miller")
Dim to As MailAddress = New MailAddress("jane#contoso.com", "Jane Clayton")
Dim message As MailMessage = New MailMessage(from, to)
This has always worked for me:
Dim myMessage As New MailMessage
Dim myFrom As MailAddress = New MailAddress("bob#contoso.com", "Bob Denver")
Dim myTo As MailAddress = New MailAddress("steve#contoso.com", "Steve Miller")
myMessage.From = myFrom
myMessage.To.Add(myTo)
The format I ended up using was: mailer.From = name & "<" & emailer & ">"
This formats the from address to include Name as well as Email address. It will be displayed in most email clients as Joe <Joe#email.com>. This was my desired outcome.
Thank you Knslyr and lincolnk for the support.
this method displays 'Rameez' instead of 'Rameez#abc.com.pk'
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim objRecip As Recipient
Dim strMsg As String
Dim res As Integer
Dim strBcc As String
On Error Resume Next
strBcc = """Rameez"" <Rameez#abc.com.pk>"
Set objRecip = Item.Recipients.Add(strBcc)
objRecip.Type = olBCC
If Not objRecip.Resolve Then
strMsg = "Could not resolve the Bcc recipient. " & _
"Do you want still to send the message?"
res = MsgBox(strMsg, vbYesNo + vbDefaultButton1, _
"Could Not Resolve Bcc Recipient")
If res = vbNo Then
Cancel = True
End If
End If
Set objRecip = Nothing
End Sub