Outlook REST API sync messages: no deltaLink in last response - office365api

I'm using Outlook REST API v2.0, and follow instructions from docs: https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations#synchronize-messages
Everything goes fine, I send Prefer: odata.track-change header with initial and "delta" requests, receive Preference-Applied: odata.track-changes with initial response (not with "delta" or "skip" responses), receive nextLink while there still are messages to sync, but when round is over, docs say I should receive deltaLink, which I can use in following rounds, but I don't receive it.
Here I print request url, count of received messages and keys of parsed json response:
<<<< init url: https://outlook.office.com/api/v2.0/users/UserX#myorg.onmicrosoft.com/MailFolders/Inbox/messages
>> init messages: 100
>> init keys: [u'#odata.deltaLink', u'#odata.context', u'value']
<<<<<<< https://outlook.office.com/api/v2.0/users/UserX#myorg.onmicrosoft.com/MailFolders/Inbox/messages/?%24deltatoken=x6ACBKs7JAHtb4FNhCplyPMw9QUAAGlsP20BAAAA
>> messages: 100
>> response keys: [u'#odata.nextLink', u'#odata.context', u'value']
<<<<<<< https://outlook.office.com/api/v2.0/users/UserX#myorg.onmicrosoft.com/MailFolders/Inbox/messages/?%24skipToken=x6ACAqs7JAHtb4FNhCplyPMw9QUAAGlsP20CAAAA
>> messages: 100
>> response keys: [u'#odata.nextLink', u'#odata.context', u'value']
<<<<<<< https://outlook.office.com/api/v2.0/users/UserX#myorg.onmicrosoft.com/MailFolders/Inbox/messages/?%24skipToken=x6ACAqs7JAHtb4FNhCplyPMw9QUAAGlsP20DAAAA
>> messages: 100
>> response keys: [u'#odata.nextLink', u'#odata.context', u'value']
<<<<<<< https://outlook.office.com/api/v2.0/users/UserX#myorg.onmicrosoft.com/MailFolders/Inbox/messages/?%24skipToken=x6ACAqs7JAHtb4FNhCplyPMw9QUAAGlsP20EAAAA
>> messages: 93
>> response keys: [u'#odata.context', u'value']
As you can see I also use x-AnchorMailbox impersonation, but it's not explicitly prohibited.
So, am I doing something wrong, or this API is broken?

Turned out, despite docs in texts and examples say you don't send Prefer: odata.track-changes header with skipToken requests, you have to do that to receive `deltaToken'.

Related

AWS Lambda Serverless endpoint exits without executing function

We have a POST endpoint in our serverless api which listens to a Magento 2 integration activation callback and processes the payload. The Content-Type of this callback request is application/x-www-form-urlencoded. However, when we try to get the callback, the lambda function finishes execution immediately, skipping the entire function body. What we see in the Cloudwatch logs is only this. Not even console.logs are printed. (the endpoint only prints a string to the console. No async operations are in place. Yet this problem persists)
2020-12-12T12:24:47.012+05:30 START RequestId: 4afba03d-54ef-4b5e-bd44-157b0b7a9f9b Version: $LATEST
2020-12-12T12:24:47.050+05:30 END RequestId: 4afba03d-54ef-4b5e-bd44-157b0b7a9f9b
2020-12-12T12:24:47.050+05:30 REPORT RequestId: 4afba03d-54ef-4b5e-bd44-157b0b7a9f9b Duration: 37.83 ms Billed Duration: 38 ms Memory Size: 128 MB Max Memory Used: 109 MB Init Duration: 893.79 ms
When we try to hit the same endpoint from POSTMAN with Content-Type: application/json, the endpoint works as expected.
Therefore we thought that the problem might be the Content-Type header and read somewhere that adding request mapping templated would solve this problem. Therefore, we even added a mapping template for content type application/x-www-form-urlencoded in the integration request of the lambda method with following content, time to time. But our problem was not solved unfortunately.
"{ "body": "$util.base64Decode($input.body)" }"
{
"formparams" : $input.json('$')
}
{
"body" : $input.json('$')
}
My question is: How we can set the endpoint to print the POST request payload, preventing it from immediate exiting?
We have been searching for a solution to this problem since a week. It would be a great help, if someone can input their helpful, valuable suggestions to solve this problem. Thanks in advance
Since the Content-Type of the Magento 2 Integration activation callback is application/x-www-form-urlencoded, the lambda event for that POST request was something like this.
console.log(event) -> {body: "a=var&b=other_var&c=another_var"}
The endpoint didn't even print anything because I had put console.log(JSON.parse(event. body)). This results in a JSON parse error and the endpoint immediately finishes execution.
When I started parsing the query parameter event body instead of JSON.parse(), the problem was solved.

Runtime Error when sending a search request to outlook for a keyword that does not exist in the mailbox

When searching for a keyword ("Test email"), using Outlook API, and the keyword exist in my mailbox, I retrived a result within a second. However, if the keyword ("blablabla") does not exist in the mailbox I do not get a reply. Almost after 2 minutes I get a runtime error.
http get on: https://outlook.office365.com:443/api/v2.0/users/user#sub.onmicrosoft.com/messages?$search=blablablablabla&$top=100&$select=Sender,ToRecipients,CcRecipients,Weblink,Subject,ReceivedDateTime,BodyPreview
http headers:
Authorization: bearer theToken
x-AnchorMailbox: theEmailAddress
I expected to get an HTTP Response that says something like "Could not find any result"
Instead I get no reply upto two minutes and than a runtime error with that yellow background that instructs to turn on
<customError mode="Off" />
Though the http staus code is 200.
I think as an API consumer I should not get such replies.

Getting SignatureDoesNotMatch error from SQS SendMessage

I am constructing my own REST calls for SQS SendMessage Action.
All the parameters for SendMessage are in request body. (QueueUrl, Action and MessageBody).
I have created my own signature calculation code(mostly copied from AWS SDK Java).
Now, when my MessageBody="HelloWorld" , it works fine.
That means my signature calculation and credentials are correct.
But, when I insert a space , MessageBody="Hello World", I am getting a 403 SignatureDoesNotMatch error from SQS.
I also tried "Hello%20World" as MessageBody , but that also returns a 403 error.
Also tried "Hello+World". But got same error.
I found that aws sdk converts spaces to '+' before calculating the hash of payload.
I tried MessageBody="Hello.World" and that also worked perfectly.
Is there any issue with spaces in Message Body ?
I am sending Host and x-amz-date as the only headers in my request.
The error response from SQS suggests that the hash of the payload is the only thing different in the actual and expected canonical request.

Publish errors with the Faye-Rails gem

I'm using the faye-rails gem for asynchronous messaging between the javascript in my frontend and my rails server. I can send messages using curl and have the javascript print them, so I know the faye server is running. I can also listen to messages on the server like this:
# In application.rb
config.middleware.use FayeRails::Middleware, mount: '/bayeux', :timeout => 25 do
map '/async/**' => FayeController
map :default => :block
end
# In faye_controller.rb
class FayeController < FayeRails::Controller
channel '/async/test' do
subscribe do
puts "Received on channel #{channel}: #{message.inspect}"
end
end
end
Then I receive messages sent via curl -X POST localhost:3000/bayeux -H 'Content-Type: application/json' -d '{"channel": "/async/test", "data": "test123"}' and get the expected output. However, I can't seem to send messages from within the server. I expected somthing like this to work, in the subscribe block (so it would be sent as a response to any message):
FayeController.publish '/async/test', :response => 'something'
but that crashes the whole server with an error:
in '+': no implicit conversion of nil into Array (TypeError)
and then a stack trace. Is this my fault - am I failing to set something up correctly, or misreading the documentation? Or is it a bug in the gem, in which case does anyone have a workaround?
I've actually alread had to use one workaround already due to a bug in the underlying faye library, see here.
You can publish to faye server using an HTTP request (like curl) from your server
uri = URI.parse("http://localhost:3000/bayeux")
begin
Net::HTTP.post_form(uri, response: 'something')
rescue Errno::ECONNREFUSED
puts "Pushing to Faye Failed"
end
--------- Update --------------------------
The previous code needs to be run in another thread to prevent the deadlock (run it in a back ground job using resque for example)
You can use the following to publish in the same thread
client = Faye::Client.new('http://localhost:3000/bayeux')
client.publish('/async/test', {response: "something"})

IMAP attachment retrieving command

I am working on a mail client using IMAP and I am looking for the command for receiving the attachments of a message.
All message info is retrieved using the FETCH command. You have two options on how to use it, however.
First, you can retrieve the entire email message, verbatim. In that case, you're going to need to include a MIME parser in your client to figure out the structure of the message. (Each platform has at least one or two popular MIME parsers; since you haven't told us what you're coding in, I can't recommend one for you.) Once you get the message structure from your MIME parser, you'll need some client logic to determine which parts are attachments. It's worth looking at RFC 2183 to get you started. In general, parts with a Content-Disposition starting with "attachment" are going to be attachments, but all mail client authors go through a phase of trial and error getting it right. In order to download the entire email message, you'd issue the IMAP command
$ UID FETCH <uid> BODY.PEEK[]
Second, you can have the IMAP server parse the message structure for you by issuing a FETCH BODYSTRUCTURE (note: no square brackets). You'll have to parse the returned BODYSTRUCTURE data yourself; the IMAP RFC explains the format and gives a few examples.
# message, no attachments:
("TEXT" "PLAIN" ("CHARSET" "ISO-8859-1" "FORMAT" "flowed") NIL NIL "7BIT" 1469 50 NIL NIL NIL NIL)
# message, one attachment
(("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "QUOTED-PRINTABLE" 56 1 NIL NIL NIL NIL)("AUDIO" "X-WAV" ("NAME" "voicemail.wav") NIL NIL "BASE64" 152364 NIL ("attachment" ("FILENAME" "voicemail.wav")) NIL NIL) "MIXED" ("BOUNDARY" "----_=_NextPart_001_01C4ACB3.5AA7B8E2") NIL NIL NIL)
Once you've determined which parts you're interested in, you can issue a FETCH for the displayable message body. Your client can then just list the message attachments (parsed out of the BODY response) and can then go back and FETCH them if the user clicks on them. So the IMAP commands you'd be issuing would be along the lines of:
$ UID FETCH <uid> (BODY ENVELOPE) # get structure and header info
$ UID FETCH <uid> (BODY[1]) # retrieving displayable body
$ UID FETCH <uid> (BODY[2]) # retrieving attachment on demand
I believe what you are looking for is the IMAP v4 FETCH command.
You could use Context.IO's files resource to quickly and easily fetch attachments.
http://context.io/docs/2.0/accounts/files#get

Resources