I am currently refining an MS Outlook Add-In to pick up emails that end up in the Junk folder with "legit" addresses and then moving them into the Inbox folder.
This is an occurence that happens a lot for Gmail addresses, and is a bit painstaking for our staff members, who have to manually link those emails to their client accounts.
Has anyone attempted this? I have registered the incoming email event handler to read the Junk folder when an email comes in, but I keep getting an exception. I suspect it has to do with the fact that some of these emails are spam; which simply means that the MailItem will have lots of errors.
Has anyone had the same issue? Here is my code:
public void OutlookApplication_ItemReceived(string entryID)
{
//this.outlookNameSpace = this.application.GetNamespace("MAPI");
//Outlook.MAPIFolder inbox = this.outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
//Outlook.MAPIFolder junkFolder = this.outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderJunk);
if (Properties.Settings.Default.AutoLink || Properties.Settings.Default.EnableLeadLoader)
{
Outlook.MailItem mail = null;
try
{
this.Log("Email detected: incoming");
mail = this.application.Session.GetItemFromID(entryID) as Outlook.MailItem;
this.leadLoaderRecipient = Properties.Settings.Default.LeadLoaderRecipient.ToLower();
Outlook.Recipients recips = mail.Recipients; //That's where its crashing as the object is null... if read from spam folder
foreach (Outlook.Recipient recip in recips)
{
Outlook.PropertyAccessor pa = recip.PropertyAccessor;
string smtpAddress = pa.GetProperty(PR_SMTP_ADDRESS).ToString();
if (Properties.Settings.Default.EnableLeadLoader)
{
if (smtpAddress.ToLower() == this.leadLoaderRecipient)
this.ProcessLead(mail);
}
}
if (Properties.Settings.Default.AutoLink)
{
this.AutoLink(mail, true);
}
}
catch (Exception ex)
{
this.Log("Exception (ItemReceived): " + ex.ToString());
}
finally
{
if (mail != null)
{
Marshal.ReleaseComObject(mail);
}
}
}
}
Looking forward to your thoughts guys! :) TIA!
When exactly does your code run? Is that an Application.NewMailEx event handler? What is the exception?
Try to use the Items.ItemAdd event on the Junk Mail folder instead of using Application.NewMailEx.
Related
I am writing a C# VSTO addin to provide some email filing helper functions. I am stuck as to how can programmatically move an email I have received into the conversations mailbox associated with an MS365 Group. The group itself is created as part of a sharepoint modern team site.
I can manually drag emails over to the group mailbox, but I cannot find a way to obtain the folder object in C#.
Microsoft® Outlook® for Microsoft 365 MSO (Version 2111 Build 16.0.14701.20254) 64-bit.
You can use the Move method of Outlook items.
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.NewMail += new Microsoft.Office.Interop.Outlook.
ApplicationEvents_11_NewMailEventHandler
(ThisAddIn_NewMail);
}
private void ThisAddIn_NewMail()
{
Outlook.MAPIFolder inBox = (Outlook.MAPIFolder)this.Application.
ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.Items items = (Outlook.Items)inBox.Items;
Outlook.MailItem moveMail = null;
items.Restrict("[UnRead] = true");
Outlook.MAPIFolder destFolder = inBox.Folders["Test"];
foreach (object eMail in items)
{
try
{
moveMail = eMail as Outlook.MailItem;
if (moveMail != null)
{
string titleSubject = (string)moveMail.Subject;
if (titleSubject.IndexOf("Test") > 0)
{
moveMail.Move(destFolder);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
I suppose the destination folder is listed in Outlook in an additional store. So, you can use the Stores property of the Namespace class to find the target folder.
When I Use OutlookSpy to get the EntryIDs from MailItems in a particular folder and supply them to the following code:
Outlook.Application myApp = new Outlook.ApplicationClass();
Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
try
{
object obj = mapiNameSpace.GetItemFromID(sEntryID);
if (obj is Outlook.MailItem)
{
var getItem = (Outlook.MailItem)mapiNameSpace.GetItemFromID(sEntryID);
getItem.Display();
}
}
catch (Exception Ex)
{
Global.Common.LogError("Error accessing MailItem", Ex, "EntryID " + sEntryID + " not found in " + sFolder, "Warning");
}
I get unknown messaging errors for some EntryID values and successful display of the messages in Outlook with others. Can anyone suggest what attributes the MailItems might have which will affect whether I can display them successfully using GetItemFromID or any other method of displaying all messages by EntryID reliably?
Was the message store where the message resides touched in the active Outlook session? The way MAPI providers work, when a provider is loaded by MAPI, it registers the set of entry id guids (bytes 5-20 in the entry id) that it will handle. If the particular PST store has not been touched in the current session, MAPI does not know anything about its entry ids.
You can either access all the stores in the current session first (to make sure MAPI knows about their entry ids) or use the store entry id (second parameter, optional) when calling GetItemFromId - this way Outlook will open the store first, then ask the store to open the item. You can also call Namespace.AddStore / AddStoreEx to load the given PST file if it is not already in the current profile.
You might also want to log the exception details (Ex.Message) in your exception handler.
Thanks to all the respondents - this explains why sometimes particular messages would open and sometimes they would not. By getting the StoreId using the following code:
Outlook.Application myApp = new Outlook.ApplicationClass();
Outlook.NameSpace mapiNameSpace = myApp.GetNamespace("MAPI");
Object oStoreID = Common.GetFolder(myApp, sFolder).StoreID;
try
{
object obj = mapiNameSpace.GetItemFromID(sEntryID,oStoreID);
if (obj is Outlook.MailItem)
{
Outlook.MailItem getItem = (Outlook.MailItem)mapiNameSpace.GetItemFromID(sEntryID,oStoreID);
getItem.Display();
}
}
Where
public static Outlook.Folder GetFolder(Outlook.Application App, string folderPath)
{
Outlook.Folder folder;
string backslash = #"\";
try
{
if (folderPath.StartsWith(#"\\"))
{
folderPath = folderPath.Remove(0, 2);
}
String[] folders =
folderPath.Split(backslash.ToCharArray());
folder =
App.Session.Folders[folders[0]]
as Outlook.Folder;
if (folder != null)
{
for (int i = 1; i <= folders.GetUpperBound(0); i++)
{
Outlook.Folders subFolders = folder.Folders;
folder = subFolders[folders[i]]
as Outlook.Folder;
if (folder == null)
{
return null;
}
}
}
return folder;
}
catch { return null; }
}
All MailItems now display in Outlook.
I'll just throw this in here for posterity-- Outlook 2002 requires that the entry ID supplied to GetItemFromID use upper-case hex characters.
I am writing a console application that searches through the current users outlook inbox. The program performs certain actions on each email based on the subject line and then moves the email to 1 of 3 subfolders. So far it has been running without throwing any errors. The problem is that it will skip over some of the emails in the inbox and I can't seem to find any logic behind why it does this. Sometimes it will skip the first email received, sometimes the last, other times it will leave 2 and move the rest. I've inserted a breakpoint in my code and stepped through each line and the skipped emails never show up. It doesn't seem to matter whether the emails are marked read or unread either. If I run the program multiple times then eventually the skipped emails are processed. What could be causing this?
Microsoft.Office.Interop.Outlook.Application application = null;
if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
{
application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application;
}
else
{
//outlook not open, do nothing
}
Microsoft.Office.Interop.Outlook.Items items = null;
Microsoft.Office.Interop.Outlook.NameSpace ns = null;
Microsoft.Office.Interop.Outlook.MAPIFolder inbox = null;
Microsoft.Office.Interop.Outlook.Application();
ns = application.Session;
inbox = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
items = inbox.Items;
try
{
foreach (Object receivedMail in items)
{
if (receivedMail is MailItem)
{
MailItem mail = receivedMail as MailItem;
string subject = mail.Subject.ToString().ToUpper();
switch (subject)
{
case "SUBJECT1":
DoStuff1(mail);
mail.Move(inbox.Folders["folder1"]);
break;
case "SUBJECT2":
DoStuff2(mail);
mail.Move(inbox.Folders["folder2"]);
break;
default:
mail.Move(inbox.Folders["folder3"]);
break;
}
}
}
Console.WriteLine("Complete");
Console.ReadLine();
}
catch (System.Runtime.InteropServices.COMException ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
catch (System.Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
If anyone happens to stumble across this I discovered a solution. I just added each email to a list first before performing any actions on them. I'm not sure why this step was necessary, maybe something to do with not being able to properly enumerate active inbox mail items.
List<MailItem> ReceivedEmail = new List<MailItem>();
foreach (Outlook.MailItem mail in emailFolder.Items)
{
ReceivedEmail.Add(mail);
}
foreach (MailItem mail in ReceivedEmail)
{
//do stuff
}
I have been working on an IMAP client to get emails from Gmail. My application worked fine until about an hour ago, when attachments stopped being retrieved.
The connection and messaging is being handled by imapX.
Connection is OKAY
Login is OKAY
Getting folders is OKAY
Getting messages is OKAY
At this point attachments.Count == 0. It was working earlier this afternoon so I wonder if I have been over testing and Google have blacklisted my computer for a while? Does anyone know if this is the case? - Been running perhaps once every 5-10 minutes, maybe more at times so this could be a plausible issue.
I have attempted to send a new email with a totally new file and it still does not see the attachment (but it is (always) seeing the messages themselves).
Can any anyone shine some light on this issue?
EDIT : Header includes the following tag {[X-MS-Has-Attach, yes]}
EDIT (code) :
private void PollMailFolders(object state)
{
try
{
if(_imapClient == null || !_imapClient.IsConnected)
_imapClient = new ImapClient(_config.Server, _config.Port, true);
if (_imapClient.Connection())
{
if(!_imapClient.IsLogined)
_imapClient.LogIn(_config.Username, _config.Password);
string dateSearch = string.Format(
"SINCE {0:d-MMM-yyyy}{1}", DateTime.Today.AddDays(-_config.HistoryOnStartupDays),
_isFirstTime ? "" : " UNSEEN");
_isFirstTime = false;
foreach (Folder folder in _imapClient.Folders["SSForecasts"].SubFolder)
{
var messages = _imapClient.Folders[folder.Name].Search(dateSearch, false);
foreach (Message m in messages)
{
m.Process();
foreach (var a in m.Attachments)
{
SendDataToParser(_encoding.GetString(a.FileData), folder.Name);
}
m.SetFlag(ImapFlags.SEEN);
}
}
}
}
catch(Exception e)
{
_diagnostics.Logger.ErrorFormat("Error in PollMailFolders: {0}", e);
}
}
I have produced a work around which allows me to get the attachment data. Not the solution I had in mind, though it does work.
Simple filename extension check followed by a conversion of the message data.
BTW: _encoding = Encoding.GetEncoding(1252);
if (bodyPart.ContentFilename.EndsWith(".csv"))
{
return _encoding.GetString(Convert.FromBase64String(bodyPart.ContentStream));
}
i have a problem with send mail in c#; it doesn't send any mail and also doesn't throw any exceptions with failure :
using System.Web.Util;
public static void SendEmail(string _FromEmail, string _ToEmail, string _Subject, string _EmailBody)
{
// setup email header .
SmtpMail.SmtpServer = "localhost";
MailMessage _MailMessage = new MailMessage();
_MailMessage.From = _FromEmail;
_MailMessage.To = _ToEmail;
_MailMessage.Subject = _Subject;
_MailMessage.Body = _EmailBody;
try
{
SmtpMail.Send(_MailMessage);
}
catch (Exception ex)
{
throw new ApplicationException("error has occured: " + ex.Message);
}
}
please help!
Check the folders in your IIS' Mailroot directory (probably located in C:\InetPub\Mailroot). Chances are your mails are dropped there, probably in the Badmail or the Queue directory.
see C:\InetPub\Mailroot\queue folder. if your emails got stuck in this folder then
1>> stop your SMTP
2>> move emails from queue folder to C:\inetpub\mailroot\Pickup folder and start your smtp server and wait for few seconds.
if your email got stuck in queue folder again then you need to enable smtp logging for more information. use this link to see how to enable smtp logging.
http://www.msexchange.org/tutorials/Logging_the_SMTP_Service.html