Office 365 Impersonation - c#

I'm trying to send an email from my Office 365 account while impersonating User2.
{
ExchangeService service = new ExchangeService();
string fromUserEmail = new string("User2#domain");
service.Credentials = new WebCredentials("User1#domain", "password");
service.UseDefaultCredentials = false;
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, fromUserEmail);
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
EmailMessage email = new EmailMessage(service);
email.ToRecipients.Add("someone#somewhere");
email.ReplyTo.Add(replyToEmail);
email.Subject = "HelloWorld";
email.Body = new MessageBody("Test message");
email.Send();
}
I get a System.NullReferenceException: 'Object reference not set to an instance of an object.' on email.Send(). When I comment out the service.Impersonation it works. What am I doing wrong?

Solved. I needed permission via
New-ManagementRoleAssignment -Name:User1_impersonation -Role:ApplicationImpersonation -User: "User1#domain"
I don't know why Visual Studio didn't provide a more useful error message.

Related

How to get Email ConversationId by EWS after send email

I want to get the email's ConversationId after sending an email.
I am using Microsoft exchange web services package for sending an email.
using Microsoft.Exchange.WebServices.Data;
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.UseDefaultCredentials = false;
service.Credentials = new WebCredentials('*****', '*****');
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.AutodiscoverUrl(emailExist.Email, RedirectionUrlValidationCallback);
EmailMessage emailMessage = new EmailMessage(service);
emailMessage.From = "abcd#xyz.com";
emailMessage.Subject = "testing email";
emailMessage.Body = new MessageBody(BodyType.HTML, "<b>Hello</b> World");
if (!string.IsNullOrEmpty(email.To))
{
var toArr = email.To.Split(',');
foreach (var toAddress in toArr)
{
emailMessage.ToRecipients.Add(toAddress.Trim());
}
}
// Send message and save copy by default to sentItems folder
emailMessage.SendAndSaveCopy();
In EWS Sends are asynchronous so you won't get back the Id of the message you just send in the Send Method. If you save the Message as a draft first before sending it that should populate both the Message and CoversationId's eg
EmailMessage em = new EmailMessage(service);
em.Subject = "Test"
em.Save();
em.Load();
Console.WriteLine(em.ConversationId.UniqueId);

Unable to send messages via SMTP mailkit and Gmail API using Service Account

I've been working for some time to try and get this system to work with the gmail api system and a service account (to avoid creating an empty user account), and I'm not sure where I've gone wrong.
public static async Task<ServiceResponse> SendMail(ContactUsModel ContactInfo)
{
ServiceResponse response = new ServiceResponse();
try
{
var certificate = new X509Certificate2(#"cert.p12", "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer("service account")
{
// Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes
Scopes = new[] { "https://mail.google.com" },
User = "service account"
}.FromCertificate(certificate));
// Note: result will be true if the access token was received successfully
bool result = await credential.RequestAccessTokenAsync(CancellationToken.None);
// create an OAuth2 SASL context
var oauth2 = new SaslMechanismOAuth2("service account", credential.Token.AccessToken);
MimeMessage msg = new MimeMessage();
msg.From.Add(new MailboxAddress(ContactInfo.Name, ContactInfo.EmailAddress));
msg.To.Add(new MailboxAddress("Me", "business email account"));
msg.Subject = ContactInfo.Subject;
msg.Body = new TextPart("plain")
{
Text = $"From: {ContactInfo.Name}\nEmail: {ContactInfo.EmailAddress}\nDate:{ContactInfo.AppointmentDate.ToString()}\nMessage: {ContactInfo.Message}"
};
using(SmtpClient client = new SmtpClient())
{
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
client.Authenticate(oauth2);
client.Send(msg);
client.Disconnect(true);
}
response.Success = true;
response.Message = "Message Sent";
}
catch (Exception e)
{
response.Success = false;
response.Message = "An error occurred. Please call us.";
}
return response;
}
I enabled the gmail api, and set the service account to cloud function invoker.
This is the error I'm currently getting, and I'm not sure why.
{"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}
Edit:
Update code and update error message.
You're using the wrong scope. The "https://www.googleapis.com/auth/gmail.send" scope is for using an HTTP-based protocol library to send messages.
You need the "https://mail.google.com/" scope for use with IMAP, POP3, and/or SMTP protocols.

How to send an email, via ExchangeService C#

I have to send an email through Exchange. I found that I can do this using ExchangeService. I've tried many ways to do this, but only what I've got is error: (440) Login Timeout.
I don't even know if there is a problem with credentials, or my code is wrong.
string login = #"login";
string password = #"password";
ExchangeService service = new ExangeService();
service.Credentials = new NetworkCredential(login, password);
service.Url = new Uri(#"https://mail.exchangemail.com");
EmailMessage message = new EmailMessage(service);
message.Subject = "Interesting";
message.Body = "The proposition has been considered.";
message.ToRecipients.Add("quarkpol#gmail.com");
message.From = "quarkpol_test#gmail.com";
message.Send();
I've found the problrm solution on the web, and it works.
using EASendMail;
string login = #"login";
string password = #"password";
SmtpMail oMail = new SmtpMail("TryIt");
SmtpClient oSmtp = new SmtpClient();
oMail.From = "from#email.com";
oMail.To = "to#email.com";
oMail.AddAttachment(fileName, fileByteArray);
oMail.Subject = "Subject";
oMail.HtmlBody = "HTMLBody";
SmtpServer oServer = new SmtpServer("mail.email.com");
oServer.Protocol = ServerProtocol.ExchangeEWS;
oServer.User = login;
oServer.Password = password;
oServer.ConnectType = SmtpConnectType.ConnectSSLAuto;
try
{
Console.WriteLine("start to send email ...");
oSmtp.SendMail(oServer, oMail);
Console.WriteLine("email was sent successfully!");
}
catch (Exception ep)
{
Console.WriteLine("failed to send email with the following error:");
Console.WriteLine(ep.Message);
}

Accessing room calendar in EWS returns "No mailbox with such guid"

I am trying to get the list of meetings from a room shared calendar using Microsoft Exchange (EWS) API and it's returning this error: No mailbox with such guid
var service = new ExchangeService();
service.Credentials = new NetworkCredential("username", "password");
service.Url = new Uri("exchangeUrl");
var startDate = DateTime.Today;
var endDate = DateTime.Today.AddDays(1);
var cv = new CalendarView(startDate, endDate);
var mailboxToAccess = "room_email_address#mycompany.com";
var calendarFolderId = new FolderId(WellKnownFolderName.Calendar, mailboxToAccess);
var appointments = service.FindAppointments(calendarFolderId, cv); // << Exception happens here
Any ideas what could be wrong?
Make sure that the user that you're using in
service.Credentials = new NetworkCredential("username", "password");
is a licensed user, with their own mailbox, that has been granted access to the Shared Mailbox in question.
Use this, if you're trying to access Outlook mail box from an application end.
Language:C#
service.Credentials = new NetworkCredential("username", "password");
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");

Regarding EWS web service for office 365

I am using EWS web services for fetching emails form office 365 account.
I am getting this error
The Autodiscover service couldn't be located.
I have written this code.
ExchangeService service = new ExchangeService(userData.Version);
if (listener != null)
{
service.TraceListener = listener;
service.TraceFlags = TraceFlags.All;
service.TraceEnabled = true;
}
service.Credentials = new NetworkCredential(userData.EmailAddress, userData.Password);
service.UseDefaultCredentials = false;
if (userData.AutodiscoverUrl == null)
{
Console.Write(string.Format("Using Autodiscover to find EWS URL for {0}. Please wait... ", userData.EmailAddress));
service.AutodiscoverUrl(userData.EmailAddress);
userData.AutodiscoverUrl = service.Url;
Console.WriteLine("Complete");
}
Please check what i am doing wrong.
Thanks
Try the following:
ExchangeService service = new ExchangeService();
service.TraceEnabled = true;
service.Credentials = new WebCredentials(User, Pwd);
service.AutodiscoverUrl(User, RedirectionUrlValidationCallback);
service.TraceEnabled = true;

Categories