Exchange 2010, find out if email is meeting invite without loading attachment - exchange-server

I have a mail sniffer program running on an Inbox in Exchange Server 2010 that checks emails at certain intervals. I would like to know if it somehow is possible to programmatically check with EWS (Exchange Web Services) if an email (EmailMessage) is a meeting invite (calendar request) without loading the attachment.
I know I can check if an attachment is an Microsoft.Exchange.WebServices.Data.ItemAttachment and then, after loading the email check if this is an Microsoft.Exchange.WebServices.Data.Appointment. But this only checks if the attachment is an invite. Theoretically someone could forward an email with amongst other thing an email invite. Then the email is really not a meeting invite, just a forwarded email.
Can you know if an email is a meeting invite without loading the attachment? Should this not be possible with EWS, is there an authorative source for this?
Edit: Forwarded emails
This is outside the question, but I originally asked:
Alternatively (but not what I am hoping for), is there a way to know
if an email was forwarded so that I can handle them differently?
This has been answered here. But I still would like to get an answer for my question as this answer only helps creating a workaround for some cases.
Thanks in advance!

You can leverage the EmailMessage Message Class ItemSchema.ItemClass property to determine what type an item is. Here is a snippet to help you out...
FindItemsResults<Item> mailItems = inbox.FindItems(new ItemView(1000) { PropertySet = new PropertySet(ItemSchema.Id, ItemSchema.HasAttachments, ItemSchema.Subject, ItemSchema.ItemClass) });
foreach (EmailMessage message in messageItems)
{
if (message.ItemClass == "IPM.Schedule.Meeting.Request")
// we have a meeting request
}

Related

Outlook VSTO error when saving appointment item

We have a VSTO add-in for Outlook, that supports booking of resources managed by our cloud system.
In addition we support resources that are also available in Exchange as rooms to support integration with other systems.
When we perform a booking of such a room, the add-in adds the corresponding Exchange email address for the room to recipients, so it will also be booked in Exchange.
This used to work fine, but now we have received a report from a customer that they can no longer create bookings for resources with Exchange integration. The error they receive is completely unhelpful:
System.ArgumentException: Der gik desværre noget galt. Du kan prøve igen.
ved Microsoft.Office.Interop.Outlook._AppointmentItem.Save()
(in English: "Something went wrong. You can try again")
This happens when add-in attempts to save the item after adding some custom properties. I think the error is triggered by the add-in adding the Exchange rooms to recipients, since it does not happen for resources without Exchange integration.
Here is the code we use to add recipients:
var rec = ...; // custom DTO with recipient info
string recipientInfo = string.IsNullOrEmpty(rec.Email)
? rec.OutlookName
: rec.Email;
var recRecip = appointment.Recipients.Add(recipientInfo);
recRecip.Type = rec.RecipientType;
if (Current.Settings.IsEnabled(FeatureFlag.ResolveAddedRecipients))
{
using (LogHelper.TimedTask($"resolving recipient [{rec}]", Log))
{
recRecip.Resolve();
}
}
I can see from the logs, that the room recipient has email address, so above code will add by email. Also, the feature flag to resolve recipients is enabled, so the code will call resolve afterwards.
What could be going wrong here?
EDIT: Their Outlook version is 16.0.0.5071.
If the problem is isolated to the user's computer, we always recommend our IT staff to share the O365 Outlook Diagnostics Tool which analyses the outlook install, data files, plugins, cache and performs checks to identify source of issues on client computers.

Outlook API, Message Moved to "Sent Items" still beign marked as "[Draft]"

I'm working on an Outlook Add-in, using office.js, where users can send secure emails using backend service.
In compose mode, when the user sends the email, using the add-in of course, the add-in will then move the message to "Sent Items" folder using the Outlook API /message/{id}/move and everything goes OK with the exception that the message in question still being marked as "Draft" by Outlook which is really annoying and does confuse the user who just sent the email by telling him that "this message hasn't been sent"
I searched through the API to see if there is a way to mark an email as "SENT" in order to prevent Outlook from showing this RED hint but with no luck so far!
So, My Question Is: Is there any way to overcome this misleading msg by marking the email as it was sent by Outlook?
Thanks in advance.
Finally, I was able to achieve a perfect solution for this challenge.
Based on:
#BrianClink's comment
This answer (Which uses Graph API but Outlook REST API): Microsoft Graph API mail office 365: Is any option create inbox message NOT as Draft?
The approach/steps I followed to mark a mailItem as "SENT" (and not shown as 'draft') and put it in "SentItems" Folder are as follow:
First, Save the mailItem as "draft" using Office.context.mailbox.item.currentMail.saveAsync then retrieve its ID
Clone this draft mailItem properties eg: 'Sender', 'Subject', 'Body', 'ToRecipients'..etc so you get an exact copy of it.
With the newly cloned mailItem, add '[SingleValueExtendedProperties]' property with this value :
[
{
PropertyId: 'Integer 0x0E07',
Value: '1'
}
];
Serialize the new item as JSON and POST it to "sentitems" folder as follows:
xhr.open('POST', restHost + '/v2.0/me/MailFolders/sentitems/messages/');
xhr.send(clonedEmailJson);
On success, with xhr.status=201 [created], Remove the draft mailitem using a [DELETE] request
And you will end up having a new mail item created in your "sentItems" folder which appears as it was sent by Outlook :)
This was a very helpful solution to me because my users are using my add-in to send secure emails (using 3rd party API) and NOT Outlook, So, I wanted them to have the same UX/feeling as when they use Outlook.
Note:
Although the solution worked for me perfectly, it came with a price!
On slow internet connections or in case emails containing large attachments, the process can be remarkably slow, because the addin will first save the draft to the remote Exchange Server, get its ID, then duplicate it and send it again to the server, then remove the draft-ed one.

Gmail New Threading Policy requires workaround - how to fix?

Per this announcement - https://gsuiteupdates.googleblog.com/2019/03/threading-changes-in-gmail-conversation-view.html -- an email with the exact same from/to and subject will no longer thread in Gmail if the emails are system generated unless we somehow reference the original message information in the subsequent system generated emails.
Does anyone have ideas for how we would do this in CDO mail using ASP / VBScript? Am guessing we would have to call a Google API to get the message ID after it created the message as well.
Google was not able to provide any help over and above the language used in this blog article which was as below:
Additional details
If you are managing a system that sends email notifications to users
and want your emails to be threaded in Gmail conversation view, then
you have to ensure that your notifications:
1) Have the same subject
2) Have reference headers that reference IDs seen earlier in the
thread, or have references headers that consistently refer to the same
message ID
Ideas are appreciated.
I'm not sure why you're looking for any sort of Google API, this sounds to be the standard "References" and "In-Reply-To" headers that any email reply should have. Refer to section 3.6.4 "Identification Fields" in RFC 5322. To create this you'd need to read the Message-ID header of the email being replied to and use it in the References header.
Just read the Message-ID of the email you're replying to like any other header:
Dim OriginalMessageId as String
OriginalMessageId = originalEmail.Fields.Item("urn:schemas:mailheader:message-id")
And use it to create the References headers in your new email:
replyEmail.Fields.Item("urn:schemas:mailheader:references") = OriginalMessageId
replyEmail.Fields.Item("urn:schemas:mailheader:in-reply-to") = OriginalMessageId
If you need more of a pointer of how this would work, you might need to include more of the code of how you're reading a message and how you're replying to it.

How to know mail send or not send in laravel and which recipient is not getting it?

Hi I am using the bellow function, can you please guide me how can I use Mail::failures(); in it
Mail::send('emails.caregiversetprimary', $templateArray, function($message)use($email)
{
$message->to($email, 'username')->subject('my subject');
});
Mail::failures(); < ====== this gives me black array as I have used wrong email
I am using laravel 4.1
tl;dr
You can know which recipients the email has been sent to but no which recipients have received it.
details
You need a better understanding of how mail servers work. From a Laravel point of view, there is no way (or at least not a simple one*) of knowing which recipients got the email. Its a matter of how mail protocol works. You may know which recipients the message has been sent to but no which recipients actually got it.
With Mail::failures() you get a list of recipients to which Laravel tried to send the email but it failed on actually sending it. But again, if it has been sent there is no straightforward way to known if the mail reached their inbox or no.
*If you happend to use Mailgun, Mandrill or any other 3rd party software then you are not dealing with a mail server 'per se' but with an API service. May be you could check the mail service provider documentation to research if they perform any kind of delivery tracking that you can programatically check.

Ical parsing Propose new time with Outlook

I'm building a web application that sends meeting requests to user's Outlook. Every meeting request is created with a virtual organiser. Then, I have a service that is polling the virtual organiser's pop3 inbox to retreive attendees response to the meeting request (Accept/Decline/Propose new time).
All the information is parsed using the ICal string that outlook sends. Now I'm able to detect if an attendee has accepted or declined easily. I can also detect if the attendee proposed a new time but my problem is that there is no where in the ICal string I can fin the actual new time proposed, except in the email message, which is something I really don'T want to parse :)
Anybody knows where I can find the new time proposed without parsing the email message itself?
thanks
I don't know how Outlook does these things, but the proper way to propose a change to the appointment date is:
List item
You send a METHOD:REQUEST, not a METHOD:REPLY.
You identify the appointment you are referring to via the UID property.
If you change the DTSTART, you propose to change the start date (DTEND for the end date...).
This is explained in iTIP, RFC 2446, 3.2.2.1, "Rescheduling an event"
So the information you need should be in the ICAL file

Resources