Facebook messenger webhook recieves attached image only with url which is getting expired in some time. How to obtain more information from facebook api to generate new url?
There is not an api to get information about message attachments currently.
I am not sure if/when the image will be deleted, as there is no mention of this in the docs. If you want to guarantee permanent access to the image, you should store it somewhere like s3.
An example of this using knox:
http.get('http://google.com/doodle.png', function(res){
var headers = {
'Content-Length': res.headers['content-length']
, 'Content-Type': res.headers['content-type']
};
client.putStream(res, '/doodle.png', headers, function(err, res){
// Logic
});
});
So far I used successfully Application Insights REST API for getting metrics with X-Api-Key header.
https://api.applicationinsights.io/beta/apps/xxxxxxxxxx/metrics/customMetrics%2FmetricName?timespan=PT2H&interval=PT20M&aggregation=min
However with our new dashboard, crawling several metrics, we hit hard the 1500 request/api key limit.
Some suggest to play around with several api keys, but I would like to prevent this approach.
According to documentation, authenticate with AAD would remove the daily cap (https://dev.applicationinsights.io/documentation/Authorization/Rate-limits)
But I fail to authenticate with AAD (in nodejs, but I suspect it's the same in any language)
I used adal-node with a simple app, I successfully get a token, however I'm not able to forward it to the Request
var context = new AuthenticationContext(authorityUrl);
context.acquireTokenWithClientCredentials(resource, clientId, clientSecret, function(err, tokenResponse) {
if (err) {
console.log('well that didn\'t work: ' + err.stack);
} else {
console.log(tokenResponse);
request({'url' : 'https://api.applicationinsights.io/beta/apps/xxxxxxxxx/metrics/customMetrics%2Fmetrics?timespan=PT2H&interval=PT20M&aggregation=min',
headers: {
'Authorization': 'Bearer ' + tokenResponse.accessToken
}
}, function (error,response,body){
console.log(body);
});
}
});
I'm getting following error message
The provided authentication is not valid for this resource
The given API Key is not valid for the requested resource
I suspect I miss something :)
We don't support AAD in our REST API directly. Your resource is managed by the Azure Resource Manager, and only it can validate a certain user has access to this resource. API Keys are our way of short circuiting the authorization directly to a resource, instead of in the user context.
You gave this AAD app access to this resource as yourself, so the authentication is still in the context of a user. The call has to be made to ARM instead: 'https://management.azure.com/subscriptions/xxxxxx/resourcegroups/xxxxx/providers/microsoft.insights/components/xxxxx/api/metrics/customMetrics%2Fmetrics?api-version=2014-12-01-preview×pan=PT2H&interval=PT20M&aggregation=min'
Documentation is linked here - though not explained explicitly: https://dev.applicationinsights.io/documentation/Authorization
This will get you a higher rate-limit, and still return the same response as the REST API.
I am playing with Google's OAuth 2.0 Playground using my own personal Google account, but I cannot seem to recover my Gmail address using the playground.
The scope I am using is:
email profile https://www.googleapis.com/auth/plus.login
But when I call the API:
https://www.googleapis.com/oauth2/v2/userinfo
I get various information about the user such as family name, first name, gender, picture, etc. but it does not return the user's email.
How do I retrieve the user's email address? Do I have the wrong scope or am I calling the wrong API? I feel like this should be very simple but I have literally been trying to figure this out for hours and I cannot find an API and scope combination that consistently provides the user's email address.
Update: December 2018
On December 20th, Google announced that the Google+ API would be turned down in March 2019, with intermittent failure starting at the end of January 2019. As part of the the plus.people.get endpoint is deprecated and scheduled to be terminated.
The userinfo endpoint is de-deprecated (see clarification) and should provide the info assuming
You request the https://developers.google.com/identity/sign-in/web/devconsole-project scope and
You request the email field.
Clarification: 24 Jan 2019
Google documented that the userinfo (v2) endpoint was deprecated, but later changed it to "deprecated, but kept available for backwards compatibility".
Current documentation discusses getting profile and email information through the currently supported openid method. This includes using the "userinfo" endpoint specified in their discovery document, as required by OpenID Connect.
At the moment, that URL is https://openidconnect.googleapis.com/v1/userinfo, but this has changed in the past and the discovery document at https://accounts.google.com/.well-known/openid-configuration is the authoritative source for the URL to use.
So, to be clear:
The old userinfo URL is maintained for backwards compatibility
The new userinfo URL is available at the discovery document
Regardless, the plus version of anything (described below) is deprecated and scheduled to be removed.
Original Answer
There are a lot of issues here in what you're doing and how you're trying to do it.
For starters, the https://www.googleapis.com/oauth2/v2/userinfo endpoint is deprecated, and scheduled to be removed in September 2014. It has begun working inconsistently - so don't use it.
As #abraham noted, you'll use the people.get endpoint at https://www.googleapis.com/plus/v1/people/me. This should give you the emails field containing an array of addresses. In your case, there will likely be only one that has a type of "account".
As of 2017: use the email scope. See Authorizing API requests.
This email scope is equivalent to and replaces the
https://www.googleapis.com/auth/userinfo.email scope.
For signing in with Google using OAuth 2.0, there's no need to make a separate request to get user's email.
When Google calls the callback URL, it provides a code in the query string that you could use to exchange for access token and ID token. The ID token is a JWT that contains identity information about the user, which includes the email address.
See more information here: https://developers.google.com/identity/protocols/oauth2/openid-connect
You'll want to add the https://www.googleapis.com/auth/userinfo.email scope or replace https://www.googleapis.com/oauth2/v2/userinfo with it. If you're using the HTML example they provide, you can list multiple scopes separated by a space.
<span
class="g-signin"
data-callback="signInCallback"
data-clientid="{{ plus_id }}"
data-cookiepolicy="single_host_origin"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-scope="https://www.googleapis.com/auth/plus.login
https://www.googleapis.com/auth/userinfo.email">
</span>
To retrieve the email address, you need to include the scope: "https://www.googleapis.com/auth/userinfo.email" as mentioned in this document. If this scope is included while you generate the refresh token, you should be able to get the email address of the authenticating user by making the following request:
you can call this with your own access token then will give the response
https://www.googleapis.com/oauth2/v3/userinfo?access_token="YOUR_ACCESS_TOKEN"
response will look like this
{
"sub": "1057abc98136861333615xz",
"name": "My Name",
"given_name": "My",
"family_name": "Name",
"picture": "https://lh3.googleusercontent.com/a-/AOh14qiJarwP9rRw7IzxO40anYi4pTTAU_xseuRPFeeYFg",
"email": "MyName#gmail.com",
"email_verified": true,
"locale": "en"
}
or simply you can just write a function
import requests
def get_user_email(access_token):
r = requests.get(
'https://www.googleapis.com/oauth2/v3/userinfo',
params={'access_token': access_token})
return r.json()
I came here looking why my server did not get email in response to /oauth2/v2/userinfo api call. It was only once that I saw this & it has been working well in past.
The answer gave good lead. While fixing this, there were several other resources that helped. Still I am not sure whether expecting always email in the response is ok. so - put error handling in code in case emails are not returned.
Google api documentation about migrating to google+ signin.
https://www.googleapis.com/auth/userinfo.email scope
People resource documentation
Add google+ api to the project using google developer console. The complimentary (quota) of calls is quite high (20m for google+ signin api per day).
Add error handling & logging in server code in case api returns no emails. In my case, I was looking only type='account' email.
This is actually a bit of a challenge as Google does not provide an email by default. You must specifically request it from Google Plus.
const scope = [
'https://www.googleapis.com/auth/plus.me', // request access here
'https://www.googleapis.com/auth/userinfo.email',
];
auth.generateAuthUrl({
access_type: 'offline',
prompt: 'consent',
scope: scope,
});
const plus = google.plus({ version: 'v1', auth });
const me = await plus.people.get({ userId: 'me' });
const userEmail = me.data.emails[0].value;
There is a full version in this blog post I wrote: https://medium.com/#jackscott/how-to-use-google-auth-api-with-node-js-888304f7e3a0
by using google nodejs sdk:
const {google} = require('googleapis');
const oauth2Client = new google.auth.OAuth2(
googleClientIdPublic,
googleClientSecret,
googleRedirectUriPublic
);
//scope you need: https://www.googleapis.com/auth/userinfo.email
oauth2Client.setCredentials(tokens);
const googleAuth = google.oauth2({
version: "v2",
auth: oauth2Client,
});
const googleUserInfo = await googleAuth.userinfo.get();
const email = googleUserInfo.data.email;
more info
I have been following Prisoner's answer right above, and it helped me... until I received the email from Google Developers about how Google+ API will be shutdown on March 7, 2019.
I scrounged around and found this solution to get the email using an id_token that is returned when you authorize an app with the email scope on your developer console.
From Google Sign-in for Websites:
To validate an ID token in PHP, use the Google API Client Library for
PHP. Install the library (for example, using Composer):
composer require google/apiclient
Then, call the verifyIdToken() function. For example:
require_once 'vendor/autoload.php';
// Get $id_token via HTTPS POST.
$client = new Google_Client(['client_id' => $CLIENT_ID]); // Specify the CLIENT_ID of the app that accesses the backend
$payload = $client->verifyIdToken($id_token);
if ($payload) {
$userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
// Invalid ID token
}
This will return an array that contains the user information, that also contains the email of the user who logged in. Hope this helps anyone else.
Please see my answer here to the identical issue:
how to get email after using google OAuth2 in C#?
In your scopes variable. Use the value "email" not the
full https address. Scope keywords in the web link are separated by spaces. I solve your issue with scopes written as: profile email openid.
https://developers.google.com/gmail/api/v1/reference/users/getProfile
For gmails api, add this to nodejs code:
function getUsersEmail (auth) {
const gmail = google.gmail({version: 'v1', auth})
gmail.users.getProfile({
userId: 'me'
}, (err, {data}) => {
if (err) return console.log('The API returned an error: ' + err)
console.log(data.emailAddress)
})
}
Gmails api: https://developers.google.com/gmail/api/guides/
Change the authorizationRequest with given scope: scope=openid%20email%20profile and use userinfoapi. This link worked for me
I suggest the following minimal code, which include '*/userinfo.email' and '#google-cloud/local-auth' package:
const path = require('path');
const { google } = require('googleapis');
const { authenticate } = require('#google-cloud/local-auth');
const scope = [
'https://www.googleapis.com/auth/userinfo.email'
];
async function runSample() {
const auth = await authenticate({
keyfilePath: path.join(__dirname, 'oauth2.keys.json'),
scopes: scope
});
google.options({ auth });
const dat = await google.oauth2('v2').userinfo.get()
console.log(dat.data.email);
}
if (module === require.main) {
runSample().catch(console.error);
}
module.exports = runSample;
The facebook docs here say "it is the Developers' responsibility to delete a Request once it has been accepted". As far as I understand, when someone sends a request to multiple users on facebook like this:
function sendRequestViaMultiFriendSelector() {
FB.ui({method: 'apprequests',
message: 'test message'
}, requestCallback);
}
only one request_id is returned via requestCallback() function.
Then, if I delete the request when someone accepts it, how would other users accept the deleted request?
when user comes following the app request, you can get request id's using
$_GET['request_ids']
then retrieve all the request ids with which you can call graph api to delete the corresponding requests like below:
if(isset($_GET['request_ids']))
{
$request_ids = $_GET['request_ids'];
}
$request_ids = explode(",", $request_ids);
foreach($request_ids as $request_id)
{
$full_request_id = $request_id."_".$fbid; //$fbid is current user facebook id
$facebook->api("$full_request_id","DELETE");
}
Check out the Request ID Format section of the FB request overview page.
The actual graph path for a request actually sent to specific user is "request-id"_"recipient-user-id".
you can access to facebook on mobile mode (m.faceook.com)
1-access the invitation panel
2-display all the invitations
3-open console mode in chrome
4-activate jquery by cpying and pasting all the jquery.min code into console
and excecute this script :
$("._54k8._56bs._56bt").trigger("click");
that will cancel or the invitation sent
I'm seeing some strange behaviour with Requests.
I initiate a requests dialog with:
method: 'apprequests'
to: 'someUid'
(and some data for message, title, data)
The user approves the Request, and I get back a valid response, giving me the request Id, the user Ids it was sent to, and the updatedFrictionless flag. However, when reading the request from the graph later with either:
https://graph.facebook.com/?ids=REQUESTID_USERID&access_token=RECEIVINGUSERTOKEN
or
https://graph.facebook.com/REQUESTID_USERID?access_token=RECEIVINGUSERTOKEN
I get back no data !
The first graph call will give me an empty array (an un-named array not 'data', just simply [ ] )
The second, gives me 'false'
REQUESTID is the request Id I get back from the original call, USERID is the receiving USERID.
The receiving user is me, and I do see the request in my notifications, but using the graph explorer to check my 'apprequests', its empty.
Any ideas? I have Requests 2.0 enabled, and call FB.init with frictionlessRequests: true..
Does it work with your app access token?