Wallet Pass auto update web service using aws api gateway - node.js

I am working on a web service to update Apple Wallet passes using AWS Lambda/API gateway/NodeJS. The Apple wallet hit the api to get update pass but each time I am getting following error:
encountered error: Received invalid pass data (The pass cannot be read because it isn’t valid.)
I have tried the same URL in the browser to get the pass. The pass is downloading every time and its opening a valid pass every time. But its not working when Apple wallet hit the URL. I have tried same URL in Postman it gives me base64 instead of binary data.
I have tried to achieve the same functionality with NodeJS and deployed on heroku, its working properly with Wallet(also gives binary in Postman). But I need to use AWS Lambda/API gateway/NodeJS.
I am not sure, if AWS changing something while delivering binary data.
Any help on this is appreciated.

I just experienced this and spent hours trying to diagnose what was happening.
For anyone using AWS API Gateway & Lambda for their PassKit web service endpoints, there's a major "gotcha" (at least as of the date of my response) with how API Gateway's logic determines whether it needs to convert a response from base64 ==> binary.
If you inspect the request headers from Apple Wallet / PassKit, you'll see that the Accept header is */*.
API Gateway apparently iterates through the items in the request Accept header and determines if there is a match with any of the Binary Media Types you've defined under Your API Name > Settings. It will use the first match it finds and then, as you'd hope, convert the base64 string (from Lambda) to binary.
Here's the crazy part -- if you define application/vnd.apple.pkpass as one of your "please convert to binary" media types, requests from Apple Wallet / PassKit will not work. Why? Well, AWS (for whatever reason...) hasn't programmed */* to match any type ... it will literally only match */*.
As a result, the Accept header's */* will not match with application/vnd.apple.pkpass and your base64-encoded .pkpass response (from Lambda) will not be converted to binary, causing PassKit to choke + report errors.
TL;DR -- there is some goofiness with AWS API Gateway. To return PassKit pass data successfully, you need to add */* (not application/vnd.apple.pkpass) under Your API Name > Settings > Binary Media Types.

Related

500 error when using the shopping.flightDates.get endpoint

Using your API for an fun app I am developing and I just started using your eendpoints, This particular endpoint gives me this responseError:
body: '{"errors":[{"status":500,"code":141,"title":"SYSTEM ERROR HAS OCCURRED","detail":"ORIGIN AND DESTINATION NOT ALLOWED FOR AMA4DEV EXTREME SEARCH REQUESTS ON ENVIRONMENT"}]}',
The endpoint I am hitting is:
amadeus.shopping.flightDates.get({
origin : 'PHX',
destination : 'MEX'
}).then(function(response){
console.log(response.data);
}).catch(function(responseError){
console.log(responseError.response);
});
To make sure it was not something with the auth token/secret I made sure to make a test call using your example on github that works which was:
amadeus.shopping.flightDates.get({
origin : 'MUC',
destination : 'MAD'
}).then(function(response){
console.log(response.data);
}).catch(function(responseError){
console.log(responseError.response);
});
No problem in hitting that endpoint. Thank you again for looking into this
If you use the test environment: it is free of charge but limited (limited number of API calls you can do per month and limited set of data (a subset of production data)). For each API you can find the data collection available here.
For Flight Cheapest Date Search API, the test environment doesn't have data for PHX as origin.
I tried in production and it does return data. Please note that Flight Inspiration Search and Flight Cheapest Date Search are built on top of a pre-computed cache (in production). As they are inspirational APIs we do not offer all pairs of origin-destination but only the most searched all over the world. If you want to get the full list of origin-destination pairs (even smaller cities), you need to use the Flight Offers Search API.

Multiple api call

I'm trying to build a nodejs app that runs and if statement to query multiple api's to return a result. Example, running yelps api first, if it finds then break, else continue query another api such as google places or white pages api until it finds a result.
I am passing in either a name of a business, address to return a telephone number. the results expected are in json. I am drawing a blank.
ideas?
so the way to achieve this is you should be able to make http req from your server side and when a result comes with a response then you should check that response. If your requested answer is not in it then you should keep on trying other API end points untill u come across with a suitable response..
so here are some npm packages to achieve this simply
http - node js built in package
Axios - here
request - here
try using one of these packages .. I would use axios .. read their doc and try to do it .. It should clear somethings out for you

php library for flickr API

I am banging my head trying to use Flickr API...
My goal is to be able to upload images and create albums in my Flickr account from my website...
I tried the phpFlickr library but apparently it needs updates for getting authenticated tokens...It keeps giving me "Invalid auth token".
I did some reading on how to get tokens and using DPZFlickr managed to get oauth_token & oauth_verifier but failed to exchange that with an access token...It also failed in uploading any photo to my account using the included upload.php example (Giving me an "empty" error!).
After digging in DBZ flickr.php code, I managed to get this error when trying to upload to Flickr: "oauth_problem=signature_invalid&"
So I began to search how to create a valid signature to eventually get a valid access token...and concluded that it is quite some work to be done here if I am going to build everything from scratch.
So my question is: Are there any updated php libraries that I can use to successfully create albums and upload photos to my Flickr account? Or should I go ahead and try building one?
OK..I finally got it to work with the DPZ library.
For future reference anybody facing the same problem as I had:
I managed to create an album using DPZFlickr by changing the method in auth.php to flickr.photosets.create....which indicated that the library correctly generates an access token with write permission..
However, the upload example kept giving me the "Invalid signature" error....
I checked the code. Flickr.php correctly unsets the photo parameter before signing the request then adds it back and submits the request which is exactly as indicated in: www.flickr.com/services/api/upload.api.html
I found a discussion in https://www.flickr.com/groups/51035612836#N01/discuss/72157650261711318/ that cleared out that the error was not actually a signature problem, but rather the 'photo' parameter that is being sent is the problem. It's just that Flickr doesn't know what to do with the photo parameter so it sends the signature error.
So what' wrong with the photo parameter?
Flickr API requires that the image has to be sent in binary form...The DBZ library, Flickr.php script line 677, does the hard work for us using the cURL function in php (http://au.php.net/manual/en/function.curl-setopt.php).
It sends the $parameters (which includes the uploaded photo) to the post field of the http request which should do the upload in binary format for us.
However, a brilliant comment I found in CURL PHP send image
states that:
"CURLOPT_SAFE_UPLOAD defaulted to true in 5.6.0... so you will need to add curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); before setting CURLOPT_POSTFIELDS"
Checking the manual: http://au.php.net/manual/en/function.curl-setopt.php
it says:
"Added in PHP 5.5.0 with FALSE as the default value. PHP 5.6.0 changes the default value to TRUE."
So if your php version is 5.5.0 the library will work just fine whilst if using version PHP 5.6.0 you need to add a line before 677 in Flickr.php to change the CURLOPT_SAFE_UPLOAD to false (that's why the library works with some and others not).
To solve the issue...Just add this line before line 677 in Flickr.php:
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
That's it. (-:

File not supported error while uploading profile image file to IBM Connections using REST API

I'm trying to upload a jpeg file for profile image using the Profiles REST API to IBM Connections_v5.0. I however get an error message "The type of the photo file you provided is not supported".
I'm however able to upload the same file directly using the Connections UI interface directly. I'm setting the MIME type correctly as "image/jpeg".
Also tried with GIF and PNG images but get the same error message.
Any pointers would be very helpful.
I'm just using FF restclient addon to fire a REST call. So basically doing a PUT on /profiles/photo.do?key=....
Content-Type is set as "image/jpeg" and the payload consists of the image data in binary (base 64) encoded.
The payload should just be the binary of the image, there is no need to Base64 encode it.
You should refer to Adding a Profile Photo
You need to use a Key (great stackoverflow post here)
If you know the key for a user's profile you can do the following:
key — This is generated by Connections itself during the population
process. It is used to define the users profile within the context of
Profiles and provides Connections with the ability to associate
content with a user when the users LDAP information has been altered.
It provides a separation of identity and helps facilitate user content
synchronization for Connections.
Once you have a key, you make the following request
URL: https://profiles.enterprise.example.com/profiles/photo.do?key=
b559403a-9r32-2c81-c99w-ppq8bb69442
METHOD: PUT
CONTENT-TYPE: image/png
input the binary content on the stream
you should be able to use "image/jpeg", "image/jpg", "image/png" or "image/gif"
If you have an error after the PUT method, you should add the SystemOut.log lines which are relevant.

Windows Azure - Set Blob Service Properties REST API Call Authentication parameter

I am trying to make a simple REST call to the Set Blob Properties API (http://msdn.microsoft.com/en-us/library/windowsazure/hh452235) to just turn off/on logging. I have gotten the REST API call to successfully work for retrieving Blob Properties, so I know my hashing algorithms, headers-setting, and Authentication signature creation works, but I can't seem to get it working on the Set Properties side of things. I keep getting an error on the Authentication Header, so I know I'm not doing something right there.
I have copied below what is being created and eventually hashed and put into the auth header string. The online documentation (http://msdn.microsoft.com/en-us/library/windowsazure/dd179428) does not really help in determining which of these fields are absolutely required for this particular type of Blob request, so I've tried filling most of them in, but I don't seem to get a difference response regardless of what I fill in. I've also tried the Shared Key Lite authentication, which would be preferred since it's much more lightweight, but that doesn't seem to work either when I fill in all 5 of those fields.
Shared Key Authentication for Blob Services:
PUT\n
\n
\n
130\n
(MD5_CONTENT_HASH)
\n
\n
\n
\n
\n
\n
\n
x-ms-date:Tue, 19 Jun 2012 19:53:58 GMT\n
x-ms-version:2009-09-19\n
/(MY_ACCOUNT)/\n
comp:properties\n
restype:service
Is there anything obvious I'm missing here? The values (MD5_CONTENT_HASH) and (MY_ACCOUNT) are of course filled in when I make the request call, and the similar request call to "GET" the properties works fine when I send it. The only difference between that one and this is that I'm sending the MD5_content, along with the content-length. I may be missing something obvious here, though.
Any advice would be greatly appreciated! Thanks in advance.
-Vincent
EDIT MORE INFO:
Programming Language I'm using: Objective-C (iOS iPhone)
I'm also using ASIHTTPRequest to make the request. I simply define the request, setRequestMethod:#"PUT", then I create the request body and convert it to NSData to calculate the length. I attach the request-body data via the appendPostData method to the request. I then build the auth string above, hash the whole thing, and attach it to the request as a header called "Authorization".
Request Body String I'm using:
<?xml version=\"1.0\" encoding=\"utf-8\"?><StorageServiceProperties><Logging><Version>1</Version></Logging></StorageServiceProperties>
I know this is an incomplete request body, but I was planning on waiting for it to give a failure on "missing request body element" or something similar, until I proceeded on creating the full XML there. (could that be my issue?)
Error I get from the server:
<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:accc4fac-2701-409c-b1a7-b3a528ce7e8a
Time:2012-06-20T14:36:50.5313236Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request '(MY_HASH)' is not the same as any computed signature. Server used following string to sign: 'POST
130
x-ms-date:Wed, 20 Jun 2012 14:36:50 GMT
x-ms-version:2009-09-19
/(MY_ACCOUNT)/
comp:properties
restype:service'.</AuthenticationErrorDetail></Error>
What's odd is that the error I get back from the server seems to look like that, no matter how many parameters I pass into the Authentication signature.
Thanks for any help you can offer!
Comparing your signed string and the error message indicates that you're sending a POST request but signing as though you're sending a PUT.

Resources