Send mail using GraphClient always goes to junk folder - java

I'm trying to send an email using Microsoft Graph API using following code spinet. It always end up in recipient's SPAM/JUNK folder.
try {
val usernamePasswordCredential: UsernamePasswordCredential = UsernamePasswordCredentialBuilder()
.clientId(clientId).username(username).password(password).build()
val tokenCredentialAuthProvider = TokenCredentialAuthProvider(usernamePasswordCredential)
val graphClient = GraphServiceClient.builder().authenticationProvider(tokenCredentialAuthProvider).buildClient()
val bundle = ResourceBundle.getBundle("messages")
val pattern = bundle.getString("email.body")
val message = Message()
message.subject = bundle.getString("email.subject")
val body = ItemBody()
body.contentType = BodyType.HTML
val content = MessageFormat.format(pattern, voornamen, demoLink, USERNAME, pwd)
body.content = content
message.body = body
val toEmail = EmailAddress()
toEmail.address = email
val recipient = Recipient()
recipient.emailAddress = toEmail
message.toRecipients = listOf(recipient)
graphClient.me().sendMail(
UserSendMailParameterSet
.newBuilder()
.withMessage(message)
.build()
).buildRequest().post()
} catch (e: Exception) {
logger.error(e) {"Exception in sending email"}
throw TenantCreationException("Email", "Failed with error message : ${e.localizedMessage}")
}
When I'm trying to send same email content with same account using outlook.office365.com. It goes into inbox only.
Can anyone please suggest what am I missing here?

Related

Pass credentials while calling an API in Scala

I'm trying to call a REST endpoint using HttpGet and pass user credentials.
var content = ""
val httpClient : CloseableHttpClient = HttpClients.createDefault();
val httpResponse = new HttpGet(url)
httpResponse.addHeader(BasicScheme.authenticate(new UsernamePasswordCredentials(“uname”,”pwd”),”UTF-8", false))
val response = httpClient.execute(httpResponse)
val entity = httpResponse.getEntity()
val inputStream = entity.getContent()
content = fromInputStream(inputStream).getLines.mkString
inputStream.close
httpClient.getConnectionManager().shutdown()
return content
Looks like BasicScheme is deprecated in "org.apache.http.impl.auth". Any pointers on how to move forward...
Thanks in Advance.
Given you're trying to use basic authentication, this should be sufficient
val credentialsProvider = new BasicCredentialsProvider()
credentialsProvider.setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials("username", "password")
)
val httpClient =
HttpClientBuilder.create()
.setDefaultCredentialsProvider(credentialsProvider)
.build()
val httpResponse = new HttpGet(url)
httpClient.execute(httpResponse)
If instead you prefer going with a simple HTTP header, you can use
def buildEncodedCredentials(): String = {
val credentialsString = username + ":" + password
val charset = StandardCharsets.ISO_8859_1
val encodedBytes = Base64.getEncoder().encode(credentialsString.getBytes(charset))
return new String(encodedBytes, charset)
}
httpResponse.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + buildEncodedCredentials())

HTTP Status 415 - RESTEASY001055: Cannot consume content type

I'm trying to upload an image (eg tiff, scan in PDF). I did a project in SoapUI and the picture was sent correctly, unfortunately my java code is wrong ... receives the 'HTTP Status 415 - RESTEASY001055: Cannot consume content type' message. The image is stored in the database as a blob.
For code 200, I should get json
private void sendRequestToRestService(byte[] imgageBlob) throws IOException {
String user = "testUser";
String password = "testPass";
String restServiceAddressToUpload = //The address of the service on which I want to send the file;
String authData = user + ":" + password;
Tika tika = new Tika();
String mimetype = tika.detect(imgageBlob);
String auth = user + ":" + password;
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("ISO-8859-1")));
String authHeader = "Basic " + new String(encodedAuth);
// ByteArrayEntity entity = new ByteArrayEntity(imgageBlob);
Client client = ClientBuilder.newClient();
Response res = client.target(restServiceAddressToUpload)
.request(MediaType.MULTIPART_FORM_DATA)
.header(HttpHeaders.AUTHORIZATION, authHeader)
.post(Entity.entity(imgageBlob, mimetype));
if (res.getStatus() == 200) {
String readEntity = res.readEntity(String.class);
// ...
} else {
String readEntity = res.readEntity(String.class);
// ...
}
}
You need to add the Content-Type header

Java mail api message id returns null in some cases

i have problem while reading mails from my mail account and save it in my database. My code is below:
Store store = null;
Folder folder = null;
Message message = null;
Message[] messages = null;
Object messagecontentObject = null;
String sender = null;
String subject = null;
Multipart multipart = null;
Part part = null;
String contentType = null;
String dateTime = "";
String fileName = "";
Session session = null;
int count = 0;
try {
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imap");
session = Session.getInstance(System.getProperties(), null);
store = session.getStore("imap");
store.connect(mailserver, mail, password);
folder = store.getDefaultFolder();
folder = folder.getFolder("Inbox");
folder.open(Folder.READ_WRITE);
messages = folder.getMessages();
// UNREAD messages
FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
messages = folder.search(ft);
for (int i = 0; i < messages.length; i++) {
message = messages[i];
subject = message.getSubject();
String msgId[] =message.getHeader("Message-Id");// Problem arise here
System.out.println(msgId[0]);
boolean flag = true;
}
} catch (Exception ex) {
}
msgId returns null in some cases and i can't find solution for this problem.
Messages aren't required to have a Message-Id header. Most do, and many servers will add one if they receive a message without one, but it's not impossible to encounter a message without such a header. Often such messages are spam.
So, depending on what you're using the Message-Id value for, you're going to have to find another way to accomplish it.

Android : Google API v.3 gives INVALID_REQUEST , but executed good in the browser

I need to geocode the address and get latitude , longitude from the city, postal code and other.
When I use this request with the Android
https://maps.googleapis.com/maps/api/geocode/json?address=Aachen-Horbach+Gzg&region=DEU&sensor=false
I receive INVALID_REQUEST as a response. But when I try this link in browser or with the help of REST client, everything works fine.
The same with this request :
https://maps.googleapis.com/maps/api/geocode/json?address=Abertamy-Horní+Blatná&region=CZE&sensor=false
What can be the reason ?
Url creation :
StringBuilder addressUrl = new StringBuilder();
if (order.getDepartureAddress().getStreet()!=null && !order.getDepartureAddress().getStreet().equalsIgnoreCase(""))
addressUrl.append(order.getDepartureAddress().getStreet() + ", ");
if (order.getDepartureAddress().getHouseNumber()!=null && ! order.getDepartureAddress().getHouseNumber().equalsIgnoreCase(""))
addressUrl.append(order.getDepartureAddress().getHouseNumber() + ", ");
if (order.getDepartureAddress().getCity()!=null && !order.getDepartureAddress().getCity().equalsIgnoreCase(""))
addressUrl.append(order.getDepartureAddress().getCity() );
if (order.getDepartureAddress().getCountryCode()!=null && !order.getDepartureAddress().getCountryCode().equalsIgnoreCase(""))
addressUrl.append("&region="+order.getDepartureAddress().getCountryCode() );
addressUrl.append("&sensor=false");
/*
Constants.URL_GEOCODING = https://maps.googleapis.com/maps/api/geocode/json?address=
*/
String finalUrl = Constants.URL_GEOCODING + addressUrl.toString();
/* request execution : */
public static JSONObject readJsonFromUrl(String urlStr) throws IOException, JSONException {
URL url = new URL(urlStr);
URI uri = null;
URI uri2= null;
try {
uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
uri2 = new URI(url.toString().replace("%20", "+"));
} catch (URISyntaxException e) {
e.printStackTrace();
}
url = uri2.toURL();
Log.i(TAG + " requested url", url.toString());
InputStream is = url.openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
}
Here is an idea: Check the output of your logcat.
If the request time and the time when the data was sent back from google are too close to each other, Google might assume you are a spammer and deny access to the server on the second request.
The solution in this case is wait 1 second if there is a next_page_token and then send the followup request.

Unable to get the subscription information from Google Play Android Developer API

I'trying to use Google APIs Client Library for Java to get information about user's subscriptions purchased in my android app. Here is how I'm doing for now:
HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
JsonFactory JSON_FACTORY = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(GOOGLE_CLIENT_MAIL)
.setServiceAccountScopes("https://www.googleapis.com/auth/androidpublisher")
.setServiceAccountPrivateKeyFromP12File(new File(GOOGLE_KEY_FILE_PATH))
.build();
Androidpublisher publisher = new Androidpublisher.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).
setApplicationName(GOOGLE_PRODUCT_NAME).
build();
Androidpublisher.Purchases purchases = publisher.purchases();
Get get = purchases.get("XXXXX", subscriptionId, token);
SubscriptionPurchase subscripcion = get.execute(); //Exception returned here
GOOGLE_CLIENT_MAIL is the email address from API Access from the Google Console.
GOOGLE_KEY_FILE_PATH is the p12 file downloaded from the API Access.
GOOGLE_PRODUCT_NAME is the product name from the branding information.
In Google APIS Console the Service "Google Play Android Developer API" is enabled.
What I'm getting is:
{
"code" : 401,
"errors" : [ {
"domain" : "androidpublisher",
"message" : "This developer account does not own the application.",
"reason" : "developerDoesNotOwnApplication"
} ],
"message" : "This developer account does not own the application."
}
I really appreciate your help for this issue...
I got it working! The steps I followed:
Prerequisite
Before start, we need to generate a refresh token. To do this first we have to create an APIs console project:
Go to the APIs Console and log in with your Android developer
account (the same account used in Android Developer Console to upload the APK).
Select Create project.
Go to Services in the left-hand navigation panel.
Turn the Google Play Android Developer API on.
Accept the Terms of Service.
Go to API Access in the left-hand navigation panel.
Select Create an OAuth 2.0 client ID:
On the first page, you will need to fill in the product name, but a
logo is not required.
On the second page, select web application and set the redirect URI
and Javascript origins. We will use it later the redirect URI.
Select Create client ID. Keep in mind the Client ID and the Client secret, we will use them later.
So, now we can generate the refresh token:
Go to the following URI (note that the redirect URI must match the value entered in the client ID exactly, including any trailing backslashes):
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=REDIRECT_URI&client_id=CLIENT_ID
Select Allow access when prompted.
The browser will be redirected to your redirect URI with a code parameter, which will look similar to 4/eWdxD7b-YSQ5CNNb-c2iI83KQx19.wp6198ti5Zc7dJ3UXOl0T3aRLxQmbwI. Copy this value.
Create a main class with:
public static String getRefreshToken(String code)
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
try
{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
nameValuePairs.add(new BasicNameValuePair("grant_type", "authorization_code"));
nameValuePairs.add(new BasicNameValuePair("client_id", GOOGLE_CLIENT_ID));
nameValuePairs.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENT_SECRET));
nameValuePairs.add(new BasicNameValuePair("code", code));
nameValuePairs.add(new BasicNameValuePair("redirect_uri", GOOGLE_REDIRECT_URI));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
org.apache.http.HttpResponse response = client.execute(post);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer buffer = new StringBuffer();
for (String line = reader.readLine(); line != null; line = reader.readLine())
{
buffer.append(line);
}
JSONObject json = new JSONObject(buffer.toString());
String refreshToken = json.getString("refresh_token");
return refreshToken;
}
catch (Exception e) { e.printStackTrace(); }
return null;
}
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET and GOOGLE_REDIRECT_URI are the previously values.
Finally, we have our refresh token! This value does not expire, so we can store in some site, like a property file.
Accessing to Google Play Android Developer API
Getting the access token. We will need our previosly refresh token:
private static String getAccessToken(String refreshToken){
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
try
{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
nameValuePairs.add(new BasicNameValuePair("grant_type", "refresh_token"));
nameValuePairs.add(new BasicNameValuePair("client_id", GOOGLE_CLIENT_ID));
nameValuePairs.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENT_SECRET));
nameValuePairs.add(new BasicNameValuePair("refresh_token", refreshToken));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
org.apache.http.HttpResponse response = client.execute(post);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer buffer = new StringBuffer();
for (String line = reader.readLine(); line != null; line = reader.readLine())
{
buffer.append(line);
}
JSONObject json = new JSONObject(buffer.toString());
String accessToken = json.getString("access_token");
return accessToken;
}
catch (IOException e) { e.printStackTrace(); }
return null;
}
Now, we can access to the Android API. I'm interesting in the expiration time of a subscription, so:
private static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static JsonFactory JSON_FACTORY = new com.google.api.client.json.jackson2.JacksonFactory();
private static Long getSubscriptionExpire(String accessToken, String refreshToken, String subscriptionId, String purchaseToken){
try{
TokenResponse tokenResponse = new TokenResponse();
tokenResponse.setAccessToken(accessToken);
tokenResponse.setRefreshToken(refreshToken);
tokenResponse.setExpiresInSeconds(3600L);
tokenResponse.setScope("https://www.googleapis.com/auth/androidpublisher");
tokenResponse.setTokenType("Bearer");
HttpRequestInitializer credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setClientSecrets(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
.build()
.setFromTokenResponse(tokenResponse);
Androidpublisher publisher = new Androidpublisher.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).
setApplicationName(GOOGLE_PRODUCT_NAME).
build();
Androidpublisher.Purchases purchases = publisher.purchases();
Get get = purchases.get(GOOGLE_PACKAGE_NAME, subscriptionId, purchaseToken);
SubscriptionPurchase subscripcion = get.execute();
return subscripcion.getValidUntilTimestampMsec();
}
catch (IOException e) { e.printStackTrace(); }
return null;
}
And that's all!
Some steps are from https://developers.google.com/android-publisher/authorization.
You can use com.google.api-client and google-api-services-androidpublisher libraries.
First go to the project on google developer console (https://console.developers.google.com)
APIs & Auth -> APIs
Enable "Google Play Android Developer API"
Go to Credentials -> Create new Client ID
Select service account
Create client ID
Save the p12 file somewhere safe
Then add the just generated email address for the service account to your google play developer console (https://play.google.com/apps/publish/)
Settings -> Users and permissions -> Invite new users
Paste the #developer.gserviceaccount.com email account
Select "View financial reports"
Send invitation
Now to the code. Add the following dependencies to your pom.xml file:
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.18.0-rc</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.18.0-rc</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidpublisher</artifactId>
<version>v1.1-rev25-1.18.0-rc</version>
</dependency>
Then first validate the signature:
byte[] decoded = BASE64DecoderStream.decode(KEY.getBytes());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(decoded));
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(publicKey);
sig.update(signedData.getBytes());
if (sig.verify(BASE64DecoderStream.decode(signature.getBytes())))
{
// Valid
}
If the signature verifies fetch subscription details:
// fetch signature details from google
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(ACCOUNT_ID)
.setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/androidpublisher"))
.setServiceAccountPrivateKeyFromP12File(new File("key.p12"))
.build();
AndroidPublisher pub = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential)
.setApplicationName(APPLICATION_NAME)
.build();
AndroidPublisher.Purchases.Get get = pub.purchases().get(
APPLICATION_NAME,
PRODUCT_ID,
token);
SubscriptionPurchase subscription = get.execute();
System.out.println(subscription.toPrettyString());
This will take care of all the token issues by generating a JWT token so you don't have to handle it yourself.
For those who want to check subscription status on Google's AppEngine with Java, here is my working example based on many codes found on SO. I spent couple of days to solve many mistakes caused by lack of experience. I see lot of suggestions to check subscription status on server but it was not easy for me to do on AppEngine. Without answers found on SO, I could not come up with this.
Step 1
First we need to go through "Prerequisite" section found on Jonathan Naguin's answer, until you get code from web browser. Now you have;
Client ID
Client secret
Redirect URI
code
ready.
Note we run all codes shown below on AppEngine. And I used logger like this.
static final Logger log = Logger.getLogger(MyClassName.class.getName());
Step 2
We need to get refresh token. Run code shown below after replacing [YOUR CLIENT ID], [YOUR CLIENT SECRET], [YOUR CODE], [YOUR REDIRECT URI] with your string.
private String getRefreshToken()
{
try
{
Map<String,Object> params = new LinkedHashMap<>();
params.put("grant_type","authorization_code");
params.put("client_id",[YOUR CLIENT ID]);
params.put("client_secret",[YOUR CLIENT SECRET]);
params.put("code",[YOUR CODE]);
params.put("redirect_uri",[YOUR REDIRECT URI]);
StringBuilder postData = new StringBuilder();
for(Map.Entry<String,Object> param : params.entrySet())
{
if(postData.length() != 0)
{
postData.append('&');
}
postData.append(URLEncoder.encode(param.getKey(),"UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()),"UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
URL url = new URL("https://accounts.google.com/o/oauth2/token");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.getOutputStream().write(postDataBytes);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer buffer = new StringBuffer();
for (String line = reader.readLine(); line != null; line = reader.readLine())
{
buffer.append(line);
}
JSONObject json = new JSONObject(buffer.toString());
String refreshToken = json.getString("refresh_token");
return refreshToken;
}
catch (Exception ex)
{
log.severe("oops! " + ex.getMessage());
}
return null;
}
Since refresh token won't expire, we can save it somewhere or simply hard-code in our code. (We only need to run above code once to get refresh token.)
Step 3
We need to get access token. Run code shown below after replacing [YOUR CLIENT ID], [YOUR CLIENT SECRET], [YOUR REFRESH TOKEN] with your string.
private String getAccessToken()
{
try
{
Map<String,Object> params = new LinkedHashMap<>();
params.put("grant_type","refresh_token");
params.put("client_id",[YOUR CLIENT ID]);
params.put("client_secret",[YOUR CLIENT SECRET]);
params.put("refresh_token",[YOUR REFRESH TOKEN]);
StringBuilder postData = new StringBuilder();
for(Map.Entry<String,Object> param : params.entrySet())
{
if(postData.length() != 0)
{
postData.append('&');
}
postData.append(URLEncoder.encode(param.getKey(),"UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()),"UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
URL url = new URL("https://accounts.google.com/o/oauth2/token");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.getOutputStream().write(postDataBytes);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer buffer = new StringBuffer();
for (String line = reader.readLine(); line != null; line = reader.readLine())
{
buffer.append(line);
}
JSONObject json = new JSONObject(buffer.toString());
String accessToken = json.getString("access_token");
return accessToken;
}
catch (Exception ex)
{
log.severe("oops! " + ex.getMessage());
}
return null;
}
Step 4
What I wanted to know is just expire UTC of the subscription. Code shown below returns expire UTC, 0 when found error. You need to provide your package name, product id (=subscription id), access token you got on Step 3, and purchase token found in your purchase data.
private long getExpireDate(String packageName,String productId,String accessToken,String purchaseToken)
{
try
{
String charset = "UTF-8";
String query = String.format("access_token=%s",URLEncoder.encode(accessToken,charset));
String path = String.format("https://www.googleapis.com/androidpublisher/v1/applications/%s/subscriptions/%s/purchases/%s",packageName,productId,purchaseToken);
URL url = new URL(path + "?" + query);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("Accept-Charset",charset);
connection.setRequestMethod("GET");
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer buffer = new StringBuffer();
for(String line = reader.readLine(); line != null; line = reader.readLine())
{
buffer.append(line);
}
JSONObject json = new JSONObject(buffer.toString());
return json.optLong("validUntilTimestampMsec");
}
catch (Exception ex)
{
log.severe("oops! " + ex.getMessage());
}
return 0;
}
Note product id or subscription id is a string found on developer console. Your subscription item appears with name/id column. It looks like this.
Description of item(product id)
Last step (fun part)
Now we have all components to verify subscription is valid or not. I did like this. You need to replace [YOUR PACKAGE NAME], [YOUR PRODUCT ID] with yours.
You need to provide purchase data which you can get with Purchase#getOriginalJson() found in iabHelper code.
private boolean checkValidSubscription(String purchaseData)
{
String purchaseToken;
JSONObject json;
try
{
json = new JSONObject(purchaseData);
}
catch (JSONException e)
{
log.severe("purchaseData is corrupted");
return true; // false positive
}
purchaseToken = json.optString("purchaseToken");
if(purchaseToken.length() == 0)
{
log.severe("no purchase token found");
return true; // false positive
}
String accessToken = getAccessToken();
if(accessToken == null)
{
return true; // false positive
}
long expireDate = getExpireDate([YOUR PACKAGE NAME],[YOUR PRODUCT ID],accessToken,purchaseToken);
if(expireDate == 0)
{
log.severe("no expire date found");
return true; // false positive
}
expireDate += 86400000l; // add one day to avoid mis judge
if(expireDate < System.currentTimeMillis())
{
log.severe("subscription is expired");
return false;
}
// just for log output
long leftDays = (expireDate - System.currentTimeMillis()) / 86400000l;
log.info(leftDays + " days left");
return true;
}
Note for debugging
Google returns JSON string for response. If code won't work as expected, logging JSON string may help understanding what is wrong.
I hope this helps someone.
To piggyback on Jonathan Naguin's great answer, here is a nodejs version of getting the refresh and access token:
//This script is to retreive a refresh token and an access token from Google API.
//NOTE: The refresh token will only appear the first time your client credentials are used.
// I had to delete my client id within api console and create a new one to get the refresh token again.
//This is the downloaded json object from Google API Console. Just copy and paste over the template below.
var googleJson = {"web":{"auth_uri":"","client_secret":"","token_uri":"","client_email":"","redirect_uris":[""],"client_x509_cert_url":"","client_id":"","auth_provider_x509_cert_url":"","javascript_origins":[""]}};
//Retrieved from OAuth
var code = ''; // Retrieved from the response of the URL generated by printGoogleAuthUrl(). You will need to be logged in as your publisher. Copy and paste the generated url. Copy the code parameter into this variable.
var refreshToken = ''; // Retrieved from the printRefreshToken() function call. Requires the code variable to be filled out.
var accessToken = ''; // Retrieved from the printAccessToken() function call. Requires the refreshToken variable to be filled out.
var querystring = require('querystring');
var https = require('https');
var fs = require('fs');
function printGoogleAuthUrl()
{
console.log("https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=" + googleJson.web.redirect_uris[0] + "&client_id=" + googleJson.web.client_id);
}
function printRefreshToken()
{
var post_data = querystring.stringify({
'grant_type' : 'authorization_code',
'client_id' : googleJson.web.client_id,
'client_secret' : googleJson.web.client_secret,
'code' : code,
'redirect_uri' : googleJson.web.redirect_uris[0]
});
var post_options = {
host: 'accounts.google.com',
port: '443',
path: '/o/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length
}
};
var post_req = https.request(post_options, function(res) {
res.setEncoding('utf8');
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function(){
var obj = JSON.parse(data);
if(obj.refresh_token)
{
refreshToken = obj.refresh_token;
}
else
{
console.log("No refresh token found. I had to clear the web client id in Google Api Console and create a new one. There might be a better way here.");
}
console.log(data);
});
});
post_req.write(post_data);
post_req.end();
}
function printAccessToken()
{
var post_data = querystring.stringify({
'grant_type' : 'refresh_token',
'client_id' : googleJson.web.client_id,
'client_secret' : googleJson.web.client_secret,
'refresh_token' : refreshToken
});
var post_options = {
host: 'accounts.google.com',
port: '443',
path: '/o/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length
}
};
var post_req = https.request(post_options, function(res) {
res.setEncoding('utf8');
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function(){
var obj = JSON.parse(data);
if(obj.access_token)
accessToken = obj.access_token;
else
console.log("No access token found.");
console.log(data);
});
});
post_req.write(post_data);
post_req.end();
}
printGoogleAuthUrl();
//printRefreshToken();
//printAccessToken();
For those looking for a more up-to-date answer with AndroidPublisher v3 please look here: https://stackoverflow.com/a/57943483/1028256.
No need to deal with refreshToken & accessToken, and just few lines of code.
For Android client I found this 'official' sample code: https://github.com/googlesamples/android-play-publisher-api/blob/master/v3/java/src/com/google/play/developerapi/samples/AndroidPublisherHelper.java and there are options to get AndroidPublisher both with .p12 file or the app credentials.
I'm pretty sure you have to use your Client ID, not the email address. It looks like this: 37382847321922.apps.googleusercontent.com
See https://developers.google.com/android-publisher/authorization
client_id=<the client ID token created in the APIs Console>
And I'm pretty sure you don't need a P12 file. You only need the
client_secret=<the client secret corresponding to the client ID>
Try doing it manually from the command line first, with 'wget'.

Categories