I'm using the MailKit client librairy to use their IMAP protocol in order to read my mails and search in it for a specific mail. It does work well for recent mail (less than a month and a half). But when I'm trying to search for an email that contains "myWordToSearch" from a long time (6 months old or stuff like that) it tells me that it does not exist, because it does not go that deep into the mails. Is there a way to retrieve/read ALL emails in order to filter them (like the search bar on gmail or stuff like that) ?
Here is my code :
using (var client = new ImapClient())
{
using (var cancel = new CancellationTokenSource())
{
client.Connect("imap." + provider , 993, true, cancel.Token);
client.Authenticate(myMail, myPassword, cancel.Token);
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly, cancel.Token);
var mail = (SearchQuery.SubjectContains(myWordToSearch));
foreach (var uid in inbox.Search(mail, cancel.Token))
{
var message = inbox.GetMessage(uid, cancel.Token);
}
}
}
Related
I'm trying to read an email from my mailbox using the MailKit library. Unfortunately the program throws this MailKit.Security.AuthenticationException: 'LOGIN failed.'
The credentials match (I tried to log in through the browser).
I'm trying to read an email from my mailbox using the MailKit library. Unfortunately the program throws this
MailKit.Security.AuthenticationException: 'LOGIN failed.'
I would be grateful for any help, I don't know what to do. I googled, tried this client.Connect("imap.outlook.com", 993, SecureSocketOptions.None);
But nothing came up
when I changed SecureSocketOptions to Auto, the same exception was thrown
using (var client = new ImapClient())
{
using (var cancel = new CancellationTokenSource())
{
client.Connect("imap.outlook.com", 993, true);
//client.AuthenticationMechanisms.Remove("XOAUTH");
client.Authenticate("mail#test.cz", "password", cancel.Token);
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly, cancel.Token);
Console.WriteLine("Total messages: {0}", inbox.Count);
Console.WriteLine("Recent messages: {0}", inbox.Recent);
for (int i = 0; i < inbox.Count; i++)
{
var message = inbox.GetMessage(i, cancel.Token);
Console.WriteLine("Subject: {0}", message.Subject);
}
var query = SearchQuery.DeliveredAfter(DateTime.Parse("2013-01-12"))
.And(SearchQuery.SubjectContains("MailKit"))
.And(SearchQuery.Seen);
foreach (var uid in inbox.Search(query, cancel.Token))
{
var message = inbox.GetMessage(uid, cancel.Token);
Console.WriteLine("[match] {0}: {1}", uid, message.Subject);
}
client.Disconnect(true, cancel.Token);
}
}
The AuthenticationException has nothing to do with SSL and therefor is not a problem with client.Connect(...). It's a problem with client.Authenticate (username, password)
Microsoft's public email servers no longer allow the use of usernames and passwords. They now require authentication via OAuth2.
For information about how to authenticate using OAuth2, see the MailKit docs: https://github.com/jstedfast/MailKit/blob/master/ExchangeOAuth2.md
I am working on a uwp app to send html email with embedded image. I was using EASendMail nuget pakage and it was fine after some time my app shows error:
A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond. (Exception from
HRESULT: 0x8007274c)
I think the trial period has expired what should I do?
using EASendMailRT;
https://www.emailarchitect.net/easendmail/kb/csharp.aspx?cat=8
I can't find any alternative
try
{
string ToAddress = MailSendPage.toAddressTxtBox;
string Subject = MailSendPage.subjectTxtBox;
SmtpMail oMail = new SmtpMail("TryIt");
oMail.From = new MailAddress(username);
if(!String.IsNullOrEmpty(ToAddress)&& !String.IsNullOrEmpty(Subject))
{
oMail.To.Add(new MailAddress(ToAddress));
oMail.Subject = Subject;
EASendMailRT.SmtpClient oSmtp = new EASendMailRT.SmtpClient();
SmtpServer oServer = new SmtpServer(host);
oServer.User = username;
oServer.Password = password;
oServer.Port = port;
if (IsStackPanalHasImg() == true)
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
string[] files = Directory.GetFiles(localFolder.Path + #"\ProjectImages");
foreach (string eachfile in files)
{
foreach (string name in covertToHtml.ControlName)
{
string pattern = string.Format("{0}.jpeg", name);
if (Regex.IsMatch(eachfile, pattern))
{
Attachment oAttachment = await oMail.AddAttachmentAsync(eachfile);
oAttachment.ContentID = name;
}
}
}
}
await oSmtp.SendMailAsync(oServer, oMail);
popUpMsgs.popup(" The Mail has been sent");
}
}
catch (Exception ep)
{
popUpMsgs.popup(String.Format("Failed to send email with the following error: {0}", ep.Message));
}
The built-in e-mail API only support sending plain text e-mail messages as Docs state:
This method only sends plain text messages. You can't set the body of the message to the HTML format.
What you can do is attach images to the e-mail:
EmailMessage mail = new EmailMessage();
mail.Sender = new EmailRecipient("test#example.com");
mail.To.Add(new EmailRecipient("someone#example.com"));
mail.Subject = "Hello";
mail.Body = "World";
var file = await StorageFile.GetFileFromApplicationUriAsync(
new Uri("ms-appx:///Assets/StoreLogo.png"));
mail.Attachments.Add(new EmailAttachment(file.Name, file));
await Windows.ApplicationModel.Email.EmailManager.ShowComposeNewEmailAsync(mail);
In addition, sending attachments works well only in case of the built-in UWP Outlook Mail client. Classic Outlook will most likely ignore the attachments altogether.
If you need to embed the image, you will need to use a e-mail service. I can recommend SendGrid or MailGun. Both have C# APIs which work like a breeze. They are also free for limited number of e-mails.
There are several ways you can embed the images in a HTML e-mail message.
The oldest is using CID (Content ID) which you were using in your question.
Second option is using Base64 encoding. You first turn your image into a Base64 string. There are many tutorials on this, for example in this blogpost. Then you can just embed the image in the src of your <img> tag:
<img src="data:image/jpeg;base64, YOURIMAGEINBASE64"/>
Finally you can embed an image which is hosted somewhere. This scales the best if you need to send the e-mail to many recipients, but of course requires actually hosting the image somewhere. Of the three methods it is also supported in most clients.
All three approaches are described in detail in this post.
I am using mailkit on monotouch xamarin. I am creating an app that will receive emails(email client). I give to the user the option to choose if he is using Pop3 or IMAP connection protocol. My issue is that I cant find solution on how he can delete a message on Pop3 and on IMAP.
I have tried to use this code:
client.Inbox.AddFlags (new int[] { index }, MessageFlags.Deleted);
from this post: MailKit Delete single message from gmail
but is not seems to work for me.
My code for capturing the Pop3 acount emails is
using (var client = new Pop3Client ()) {
var credentials = new NetworkCredential (Convert.ToString (username), Convert.ToString (password));
var uri = new Uri (Convert.ToString ("pops://"+pop3));
using (var cancel = new CancellationTokenSource ()) {
client.Connect (uri, cancel.Token);
var _emailItems=new List<EmailItem>() ;
client.Authenticate (credentials, cancel.Token);
string[] mycell = new string[200];
int count = client.GetMessageCount (cancel.Token);
int lastcount;
for (int i = 0; i < count; i++) {
lastcount = (count - 1) - i;
var message = client.GetMessage (lastcount, cancel.Token);
}
}
}
Different protocols have different ways of deleting messages.
For POP3, this is how you would delete a message:
client.DeleteMessage (lastcount, cancel.Token);
(Note: unless you are actually allowing the user to cancel the operations, you do not need to use cancel.Token)
The other way of deleting messages that you pasted is meant for IMAP.
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();
}
}
I use free .net library to read email and I release: If I want to view body message, all free .net email library download body message and attachments. If attachments have a big size, I wait for a long time. Example: I use AE.NET.Mail to read the lastest email:
var dt = DateTime.Now;
Console.WriteLine(dt.ToLongTimeString());
// Connect to the IMAP server. The 'true' parameter specifies to use SSL
// which is important (for Gmail at least)
var ic = new ImapClient("imap.gmail.com", "yourEmail", "yourPassword",
ImapClient.AuthMethods.Login, 993, true);
// Select a mailbox. Case-insensitive
var mailCount = ic.GetMessageCount();
ic.SelectMailbox("INBOX");
var message = ic.GetMessage(mailCount - 1);
var body = message.Body;
Console.WriteLine(body);
ic.Disconnect();
ic.Dispose();
Console.WriteLine(DateTime.Now.ToLongTimeString());
Console.WriteLine((DateTime.Now - dt).TotalSeconds);
result: 478,6s with attachment size 23mb.
How can I do if I want to view only body message with fastest speed?
I am giving you link please follow it and try another open source mail library It helps you to consume less time . TRY THIS Then put the code as shown below
MailRepository rep = new MailRepository("imap.gmail.com", 993, true, #"username", "password");
foreach (ActiveUp.Net.Mail.Message email in rep.GetUnreadMails("Inbox"))
{
System.Web.HttpContext.Current.Response.Write(string.Format("<p>{0}: {1}</p><p>{2}</p>", email.From, email.Subject, email.BodyHtml.Text));
}