I'm making a call to get multiple routes from google maps Distance Service API and I'm able to get a successful response. But I want to get the route URL (shortURL), so if the client clicks on the link he'll be directly redirected to google maps showing the route. Here is my code:
var directionsService = new google.maps.DirectionsService;
return directionsService.route({
origin: origin,
destination: destination,
travelMode: 'DRIVING',
provideRouteAlternatives: true,
unitSystem: google.maps.UnitSystem.IMPERIAL,
}, shortestRoute);
If you are not trying to use the Google Maps Directions Service for navigation purposes, what you could do instead is dynamically supply the (shortURL) based on user input assuming you are listening to user input on your side of the application.
One simple implementation is that you provide the (shortURL) right off the bat so that users may type the Directions information on the actual Google Maps page instead of on your site assuming you are not loading a modal and/or iframe since you mentioned redirecting.
Now if you are not planning on redirecting before the user inputs their data. You could setup something like:
See Documentation.
var origin;
// This function gets called when you are ready to submit the user's input.
function directionsOrigin(){
var origin = document.getElementById('origin-input').value;
placeholdDynamicInput(origin);
}
function placeholdDynamicInput(origin, dynamicUrl){
// Following this
// protocol-> https://www.google.com/maps/dir/?api=1¶meters
var url = 'https://www.google.com/maps/dir/?api=1&origin=' + origin;
// Dynamically create your placeholder URL using user input.
}
function dynamicUrl(){
// Handle this function however makes sense with your application
}
Related
Hello! I'd appreciate any help in making a connection. Here's what I'm trying to 'Get' info from:
curl https://connect.squareup.com/v2/locations
-H 'Square-Version: 2022-01-20'
-H 'Authorization: Bearer ACCESS_TOKEN'
-H 'Content-Type: application/json'
Setting the Scopes:
First I set the following scopes in the manifest file (here's a picture). I followed a similar notation as google's.
The Apps Script:
function squareLocations() {
var url = "https://connect.squareup.com/v2/locations";
var headers = {
"contentType":"application/json",
"headers": {"Square-Version": "2022-01-20",
"Authorization": "Bearer <TOKEN>"}
};
var data =
{
'locations':
{
'id': locationID,
'name': locationName,
'address': locationAdress,
}
}
var response = UrlFetchApp.fetch(url, headers);
var text = response.getResponseCode();
var json = JSON.parse(response.getContextText());
Logger.log (text);
Logger.log (json);
}
response returns a 400 error: invalid scope (lists all scopes).
In the appsscript.json file remove the OAuth scope from square. On this file only include the OAuth scopes required by the Google Apps Script and Advanced Services (like Advanced Sheets Service).
The scopes of APIs called using by UrlFetchApp.fetch() might be included when generating the token or on the corresponding API console / App settings (I'm sorry , I don't know the details of Square API).
Background: why the manifest scopes are not relevant to the Square API##
The Square API uses the Oauth2 protocol. The idea of this protocol is as follows: you provide the user an opportunity to log in to their Square account, and in the process, you capture an oauth token that represents that user's login. This token allows your script to take action on the user's behalf. The scopes you specify tell the user what types of actions you'll be performing on their behalf, and you are limited to only those actions when calling the API.
The scopes listed in the Apps Script manifest represent the same idea, but for Google's services, not any external services like Square. When you call ScriptApp.getOauthToken(), you get a token for performing actions within the Google account of the user currently running the Apps Script script. (The reason you can do this for Google services without presenting a login screen is that the Google user has already logged in in order to run the script in the first place.)
But for any non-Google API like Square, you need to set up a full OAuth2 process, as detailed below:
The main question: How to access Square's API from Google Apps Script
There is an OAuth2 library for Apps Script that handles most of the mechanics of obtaining and storing the token for any API that uses OAuth2. Start by adding the library to your script (the library's script id is 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF).
Then obtain the callback uri for your project. Do this by executing the following function from the script editor:
function logRedirectUri()
{
console.log(
OAuth2.getRedirectUri()
)
}
Now go to the Square developer dashboard, and create a new application. There's an OAuth link on the left side of the app's main screen. Go to that link and you'll get the app's Application ID and Application Secret. You'll need those for your script. In addition, on this screen you should add the redirect uri you obtained above (when the user logs in to Square, the Square API will now know to redirect to this uri, which your script uses to record the oauth token).
Now you're ready to use the OAuth library to provide the Square sign-in process and then call the API. I've created a repo of the code I use for doing this, which you should be able to drop in to your script, but the relevant points are:
In the getSquareService function, set SQUARE_CLIENT_ID and SQUARE_CLIENT_SECRET to the id and secret you got from the Square developer dashboard.
getSquareService is also where you list the scopes you want for the Square API.
function getSquareService()
{
var SQUARE_CLIENT_SECRET = '{your square application secret}'
var SQUARE_CLIENT_ID = '{your square application id}'
return OAuth2.createService('Square')
// Set the endpoint URLs.
.setAuthorizationBaseUrl('https://connect.squareup.com/oauth2/authorize')
.setTokenUrl('https://connect.squareup.com/oauth2/token')
// Set the client ID and secret.
.setClientId(SQUARE_CLIENT_ID)
.setClientSecret(SQUARE_CLIENT_SECRET)
// Set the name of the callback function that should be invoked to
// complete the OAuth flow.
.setCallbackFunction('authCallbackSquare')
// Set the property store where authorized tokens should be persisted.
// Change this to .getUserProperties() if you are having multiple google users authorize the service:
// this will prevent one user's token from being visible to others.
.setPropertyStore(PropertiesService.getScriptProperties())
// Set the scopes needed. For a full list see https://developer.squareup.com/docs/oauth-api/square-permissions
.setScope(
[
'ORDERS_WRITE',
'PAYMENTS_WRITE',
'PAYMENTS_READ',
'ORDERS_READ',
'MERCHANT_PROFILE_READ'
]
.join(" ")
)
// Set grant type
.setGrantType('authorization_code')
}
And include the callback function that will store the token:
function authCallbackSquare(request)
{
var service = getSquareService();
// Now process request
var authorized = service.handleCallback(request);
if (authorized)
{
return HtmlService.createHtmlOutput('Success! You can close this tab.');
} else
{
return HtmlService.createHtmlOutput('Denied. You can close this tab.');
}
}
If your script is bound to a spreadsheet, you can run authorizeSquareUser() in the repo to get a sidebar that initiates the authorization flow. Otherwise, run this modified version:
function authorizeSquareUser()
{
var service = getSquareService();
var authorizationUrl = service.getAuthorizationUrl();
console.log("Auth URL is %s", authorizationUrl);
}
and then visit the url that is logged. At this url you will log in to your square account, and then you should be redirected to a page that says "Success! You can close this tab."
At this point, the Square user's OAuth token has been stored in the script properties of your project. You are now ready to make a call to the Square API. When doing this, you access the stored token using getSquareService().getAccessToken(), so your headers will look like
var headers = {
'Authorization': 'Bearer ' + getSquareService().getAccessToken(),
'Square-Version': '2022-01-20',
'Content-Type': 'application/json'
}
Then you can call
UrlFetchApp.fetch(url, {'method': 'GET', 'headers': headers}) // Change GET method depending on the action you are performing
I have a MySQL address database which contains all the necessary information to look up the address on google maps. Each row with data contains an extra field naming LATLNG. Which contains the Lat and Lng in the preferred format of google maps. ####, ####. I have already created a viewing page with a ‘show’ button to display the content on a separated html page in Google maps with the address above it.
The problem is that I could find all kinds of tutorials (also from google themselves) with the vast possibility’s that google maps provide. The feature I would like to use however isn’t found in a tutorial. And whatever I do, I seem to get stuck with the result of it.
Example (own database):
After each address field there is a button with the next caption:
echo '<td>Show</td>';
Example (google maps) what opens after pressing the SHOW button:
<script>
function myMap() {
var Lelystad = new google.maps.LatLng(LAT LNG INFORMATION);
var mapCanvas = document.getElementById("map");
var mapOptions = {center: TOWN NAME, zoom: 15};
var map = new google.maps.Map(mapCanvas, mapOptions);
var marker = new google.maps.Marker({position:TOWN NAME});
marker.setMap(map);
var infowindow = new google.maps.InfoWindow({
content: "DISPLAY CONTENT OF ADDRESS ABOVE MARKER"
});
infowindow.open(map,marker);
}
</script>
What I want is that after pressing the ‘show’ button the latlng from that given address is being picked up by google maps and show it.
Hopefully someonw can help me, if some of the information is not clear enough don't hesitate to ask me.
I am not sure you want to use the JavaScript. There is a very simple API giving you the latitude and longitude through a URL:
http://maps.googleapis.com/maps/api/geocode/json?address=eiffel%20tower,paris
where "address" is the address you are looking for. You must first register to obtain a key and you are limited to 2500 requests per day (but you can store the results in the database).
See full documentation here: https://developers.google.com/maps/documentation/geocoding/intro?hl=fr
Im using the Google Places Autocomplete API, to have an input in which users type a city and get suggestions for which place they are searching for.
I need to get not only the name of the place but the Latitude and Longitud of the place for then centering a google map there.
The problem is that Google Places Autocomplete API just returns description of the place but not the coordinates, at least with what i tried.
Anybody knows if there is a way to get the Latitud & Longitud in the same request?
Many thanks to any help :')
All the information you are looking for can be found inside the Place Result. This is what your code would look like:
var input = document.getElementById("address");
var autocomplete = new google.maps.places.Autocomplete(input, {types: ["geocode"]});
autocomplete.addListener("place_changed", function() {
var placeResult = autocomplete.getPlace();
var name = placeResult.name;
// The selected place's position
var location = placeResult.geometry.location;
// The preferred viewport when displaying this Place on a map.
// This property will be null if the preferred viewport for the Place is not known.
var viewport = placeResult.geometry.viewport;
// This is assuming your google map is saved in a variable called myMap
if (viewport) {
myMap.fitBounds(viewport)
}
else if (location) {
myMap.setCenter(location)
}
});
I recently created a jQuery plugin that makes interacting with Google Maps Autocomplete a breeze. This would be the code to center a map every time a place was selected:
$("#address").geocomplete({
map: myMap
});
The plugin will also allow you to autofill an address form, adds custom styling, provides callbacks and fixes an annoying scrolling issue.
So im running through a Freecodecamp challenge and this seems to be a common thing.
requesting Json from unsecure host openweathermap.org
On my domain http:// I can now get it to work but at https:// it will not (also codepen).
I found a few workarounds but none worked.
Any help would be great.
http://codepen.io/Middi/pen/peLMBQ
function weather() {
// Get Location
$.getJSON('http://ip-api.com/json', function (response) {
var city = response.city;
var country = response.country;
displayWeather(city, country);
});
// Make API URL
function displayWeather(city, country) {
var weatherAPI = "http://api.openweathermap.org/data/2.5/weather?q=";
var API_Key = "&APPID=1f3e30098d59daa0ee84d36dca533728";
var full_API_Link = weatherAPI + city + units + API_Key;
$.getJSON(full_API_Link, function (response) {
// Interpret data
var temp_c = Math.round(response.main.temp);
var description = response.weather[0].description;
var icon = response.weather[0].icon;
//Switch Icons and send to DOM
replace(icon, city, country, temp_c, endUnit, description);
});
}
}
Due to browser security policy, you cannot load insecure resource (HTTP) in secure page (HTTPS) via Ajax request.
There is one workaround: make a forward layer in your backend. The steps would be:
When you want to load data from http://ip-api.com/json or http://api.openweathermap.org, send Ajax request to your own backend API, via HTTPS.
In backend, accept the previous HTTPS request, parse the parameter, and send real HTTP request to ip-api.com or api.openweathermap.org. Return the data to browser after it is retrieved.
In browser, get the data and do corresponding operation.
In codepen, as the page is loaded via HTTP, your Ajax code works well. The request/response can be observed in debug window.
As far as I understand, in order to track our quota usage, we need to provide our API key to the Google App Service on the service we are planning to use.
In my case I have a spreadsheet with Origin and Destination and a Custom function to calculate the distance between.
I ran into the problem of meeting the quota from invoking .getDirections():
Error: Service invoked too many times for one day: route. (line **).
Sample of the code:
function getDirections_(origin, destination) {
var directionFinder = Maps.newDirectionFinder();
directionFinder.setOrigin(origin);
directionFinder.setDestination(destination);
var directions = directionFinder.getDirections();
return directions;
}
So I read that if I assign the API Key to my project I should be able to see the usage and how close to the free quota I am.
In the script editor, I did enable all of the APIs under Resources menu/ Advanced Google Services. Then I went to the Google Developers Console and there
I did not see any record of how many times my custom function called the Google Maps API or any API usage.
Logically I think that in my script I need to set my google API Key so my scripts start to call the API under my user name and count the number of time I used certain API. I guess right now I am using the Google Maps API as anonymous and since the whole company is assigned with the same IP, so we exhaust the permitted numbers to call this function.
Bottom line please reply if you know a way to connect my simple Spreadsheet function to the Public API access Key I have.
Thank you,
Paul
I also have been eager to find this answer for a long time and am happy to say that I've found it. It looks like Google might have just made this available around Oct 14, 2015 based on the date this page was updated.
You can leverage the UrlFetchApp to add your API key. The link I posted above should help with obtaining that key.
function directionsAPI(origin, destination) {
var Your_API_KEY = "Put Your API Key Here";
var serviceUrl = "https://maps.googleapis.com/maps/api/directions/json?origin="+origin+"&destination="+destination+
"&mode="+Maps.DirectionFinder.Mode.DRIVING+"&alternatives="+Boolean(1)+"&key="+Your_API_KEY;
var options={
muteHttpExceptions:true,
contentType: "application/json",
};
var response=UrlFetchApp.fetch(serviceUrl, options);
if(response.getResponseCode() == 200) {
var directions = JSON.parse(response.getContentText());
if (directions !== null){
return directions;
}
}
return false;
}
So walking through the code... first put in your API key. Then choose your parameters in the var serviceUrl. I've thrown in additional parameters (mode and alternatives) to show how you can add them. If you don't want them, remove them.
With UrlFetch you can add options. I've used muteHttpExceptions so that the fetch will not throw an exception if the response code indicates failure. That way we can choose a return type for the function instead of it throwing an exception. I'm using JSON for the content type so we can use the same format to send and retrieve the request. A response code of 200 means success, so directions will then parse and act like the object that getDirections() would return. The function will return false if the UrlFetch was not successful (a different response code) or if the object is null.
You will be able to see the queries in real time in your developer console when you look in the Google Maps Directions API. Be sure that billing is enabled, and you will be charged once you exceed the quotas.
1.) I added an API key from my console dashboard. Remember to select the correct project you are working on. https://console.developers.google.com/apis/credentials?project=
2.) In my Project (Scripts Editor) I setAuthentication to Maps using the API key and the Client ID from the console. I have included the script below:
function getDrivingDirections(startLoc, wayPoint, endLoc){
var key = "Your_API_Key";
var clientID = "Your_Client_ID";
Maps.setAuthentication(clientID, key);
var directions = Maps.newDirectionFinder()
.setOrigin(startLoc)
.addWaypoint(wayPoint)
.setDestination(endLoc)
.setMode(Maps.DirectionFinder.Mode.DRIVING)
.getDirections();
} return directions;
https://developers.google.com/apps-script/reference/maps/maps#setAuthentication(String,String)
As of 7/13/2017, I was able to get the API to function by enabling the Sheets API in both the "Advanced Google Services" menu (images 1 and 2), and in the Google Developer Console. If you're logged into Google Sheets with the same email address, no fetch function should be necessary.
[In the Resources menu, select Advanced Google Services.][1]
[In Advanced Google Services, make sure the Google Sheets API is turned on.][2]
[1]:
[2]:
Thank goodness for JP Carlin! Thank you for your answer above. JP's answer also explains his code. Just to share, without a code explanation (just go look above for JP Carlin's explanation), below is my version. You will see that I also have the departure_time parameter so that I will get distance and driving-minutes for a specific date-time. I also added a call to Log errors (to view under "View/Logs"):
Note: Google support told me that using your API-key for Google Maps (e.g. with "Directions API") with Google Sheets is not supported. The code below works, but is an unsupported work-around. As of 11/4/2018, Google has an internal ticket request to add support for Google Maps APIs within Google Sheets, but no timeline for adding that feature.
/********************************************************************************
* directionsAPI: get distance and time taking traffic into account, from Google Maps API
********************************************************************************/
function directionsAPI(origin, destination, customDate) {
var Your_API_KEY = "<put your APK key here between the quotes>";
var serviceUrl = "https://maps.googleapis.com/maps/api/directions/json?origin="+origin+"&destination="+destination+"&departure_time="+customDate.getTime()+"&mode="+Maps.DirectionFinder.Mode.DRIVING+"&key="+Your_API_KEY;
var options={
muteHttpExceptions:true,
contentType: "application/json",
};
var response=UrlFetchApp.fetch(serviceUrl, options);
if(response.getResponseCode() == 200) {
var directions = JSON.parse(response.getContentText());
if (directions !== null){
return directions;
}
}
Logger.log("Error: " + response.getResponseCode() + " From: " + origin + ", To: " + destination + ", customDate: " + customDate + ", customDate.getTime(): " + customDate.getTime() );
return false;
}