I'm currently using Exchange Web Services in C#. I basically have a small application that reads emails from an inbox and process them.
I would like to forward those emails I receive as an attachment of an email. This attachment will be an outlook email that will include the original email (including its own attachments if any).
Any ideas?
Thanks!
EDIT:
Not sure why I'm getting the down votes but it seems this is not possible as the EWS API does not provide such functionality
You can create an ItemAttachment with EWS but you can't replicate fully what is possible in Outlook with MAPI. Eg with EWS you can create an ItemAttachment and then use the MIMEContent to create an attachment based on a current message as a workaround eg
FolderId Inboxid = new FolderId(WellKnownFolderName.Inbox, "target#domain.com");
ItemView InboxItemView = new ItemView(1);
FindItemsResults<Item> inFiResuls = service.FindItems(Inboxid,InboxItemView);
if(inFiResuls.Items.Count == 1){
EmailMessage fwdMail = new EmailMessage(service);
EmailMessage orgMail = (EmailMessage)inFiResuls.Items[0];
PropertySet psPropSet = new PropertySet(BasePropertySet.FirstClassProperties);
psPropSet.Add(ItemSchema.MimeContent);
orgMail.Load(psPropSet);
ItemAttachment emAttach = fwdMail.Attachments.AddItemAttachment<EmailMessage>();
emAttach.Item.MimeContent = orgMail.MimeContent;
ExtendedPropertyDefinition pr_flags = new ExtendedPropertyDefinition(3591,MapiPropertyType.Integer);
emAttach.Item.SetExtendedProperty(pr_flags,"1");
emAttach.Name = orgMail.Subject;
fwdMail.Subject = "see Attached";
fwdMail.ToRecipients.Add("user#domain.com");
fwdMail.Send();
}
This however doesn't give full fidelity of all the mapi properties associated with a particular message as the MIMEContent is just that, for most normal email messages this isn't an issue however for a message with an attached Outlook Task or other TNEF attachment then you would loose these of attachments or for other properties like categories,flags you would loose these also (you could copy these manually if needed).
Cheers
Glen
you can forward your email using this way. It first loads and reads the each emails with attachment who has "msg" extension. then forwards it to given address. see the below code
FindItemsResults<Item> findResults = exchange.FindItems(WellKnownFolderName.Inbox, newItemView(50,50));
Item[] msgItems = findResults.Where(msgItem => msgItem.HasAttachments).ToArray();
EmailMessage msgInfo = null;
var fileExtensions = new List<string> { "msg", "MSG", "Msg" };
foreach (MSEWS.Item msgItem in msgItems )
{
msgInfo = EmailMessage.Bind(exchange, msgItem.Id);
FileAttachment fa = msgInfo.Attachments[0] asFileAttachment;
if (fileExtensions.Any(ext => ext.Contains(fa.Name.Substring(fa.Name.Length - 3))))
{
fa.Load();
ResponseMessage responseMessage = msgInfo.CreateForward();
responseMessage.BodyPrefix = "messageBody";
responseMessage.ToRecipients.Add("toAddress");
responseMessage.Subject = "subject";
responseMessage.SendAndSaveCopy();
}
}
Related
In my application I use some code to send automated mails over our Exchange server.
My current goal is to send a HTML mail with some pictures as a handout. That pictures shall be attachments of the mail.
To this point the code is working (I have changes internal names in the code example):
ExchangeService MailClient = new ExchangeService
{
UseDefaultCredentials = true,
Url = new Uri("https://<domain.of.company>/EWS/Exchange.asmx")
};
EmailMessage msg = new EmailMessage(MailClient);
msg.ToRecipients.Add(new EmailAddress(user.EmailAddress));
msg.Sender = new EmailAddress("sender#domain.of.company");
msg.Subject = "Some text here";
MessageBody Body = new MessageBody
{
BodyType = BodyType.HTML,
Text = NameOfApplication.Properties.Resources.Embedded_HTML_File
};
msg.Body = Body;
msg.SendAndSaveCopy(new FolderId(WellKnownFolderName.SentItems, "sender#domain.of.company")));
With this code the E-Mail get saved in the "Sent" folder and arrives the target mailbox. Success so far.
But as soon I add an attachement by this (no other changes were made)
msg.Attachments.AddFileAttachment(AppContext.BaseDirectory + "Logo.jpg");
SendAndSaveCopy throws an exception with the description "No mailbox with such guid."
When I comment out the AddFileAttachment line the code is working again.
Any idea whats wrong with attachments?
Found the solution. Reading tooltips might help.
Maybe the day will come, when Microsoft will change SendAndSaveCopy to include this step.
But yes: The error message is misleading.
Is it possible to assign EmailMessage specific GUID/ID, which will be later used for search?
var email = new EmailMessage(_service);
email.ExternalGuid = /*Guid or Identifier*/;
email.Send();
And later I should be able to use it to find if this mail is present:
var isExist = _service.IsExistByExternalGuid(/*Guid or Identifier*/);
Why don't you use the InternetMessageid eg Internet Message ID FROM EWS Managed API Send Email c# this Id will then appear in any tracking logs associated with the Message and you can search for the message at a later date using a SearchFilter eg
ItemView ivew = new ItemView(3);
service.TraceEnabled = true;
ExtendedPropertyDefinition PidTagInternetMessageId = new ExtendedPropertyDefinition(4149, MapiPropertyType.String);
SearchFilter sf = new SearchFilter.IsEqualTo(PidTagInternetMessageId, MessageID);
FindItemsResults<Item> iCol = service.FindItems(WellKnownFolderName.Inbox, sf, ivew);
foreach (Item item in iCol.Items)
{
Console.WriteLine(item.Subject);
}
I'm having trouble attaching an email to a new email using EWS.
So i have the Microsoft.Exchnage.Webservice.Data.Item in my findResults.
If I find an issue in the form data of the email then I want to attach that item to a new email and send it to a supervisor for manual input.
I have tried;
EmailMessage newMessage = new EmailMessage(exchange);
newMessage.Subject = "Failed lead creation";
ItemAttachment attachment = new ItemAttachment("New Lead", message);
I can't seem to create the ItemAttachment as the erro I am getting is "ItemAttachment does not contain a constructor that takes 2 arguments".
How do I create a new message in EWS, attach the current Item to it and send to another recipient?
Thaks
You can't another message directly you need to use the MimeContent of the Original Message and then create an ItemAttachment based on that eg something like
FolderId folderid= new FolderId(WellKnownFolderName.Inbox,"MailboxName");
Folder Inbox = Folder.Bind(service,folderid);
ItemView ivItemView = new ItemView(1) ;
FindItemsResults<Item> fiItems = service.FindItems(Inbox.Id,ivItemView);
if(fiItems.Items.Count == 1){
EmailMessage mail = new EmailMessage(service);
EmailMessage OriginalEmail = (EmailMessage)fiItems.Items[0];
PropertySet psPropset= new PropertySet(BasePropertySet.IdOnly);
psPropset.Add(ItemSchema.MimeContent);
psPropset.Add(ItemSchema.Subject);
OriginalEmail.Load(psPropset);
ItemAttachment Attachment = mail.Attachments.AddItemAttachment<EmailMessage>();
Attachment.Item.MimeContent = OriginalEmail.MimeContent;
ExtendedPropertyDefinition PR_Flags = new ExtendedPropertyDefinition(3591, MapiPropertyType.Integer);
Attachment.Item.SetExtendedProperty(PR_Flags,"1");
Attachment.Name = OriginalEmail.Subject;
mail.Subject = "See the Attached Email";
mail.ToRecipients.Add("glen.scales#domain.com");
mail.SendAndSaveCopy();
Cheers
Glen
Utilizing answer from Glen Scales, if you have message id, code should look like below.
Additional info on PR_Flags extended property can be found on folowing link:
http://systemmanager.ru/windowsmobile_6_5.en/html/45cd0e95-9622-4180-bf85-290c421524f3.htm
PropertySet psPropset = new PropertySet(BasePropertySet.IdOnly);
psPropset.Add(ItemSchema.MimeContent);
psPropset.Add(ItemSchema.Subject);
EmailMessage attachment = EmailMessage.Bind(_exchangeService, new ItemId(ewsItemAsAttachment).UniqueId, psPropset).Result;
ItemAttachment Attachment = message.Attachments.AddItemAttachment<EmailMessage>();
Attachment.Item.MimeContent = attachment.MimeContent;
ExtendedPropertyDefinition PR_Flags = new ExtendedPropertyDefinition(3591, MapiPropertyType.Integer);
Attachment.Item.SetExtendedProperty(PR_Flags, "1");
Attachment.Name = attachment.Subject;
I'm using Exchange web service to read email from Office365. The C# program works fine. I can get EmailMessage in Inbox, and get their subject and message body, etc. However, I could not figure out the way to check whether the message is a bounce back message or not.
Do I have to parse the message body to see whether there are some special sentence, ie. Mail Delivery Failure? If so, is it possible different email servers bounce back emails with different words? i.e some use 'Mail Delivery Failure', some use 'Mail Delivery Not Succeeded'? (just an example, I do not know whether this is true)
Or, the message object has an attribute that can be used for this purpose?
Thanks
*** Just found that the exchange webservice can not see 'Bounce back' messages in INBOX. I'm using below code, all messages can be 'seen' except Bounce Back ones. Do I miss anything to filter te bounce back messages? They are actually in INBOX, unread, and I can see it from Office365 page.
private static void ProcessEmailMessages(SearchFolder searchFolder, Folder folderHistory, Folder folderBounceBack)
{
if (searchFolder == null)
{
return;
}
const Int32 pageSize = 50;
ItemView itemView = new ItemView(pageSize);
PropertySet itempropertyset = new PropertySet(BasePropertySet.FirstClassProperties);
itempropertyset.RequestedBodyType = BodyType.Text;
itemView.PropertySet = itempropertyset;
PropertySet propertySet = new PropertySet(BasePropertySet.IdOnly, FolderSchema.DisplayName);
folderHistory.Load(propertySet);
folderBounceBack.Load(propertySet);
FindItemsResults<Item> findResults = null;
do
{
findResults = searchFolder.FindItems(itemView);
foreach (Item item in findResults.Items)
{
if (item is EmailMessage)
{
// load body text
item.Load(itempropertyset);
EmailMessage email = item as EmailMessage;
//email.Move(folder.Id);
// check email subject to find the bounced emails
bool subjectContains = Regex.IsMatch(email.Subject, "Mail Delivery Failure", RegexOptions.IgnoreCase);
bool bodyContains = Regex.IsMatch(email.Subject, "Delivery", RegexOptions.IgnoreCase);
if (subjectContains || bodyContains)
{
email.Move(folderBounceBack.Id);
Console.WriteLine("Move the Bounced email: {0}", email.Subject);
ShowMessageInfo(email);
}
else
{
email.Move(folderHistory.Id);
Console.WriteLine(">>> Keep the email: {0}", email.Subject);
}
}
}
itemView.Offset += pageSize;
} while (findResults.MoreAvailable);
}
Check the ItemClass attribute. Messages like that should have a class that contains "REPORT" in it.
I use EWS in an O365 environment to help process bounce backs and use the following code to just get the NDRs from a users' inbox.
var sf = new SearchFilter.IsEqualTo(ItemSchema.ItemClass, "REPORT.IPM.Note.NDR");
var SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, sf);
var view = new ItemView(1000) {PropertySet = new PropertySet(BasePropertySet.IdOnly)};
var findResults = service.FindItems(WellKnownFolderName.Inbox, searchFilter, view);
Hope it helps.
I've noticed that when someone copy paste an email and then sends it the "src" value of the images changes. For example if the original email has an image which is an attachment and its contentId is: cid:companlyLogo. And then someone copy paste this email into a new draft and sends it this src value changes to: src="cid:image001.jpg#01CCF6B1.A4CA2FE0".
I have no clue whatsoever on how to get this image and save it in an image object in c#. Am currently using EWS api for doing this. Problem is that since its a copy paste it no longer has attachments as the original email.
Does anyone has any idea on how to retrieve the images of this types of emails?
Embedded images are treated as email attachments by Exchange. That means you can retrieve the images from the Item.Attachments property. The following example shows you how to do this using the EWS Managed API. Notice that EWS will not load the attachments unless you explicitly tell it to by calling LoadPropertiesForItems.
You can tell that an attachment is embedded by checking the Attachment.IsInline property. EWS lets you load the attachment and save it to disk by calling the FileAttachment.Load method.
ExchangeService service = GetService();
var view = new ItemView(1);
var searchFilter = new SearchFilter.IsEqualTo(EmailMessageSchema.Subject, "Some subject text");
var items = service.FindItems(WellKnownFolderName.Inbox, searchFilter, view);
service.LoadPropertiesForItems(items, new PropertySet(BasePropertySet.FirstClassProperties, EmailMessageSchema.Attachments));
var item = items.ElementAt(0) as EmailMessage;
for (int i = 0; i < item.Attachments.Count; i++)
{
var att = item.Attachments[i] as FileAttachment;
if (att.IsInline && att.ContentType.Contains("image"))
{
att.Load(String.Format(#"c:\temp\attachedimage_{0}.jpg", i));
}
}