Is there an easy way to grab a users LinkedIn profile photo?
Ideally similar to how you would with Facebook - http://graph.facebook.com/userid/picture
You can retrieve the original photo size with this call:
http://api.linkedin.com/v1/people/~/picture-urls::(original)
Note that this could be any size, so you'll need to do scaling on your side, but the image is the original one uploaded by the user.
Not as easy... You need to go through OAuth, then on behalf of the member, you ask for:
http://api.linkedin.com/v1/people/{user-id}/picture-url
If you use the 2.0 version of the API (all developers need to migrate by March 1, 2019), you should use projections to expand the profilePicture.displayImage. If you do this, you will have a full JSON element displayImage~ (the '~' is not a typo) inside profilePicture with all the info you may need.
https://api.linkedin.com/v2/me?projection=(id,profilePicture(displayImage~:playableStreams))
You can see more at the Profile Picture API doc to look at the JSON response or the Profile API doc.
Once the Linkedin user authentication using OAuth 2.x is done, make a request to the people URL.
https://api.linkedin.com/v1/people/~:(id,email-address,first-name,last-name,formatted-name,picture-url)?format=json
Where ~ stands for current authenticated user. The response will be something like this ...
{
"id": "KPxRFxLxuX",
"emailAddress": "johndoe#example.com",
"firstName": "John",
"lastName": "Doe",
"formattedName": "John Doe",
"pictureUrl": "https://media.licdn.com/mpr/mprx/0_0QblxThAqcTCt8rrncxxO5JAr...cjSsn6gRQ2b"
}
Hope this helps!
I'm using OWIN in my solution so after the user allows your application to use LinkedIn credentials a simple and plain GET request to URL https://api.linkedin.com/v1/people/~:(picture-URL)?format=json, as explained before with a Bearer authorization in request headers, solved my problems.
My Startup.Auth.cs file
var linkedInOptions = new LinkedInAuthenticationOptions()
{
ClientId = [ClientID],
ClientSecret = [ClientSecret],
Provider = new LinkedInAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
// This is the access token received by your application after user allows use LinkedIn credentials
context.Identity.AddClaim(new Claim(
"urn:linkedin:accesstoken", context.AccessToken));
context.Identity.AddClaim(new Claim(
"urn:linkedin:name", context.Name));
context.Identity.AddClaim(new Claim(
"urn:linkedin:username", context.UserName));
context.Identity.AddClaim(new Claim(
"urn:linkedin:email", context.Email));
context.Identity.AddClaim(new Claim(
"urn:linkedin:id", context.Id));
return Task.FromResult(0);
}
}
};
app.UseLinkedInAuthentication(linkedInOptions);
My method to get the user's profile picture in LinkedIn:
public string GetUserPhotoUrl(string accessToken)
{
string result = string.Empty;
var apiRequestUri = new Uri("https://api.linkedin.com/v1/people/~:(picture-url)?format=json");
using (var webClient = new WebClient())
{
webClient.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + accessToken);
var json = webClient.DownloadString(apiRequestUri);
dynamic x = JsonConvert.DeserializeObject(json);
string userPicture = x.pictureUrl;
result = userPicture;
}
return result;
}
And finally a snippet of my action that consumes the method above:
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
...
var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
string accessToken =
externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == "urn:linkedin:accesstoken").Value;
model.PhotoUrl = GetUserPhotoUrl(accessToken);
...
}
I hope it could help.
Best regards
This works well for me!
Explained -
This is for a thumbnail with all other data-
https://api.linkedin.com/v1/people/~:(id,location,picture-urls::(original),specialties,public-profile-url,email-address,formatted-name)?format=json
This is for original image with all other data -
https://api.linkedin.com/v1/people/~:(id,location,picture-url,specialties,public-profile-url,email-address,formatted-name)?format=json
Just use picture-urls::(original)instead of picture-url !
This is currently being used in Gradbee
When you login to linkedin, you will get accesstoken. Use that access token and you can retrieve users data
LinkedInApiClient client = factory.createLinkedInApiClient(accessToken);
com.google.code.linkedinapi.schema.Person person = client.getProfileForCurrentUser(EnumSet.of(
ProfileField.ID, ProfileField.FIRST_NAME, ProfileField.LAST_NAME, ProfileField.HEADLINE,
ProfileField.INDUSTRY, ProfileField.PICTURE_URL, ProfileField.DATE_OF_BIRTH,
ProfileField.LOCATION_NAME, ProfileField.MAIN_ADDRESS, ProfileField.LOCATION_COUNTRY));
String imgageUrl=person.getPictureUrl();
If your goal is simply to display the photo on your site then the LinkedIn Member Profile Plugin may work out for you. It will display the photo, some additional info, along with LinkedIn branding.
Since the LinkedIn API is designed to be used only on behalf of the current logged in user it does not offer similar functionality as the facebook graph api.
This is my solution and it works very very well:
def callback(self):
self.validate_oauth2callback()
oauth_session = self.service.get_auth_session(
data={'code': request.args['code'],
'grant_type': 'authorization_code',
'redirect_uri': self.get_callback_url()},
decoder=jsondecoder
)
me = oauth_session.get('people/~:(id,first-name,last-name,public-profile-url,email-address,picture-url,picture-urls::(original))?format=json&oauth2_access_token='+str(oauth_session.access_token), data={'x-li-format': 'json'}, bearer_auth=False).json()
social_id = me['id']
name = me['firstName']
surname = me['lastName']
email = me['emailAddress']
url = me['publicProfileUrl']
image_small = me.get('pictureUrl', None)
image_large = me.get('pictureUrls', {}).get('values', [])[0]
return social_id, name, surname, email, url, image_small, image_large, me
This may not be quite what you're asking for, but it's useful for individual investigations.
Call up the page in Firefox, left-click the menu over the background image.
Select Inspect Element(Q).
search for -target-image"
That will be the end of of id attribute in an img element.
The src attribute of that img element, will be the URL of the background image.
For me this works
image= auth.extra.raw_info.pictureUrls.values.last.first
with omniauth-linkedin gem
Related
I'm adding the "Forgot password" option in my project. The problem is that when I click on the link which was sent in email, the token changes some characters. I inspected the link element received in the email and it's correct. The problem is that when I click on the link to open it, then the bug occurs.
Example: In the correct token, a letter that was "a" will go to "A", "b" to "B" was changed to uppercase as you can see in the print in attach below
var token = await _userManager.GeneratePasswordResetTokenAsync(user);
when the controller ResetPassword is called:
user = await _userManager.FindByEmailAsync(resetPasswordModel.Email);
var resetPassResult = await _userManager.ResetPasswordAsync(user, resetPasswordModel.Token, resetPasswordModel.Password);
if (!resetPassResult.Succeeded) //get invalid token here =/
{
return false;
}
Update
i got fix by using follow code:
var token = resetPasswordModel.Token.Replace("%20","+").Replace(" ", "+");
Update
yes, i already try use UrlEncoding but was useless.
fix using follow code
var token = resetPasswordModel.Token.Replace("%20","+").Replace(" ", "+");
I'm trying to use google API for login but for some reason both $_GET["code"] and $this->request->getVar('code') are empty and I can't fetch my token because of it. I have tried $_GET["code"] instead of $this->request->getVar('code') but nothing is working:
Error Image second image
I was following this video tutorial: click here
public function signup_with_gmail() {
require_once APPPATH.'Libraries\vendor\autoload.php';
$google_client = new \Google_Client();
//$google_client->setApplicationName("pharma");
$google_client->setClientId('clientID');
$google_client->setClientSecret('SECRET');
$google_client->setRedirectUri('http://localhost/pharma/User/sign_in');
$google_client->addScope('email');
$google_client->addScope('profile');
print_r($this->request->getVar('code') === NULL);
print_r($_GET['code']);
if ($this->request->getVar('code') != NULL) {
$token = $google_client->fetchAccessTokenWithAuthCode($this->request->getVar('code'));
if(!$token['error']){
$google_client->setAccessToken($token['access_token']);
$session->set('access_token', $token['access_token']);
//now get profile data create another object
$google_service = new \Google_Service_Oauth2($google_client);
$data = $google_service->userinfo->get();
print_r($data);
}
}
print_r($data);
}
The code in $this->request->getVar('code') will be generated only when you will hit the URL created using $google_client->createAuthUrl();
So, you can do it like this...
In Controller write
$data['loginButton'] = $google_client->createAuthUrl();
Pass this $data['loginButton'] to the view in the anchor tag for the Sign in with Google button.
Now when you will click on the Sign in with Google button it will redirect back to the same localhost.com/login URL but this time you will have the code in the URL. So you can fetch it with $this->request->getVar('code') and follow the rest of the process.
Please make sure all the detail like ClientId & ClientSecret is correct
And update to the latest "google/apiclient": "^2.10"
I was using the YouTube search API to retrieve live videos by channel ID, but recently, the API has begun to return an empty response.
For example, I am retrieving from https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&eventType=live&key={YOUTUBE_KEY}&channelId=UCPde4guD9yFBRzkxk2PatoA which should return all videos which are live from channelID = UCPde4guD9yFBRzkxk2PatoA. This channel has a 24/7 live stream, but the response I get back is:
{
"kind": "youtube#searchListResponse",
"etag": "\"8jEFfXBrqiSrcF6Ee7MQuz8XuAM/-f6JA5_OcXz2RWuH1mpAA2_9mM8\"",
"regionCode": "US",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 5
},
"items": []
}
As I mentioned before, this request was retrieving data fine up until recently. I was unable to find any changes on the YouTube API docs, so I'm wondering if anyone has any idea on what changed or if there's a different approach I can take to pull live videos by channel ID.
Not an answer, but it seems that endpoint isn't returning ANY recent videos that would include live. From what I can tell it doesn't return anything published in the previous 24 hours.
Found an open issue on Google Support
https://support.google.com/youtube/thread/14611425?hl=en
As an alternative, instead, you could load "uploads" playlist,
check https://stackoverflow.com/a/27872244/2154075
try this code
async static Task<IEnumerable<YouTubeVideo>> GetVideosList(Configurations configurations, string searchText = "", int maxResult = 20)
{
List<YouTubeVideo> videos = new List<YouTubeVideo>();
using (var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = configurations.ApiKey
}))
{
var searchListRequest = youtubeService.Search.List("snippet");
searchListRequest.Q = searchText;
searchListRequest.MaxResults = maxResult;
searchListRequest.ChannelId = configurations.ChannelId;
searchListRequest.Type = "video";
searchListRequest.Order = SearchResource.ListRequest.OrderEnum.Date;// Relevance;
var searchListResponse = await searchListRequest.ExecuteAsync();
foreach (var responseVideo in searchListResponse.Items)
{
videos.Add(new YouTubeVideo()
{
Id = responseVideo.Id.VideoId,
Description = responseVideo.Snippet.Description,
Title = responseVideo.Snippet.Title,
Picture = GetMainImg(responseVideo.Snippet.Thumbnails),
Thumbnail = GetThumbnailImg(responseVideo.Snippet.Thumbnails)
});
}
return videos;
}
}
As 8/2020 there some changes in the API and you need to add &type=video or add it to your post request otherwise in some cases you will get empty or random response from the endpoint
for the older channels you may get the right response and it seems to be a bug in the API
https://www.googleapis.com/youtube/v3/search?key={your_key_here}&channelId={channel_id_here}&part=snippet&order=date&maxResults=20&type=video
I have some problem on this. Can I get public tagged photo from Instagram api without getting any code or access token?
Please share any link for reading because I cannot found any. I feel it is less knowledge about Instagram api on web.
Thanks!
You can pull public media by tag without authentication.
Take a look at the API documentation for the get /tags/tag-name/media/recent endpoint. Here's the URL: http://instagram.com/developer/endpoints/tags/#get_tags_media_recent
The documentation can be confusing, it shows using an access_token for this endpoint in the example, but it is not required. You will need to register an application and get a client ID.
I use MeteorJS and call a method server side that returns essentially the 'view source' of the instagram page. So if you can run a server side scrape on the tag url you will be able to handle the response with what i have below and it will push all the images into an array.
//server side method
Meteor.methods({
'scrapeInst':function(tag){
return Scrape.url('https://www.instagram.com/explore/tags/'+tag+'/')
}})
//client side logic
Meteor.call('scrapeInst',Session.get('params').tag,function(err,resp){
var theInstResp = resp;
cleanOne = resp.replace(/>|window._sharedData = |;</|;|#47;|<|/g,'').split('script')
var splitter = cleanOne[22].split(',');
var theArr = [];
_.each(splitter,function(e){
var theFinal = {};
var theS = e.split(":");
if(theS[0].replace(/"| |/g,'') === "display_src"){
theFinal[theS[0].replace(/"| |/g,'')] = theS[2].replace(/%22/g,'');
theArr.push(theFinal)
}
});
Session.set('photos',theArr);
setTimeout(function(){
Session.set('loading',false)
},1000)
})
I am using Google Place Api where is on some results "photo_reference" (similar to "reference") value. I cannot find any mention about that how to use it to get that photo. I know how to use "reference" to get PlaceDetail and I am sure that usage of photo_reference will be similar, but I cannot find JSON/XML URL for this photo_reference request. Thank you for any help. Pavel
Please take a look at documentation here: https://developers.google.com/places/documentation/photos
They've just announced this new Place Photos feature
In short this is how you should use this new feature:
https://maps.googleapis.com/maps/api/place/photo?photoreference=PHOTO_REFERENCE&sensor=false&maxheight=MAX_HEIGHT&maxwidth=MAX_WIDTH&key=YOUR_API_KEY
just substitute your own values in place of:
PHOTO_REFERENCE
MAX_HEIGHT - int value from 1 to 1600
MAX_WIDTH - int value from 1 to 1600
YOUR_API_KEY
and you are done
The Places API now supports the return of one place photo if available for a Place Search request and up to ten place photos for a Place Details request.
If a photos array is returned with your request, you can pass the photo_reference from a contained photo object to a Place Photo request with the maxheight and/or maxwidth, sensor and key parameters:
https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRvAAAAwMpdHeWlXl-lH0vp7lez4znKPIWSWvgvZFISdKx45AwJVP1Qp37YOrH7sqHMJ8C-vBDC546decipPHchJhHZL94RcTUfPa1jWzo-rSHaTlbNtjh-N68RkcToUCuY9v2HNpo5mziqkir37WU8FJEqVBIQ4k938TI3e7bf8xq-uwDZcxoUbO_ZJzPxremiQurAYzCTwRhE_V0&sensor=false&key=AddYourOwnKeyHere
Please see the documentation for more details.
please bear in mind that there are no free photo requests anymore.
At this moment (November 2020), it is $7.0 for 1000 requests (if your volume is up to 100,000). Check the photo below.
Read more on Google Places billing info page.
Step 1: The URL you should use to call Google Place Photos is :
String url = https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=PHOTOREF&key=YOUR_API_KEY
Refer: https://developers.google.com/places/web-service/photos
Step 2: Since the above URL redirects to another URL, use HTTPClient, as it automatically handles redirect stuff.
Code:
DefaultHttpClient hc = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpContext context = new BasicHttpContext();
hc.setRedirectHandler(new DefaultRedirectHandler() {
#Override
public URI getLocationURI(HttpResponse response,
HttpContext context) throws org.apache.http.ProtocolException {
//Capture the Location header here - This is your redirected URL
System.out.println(Arrays.toString(response.getHeaders("Location")));
return super.getLocationURI(response,context);
}
});
// Response contains the image you want. If you test the redirect URL in a browser or REST CLIENT you can see it's data
HttpResponse response = hc.execute(httpget, context);
if(response.getStatusLine().getStatusCode() == 200) {
// Todo: use the Image response
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
Bitmap bmp = BitmapFactory.decodeStream(instream);
ImageView imageView = new ImageView(context);
imageView.setImageBitmap(bmp);
images.add(imageView);
instream.close();
}
}
else {
System.out.println(response.getStatusLine().getStatusCode()+"");
}
Hope this helps everyone.
After initiating map you can get place details with it's images
const service = new window.google.maps.places.PlacesService(map);
service.getDetails(
{
placeId: "some_place_id_here"
},
(data, status) => {
if (status === window.google.maps.places.PlacesServiceStatus.OK) {
data.photos &&
data.photos.forEach(photo => {
console.log(photo.getUrl({ maxWidth: 500, maxHeight: 500 }));
});
}
}
);
Solving the PhotoReference issue for Javascript
User #R.K solved this issue in java, however in js you need to use fetch(). Here's the code I used:
await fetch(proxyUrl+url).then(async(ref)=>{
await ref.blob()}).then((image)=>{
// do what you need to do
console.log(image)
}).catch((err)=>{
console.log(err);
})
In this, I used a heroku link for the proxyUrl and the url shown in #Chriss Green's post for url. Hope this helps anyone confused using js!