Celso
Celso

Reputation: 127

In Outlook Graph API, the message ID appears to change after calling send on a draft

I'm working on an integration with Outlook365 that needs to track the email replies sent through the app, as to make it possible to open the email with Outlook online.

Because /sendMail returns an empty response, reading the documentation I noticed that it's possible to create a draft reply to an existing message with:

POST /v1.0/me/messages/{previous message ID}/createReply

This returns a message representing a reply, that already has a message ID allocated. After updating the message with the correct values, I'm sending it with:

POST /v1.0/me/messages/{draft message ID}/send

This call returns an empty response. Trying to retrieve the message results in a not found error:

GET /v1.0/me/messages/{draft message ID}

However I noticed after listing the messages that after sending, the message was allocated a new ID.

Is there a way to correlate both IDs, or to somehow track a sent message ID so that I can get access to the correct (and final) webLink attribute of the message?

Thanks very much in advance.

Upvotes: 4

Views: 2829

Answers (1)

Saeed
Saeed

Reputation: 182

Unfortunately Microsoft-Graph-API does not return sent-message-id after calling the send-mail-API.

There are some solutions to find sent-message-id.

  1. Search by internet-message-id
  2. Create draft, update the body and send the message (use the draft-message-id)
  3. List messages and filter by conversationId and get the most recent message.

Solutions 1 and 2 are not stable, Microsoft doesn't provide solid documentation and It is not easy to fix the problem.

But, the third solution works fine.

Please consider that Microsoft-Graph-API doesn't support the combination of filter and orderBy.


Graph wrapper


// Microsoft-Graph-API built-in method for list-messages doesn't work fine, so we have to implement it
MGraph.geMessagesByUrl = async function(url) {
  const responseString = await request.get({
    url: url,
    headers: { Authorization: `Bearer ${this.tokens.access_token}` }
  })

  const data = JSON.parse(responseString)

  return data.value
}

MGraph.createMessage = async function(message) {
  // setup your microsoft-graph-api client

  return await client.api('/me/messages').post(message)
}

MGraph.updateMessage = async function(messageId, message) {
  // setup your microsoft-graph-api client

  return await client.api(`/me/messages/${messageId}`).update(message)
}

// Microsoft-Graph-API built-in method for add-attachments doesn't work fine, so we have to implement it
MGraph.addAttachmentNative = async function(messageId, attachment) {
  const options = {
    method: 'POST',
    url: `https://graph.microsoft.com/v1.0/me/messages/${messageId}/attachments`,
    headers: { 
      Authorization: `Bearer ${tokens.access_token}`,
      'Content-Type': 'application/json' 
    },
    body: JSON.stringify(attachment)
  }

  const responseString = await request.post(options)

  return JSON.parse(responseString)
}

MGraph.sendMessage = async function(messageId) {
  // setup your microsoft-graph-api client

  return await client.api(`/me/messages/${messageId}/send`).post({})
}


Sender

const sender = async function(email, attachments) {
  const createMessageResult = await MGraph.createMessage(email)

  for (const attachment of attachments) {
    await MGraph.addAttachmentNative(createMessageResult.id, attachment)
  }

  const updateMessageResult = await MGraph.updateMessage(createMessageResult.id, email.message)
  await MGraph.sendMessage(updateMessageResult.id)

  const conversationId = updateMessageResult.conversationId

  return conversationId
}


List messages, filter by conversatinId and get the sent message

const generateGetByConversationIdQuery = function (conversationId) {
  const syncMessagesPprojection = [
    'id', 'conversationId',
    'internetMessageHeaders', 'internetMessageId',
    'createdDateTime', 'lastModifiedDateTime',
    'sender', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients',
    'hasAttachments', 'subject', 'isDraft', 'isRead'
    // 'bodyPreview', 'uniqueBody', 'body'
  ]

  const projection = syncMessagesPprojection.join(',')

  const select = `&$select=${projection}`
  const expand = '&$expand=attachments($select=id,name,contentType,size,isInline)'
  const filter = `$filter=conversationId eq '${conversationId}'`
  const top    = '&top=100'
  const url    = `https://graph.microsoft.com/v1.0/me/messages?${filter}${select}${expand}${top}`

  return url
}

// Setup you email and attachments objects

const conversationId = sender(email, attachments)
const url    = generateGetByConversationIdQuery(conversationId)
const result = await MGraph.geMessagesByUrl(url)

// Here is your sent message
const sentMessage = result[result.length - 1]

Upvotes: 3

Related Questions