Google Contacts API v3 parameter for multiple search terms - google-contacts-api

I am trying to search multiple terms in Google contacts API using JS. When I try with single term it is working fine. Here is the code used for single term.
gapi.client.request({
method: 'GET',
path: 'm8/feeds/contacts/default/full?q=TERM&alt=json',
headers: {
"GData-Version": "3.0",
"if-match":"*",
"data":token,
},
callback: function(response) {
console.log(response);
}
});
For multiple terms, I am using the following codes "q=TERM1 TERM2" or "q=TERM1+TERM2" or "q=TERM1%20TERM2" but it is not working. I got 0 contacts matched for this search.
I have followed "standard query parameters" as in this link https://developers.google.com/gdata/docs/2.0/reference. I knew it is v2 document, but still it is connected with v3 document https://developers.google.com/google-apps/contacts/v3/reference#ProjectionsAndExtended. Please advice what I did wrong.
Thank you.

Related

Unable to get users by orgUnitPath with Admin SDK

Why am I unable to retrieve a list of users when using query to search the orgUnitPath? When I try the same parameters on the Google API Explorer (https://developers.google.com/admin-sdk/directory/reference/rest/v1/users/list) the response returns the expected result of users. However, in my code, the response returned is undefined because the full response does not seem to be pulled. Code.gs for reference:
function myFunction() {
var options = {
domain: schoolDomain, // Google Workspace domain name
query: orgUnitPath='/School Staff',
type: 'all',
maxResults: 5,
orderBy: 'familyName',
viewType: 'admin_view'
};
var response = AdminDirectory.Users.list(options);
console.log(response.users);
}
I'm writing this answer as a community wiki since the solution was provided by the OP in the comments section.
The issue was related to the syntax of the query, when using the query for orgUnitPath, it needs to be inside '' like this:
"orgUnitPath='/School Staff'"
or
'orgUnitPath="/School Staff"'
This information can be found in the Google Documentation here.

How to build custom Zapier integration for Xero

I am attempting to build my own integration in zapier that will allow me to create quotes in Xero (a feature not currently supported natively). I've been using this this post and this reference to help me.
I've gotten to the point where I'm creating the action and testing it with test data. Unfortunately, the response I get is "Got 400 calling POST https://identity.xero.com/connect/token, expected 2xx." Perhaps I'm sending the json data incorrectly. I've tried using the 'pretty' and 'raw' ways of sending data:
Could a zapier "expert" help me with this? Perhaps by creating their own xero integration?
EDIT
Not sure if necessary, but blocked out the IDs. Although I now see that I didn't do that for the contactID in the first post lol...
Here is how to get it done, but remember that you will need to have a search action to find information for the required ID's. Given your error I think the problem is that you did not have the tenantId that should be defined in your header like so: 'xero-tenant-id': 'YOURNUMBERHERE'. See step 8 below to compare it to yours.
In case you can't find it, these are the steps I took:
XERO
Create Account
Create Xero App and add the Zapier OAuth Redirect URL to the Xero redirect section(from your 'Zapier Dev' app on 'step 2').
ZAPIER
In your dev app, add the CLient ID & Secret from xero to the appropriate sections in 'Zapier Dev step 3'
Add the POST endpoint (requested in 'Zapier Dev step 4') https://login.xero.com/identity/connect/authorize
with the HTTP headers:
response_type: code
client_id: {{process.env.CLIENT_ID}}
redirect_uri: {{bundle.inputData.redirect_uri}}
state: {{bundle.inputData.state}}
Add the scope: openid profile email accounting.transactions
Refresh token ('Zapier Dev step 4: Access Token') can be obtained using this:
REFRESH TOKEN: POST https://identity.xero.com/connect/token
TEST CALL: GET https://api.xero.com/connections
-Keep the returned tenantId for later use
-Test the authentication. Does it work? If yes, move on to step 7.
-If test fails: review for typos, check for correct url's and make sure your Headers match what xero requires (see link at bottom).
Add Action called createQuote
-Add input contactID
-Add input lineitem with label of description
-Add input tenantId
Add POST to API Config at url https://api.xero.com/api.xro/2.0/Quotes
Example POST:
const options = {
url: 'https://api.xero.com/api.xro/2.0/Quotes/',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${bundle.authData.access_token}`,
'xero-tenant-id': bundle.inputData.tenantID
},
params: {
},
body: {
"Contact": {
"ContactID": bundle.inputData.ContactID
},
"Date": "2019-11-29",
"LineItems": [
{
"Description": bundle.inputData.LineItems
}
]
}
}
return z.request(options)
.then((response) => {
response.throwForStatus();
const results = z.JSON.parse(response.content);
return results;
});
Plug in the test contactID, tenantID, lineitems and test it out
After completing this you will need to create a search action to grab the contactID and tenantID if you want it all automated. If you have problems I found the start-up doc to be useful.

Understanding JSON and Dropbox API pulls

so I'm jumping in head first here and trying to learn something new... I have an Angular Function that will pull in all the contents of a folder using the Dropbox API and list it into a JSON file (and later display it on a webpage.)
what I want to do next is to get a share link for all those files using the create_shared_link_with_settings API and put them into a JSON file for all the files in the folder.
here's what I have for the first part. If you could help me out or point me in the right direction on the proper way to tackle this.
var app = angular.module("content-review", []);
app.controller("Content-folders-4K", function ($scope, $http) {
$http({
url: 'https://api.dropboxapi.com/2/files/list_folder',
method: 'POST',
processData: false,
contentType: 'application/json',
data: ({
"path": "/MIG/Projects/Hippo content Watermark/HD/011_Blue"
}),
headers: {
"Authorization": "Bearer APIKEYTHATIMNOTSHARING",
},
})
.then(function (response) {
$scope.UHD = response.data.entries;
$scope.json = angular.toJson(response.data, true);
console.log($scope.json)
});
});
To create a shared link for a file or folder in Dropbox, the /2/sharing/create_shared_link_with_settings endpoint you mentioned is the correct endpoint to use. You can find the documentation here. There's also an example of calling it in curl that you can translate for use with your own HTTPS client.
You specify which item you want the link for using the path parameter similar to how you did for the /2/files/list_folder call you showed. You can get the path value from the path_lower value for each "entry" in the /2/files/list_folder responses.
Note that if a shared link already exists for the item, you'll get a shared_link_already_exists error. The error will include the existing shared link only if the settings for the existing link match the settings you requested. Otherwise, you'll need to call /2/sharing/list_shared_links to get the existing link.
Either way, you can parse the result of the successful call to get the SharedLinkMetadata.url value for use in your app.

How to create microsoft/google translate button for each div separately?

How to create microsoft or google translate button for each div?
Each div has content in different language and I would like to add a translate button for each div and make it respond to only that div like the button in the following link.
http://www.bing.com/widget/translator
But when I use the code mentioned in the link above, it translates the whole webpage. I would like to translate each div separately by clicking on the respective translate button.
Can the same thing be done easily using google translate?
Any translator is fine with me. Kindly help. Thanks.
This how the users' post appear on my website.
I would like to have a translate button for each of the divs so that the users can translate each div into any language they want.
Each of my div has an id.
Below I'm explaining how to get started with Microsoft Translator API. The very same functionality can be implemented via Google Translate API however it was somehow easier for me with MS as they offer 2M characters/monthly translation for free whereas Google charges minimum of 1$ for testing.
Prerequisites:
Sign up for free subscription on Microsoft Translator. For that you will be asked to create new MS account or login with existing one.
Register your application on Azure Datamarket.
Registration example. Note: There are two important fields here Client ID and Client secret you will need them for access token requests.
Implementation:
First things first, every request to the API should include access token. Expiration time is 10 minutes so you will have to renew them before they expire. Ideally the process should be done on the back-end side to protect your Client secret and result (token + expiration time) send back to web application.
Node.js example:
var request = require("request");
var options = {
method: 'POST',
url: 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13/',
form: {
// Client ID & Client secret values (see screenshot)
client_id: 'translator_3000',
client_secret: 'ZP8LzjZkKuFAb2qa05+3nNq+uOcqzWK7e3J6qCN1mtg=',
scope: 'http://api.microsofttranslator.com',
grant_type: 'client_credentials'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Response contains few fields including access_token, use its value for further requests.
{
"token_type": "http://schemas.xmlsoap.org/ws/2009/11/swt-token-profile-1.0",
"access_token": "http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=translator_3000&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&Audience=http%3a%2f%2fapi.microsofttranslator.com&ExpiresOn=1435405881&Issuer=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&HMACSHA256=st9LJ0F8CKSa6Ls59gQN0EqMWLFed5ftkJiOCVXE4ns%3d",
"expires_in": "600",
"scope": "http://api.microsofttranslator.com"
}
Now when we have access token it's time for translation request. Note: These are JSONP requests and access token is supplied using query string parameter appId in the format Bearer <token> (separated by space). Query string also includes text parameter - text of your post and to parameter - language code selected by user, list of all supported codes and language friendly names you can get from API as well.
Here is example:
var settings = {
"url": "https://api.microsofttranslator.com/v2/Ajax.svc/Translate",
"method": "GET",
"dataType": "jsonp",
"jsonp" : "oncomplete",
"data" : {
"text" : "Good Morning StackOverflow",
"to" : "uk",
"appId" : "Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=translator_3000&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&Audience=http%3a%2f%2fapi.microsofttranslator.com&ExpiresOn=1435405881&Issuer=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&HMACSHA256=st9LJ0F8CKSa6Ls59gQN0EqMWLFed5ftkJiOCVXE4ns%3d"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
Response is translated string to be replaced with post original text:
"Доброго ранку StackOverflow"
And lastly, all language codes:
http://api.microsofttranslator.com/V2/Ajax.svc/GetLanguagesForTranslate
and friendly names for selected codes:
http://api.microsofttranslator.com/V2/Ajax.svc/GetLanguageNames?locale=en&languageCodes=["en", "de", "es", "uk"]
Official documentation included.
Use the Class element <div class="micropost293"> shown below.
<div class="micropost293"><p>Тестирование</p>
<div class="micropost293_control" lang="en"></div>
<script>
function googleSectionalElementInit() {
new google.translate.SectionalElement({
sectionalNodeClassName: 'micropost293',
controlNodeClassName: 'micropost293_control',
background: '#f4fa58'
}, 'google_sectional_element');
}
</script>
</div>
//Place this Script at bottom of page.
<script src="//translate.google.com/translate_a/element.js?cb=googleSectionalElementInit&ug=section&hl=en"></script>

files.list behavior seems to have changed

I've been naming Drive files with a very specific convention to facilitate searching for them from an app. The search functionality in the v3 Drive API (files.list) had been working as recently as three weeks ago and has since stopped working.
For example, using the following files,
"ABC-123 template", "ABC-123 gogo", "ABC-123 bobo"
... enables me to search via the API with
name contains 'ABC-123'
This search should return all three files. Instead it returns no results. Note that the same query in the Drive web interface is successful and the convention follows the rules laid out in the documentation.
This was working, and now it has stopped. Did the search API change?! I can find other files with the implementation, just not those that use the naming convention.
Here's the full code snippet of the request in NodeJS.
Google.prototype.findFiles = function(file_prefix, callback) {
var service = google.drive('v3');
service.files.list({
q: "name contains '" + file_prefix + "'",
fields: 'nextPageToken, files(id, name)',
spaces: 'drive',
corpus: 'domain',
auth: this.auth
}, function(err, response) {
if(err) {
console.log('Error : findFiles failed. ' + err);
callback(err);
} else {
callback(null,response.files);
}
});
};
The root cause turned out to be the corpus value. For reasons that are not clear from the documentation, the use of corpus=domain is preventing the search from working.
Removing corpus: 'domain', from the above code sample solves the problem.
The files I'm searching are very much in my domain. I'm not sure if this behavior changed recently or if added this constraint in the code and simply don't remember doing so.
Onward.