How to mark mails as read using ImapX lib? C# - c#

I'm using the free lib ImapX and I'm making an application to mark all my mails as receieved. Can anyone lend me a hand?
EDIT: Nevermind, found it out myself. They get marked as read when you process them.

You need to add flag, which will help you to update status as seen.
foreach (var mess in messages)
{
mess.SEEN = true;
}
Let me know if you are unable to change status.

First of all, if you're using the old ImapX library, I invite you to upgrade to ImapX 2. It's being constantly developed and supported. There is also sample code for all common operations.
The Process method of a message doesn't mark the message as read, it only downloads the whole message including attachments. In your case, if you call the Search method setting the second parameter to true, you don't have to call it for every single message.
To mark a message as read simply use the AddFlag method of Message:
ImapX.FolderCollection folders = imapclient.Folders;
ImapX.MessageCollection messages = imapclient.Folders["INBOX"].Search("UNSEEN", true);
foreach (var mess in messages)
{
mess.AddFlag(ImapFlags.SEEN);
}

Related

EWS Attached emails missing DatatimeReceived property after .Load()

I am currently working on a former colleague's project that deals with saving emails from Exchange to our ERP system.
But I have run into a strange problem. Sometimes when the system receives an email, that contains an email as an attachment. It throws an error because the DataTimeReceived date is not set. Even after a .Load();
private int HandleEmail(Item item, Folder moveToFolder, Folder moveToFailedFolder, Mailbox mailbox, int fatherId = 0, string uploaderEmail = "", bool isEmbeddedMail = false)
The way it work. is that the HandleEmail() method goes through the original email until it gets the if-check.
If the attachment is not a FileAttachment, and is an ItemAttachment. The following code is called.
else if (attachment is ItemAttachment)
{
var itemAttachment = attachment as ItemAttachment;
itemAttachment.Load(new PropertySet(ItemSchema.Attachments, ItemSchema.TextBody, EmailMessageSchema.Sender, EmailMessageSchema.DisplayCc, EmailMessageSchema.DateTimeReceived, EmailMessageSchema.From, ItemSchema.MimeContent, ItemSchema.Body, ItemSchema.TextBody, EmailMessageSchema.BccRecipients, ItemSchema.Attachments));
var item_ = itemAttachment.Item;
HandleEmail(item_, null, null, mailbox, (int)mailid, uploaderEmail, true); // The attached email is then looped through like it is an regular email instead of like an image.
}
In this check. It takes the item attachment and loads an additional property set, which contains some data that is needed.
Finally the method calls it self, but now with the Item Attachment as to read it like a regular email.
My issue is the fact, that some attached emails do not have the DatetimeReceived property set.
Instead this error is shown in its place.
Microsoft.Exchange.Webservice.Data.ServicesObjectPropertyException
And this expection message is thrown
You must load or assign this property before you can read its value
And I can't quite figure out why it only happens to some attached emails. When I look at the emails it self, it does have an received date. But for some reason I can't get it using .Load()
I've tried a few things, such as using .Load for both Item and ItemAttachment, both without getting anything worthwhile.
Tried looking into using the service.loadpropertiesforitems()
I've forgotten a few of the other things I've looked into, since I have been looking at this for a few days before the weekend aswell.
Two suggestions i would have is first try the EmailMessageSchema.DateTimeSent (which should be the same as DateTimeReceived) the difference maybe being caused when attaching a messages that was sent. The other thing would be enable tracing and have a look at the traces to see what is actually coming back from the server also maybe just try loading the BasePropertySet.FirstClassProperties rather then your custom set (just to test that property anyway)

Reading Emails from Gmail C# - IMAP

I'm trying to read emails from specific Gmail account. I have found something here(Stackoverflow) but I can't manage reading the emails.
this is what I'm using:
public static void logingmail()
{
// Connect to the IMAP server. The 'true' parameter specifies to use SSL
// which is important (for Gmail at least)
ImapClient ic = new ImapClient("imap.gmail.com", "Any#gmail.com", "4521945219",AuthMethods.Login, 993, true);
// Select a mailbox. Case-insensitive
ic.SelectMailbox("Inbox");
string countmessages = ic.GetMessageCount().ToString();
// Get the first *11* messages. 0 is the first message;
// and it also includes the 10th message, which is really the eleventh ;)
// MailMessage represents, well, a message in your mailbox
MailMessage[] mm = ic.GetMessages(0, 10);
foreach (MailMessage m in mm)
{
var subject = m.Subject.ToString();
}
// Probably wiser to use a using statement
ic.Dispose();
}
The problem I'm experiencsing probably happening when I'm first creating the new ImapCliient class. for some reason it's opening a browse path to choose a file(?).
I'll be happy for some assistance.
Thanks
You should use the solution of the second post of the topic were you have found something, S22.Imap.
(Here you can find a compiled version).
After download, you can read the documentation. It is simple and readable.
Actually, I use this library and that works well !

Getting attachments from a mail account with .NET

I'd like a free library for .NET to get attachments from an account (such as gMail, or others) via imap4 (not necessarely), and save them in a folder.
Ideally it would allow me to get a list of them, and download only some given ones (filtering by extension, name, and/or size) and be free.
I've already done this with a trial version of EAGetMail, but for the purpose of what i'm trying to attempt buying the unlimited version of this library isn't quite suitable (i didn't know that this functionality itself was one among the ones with limited time).
---[edit - Higuchi]---
I'm using the following code:
Dim cl As New Pop3Client()
cl.UserName = "marcelo.f.ramires#gmail.com"
cl.Password = "mypassword"
cl.ServerName = "pop.gmail.com"
cl.AuthenticateMode = Pop3AuthenticateMode.Pop
cl.Ssl = False
cl.Authenticate() //takes a while, but passes even if there's a wrong password
Dim mg As Pop3Message = cl.GetMessage(1) //gives me an exception: Message = "Pop3 connection is closed"
UPDATE: Setting the port to 995 gives me a "Response TimeOut" exception
As commented, I am having some issues while trying to connect and get the first e-mail. any help ?
Well, I know you specified IMAP4, but I figured I'd offer this anyway in case POP3 is an option, since it's been useful for me:
http://csharpmail.codeplex.com/
This library provides access to POP3 mail, which many e-mail services (including Gmail) do offer in addition to the newer IMAP.
The core class is Pop3Client, which provides access to POP3 functions such as ExecuteList, ExecuteTop, etc. I have used this for specifically what you are asking about -- scanning for and downloading attachments.
If you decide this is something you could use after all and need further guidance, let me know.
UPDATE: In response to your updated question, I have just a few preliminary suggestions:
Consider setting the Pop3Client.Port property to 995. I know this is what Gmail uses for POP3.
The Pop3Client.Authenticate method returns a bool value indicating whether or not authentication was successful. You can check this value after calling the method to know whether it will be possible to progress further.
UPDATE 2: I tried this at home with the following settings and it worked for me:
Using client As New Pop3Client
client.UserName = "username#gmail.com"
client.Password = "[insert password here]"
client.ServerName = "pop.gmail.com"
client.AuthenticateMode = Pop3AuthenticateMode.Pop
client.Ssl = True ' NOTICE: in your example code you have False here '
client.Port = 995
client.Authenticate()
Dim messageList = client.ExecuteList()
Console.WriteLine("# Messages: {0}", messageList.Count)
End Using
Try these settings and see if they work for you.
UPDATE 3: One more thing! Have you made sure to enable POP for your Gmail account? If not, you need to do that!
From your Gmail inbox, click "Settings" (top right).
From the Settings page, click the tab labeled "Forwarding and POP/IMAP."
In the POP Download section, select one of the radio buttons to enable POP mail.
Click "Save Changes" at the bottom.

Reading and parsing email from Gmail using C#, C++ or Python

I have to do a Windows application that from times to times access a Gmail account and checks if there is a new email. In case there is, it must read the email body and subject (a simple text email, without images or attachments).
Please, do not use paid libs, and in case of any other libs used, give the download path.
And I need the email body and subject only. So if the long and complex message that comes from Gmail could be parsed and only two strings containing the subject and the body, it would be perfect.
Finally, I only have to get the new messages arrived since the last execution. So the read messages could be marked as "read" and only the new ones (marked as "new") are considered.
The code can be written in Python or C++, but I prefer it in C#.
Related question:
Properly formatted example for Python iMAP email access?
This prints the subject and body of unseen messages, and marks those messages as seen.
import imaplib
import email
def extract_body(payload):
if isinstance(payload,str):
return payload
else:
return '\n'.join([extract_body(part.get_payload()) for part in payload])
conn = imaplib.IMAP4_SSL("imap.gmail.com", 993)
conn.login("user", "password")
conn.select()
typ, data = conn.search(None, 'UNSEEN')
try:
for num in data[0].split():
typ, msg_data = conn.fetch(num, '(RFC822)')
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1])
subject=msg['subject']
print(subject)
payload=msg.get_payload()
body=extract_body(payload)
print(body)
typ, response = conn.store(num, '+FLAGS', r'(\Seen)')
finally:
try:
conn.close()
except:
pass
conn.logout()
Much of the code above comes from Doug Hellmann's tutorial on imaplib.
Use one of the many C# IMAP libraries.
Note that there are some differences between Gmail-IMAP and IMAPA. For example, due to the fact that Gmail treats folders like labels, the code like the one below doesn't delete message if it's tagged with some other folder:
imap_instance.uid('store', uid, '+FLAGS', '\\Deleted')
imap_instance.expunge()
I know this is an old post but I wanted to add the following link to the Open Source ImapX 2 Library discussion: https://imapx.codeplex.com/ the developers seem to be keeping the project up to date. Great job to those all involved
Google has opened it's Gmail API for accessing your gmail account. You can check a quickstart sample with the basic functionalities at this link:
https://developers.google.com/gmail/api/quickstart/python
from imap_tools import MailBox, Q
# This prints the subject and body of unseen messages, and marks those messages as seen.
with MailBox('imap.mail.com').login('test#mail.com', 'password') as mailbox:
# *mark_seen param = True by default
print([(m.subject, m.html or m.text) for m in mailbox.fetch(Q(seen=False), mark_seen=True)])
imap_tools

How do I popup the compose / create mail dialog using the user's default email client?

The use case is simple. At a certain point of time, I need to be able to show the user his familiar compose email dialog (Outlook or other) with
fields like from, to, Subject already filled up with certain application determined values.
The email would also have an attachment along with it.
The mail should not be sent unless the user explicitly okays it.
I did this once back in the ol' VB6 days.. can't figure out how now.. I just remember that it was quite easy.
Managed app, C#, .net 3.0+
Update#1: Yeah seems like mailto removed support for attachments (as a security risk?). I tried
You need to include ShellExecute signature as described here. All I got from this was a 5 SE_ERR_ACCESSDENIED and a 2 just for some variety
string sMailToLink = #"mailto:some.address#gmail.com?subject=Hey&body= yeah yeah yeah";
IntPtr result = ShellExecute(IntPtr.Zero, "open", sMailToLink, "", "", ShowCommands.SW_SHOWNORMAL);
Debug.Assert(result.ToInt32() > 32, "Shell Execute failed with return code " + result.ToInt32());
The same MailtoLink works perfectly with Process.Start... but as long as thou shalt not mention attachments.
System.Diagnostics.Process.Start(sMailToLink);
The other options are using the Outlook Object model to do this.. but I've been told that this requires you to add assembly references based to the exact version of Outlook installed. Also this would blow up if the user doesn't prefer MS for email.
The next option are Mapi and something called Mapi33.. Status still IN PROGRESS. Ears still open to suggestions.
You can create a process object and have it call "mailto:user#example.com?subject=My+New+Subject". This will cause the system to act on the mailto with its default handler, however, while you can set subjects and such this wont handle adding an attachment. I'll freely admit im not entirely sure how you'd go about forcing an attachment without writing some mail plugin.
The process code is:
System.Diagnostics.Process.Start("mailto:user#example.com?subject=My+New+Subject");
It's probably not the most efficient or elegant way, but shelling a "mailto:" link will do what you want, I think.
EDIT: Sorry, left out a very important "not".
Since mailto does not support attachments, and since MAPI is not supported within managed code, your best bet is to write (or have someone write) a small non-managed program to call MAPI functions that you can call with command-line arguments. Pity that .NET does not have a cleaner alternative.
See also : MAPI and managed code experiences?
Could it be that you used the mailto: protocol?
Almost all of what you highlight can be done, but I am quite sure, that you cant do attachments.
Microsoft MailTo Documentation
Starting process with mailto: arguments is the simplest approach. Yet, it does not allow anything more or less complex.
Slightly different approach involves creating email template and then feeding it to the Process.Start:
var client = new SmtpClient();
var folder = new RandomTempFolder();
client.DeliveryMethod =
SmtpDeliveryMethod.SpecifiedPickupDirectory;
client.PickupDirectoryLocation = folder.FullName;
var message = new MailMessage("to#no.net",
"from#no.net", "Subject","Hi and bye");
// add attachments here, if needed
// need this to open email in Edit mode in OE
message.Headers.Add("X-Unsent", "1");
client.Send(message);
var files = folder.GetFiles();
Process.Start(files[0].FullName);
Scenarios for the default email handler:
Outlook express opens
Windows: Outlook - does not handle by default, Outlook Express is called instead
Windows: The Bat! - message is opened for viewing, hit Shift-F6 and Enter to send
I've also tested with Mono and it worked more or less.
Additional details are available in this post: Information integration - simplest approach for templated emails
PS: in the end I went for slightly more complex scenario:
Defined interface IEmailIntegraton
Code above went into the DefaultEmailIntegration
Added implementations for OutlookEmailIntegration (automation) and theBat! email integration (using their template format).
Allowed users of the SmartClient to select their scenario from the drop-down (alternatively this could've been implemented as "Check the system for the default email handler and decide automatically")
You're making the assumption that they will have an email client installed, of course.
The option I've taken in the past (in a corporate environment where everyone has at least one version of Outlook installed) was to use the Outlook interop - you only need to reference the earliest version you need to support.
You could look at P/Invoking MAPISendDocuments (which I'd try and avoid, personally), or the other option would be to create your own "compose" form and use the objects from the System.Net.Mail namespace.
you can use a trick if you intend to use Outlook[this code is based on outlook 2010[v14.0.0.]]
Create Outlook MailItem
and transmit file (ie download)
if user opens the file (.msg) the compose message dialog opens automatically
here is the code ...
Microsoft.Office.Interop.Outlook.Application outapp = new Application();
try
{
_NameSpace np = outapp.GetNamespace("MAPI");
MailItem oMsg = (MailItem)outapp.CreateItem(OlItemType.olMailItem);
oMsg.To = "a#b.com";
oMsg.Subject = "Subject";
//add detail
oMsg.SaveAs("C:\\Doc.msg", OlSaveAsType.olMSGUnicode);//your path
oMsg.Close(OlInspectorClose.olSave);
}
catch (System.Exception e)
{
status = false;
}
finally
{
outapp.Quit();
}
then transmit the file you created say "Doc.msg"
string filename ="Doc.msg";//file name created previously
path = "C:\\" + filename; //full path ;
Response.ContentType="application/outlook";
Response.AppendHeader("Content-Disposition", "filename=\"" + filename + "\"");
FileInfo fl = new FileInfo(path);
Response.AddHeader("Content-Length", fl.Length.ToString());
Response.TransmitFile(path,0,fl.Length);
Response.End();

Categories