Reputation: 426
I want to log into my amazon account and retrieve purchase history programmatically in java.
I did a lot of research and came across screen scraping. Is this the only way or does amazon provide apis for logging in and retrieving purchase history?
Also researched about AWS but its too confusing. There are lot of APIs and I'm not able to figure out which one to use.
Upvotes: 17
Views: 14192
Reputation: 146
Amazon doesn't have a first party API but you can use Gandalf's SDK to programmatically pull Amazon order history (from the beginning of the previous year)
Caveats/Disclosure
Since the docs don't contain Java specific instructions, despite the service being language agnostic. Here's how you might do it with Java.
First you construct the Gandalf URL and embed it in your application such that when you click on it, it triggers the Gandalf App Clip that will ask you to sign in to Amazon.
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public static String createGandalfConnectURL(String redirectUrl, String publicKey) {
try {
String encodedServices = URLEncoder.encode("{\"amazon\":true}", "UTF-8");
String encodedRedirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
String encodedPublicKey = URLEncoder.encode(publicKey, "UTF-8");
return "https://appclip.apple.com/id?p=network.gandalf.connect.Clip" +
"&services=" + encodedServices +
"&redirectUrl=" + encodedRedirectUrl +
"&publicKey=" + encodedPublicKey;
} catch (UnsupportedEncodingException e) {
// Handle the exception according to your needs
e.printStackTrace();
return null;
}
}
// Example invocation
String url = createGandalfConnectURL("https://your.redirect.url", "your-public-key");
System.out.println(url);
Once the authentication process is complete, the App Clip will navigate to the redirect URL specified above with a dataKey
query parameter.
Next steps:
Receive the dataKey: Extract the dataKey from the query parameter sent to your server's redirect endpoint after the user has linked their account.
Prepare the GraphQL query: Craft a GraphQL query that will be used to request the desired data from the Sauron API.
Sign the request: Generate a digital signature of your request body. You would hash the body of your request using SHA-256 and then sign the hash with ECDSA using your private key.
Execute the query: Send the GraphQL query to the Sauron API using an HTTP client, including the signature in the header to authenticate the request.
Here's a simplified Java code snippet that demonstrates these steps:
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class SauronApiRequest {
private static final String GRAPHQL_ENDPOINT = "https://sauron.gandalf.network/public/graphql";
private static final String PRIVATE_KEY_BASE64 = "YOUR_PRIVATE_KEY_BASE64"; // replace with your actual private key in base64 format
public static void main(String[] args) throws Exception {
String dataKey = "dataKeyReceivedFromRedirect"; // Replace with actual dataKey received
// Prepare your GraphQL query
String query = "{\"query\":\"{ getActivity(dataKey: \\\"" + dataKey + "\\\", source: Amazon, limit: 10, page: 1) { ... } }\"}";
// Generate signature
String signature = generateSignature(query);
// Execute GraphQL request
String response = executeGraphQLRequest(query, signature);
System.out.println(response);
}
private static String generateSignature(String payload) throws Exception {
// Decode the base64 private key
byte[] privateKeyBytes = Base64.getDecoder().decode(PRIVATE_KEY_BASE64);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// Create a SHA256withECDSA signature
Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
ecdsaSign.initSign(privateKey);
ecdsaSign.update(payload.getBytes("UTF-8"));
byte[] signature = ecdsaSign.sign();
// Encode signature in base64 to attach to the header
return Base64.getEncoder().encodeToString(signature);
}
private static String executeGraphQLRequest(String query, String signature) throws Exception {
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(GRAPHQL_ENDPOINT);
// Set the GraphQL query as the request body
StringEntity entity = new StringEntity(query);
httpPost.setEntity(entity);
// Add the required headers
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
httpPost.setHeader("X-Gandalf-Signature", signature);
// Execute the request
return EntityUtils.toString(client.execute(httpPost).getEntity());
}
}
}
Make sure to:
Upvotes: 0
Reputation: 86
I had the same problem, and didn't find a public Amazon API for retrieving purchase history.
So, I built a Chrome Extension to solve it. The repo is open-source and available here.
I also built a Udemy Course which essentially reviews the codebase: https://www.udemy.com/course/build-a-full-stack-chrome-extension-with-nodejs-and-mongdb
Here's the Chrome Extension: Amazon Scraper King
I also built a web app which enables you to take your Amazon History and create a Social Shopping Profile.
Upvotes: -2
Reputation: 2142
Doesn't look like Amazon provides an API to specifically do what you need, however I came across this thread. You may have already seen it.
Upvotes: 6