How to check whether Google User's image is default or uploaded? - google-api

How do I check whether user's profile picture is default or uploaded in Google?
Note: When you get user details from APIs.

All of default profile pictures have the following URL:
https://lh3.googleusercontent.com/-XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg
You can just compare string equality of profile picture with the given one.

people.get includes a isDefault value in the image object. E.g. if you try it for +Google you will get;
"image": {
"url": "https://lh4.googleusercontent.com/-v0soe-ievYE/AAAAAAAAAAI/AAAAAAACyas/yR1_yhwBcBA/photo.jpg?sz=50",
"isDefault": false
}

people.get no longer has isDefault as a property.
https://developers.google.com/+/web/api/rest/latest/people#resource

Updating this answer for 2020: it's now possible to get the user's profile picture by sending a request to the people.get API with photos as the personFields to request.
You'll get back an array of images, and whenever default: true is present, it means it's a default (not user-set) image:
Example (if you're using this with OAuth):
GET https://people.googleapis.com/v1/people/me
Sample response (with profile picture)
{
"resourceName": "people/117055959617985617271",
"etag": "%EgQBAzcuGgQBAgUHIgxHamp6MG9wZ3hOcz0=",
"photos": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "117055959617985617271"
}
},
"url": "https://lh3.googleusercontent.com/a-/AOh14Gg_-udXd3O6K1URTBTEK2rLa2DOh6G2dgmOHcOBOtE=s100"
},
{
"metadata": {
"source": {
"type": "CONTACT",
"id": "2"
}
},
"url": "https://lh3.googleusercontent.com/a/default-user=s100",
"default": true
}
]
}
Sample response (default only)
{
"resourceName": "people/113009277022343767972",
"etag": "%EgQBAzcuGgQBAgUHIgxxdHVTY3IxZVJIUT0=",
"photos": [
{
"metadata": {
"primary": true,
"source": {
"type": "PROFILE",
"id": "113009277022343767972"
}
},
"url": "https://lh6.googleusercontent.com/-6NS3awoYRXw/AAAAAAAAAAI/AAAAAAAAAAA/AMZuucnTo-mElIpcAEazDV9DAs1VyYDEIw/s100/photo.jpg",
"default": true
}
]
}

in ruby with devise and omniauth-google-oauth2
in your devise.rb
config.omniauth :google_oauth2 (Other options....), skip_image_info: false
then in your user.rb / other place:
def self.parse_auth_image(auth)
if auth.provider == "google_oauth2"
return nil if auth.dig("extra", "raw_info", "image", "isDefault")
end
auth.info.image
end

The best way to do this in FULL DETAIL:
require 'open-uri'
Default image:
default = "https://lh3.googleusercontent.com/-
XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/photo.jpg"
Image to check:
image_to_check = "https://lh3.googleusercontent.com/-
uh4wK1JDtCI/AAAAAAAAAAI/AAAAAAAAAAA/huieBSbV4zg/s64-
c/100695019739939096169.jpg"
Comparison check
blob_for_default_image = open(default).read
blob_for_image_to_check = open(image_to_check).read
Then you compare the 2 image blobs:
blob_for_default_image == blob_for_image_to_check

If you are using PHP, It's fairly simple, just use this code
$profile_img_end = explode("/", $userData['picture']); // Exploding the URL and Dividing it into several terms
if (end($profile_img_end) === "photo.jpg") { // Now Simply Check if last part of array is equal to "photo.jpg" which is common in all default images
$profile_img = null; // If it's default then set it equal to null
} else {
$profile_img = $userData['picture']; // Else get the Link of the Image
}
Alternative in JavaScript
var url = ""; // Image URL
var img_split = url.split("/"); // Split it Again from / (forward slash)
if (img_split[img_split.length - 1] === 'photo.jpg') { // Check if last array is equal to photo.jpg (By Default Image)
var image = null;
} else {
var image = url;
}
HOPE IT HELPS!

Related

VueJs not sending data via Inertia to Laravel?

I have question it seems like when I try to send some data via Inertia I dont recieve any in Laravel for some reason any suggestion? Can it have to do something with the fact that the object is proxy object ?
Here are some images:
dd() in php controlelr
console.log() of the object before beeing sent via Inertia
Code of how I send the data + the console log right before sending it
UPDATE:
This is how I add page object to array of pages:
this.Pages.push({
"name": "Untitled",
"icon": "home",
"order": order,
"sections": [],
"DisplayName":true,
"Banner":"Medium",
"Published":"Published",
"DisplayLogo":true,
"media":{
'BackgroundImage': null,
'LogoImage': null,
'BackgroundImageHeight': null,
'LogoImageHeight': null,
'BackgroundImageStyle': {
"value": []
},
"LogoImageStyle": {
"value": []
},
}
});
This is my inertia form:
saveForm: {
applications: [],
},
This is whole save() method:
Save() {
if(this.localProduct.translation.applications.mobile_label[this.currentMobileLabel] != undefined){
if(this.localProduct.translation.applications.mobile_label[this.currentMobileLabel].data == undefined){
this.localProduct.translation.applications.mobile_label[this.currentMobileLabel] = {
"Pages": this.Pages,
"media": this.media,
"name": this.localProduct.translation.applications.mobile_label[this.currentMobileLabel].name,
"active": this.localProduct.translation.applications.mobile_label[this.currentMobileLabel].active,
};
}
else{
this.localProduct.translation.applications.mobile_label[this.currentMobileLabel] = {
"Pages": this.Pages,
"media": this.media,
"name": this.localProduct.translation.applications.mobile_label[this.currentMobileLabel].name,
"active": this.localProduct.translation.applications.mobile_label[this.currentMobileLabel].active,
"data" : this.localProduct.translation.applications.mobile_label[this.currentMobileLabel].data,
};
}
}
this.saveForm.applications = toRaw(this.localProduct.translation.applications);
console.log(this.saveForm);
Inertia.post(this.route(`product.translations.applications`,{translation: this.localProduct.translation.id}),this.saveForm);
},
The applications should be array, the mobile_label should be also array.As it is.
!!!IMPORTANT ALSO!!!
All of this code worked before the project started to shift to vue js 3 and I suppose many libraries had to be updated/exchanged for others.
According to Inertia's documentation the first parameter expected when using Inertia.post() is a URL. Does all of this.route(`product.translations.applications`,{translation: thislocalProduct.translation.id}) return a URL?
To anyone who's having same problem check your array/object assiging to your variables there could be the mistake like in mine I fixed mine with this:
this.saveForm.applications = toRaw(this.localProduct.translation.applications);
var fixed = Object.assign({},this.localProduct.translation.applications);
Inertia.post(this.route(`product.translations.applications`,{translation: this.localProduct.translation.id}),fixed);

Microsoft Teams: get timezone of user?

I'm developing a bot for MS Teams and I'm looking to know the timezone of a user, to deliver messages at an appropriate time (e.g. not in the middle of the night).
I didn't found something appropriate in the bot framework REST API. Although messages we receive include a 'clientInfo.country' property, which is a start, but definitely not enough to time messages as we would like.
On every message to a user, there is an entities[] collection, one of which is details of the user's locale. For example (copied/pasted from here):
"entities": [
{
"locale": "en-US",
"country": "US",
"platform": "Windows",
"timezone": "America/Los_Angeles",
"type": "clientInfo"
}
],
And the answer is: there’s a localTimestamp property that can be used to get the time offset, which is good enough for what I need.
From #Savageman 's answer
And the answer is: there’s a localTimestamp property that can be used to get the time offset, which is good enough for what I need.
We can solve the issue "NOT Receive the timezone" by mapping the utcOffset of localTimestamp and country in entities to timezone.
I wrote a javascript code to get timezone such as "Asia/shanghai" by using the "localTimestamp": "2019-08-06T18:23:44.259+08:00" and "country": "CN" from Session in Teams message.
More details in my github readme.md.
let moment = require("moment-timezone");
let ct = require("countries-and-timezones");
let partOfSampleSession = {
"message": {
"entities": [
{
"country": "CN",
"locale": "zh-CN",
"platform": "Web",
"type": "clientInfo"
}
],
"localTimestamp": "2019-08-06T18:23:44.259+08:00"
}
}
function getTimezoneFromSession(session) {
// Get the name of country, such as "CN", "JP", "US"
let country = session.message.entities[0].country;
// Get the localTimestamp from message in session, such as "2019-08-06T18:23:44.259+08:00"
let localTimestamp = session.message.localTimestamp;
// Caculate the utfOffset of "localTimestamp", such as "480" by "2019-08-06T18:23:44.259+08:00"
let utcOffsetOfLocalTime = moment().utcOffset(localTimestamp).utcOffset();
// Mapping country to an object array which contains utcOffsets and it's corresponding timezones
// One element from mxTimezones is {"utcOffset": "480", "name": "Asia/Shanghai"}
let mxTimezones = ct.getTimezonesForCountry(country);
// get the same timezone as localtime utcOffset from timezones in a country
let timezone = "";
mxTimezones.forEach(mxTimezone => {
if (mxTimezone.utcOffset == utcOffsetOfLocalTime) {
timezone = mxTimezone.name;
}
});
return timezone;
}
let timezone = getTimezoneFromSession(partOfSampleSession);
// timezone = "Asia/Shanghai"
console.log(timezone);
// example of ct.getTimezonesForCountry("US")
// mxTimezones = [
// {
// "name": "America/New_York",
// "utcOffset": "-300",
// },
// {
// "name": "America/Los_Angeles",
// "utcOffset": "-480",
// }
// ...
// 27 elements
// ...
// ]

How can I sort GeoJson file showing defined tags?

Good morning to all and thank you for your help.
I'm working in a map page (map.html) create by leaflet library that take data from a external geojson file called water_well.js. This file, previously generated by overpass service is just a list of markers. every Marker have some proprerties. Follow an exemple:
"properties": {
"operator:type": "international",
"is_in:district": "west_mamprusi",
"is_in:region": "northern",
"source:date": "2012-02-11",
"source:ele": "gps",
"water_wells:source_type": "borehole"
},
The main page extract those data from the file before with this javascript:
var wwMarker = L.geoJson(water_well, {
pointToLayer : function (feature, latlng) {
lat = feature.geometry.coordinates[0];
lng = feature.geometry.coordinates[1];
//following code that make error
op_type = feature.properties.operator_type;
district = feature.properties.is_in:district;
region = feature.properties.is_in:region;
source_date = feature.properties.source:date;
source_ele = feature.properties.source:ele;
source_type = feature.properties.water_wells:source_type;
.....
I'm sure the problem is my Zero javascript knowledge, but I'm not a programmer and I do this map for my NGO engaged in water wells in Burkina Faso.
The script for extraction of the data don't work in this point:
op_type = feature.properties.operator:type;
The problem is ":" because is invalid character.
The second question is that not all markers in the first file called water_well.js have the same "properties" filled ad actually it is possible that someone have different group of "properties like those two:
{
"type": "Feature",
"id": "node/1606958159",
"properties": {
"#id": "node/1606958159",
"amenity": "drinking_water",
"man_made": "water_well",
"name": "puits 4"
},
"geometry": {
"type": "Point",
"coordinates": [
-3.6235696,
12.02171
]
}
},
{
"type": "Feature",
"id": "node/1913126817",
"properties": {
"#id": "node/1913126817",
"ele": "170.8000030517578",
"grid_proximity": "grid_further_500_m",
"is_in:district": "builsa",
"is_in:region": "upper_east",
"man_made": "water_well",
"operational_status": "open",
"operator:type": "individual",
"pipe_connection": "no",
"pump": "manual",
"seasonal": "another_pattern",
"source": "MVP,Columbia University",
"source:date": "2012-02-14",
"source:ele": "gps",
"water_wells:source_type": "unprotected_well"
},
"geometry": {
"type": "Point",
"coordinates": [
-1.2430456,
10.3233693
]
}
},
maybe it is possible to extract all properties of each item independently from which one is present or not..... This can be de better way to solve the problem but I've no idea how to do that.
This is what I do (ckick the water tap to see pop-up): www.h2openmap.org/map
This is almost what I would like to do (ckick the water tap to see pop-up): overpass-turbo.eu/s/7Ov
Thank you for spending your time reading my question.
Have a nice day everyone, Francesco
You can access those properties using the bracketnotation, instead of using:
district = feature.properties.is_in:district;
Use bracketnotation:
district = feature.properties['is_in:district'];
Reference on property-accessors: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
Now if you want to do something based on if a property exists there is a hasOwnProperty method available on objects. Since feature.properties is an object you can use that in a condition:
if (features.properties.hasOwnProperty('is_in:district')) {
// Property exists, do stuff
}
// or
if (!features.properties.hasOwnProperty('is_in:district')) {
// Property does not exist, do stuff
}
If you want to do something base on wether multiple properties exist you can use the && (and) operator:
if (features.properties.hasOwnProperty('is_in:district') &&
features.properties.hasOwnProperty('source:data')) {
// Properties exist, do stuff
}
// Or
if (!features.properties.hasOwnProperty('is_in:district') &&
!features.properties.hasOwnProperty('source:data')) {
// Properties do not exist, do stuff
}
You could use the || (or) operator to see if at least one of the conditions matches:
if (features.properties.hasOwnProperty('is_in:district') ||
features.properties.hasOwnProperty('source:data')) {
// At least one of the properties exist, do stuff
}
// Or
if (!features.properties.hasOwnProperty('is_in:district') ||
!features.properties.hasOwnProperty('source:data')) {
// At least one of the properties does not exist, do stuff
}
Reference for this can be found here under "Logical operators": https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
You can use something like to build (or don't build) the data object that you need for your popup. Hope that helps.

Intel XDK : Parse.com integration "Unauthorized"

I am very new to Intel XDK and i try to make a very simple app like this in that video tutorial: Using Services Datafeed in App Designer.
But instead of the specific service from Rotten Tomatoes i want to integrate a database i have in Parse.com. For that i followed this video tutorial: "Integrating a New Service"
"[https]://software.intel.com/en-us/html5/videos/integrating-a-new-service",
and at the end the response was: "Unauthorized".
Then i found only this answer which comes from Intel's HTML5 Development Forums. I did not get anything either with this. The response was again: "Unauthorized".
And now i am confused and disappointed because:
I can't find other resources to help my self
I don't want to do it someone else instead of me, but
Without a full example, how is supposed to make it to learn?
My code now is similar with this in video: "Integrating a New Service"
In apiconfig.json
{
"MyService": {
"name": "The external service",
"description": "A great API with an external service",
"dashboardUrl": "https://parse.com",
"auth": "key",
"signature": "apiSecret"
}
}
In MyService.js
(function (credentials) {
var exports = {};
exports.ServiceObject = function(params) {
var url = 'https://api.parse.com/1/classes/ServiceObject';
params['apiKey'] = credentials.apiKey;
url = url + '?' + $.param(params);
return $.ajax({url: url, type: 'GET'});
};
return exports;
})
And in MyService.json
{
"endpoints": [
{
"name": "classes",
"dashboardUrl": "https://parse.com/docs/rest",
"methods": [
{
"MethodName": "ServiceObject",
"Synopsis": "Show the entries",
"parameters": [
{
"Name": "objectId",
"Required": "N",
"Default": "",
"Type": "string",
"Description": "The object ID"
},
{
"Name": "text",
"Required": "N",
"Default": "",
"Type": "string",
"Description": "The text"
}
]
}
]
}
]
}
Can someone help me more? In whatever way he thinks best.
Thank you all
Edit:
After the following answer, my problem solved.
"MyService.js" file after the correction is:
(function (credentials) {
var exports = {};
exports.ServiceObject = function(params) {
var url = 'https://api.parse.com/1/classes/ServiceObject';
return $.ajax({
url : url,
headers : {
'X-Parse-Application-Id' : credentials.apiKey,
'X-Parse-REST-API-Key' : credentials.apiSecret
}
});
};
return exports;
})
# user1736947: Your answer was concise and precise, exactly what i needed.
Certainly in the future I will need a lot of help, but for now I can go on my self-education thanks to you.
Thank you very much.
The way the authentication keys are accepted is different for different services. The example in the video.. rottentomatoes.. it accepted keys as a url parameter, so we append the key to the url and send it. However, seems like parse wants the keys in the headers (according to this)
So the equivalent ajax call will be something like :
exports.ServiceObject = function(params) {
var url = 'https://api.parse.com/1/classes/ServiceObject';
return $.ajax({
url : url,
headers : {
'X-Parse-Application-Id' : credentials.apiKey,
'X-Parse-REST-API-Key' : credentials.apiSecret
}
});
This might not fix everything but it will move you a step beyond the authorization issue. Let me know if you are able to retreive the class this way.
To get a particular row entry, append the url with params.objectID.
Also, the XDK services tab has a parse-similar service ... kinvey. It also allows you to create a database online and retreive it.

google-api-javascript-client : How to get contents of file using Drive API?

First off, if there is a question/answer that solves my problem already then I sincerely apologize for creating a new one. However, I have been searching for 3 days now, and have not found an answer...
My problem is, I cannot for the life of me figure out how to pull the contents of a file(any file). From reading the docs I've discovered that my returned file resource object is supposed to have a property named "downloadUrl", and from this I should be able to access the file contents.
None of the file resource objects that are returned to me(via gapi.client.request) have this field/property. Below is the function I am using to get a file.
Can someone please help point me in the right direction? I have to have this demo done by Monday and I've been stuck on this for 2 days....
Here is the code for my get function :
Client.getFileContent = function getFileContent() {
gapi.client.load('drive', 'v2', function() {
var request = gapi.client.request({
path : '/drive/v2/files/1QmaofXyVqnw6ODXHE5KWlUTcWbA9KkLyb-lBdh_FLUs',
method : 'GET',
params : {
projection: "FULL"
}
});
request.execute(function(response) {
console.log(response);
});
});
};
The file resource object that is returned to me does not have the downloadUrl property.
As requested, here is the response object I get back for a text file. Note, I replaced some of the ids with "fileid" for posting here.
"kind": "drive#file",
"id": "fileID",
"etag": "\"-tJAWr_lbRQU2o8gZ0X7BCBIlVk/MTM0MjYyODQ1MTQ2Nw\"",
"selfLink": "https://www.googleapis.com/drive/v2/files/fileID",
"alternateLink": "https://docs.google.com/document/d/fileID/edit",
"embedLink": "https://docs.google.com/document/d/fileID/preview",
"thumbnailLink": "https://docs.google.com/feeds/vt?gd=true&id=fileID&v=1&s=AMedNnoAAAAAUAfLhbYIDsNIn40k7DfRYBsrquijmCii&sz=s220",
"permissionsLink": "https://www.googleapis.com/drive/v2/files/fileID/permissions",
"title": "Copied filed.txt",
"mimeType": "application/vnd.google-apps.document",
"labels": {
"starred": false,
"hidden": false,
"trashed": false,
"restricted": false,
"viewed": true
},
"createdDate": "2012-07-18T16:20:51.132Z",
"modifiedDate": "2012-07-18T16:20:51.467Z",
"modifiedByMeDate": "2012-07-18T16:20:51.467Z",
"lastViewedByMeDate": "2012-07-18T16:20:51.467Z",
"parents": [
{
"kind": "drive#parentReference",
"id": "0AAAYYkwdgVqHUk9PVA",
"selfLink": "https://www.googleapis.com/drive/v2/files/fileID/parents/0AAAYYkwdgVqHUk9PVA",
"parentLink": "https://www.googleapis.com/drive/v2/files/0AAAYYkwdgVqHUk9PVA",
"isRoot": true
}
],
"exportLinks": {
"application/vnd.oasis.opendocument.text": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=odt",
"application/msword": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=doc",
"text/html": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=html",
"application/rtf": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=rtf",
"text/plain": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=txt",
"application/pdf": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=pdf"
},
"userPermission": {
"kind": "drive#permission",
"etag": "\"-tJAWr_lbRQU2o8gZ0X7BCBIlVk/9STkNeCmz61YXorH3hoJimnEgfM\"",
"id": "current",
"role": "owner",
"type": "user"
},
"quotaBytesUsed": "0",
"ownerNames": [
"Joshua.morine"
],
"lastModifyingUserName": "Joshua.morine",
"editable": true,
"writersCanShare": true
}
For native Google documents (Google Spreadsheet, Presentation etc...) we don;t provide a downloadUrl as these can't really be downloaded as files in their native format. Instead you'll have to use one of the URLs in the list of exportLinks which provides URLs to download the Google Documents in a few different export formats.
In your case, a Google Documents the following can be used:
"exportLinks": {
"application/vnd.oasis.opendocument.text": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=odt",
"application/msword": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=doc",
"text/html": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=html",
"application/rtf": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=rtf",
"text/plain": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=txt",
"application/pdf": "https://docs.google.com/feeds/download/documents/export/Export?id=fileID&exportFormat=pdf"
}
The meta-data function you are looking for is actually:
request = gapi.client.drive.files.get({
'fileId': fileId
});
This one produces a result with the downloadUrl that you're referring to. Then it's easy to grab the file using any HTTP request.

Resources