Help

Re: Add google static maps to an attachments field

656 0
cancel
Showing results for 
Search instead for 
Did you mean: 
Z_Goddard
5 - Automation Enthusiast
5 - Automation Enthusiast

Add static Google Maps to attachments based on addresses in a table.

Source Code
/**
 * Copyright 2020 Bocoup
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

/**
 * Airtable attach google static maps script
 *
 * This script looks at each row and adds google map images to an attachment
 * field cell in that row based on the addresses in the row. Rows with no
 * addresses or that already has attachments are skipped.
 *
 * This script uses Google's static map API. See for more info:
 * https://developers.google.com/maps/documentation/maps-static/intro
 *
 * **Notes on adapting this script.**
 *
 * Before running this script set the apiKey, tableName, addressFieldNames, and
 * mapTileAttachmentFieldName variables below. After that it can be run at any
 * time and it will update new records or old records with an empty attachments
 * cell. Further customizations can be made to the maps by modifying
 * staticmapOptions further down.
 */

'use strict';

// Google Maps API key
// See google's documentation to get a key.
// https://developers.google.com/maps/documentation/javascript/get-api-key
//
// The text of this script including the apiKey will be visible to everyone who
// can view this airtable base.
let apiKey = '**************';

// The name of the table this script will update.
let tableName = 'Map Table';
// Names of fields with an address to get a map for. Each field can have 0 or 1
// addresses.
let addressFieldNames = [
    'Map Address',
    // 'Start Address',
    // 'Special Address',
];
// Name of an attachments field that will be updated with static google map images.
let mapTileAttachmentFieldName = 'Map Attachments';

//
// After this line is the script logic. To use this script as-is, you do not need
// to edit anything after this point.
//

let RECORD_BATCH_COUNT = 50;

let table = base.getTable(tableName);
let allRecords = await table.selectRecordsAsync({
    // In the case there are a lot of fields, get the address and map tile fields only.
    fields: [...addressFieldNames, mapTileAttachmentFieldName],
});

let updates = [];

// Iterate every record in the table.
for (let recordId of allRecords.recordIds) {
    let record = allRecords.getRecord(recordId);

    // Skip records that have no addresses or already have attached images.
    if (
        !addressFieldNames.some(fieldName => record.getCellValue(fieldName)) ||
        record.getCellValue(mapTileAttachmentFieldName)
    ) {
        continue;
    }

    // Create google static map api urls from address fields for this record.
    let urls = [];
    for (let fieldName of addressFieldNames) {
        let staticmapOptions = {
            // The Google API Key. Required.
            key: apiKey,
            // The center of the returned map. Can be latitude, longitude
            // coordinates or an address. Required.
            // See for more info:
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#Locations
            center: record.getCellValue(fieldName),
            // Smaller numbers zoom out, larger numbers zoom in. Required.
            // See for more info:
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#Zoomlevels
            zoom: 17,

            // 640 by 640 pixels is the largest normal resolution at scale 1. Optional.
            // See for more info:
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#Imagesizes
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#Largerimagesizes
            size: [640, 640],
            // Scale can be 1 or 2. Optional.
            // See for more info:
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#scale_values
            scale: 1,
            // Which image format to return. Optional.
            // See for more info:
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#ImageFormats
            format: 'jpg',
            // Maptype can be roadmap, terrain, hybrid, or streetview. Optional.
            // See for more info:
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#MapTypes
            maptype: 'roadmap',
            // Language and region are optional.
            // See for more info:
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#map-parameters
            language: 'en-US',
            region: 'us',

            // There are other options.
            // See for more info:
            // https://developers.google.com/maps/documentation/maps-static/dev-guide#feature-parameters
        };

        let staticmapParameters = Object.entries(staticmapOptions).map(([key, value]) => {
            if (key === 'size') {
                return `size=${value[0]}x${value[1]}`;
            }
            return `${key}=${encodeURIComponent(value)}`;
        });
        let staticmapUrl = `https://maps.googleapis.com/maps/api/staticmap?${staticmapParameters.join('&')}`;

        // Add a attachment cell object to urls to add to the record update.
        urls.push({url: staticmapUrl});
    }

    // Create record update with map urls.
    updates.push({id: record.id, fields: {[mapTileAttachmentFieldName]: urls}});
}

output.markdown(`Prepared ${updates.length} row updates out of ${allRecords.recordIds.length} in the table.`);

// For subsets of updates
for (let i = 0; i < updates.length; i += RECORD_BATCH_COUNT) {
    // Update table with a subset of all the updates ready to be made.
    output.markdown(`Applying update ${i + 1} through ${Math.min(i + RECORD_BATCH_COUNT, updates.length)} of ${updates.length}.`);
    await table.updateRecordsAsync(updates.slice(i, i + RECORD_BATCH_COUNT));
}

output.markdown('Done.');

This script looks at each row and adds google map images to an attachment field cell in that row based on the addresses in the row. Rows with no addresses or that already has attachments are skipped.

This script uses Google’s static map API. See for more info:

Notes on adapting this script.

Before running this script set the apiKey, tableName, addressFieldNames, and mapTileAttachmentFieldName variables below. After that it can be run at any time and it will update new records or old records with an empty attachments cell. Further customizations can be made to the maps by modifying staticmapOptions further down.

Made this to help do things like what is mentioned in Map in Page Designer?.

22 Replies 22
Bill_Robinson
6 - Interface Innovator
6 - Interface Innovator

The script “runs” fine but no attachment gets put in. My API works in the Maps extension. Trying to set up a script to run based on an automation.

rp2
5 - Automation Enthusiast
5 - Automation Enthusiast

This is  really helpful script, thank you!

I keep getting an error when trying to do this Marker Mod and replace center. Im not that familiar with Javascript so probably missing something fairly obvious

 

Error

SyntaxError: illegal character U+2018
    at u/< on line 1    at E on line 1    at _/< on line 1    at m/</< on line 1    at r on line 1    at a on line 1    at n/</< on line 1    at n/< on line 1    at ai on line 1    at Di on line 1    at u/< on line 1    at E on line 1    at _/< on line 1    at m/</< on line 1    at r on line 1    at a on line 1    at n/</< on line 1    at n/< on line 1    at si< on line 1    at r/< on line 1    at E on line 1    at _/< on line 1    at m/</< on line 1    at r on line 1    at a on line 1    at n/</< on line 1    at n/< on line 1    at _handleCallAsync on line 1    at handle on line 1    on line 1
rp2
5 - Automation Enthusiast
5 - Automation Enthusiast

Error was the way the single quotes pasted in. I had to retype those for some reason. works great!👍