The use case:
We are creating a system which analyses mail content. If we are able to categorize and archive an email based on its content, we want to automatically categorize subsequent emails in the same conversation / thread.
The issue is that the conversationId we get as part of the (mail)message is not unique when we query on behalf of different users.
An example:
A: The conversationId for a given thread in my inbox.
B: The conversationId for the same thread, but in a different user's inbox.
Values:
A:AAQkADUyZWYxNzljLTc4NjItNGMzYy1iZDYwLTE4NWEzNDg1OWUzZQAQABlanHOPI0v1ukA7KePaYv4=.
B:AAQkAGVkNGRjNWNmLTAwNTItNDA2NC1hOThhLTU5NTUyNGFjNTM5ZAAQABlanHOPI0v1ukA7KePaYv4=.
Can I use parts of this conversationId to identify the same conversation across different users? The pattern seems to be that the last 25-26 characters are unique for the given conversation. The rest is a Guid + a postfix of some sort.
Edit: My question is related to usage of the Microsoft Graph API. There are questions answered on SO related to ConversationIds and Outlook emails, but these describe cases getting emails direct from the outlook client (or maybe through the outlook api). For instance are properties like the ConversationIndex and ConversationTopic not in the message I get from the Graph API.
Related
we have a chat bot that seems to be receiving messages from another bot. we'd like to ignore these messages, as responding to them leads to an infinite loop of ping pong between the two bots.
we were hoping to rely on activity.from.role as documented here, but it seems like that field is never set.
activity.from.id looks something like 28:app:00000000-dfae-4fe1-a068-80fe8fc61f2b_62b732f7-fc71-40bc-b27d-35efcb000000, and we are thinking that the only way to identify the account as a bot is by detecting the :app: in these IDs. this is sub-optimal, as this ID format is not part of the official API and could change at any time.
that said, how should we detect if an activity event is coming from a bot?
If you've to deal with potential bots from outside your organisation, a simple way could be to keep a dictionary of few last text exchanges indexed by userId or UserName in the Activity object. Then, at each POST received by your bot, check if the received text match fully one of the precedent message entries in this dictionary. If it is the case, then mark the related userId/UserName as a candidate for the bot role but continue to check further text exchanges in case a non bot user just said hi twice.
If the few following further exchanges doesn't meet anymore the full match requirement, unmark the userId/UserName as a potential bot. If there is marked UserId/UserName as candidate for bot role, apply the bot role to them if there's no more further exchanges past the full match entry or after a delay of your choice. For the latter, it might be useful to provoke a last text exchange after the delay to decide.
For the Watson/Eliza kind of bots, i recommended to check the speed of the exchanges, as far as i know, no human being can exchange more than twenty messages per second.
I'm setting up a MS Outlook Add-In that performs some analysis on newly composed messages. To read the message body, I use the Office.context.mailbox.item.body.getAsync() function that's part of the outlook JS API. If the user is composing a message that's part of a conversation, i.e. when replying or forwarding, this will also yield messages that are part of that conversation. I want to remove previous messages from the returned body, since they are not relevant for the analysis. What is the best way to do this?
What I've come up with is a regex that matches common Conversation headers, specifically "From: ..... abc#def.gh" or similar.
The specific Regex I used:
/((From|Von|De|Desde).+)[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.+/g
I am aware that this will yield many false positives, so I am looking for a better way to accomplish this.
I am developing using the Microsoft Mail Graph API I'd like to provide conversation actions.
For example, if a conversation has several unread messages, marking as read the last one doesn't mark the whole conversation as read (like I'd want).
I didn't see any conversation-level API to mark as read / mark as unread or delete whole conversations.
What would be the best way to achieve conversation updates?
Thanks!
I'm afraid there are not APIs specific to email conversations. In order to process a batch of emails within a conversation, you'll need to update each message individually.
You can determine which messages belong in the conversation using the conversationId. Keep in mind however that a "conversation" is a somewhat loosely defined entity. Exchange generally gets good results but it isn't foolproof by a long shot (for example, a conversation with 10 participants, forward it to an 11th and you often end up with two threads in a single "conversation").
I would suggest using JSON batching for something like this. Batching allows you to bundle multiple Graph commands into a single call. Using batching you could update up to 20 messages at a time.
I would like to use the Outlook REST API to display the messages in a mail folder and group messages by conversations, like you have in any modern webmail.
For example with inbox, I would request using a first query such as <mailuri>/inbox/messages?$select=ConversationId (by default it is reverse chronological order)
It is not sufficient to group this request results by ConversationId because some emails may not be in inbox (think of sentmails) or they may be paginated and not returned in the first page.
Consequently, for each distinct ConversationId I need to perform another REST request, for retrieving participants or simply counting the emails in the conversation. I may use the new batch request to do this.
There are a lot of requests involved. Is there a better solution ?
As you've probably realized the REST API doesn't directly provide a way to work with conversations as an entity. This is something that we have on our roadmap to improve.
With the current state of the API what you're describing is basically the right approach. You could possibly defer the second request to "fill in" a conversation until the user selects it.
You can actually use this endpoint to cover both inbox and sentitems
https://outlook.office.com/api/v2.0/me/messages/?$select=ConversationId & $filter=ConversationId eq '${params.conversationId}'
A web application sends an email on behalf of a UserA to UserB, using the new Gmail API (Users.messages: send).
The synchronous response contains threadId, messageId which are stored in the database.
We then query the history API for any changes in user's inbox (Users.history: list).
Is there an efficient way to get all the updates since last sync (new replies, read/unread changes)?
One implementation that we tried was to filter the history API results through a custom label. Unfortunately, we noticed that once a thread/message is tagged with a specific label any subsequent responses are not labeled automatically and new replies are not included in the history API response.
A second approach was to query threads using gmail advanced search for a particular label and date (e.g. after:2014/08/29 label:MY_LABEL). The problem was that gmail does not return threads that were created before 2014/08/29 but had a reply on that date.
Any scalable suggestions would be greatly appreciated.
Not sure I understand here, users.history.list was made exactly for this. Given a previous historyId, you can then call history.list(previousHistoryid), iterate through the results to find all the message Ids that have been updated since the previous historyId. Then call messages.get() on all of those--for any messages you already knew about you can just call format=MINIMAL (to see label updates), and for new messages you can use a different format to get the message content if you need it.