How to set status after email reading from Google Api - c#

Usually in normal mail the unread status will be changed as read
after we visit that mail like the same way how to find the status
as read while reading email content in google api code in c#

Messages.modify method allows you to make changes to the message. You need to modify the message and remove the UNREAD label. The message will then appear to be read
public static Message ModifyMessage(GmailService service, String userId,
String messageId, List<String> labelsToAdd, List<String> labelsToRemove)
{
ModifyMessageRequest mods = new ModifyMessageRequest();
mods.RemoveLabelIds = "UNREAD";
try
{
return service.Users.Messages.Modify(mods, userId, messageId).Execute();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
return null;
}
Not on access
This method requires one of the following scopes of access
https://mail.google.com/
https://www.googleapis.com/auth/gmail.modify

Related

Can someone help me understand this exception? System.InvalidOperationException: ReferenceAttachment header is corrupt

I'm using aspose.email to automate the process of migrating emails. For only one of the accounts, I'm getting this exception:
System.InvalidOperationException: ReferenceAttachment header is corrupt
at   .    (IAsyncResult )
at   .     ()
at Aspose.Email.Clients.Imap.ImapClient.Backup(IConnection connection, ImapFolderInfoCollection folders, String fileName, BackupSettings options)
at pst_creator.Program.GetEmails() in C:\Users\process.control\source\pst\AlexPST\AlexPST\Program.cs:line 103
Here's the relevant code:
private void GetEmails() //Downloads emails from IMAP server
{
ImapFolderInfoCollection infos = new ImapFolderInfoCollection();
try
{
foreach(string folder in folders)
{
infos.Add(client.GetFolderInfo(folder));
}
client.Backup(infos, $"{pstPath}{client.Username.Replace(accountSuffix, "")}.pst", BackupOptions.Recursive);
logger.Log($"SUCCESS - .pst created for {client.Username}");
}
catch (Exception ex)
{
logger.Log(Environment.NewLine + ex);
}
}
I'm assuming in the users mailbox theres a corrupted inline attatchment. Is there a way I can bypass this error? I would like to be able to skip over corrupted emails.

XmlReader Other Options

I am currently working on an application for the company I work for. Part of this application deals with discrepancy reporting and sending emails out when a new discrepancy number has been created. First, it is important to realize that I am redeveloping this application from VB.NET to C#. In the old application the developer chose to read an XML file for a few email addresses. I've read to use alternate options unless the XML file is full of information. This is not intended to be an opinionated question and sorry if this sounds like one. However, I am looking for the correct way of doing this. Should these email addresses be kept in a database table for easy adding/deleting or is there a more standardized way to do this? Please find the current code below.
public void PrepareEmail(string subject, string message)
{
if (MessageBox.Show(#"Are you sure you want to save and send Discrepancy Report: " + tbxDRNumber.Text + #"?\n Click YES to save\n Click NO to cancel", #"Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
SendEmail(subject, message);
}
}
public Array AddEmail()
{
string[] dRemail = { "", "", "" };
if (File.Exists(#"\\fs01\Applications\EMS-Manager\DREmailAddresses.xml"))
{
XmlReader emailDocument = new XmlTextReader(#"\\fs01\Applications\EMS-Manager\DREmailAddresses.xml");
while (emailDocument.Read())
{
var type = emailDocument.NodeType;
switch (type)
{
case XmlNodeType.Element:
if (emailDocument.Name == "DRCreatedAddEmail")
{
dRemail[0] = emailDocument.ReadInnerXml();
}
if (emailDocument.Name == "DRActionNeededAddEmail")
{
dRemail[1] = emailDocument.ReadInnerXml();
}
if (emailDocument.Name == "DRPendingAddEmail")
{
dRemail[2] = emailDocument.ReadInnerXml();
}
else
{
MessageBox.Show(#"The file: 'DREmailAddresses.xml' was not found at: \\fs01\Applications\EMS-Manager");
}
break;
}
}
}
return dRemail;
}
public void SendEmail(string subjectText, string bodyText)
{
string[] email = (string[])AddEmail();
//object oOutlook = default(Microsoft.Office.Interop.Outlook.Application);
var oMessage = default(MailItem);
Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application"));
if (subjectText == "New Discrepancy Created. DR" + tbxDRNumber.Text + " ")
{
oMessage.To = email[0];
oMessage.Subject = subjectText;
oMessage.HTMLBody = bodyText;
try
{
oMessage.Send();
}
catch (System.Exception e)
{
MessageBox.Show(#"Send Failed with error: " + e);
throw;
}
}
else if (subjectText == tbxDRNumber.Text + " - Action Needed")
{
oMessage.To = email[1];
oMessage.Subject = subjectText;
oMessage.HTMLBody = bodyText;
try
{
oMessage.Send();
}
catch (System.Exception e)
{
MessageBox.Show(#"Send Failed with error: " + e);
throw;
}
}
else if (subjectText == tbxDRNumber.Text + "DR Pending Approval")
{
oMessage.To = email[2];
oMessage.Subject = subjectText;
oMessage.HTMLBody = bodyText;
try
{
oMessage.Send();
}
catch (System.Exception e)
{
MessageBox.Show(#"Send Failed with error: " + e);
throw;
}
}
}
There isn't necessarily anything wrong with flat file configuration files. It really depends on your use case. How often do the emails in the file change? How many entries are there? Do users of the application edit the list? Are there any complex rules where different addresses will get sent different emails?
If this just a simple mailing list that doesn't change often it's probably fine to use the xml file. You could also just create an email distribution list to send to instead, like ApplicationDiscrepancyReport. That way you can just manage the recipients in active directory. If you stick with the XML email addresses, at the very least I would try to get rid of the hardcoded path to the xml file located on your file share.
If the email addresses change a lot, and are changed by users of the application, I would recommend moving this to a SQL database. If the recipients list is changing frequently you may want to add tracking of when these addresses get edited as well.

Cannot delete an email message using POP3

I have code that uses POP3 to access an email account and search for messages that were sent but the address did not exist. After processing them, I delete the failure message. I have one client who can get and process the messages, but is not able to delete them. They keep getting the message Error deleting message 1: -ERR The specified message is out of range.
The code for my delete method is below. This works for most clients, and is pretty simple, so I'm not sure why it isn't working.
public bool Delete(int index)
{
bool result = false;
String response = SendReceive("DELE ", index.ToString());
if (response.StartsWith("+OK"))
result = true;
else
logger.Log("Error deleting message " + index + ": " + response, Verbose.LogImportant);
return result;
}
For the SendReceive method:
private String SendReceive(String command, String parameter)
{
String result = null;
try
{
String myCommand = command.ToUpper().Trim() + " " + parameter.Trim() + Environment.NewLine;
byte[] data = System.Text.Encoding.ASCII.GetBytes(myCommand.ToCharArray());
tcpClient.GetStream().Write(data, 0, data.Length);
result = streamReader.ReadLine();
}
catch { } // Not logged in...
return result;
}
The index is taken directly from the received email, and the connection is not closed until after the delete method has processed. Since there has to be an email returned to run this method, and since the index runs from 1 to n, with a 1 being sent, I don't see what is causing this to fail.
The SendReceive() call looks wrong. My guess is that it should probably have a {0} in the format string. In other words, your code is probably sending DELE instead of DELE 1.

SmtpMail.Send() doesn't work

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

Outlook MailItem Save/SaveAs

I have an outlook add-in that allows the user to save an email into a database. When the user does save the email I modify the email subject so it can be identified as being saved.
Saving the email can happen in two ways. Via a button on the tool bar which allows the user to save any email they want, and also via a prompt which appears when a new email is put into the Sent Items folder. Both methods use the same form to save the email!
OK, now to the problem ....
In the process of saving the email I use the mailItem.SaveAs method to put it into the file store. After this has completed successfully i want to change the subject of the email which still exists in outlook to say that it has been saved successfully. I do this by changing myItem.Subject and then using the mailItem.Save method to save the change.
The above works perfectly when the email isn't being saved via the prompt method. So when the user tries to save the email after they send it the mailItem.Save method does not work.
I have narrowed it down to it actually working if i put the myItem.Save() line before the myItem.SaveAs() line, but obviously if I do this I can not guarantee the email was actually saved properly.
So does any one know of a reason that the mailItem.Save method would want to not work after the mailItem.SaveAs method as been called?
Thank you in advance to any suggestions to what might be the problem.
EDIT : Code
if (_item is Outlook.MailItem) { // if the incoming item is an Outlook mail Item
// cast as a mail item
Outlook.MailItem myItem = (Outlook.MailItem)_item;
if (directoryExists(directoryTemp)) { // if the temporary directory exists
bool _profiled = true;
// copy the item as type .msg in the temporary location
myItem.SaveAs(saveTemp, Outlook.OlSaveAsType.olMSG);
// setup impersonation to copy the file to a secure location
PImpersonateUser _iU = new PImpersonateUser();
// do impersonation
try {
_iU.Impersonate("******", "******", "******");
if (File.Exists(savefile)) { // if file already exists in the location
// delete existing file
File.Delete(savefile);
}
// move the temporary file to the secure location with the proper name
File.Move(saveTemp, savefile);
string year = "";
if (ipt_year.SelectedItem != null) { // else if year has been selected
year = ipt_year.SelectedItem.ToString();
}
_profile.profileEmail(folderString(_subject_), _fileName, year);
} catch (Exception e) {
_profiled = false;
// if impersonation fails cancel the impersonation
_iU.Undo();
// show error
MessageBox.Show(e.Source + "\n\n" + e.Message + "\n\n" + e.StackTrace, "SaveAs() Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
} finally {
_iU.Undo();
}
if (_profiled) { // if the email was profiled successfully
// mark the original email as being profiled
markAsProfiled();
}
} else {
// if temporary file save fails throw error
MessageBox.Show("Temporary Directory (" + directoryTemp + ") Does Not Exist!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
and the markAsProfiled function ...
private void markAsProfiled() {
if (_item is Outlook.MailItem) { // if the incoming item is an Outlook mail Item
// cast as a mail item
Outlook.MailItem myItem = (Outlook.MailItem)_item;
// make sure subject doesnt already have a profiled flag in the subject
_subject_ = _subject_.Replace("[PROFILED] - ", "");
// add a profiled flag in the subject of the email
myItem.Subject = "[PROFILED] - " + _subject_;
// add a yellow flag to the email
myItem.FlagIcon = Microsoft.Office.Interop.Outlook.OlFlagIcon.olYellowFlagIcon;
// save email with changes made
myItem.Save();
//MessageBox.Show("Mark as Profiled :: " + myItem.Subject + " :: " + myItem.Saved.ToString() + " :: ");
}
}
if this is still relevant to you: You could use a self-defined column in which you could write wether the saving was successfull or not.
Example code:
mail.UserProperties.Add("Profiled", Outlook.OlUserPropertyType.olText, true);
mail.UserProperties["Profiled"].Value = "Yes";
mail.Save();
The only disadvantage is that you've to add the field to the displayed columns in Outlook. (maybe that can be done programmatically)
About why your method doesn't work: I could imagine that Outlook doesn't like it when you change the subject of an email after it was sent.

Categories

Resources