Google Custom App Publishing API from NodeJS server: apkInvalidFile - google-play-developer-api

When using the Google Custom App Publishing API from my NodeJS, I encounter an error
config: [Object: Inspection interrupted prematurely. Maximum call stack size exceeded.],
code: 403,
errors: [
{
domain: 'global',
reason: 'forbidden',
message: 'apkInvalidFile'
}
]
And no much more details about it.

There is a very precise way to create this request. The right way is not documented anywhere and requires some retro-engineering.
Here is what works:
result = await getPlayCustomApp().accounts.customApps.create({
account: 'FIXME entreprise developer account id',
requestBody: {
title: 'Trololo app title',
languageCode: 'en_US',
},
media: {
body: fs.createReadStream('/path/to/app.apk'),
},
});
I hope it helps people not waste their afternoon!

Related

Webhook JSON return from Cloud Run Endpoint not showing in Dialogflow CX

I developed a chatbot solution with Dialogflow CX, where a question is made by the user, and Dialogflow uses an unauthenticated webhook (temporary) to call a Cloud Run endpoint. Cloud Run runs a Python code with a Flask application that jasonifies the output of the algorithm.
Locally I can call the Cloud Run endpoint successfully (200) with the following script:
import requests
url='https://container-xxx-acc12345.run.app/predict'
r = requests.post(url, json={"text": "which is the deadline provided by the law?"})
print(r.json())
Which returns me:
{'prediction': 'Second year after initial deadline'}
Then when I go back to Dialogflow, it successfully calls the Cloud Run Endpoint (200 above), but I do not get a valid text response in the chat:
Cloud Run allows unauthenticated calls and the webhook is well configured. The webhook was added at the parameters session of the Ask Question page, whose tag is prediction.
As configured at the event handlers, the chatbot does not show any webhook error, but the result of the prediction does not show up in the chat.
Cloud Logging data:
httpRequest: {
latency: "0.010078946s"
protocol: "HTTP/1.1"
remoteIp: "22.222.222.164"
requestMethod: "POST"
requestSize: "2327"
requestUrl: "https://container-xxx-1234abc.run.app/predict"
responseSize: "959"
serverIp: "222.222.34.33"
status: 200
userAgent: "Google-Dialogflow"
}
This is the return of Flask application:
return jsonify({
"fulfillment_response": {
"messages": [{
"text":
predict(data)
}]
}
})
Any ideas on how to solve this issue are welcome.
I solved the problem. My return from Flask app in Cloud Run is fixed to:
return jsonify({
"fulfillment_response": {
"messages": [{
"text": {
"text": [
predict(data)
]
}
}]
}
})
I also found out you can define the body request payload also.

Get Google Business Notifications from push Pub/Sub

I'm trying to be notified when a new review is added on my Google Business Profile.
According to the documentation, I have setup the notification but I got nothing when a new review is added.
First of all, I have created a Pub/Sub Topic projects/my-project/topics/business-profile-notifications.
Then, I have created a Push subscription projects/my-project/subscriptions/business-profile-notifications-push attached to the previous created Topic. I have also defined an endpoint: https://my-endpoint/webhook. This endpoint is listening POST requests
Finally, I have added the service account mybusiness-api-pubsub#system.gserviceaccount.com into IAM with Pub/Sub admin role.
On the code side, I'm using NPM googleapis client in a TypeScript Node.js server.
I'm updating the account settings to setup the notifications:
const { data }: GaxiosResponse<mybusinessnotifications_v1.Schema$NotificationSetting> = await google.mybusinessnotifications({
version: 'v1',
auth,
}).accounts.updateNotificationSetting({
name: `accounts/${params.accountID}/notificationSetting`,
updateMask: 'notification_types',
requestBody: {
name: `accounts/${params.accountID}/notificationSetting`,
pubsubTopic: 'projects/my-project/topics/business-profile-notifications',
notificationTypes: [
'NEW_REVIEW',
'UPDATED_REVIEW',
],
},
});
At this point, nothing happens when a new review is added.
When I'm sending a POST request on my endpoint via curl command curl -X POST -H "Content-Type: application/json" -i "https://my-endpoint/webhook", the request is successfully catched.
In the other hand, when I'm getting notifications settings from the configured account, I have the notifications types but not any subscribed topic:
const { data }: GaxiosResponse<mybusinessnotifications_v1.Schema$NotificationSetting> = await google.mybusinessnotifications({
version: 'v1',
auth,
}).accounts.getNotificationSetting({
name: `accounts/${accountID}/notificationSetting`,
fields: 'pubsubTopic,notificationTypes',
});
Response:
{
"notificationTypes": [
"NEW_REVIEW",
"UPDATED_REVIEW"
]
}
What I forgot to do ?
I resolved the issue by myself 😁
In the documentation of updateNotificationSetting method, is it stated that "The only editable field is notificationSetting" about the updateMask field. But it's wrong. I had to add pubsubTopic as value.
Finally, the parameter values of this method are:
const opts = {
name: `accounts/${params.accountID}/notificationSetting`,
updateMask: 'notificationTypes,pubsubTopic',
requestBody: {
name: `accounts/${params.accountID}/notificationSetting`,
pubsubTopic: params.pubsubTopic,
notificationTypes: params.notificationTypes,
},
};
const { data }: GaxiosResponse<mybusinessnotifications_v1.Schema$NotificationSetting> = await google.mybusinessnotifications({
version: 'v1',
auth,
}).accounts.updateNotificationSetting(opts);

Error: Amplify has not been configured correctly - VueJS/NuxtJs - Reconfigure Amplify

I'm trying to setup SignInWithApple on my webpage. Currently there is the basic auth and the google auth. Because of some required fields in my current user pool which not work together with apple, I created a second user pool. Now I am trying to make both of them work by switching the configuration.
manual config (not using the cli for the aws-exports)
export default () => {
return {
default: {
region: process.env.AWS_COGNITO_REGION,
userPoolId: process.env.AWS_COGNITO_USER_POOL_ID_DEFAULT,
userPoolWebClientId: process.env.AWS_COGNITO_APP_CLIENT_ID_DEFAULT,
mandatorySignIn: false,
oauth: {
domain: process.env.AWS_COGNITO_DOMAIN_DEFAULT,
scope: [
'profile',
'phone',
'openid',
'email',
'aws.cognito.signin.user.admin'
],
redirectSignIn: process.env.AWS_COGNITO_REDIRECT_SIGN_IN,
redirectSignOut: process.env.AWS_COGNITO_REDIRECT_SIGN_OUT,
responseType: 'code'
}
},
SignInWithApple: {
region: process.env.AWS_COGNITO_REGION,
userPoolId: process.env.AWS_COGNITO_USER_POOL_ID_APPLE,
userPoolWebClientId: process.env.AWS_COGNITO_APP_CLIENT_ID_APPLE,
mandatorySignIn: false,
oauth: {
domain: process.env.AWS_COGNITO_DOMAIN_APPLE,
scope: ['openid'],
redirectSignIn: process.env.AWS_COGNITO_REDIRECT_SIGN_IN,
redirectSignOut: process.env.AWS_COGNITO_REDIRECT_SIGN_OUT,
responseType: 'code'
}
}
}
}
And then I have a vue component with a Google and Apple login button, triggering the same function but passing either "Google" or "SignInWithApple".
import Amplify, { Auth } from 'aws-amplify'
import amplifyResources from '#/plugins/amplifyResources'
export default {
data() {
return {
bucket: null
}
},
methods: {
federatedAuth(provider) {
if ('SignInWithApple' === provider)
this.bucket = amplifyResources().SignInWithApple
if ('Google' === provider)
this.bucket = amplifyResources().default
Amplify.configure(this.bucket) **RECONFIGURE OF AMPLIFY CONFIG **
Auth.federatedSignIn({ provider })
}
}
}
And I am getting the following error:
34:03.80 AuthError -
Error: Amplify has not been configured correctly.
The configuration object is missing required auth properties.
So the funny thing is, if I init the "default" or "apple" config as a plugin, which I link and load in my nuxt.config.js file, the authentication works. The users are getting registered and logged in. With google on the default user pool auth or with apple at the new user pool. Both work then.
But I am trying to switch the userpool in some component directly, based on the auth method the user is choosing. There I am "reconfiguring" the amplify config with Amplify.configure(this.bucket). From that point I am getting the error message from above. But the config is indeed switching. Otherwise I wouldn't get redirected to apple on the apple button or to google on the google button. Both have completely different configs. So I know the "reconfiguration" is happening. I also know that in general I have the right properties in the default & apple config, since the login for both is working, if I set the config as a plugin in the nuxt.config.js file.

Power BI Embedded on LOCALHOST

I know that one of the major steps in power bi embedded is to give your app permission to it (I have an existing app in azure ad) but what if I'm just trying to get it working on localhost!
Here's my code: and nothing is working. Getting 403 currently.
**for testing purposes, I retreived my access token via: https://learn.microsoft.com/en-us/rest/api/power-bi/embed-token/reports-generate-token-in-group#code-try-0
<PowerBIEmbed
embedConfig={{
type: 'report', // Supported types: report, dashboard, tile, visual and qna
id: 'myreportId',
embedUrl:
'https://embedded.powerbi.com/appTokenReportEmbed?reportId=myreportid',
accessToken:
'xxx',
permissions: models.Permissions.All,
tokenType: models.TokenType.Embed,
viewMode: models.ViewMode.View,
settings: {
panes: {
filters: {
expanded: false,
visible: false,
},
},
background: models.BackgroundType.Transparent,
},
}}
eventHandlers={
new Map([
[
'loaded',
function() {
console.log('Report loaded');
},
],
[
'rendered',
function() {
console.log('Report rendered');
},
],
[
'error',
function(event) {
console.log(event.detail);
},
],
])
}
cssClassName="report-style-class"
getEmbeddedComponent={embeddedReport => {
console.log({ embeddedReport });
// this.report = embeddedReport as Report;
// window.report = this.report;
}}
/>
It seems like you are using the wrong tokenType
You need to use tokenType: models.TokenType.Aad
For more information regarding tokenType, you can check this documentation: https://learn.microsoft.com/javascript/api/overview/powerbi/embedding-solutions
If this does not resolve the problem, there may be other causes of error 403.:
• The user has exceeded the amount of embedded token that can be generated on a shared capacity.
• The Azure AD auth token expired.
• The authenticated user isn't a member of the group (workspace).
• The authenticated user isn't an admin of the group (workspace).
• The authenticated user doesn't have permissions. Permissions can be updated using refreshUserPermissions API
• The authorization header may not be listed correctly. Make sure there are no typos.
Reference:
https://learn.microsoft.com/power-bi/developer/embedded/embedded-troubleshoot

Client authentication failed in Postman request for Amazon Alexa Smart Home Skill LWA

I am referring to Amazon documentation for the purpose of Customer Authentication. Currently, I am using LWA.
Steps I followed:
I enabled the Send Alexa Events Permission from the Alexa developer Console in Build > Permission page.
I took the grant code from the request in the cloudwatch logs which was sent when I logged in using Alexa companion app.
Example:-
{
"directive": {
"header": {
"messageId": "Example",
"name": "AcceptGrant",
"namespace": "Alexa.Authorization",
"payloadVersion": "3"
},
"payload": {
"grant": {
"code": "Example2",
"type": "OAuth2.AuthorizationCode"
},
"grantee": {
"token": "Example3",
"type": "BearerToken"
}
}
}
}
Permission Page under build on Alexa Developer console gave me client-Id and client-secret Which I used for making the post request to https://api.amazon.com/auth/o2/token.
Example:-
POST /auth/o2/token HTTP/l.l
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
grant_type=authorization_code&code=&client_id=&client_secret=
I passed the code,client_id, and client_secret in the above example and made the post request to this URL https://api.amazon.com/auth/o2/token
I tried using x-www-form-urlencoded;charset=UTF-8 and also JSON for the Content-Type.
I followed the step given in the above documentation and I am stuck on the error ( 401 Unauthorized ):
{
"error_description": "The request has an invalid grant parameter : code",
"error": "invalid_grant"
}
I tried implementing it using Python code and Postman both. Ending up with the Same above error scenario.
Here is a sample code to help you and others who are looking to send events to alexa gateway.
const AWS = require('aws-sdk');
AWS.config.update({region: 'eu-west-1'});
// Create the DynamoDB service object
const ddb = new AWS.DynamoDB({ apiVersion: 'latest' });
const doc = new AWS.DynamoDB.DocumentClient({
convertEmptyValues: true,
service: ddb
});
// Using 'request' for http POST and GET request.
// https://www.npmjs.com/package/requests
// npm install --save requests
const r = require('request');
//Handle Authorization. Call this method from your lambda handler whenever you get Alexa.Authorization message. You will get this message only when you select permission to
//send events in your Smart Home Skill.
//Access to Event gateway allows you to enable Proactive Device Discovery and
//Proactive State Reporting in your skill
//More information on Alexa.Authorization can be found on https://developer.amazon.com/docs/device-apis/alexa-authorization.html
function handleAuthorization(request, context, user) {
//Even when you are using your own authentication, the url below will still
//point to amazon OAuth token url. The token you obtain here has to be stored
//separately for this user. Whenever sending an event to alexa event gateway you will
//require this token.
//URL below is for EU server. Look at following documentation link to identify correct url
//for your system.
//https://developer.amazon.com/docs/smarthome/send-events-to-the-alexa-event-gateway.html
var url = "https://api.amazon.com/auth/o2/token";
var body = {
grant_type : 'authorization_code',
code : request.directive.payload.grant.code,
client_id : 'your client id from permissions page on developer portal where you enable alexa events. This is id different than one you specify in account linking settings',
client_secret : 'client secret from permissions page'
}
//https://developer.amazon.com/docs/smarthome/authenticate-a-customer-permissions.html
r.post({
url: url,
form : body
}, function(error, response, b){
if (error) { return console.log(error); }
var body = JSON.parse(b);
var params = {
TableName: 'Devices',
Item: {
'id' : user,
'auth_token' : body.access_token,
'refresh_token' : body.refresh_token
}
}
log("DEBUG:", "Authorization Body", JSON.stringify(body));
log("DEBUG:", "Authorization Response", JSON.stringify(response));
log("DEBUG:", "Database Params", JSON.stringify(params));
// Call DynamoDB to add the item to the table
var putObjectPromise = doc.put(params).promise();
//Store auth_token and refresh_token in database. We will need these
//while sending events to event gateway.
//Send a success response.
putObjectPromise.then(function(data) {
var response = {
event: {
header: {
messageId: request.directive.header.messageId,
namespace: "Alexa.Authorization",
name: "AcceptGrant.Response",
payloadVersion: "3"
},
"payload": {
}
}
};
context.succeed(response);
}).catch(function(err) {
//TODO - Add a Authorization error response JSON here.
console.log(err);
});
});
}