This article explains how to use Google Apps Script within Google Slides to create dynamic, self-updating content for digital signage. This allows a slide to automatically show live information like weather forecasts, news headlines, or social media posts.
How It Works
Google Apps Script is a cloud-based scripting language for light-weight application development in the Google Workspace platform. When applied to Google Slides, a script can be set to run automatically on a timer. The typical process is:
- The script fetches data from an external source using an API.
- The information is reformatted within the script.
- The script then populates the content into a specified location on a slide.
Step-by-Step: Adding a Weather Forecast to a Slide
This example demonstrates how to add a script that shows the current weather for a specific location.
- Open a Google Slides presentation.
- Open the Script Editor
- In the top menu, navigate to Extensions > Apps Script.
- A new browser tab will open with the script editor.
- Add the Script
- Delete any existing code in the
Code.gsfile. - Copy and paste the entire script below into the editor. This script uses the Open-Meteo API to get weather data and OpenWeatherMap for the icons.
- Delete any existing code in the
/**
* This script fetches weather data from a free API and displays it
* as a footer on the first slide of a Google Slides presentation.
*/
// ===============================================================
// === CONFIGURATION SETTINGS ===
// === Change the variables below to customize the app ===
// ===============================================================
// --- Location Settings ---
// Find your coordinates by right-clicking a spot on Google Maps.
const LATITUDE = "55.6761"; // Copenhagen, Denmark Latitude
const LONGITUDE = "12.5683"; // Copenhagen, Denmark Longitude
const LOCATION_NAME = "Copenhagen"; // The name of the city to display
// --- Temperature Unit ---
const TEMPERATURE_UNIT = "C"; // Use "C" for Celsius or "F" for Fahrenheit
// --- Style Settings ---
const FOOTER_BACKGROUND_COLOR = "#093607"; // A dark slate gray color
const PRIMARY_TEXT_COLOR = "#fffce9"; // White for high contrast
const SECONDARY_TEXT_COLOR = "#fffce9"; // A lighter gray for less important text
// ===============================================================
// === MAIN SCRIPT LOGIC ===
// === You probably don't need to edit below this line ===
// ===============================================================
/**
* Adds a custom menu to the Google Slides UI when the presentation is opened.
*/
function onOpen() {
SlidesApp.getUi()
.createMenu('Weather')
.addItem('Update Weather Footer', 'updateWeatherFooter')
.addToUi();
}
/**
* The main function that orchestrates fetching the weather and drawing it.
*/
function updateWeatherFooter() {
const presentation = SlidesApp.getActivePresentation();
const slides = presentation.getSlides(); // Get all slides
// 1. Fetch the new weather data from the API once for all slides
const weatherData = getWeatherData();
// 2. If we got data, process each slide
if (weatherData) {
slides.forEach(slide => {
// Remove any old weather elements from this specific slide
clearOldWeatherElements(slide);
// Create the new footer on this specific slide
createWeatherDisplay(slide, weatherData);
});
} else {
SlidesApp.getUi().alert('Could not fetch weather data. Please try again later.');
}
}
/**
* Fetches forecast data from the free Open-Meteo API.
* @returns {object|null} A parsed JSON object of the weather data, or null if it fails.
*/
function getWeatherData() {
// This API is free and doesn't require an API key.
let apiUrl = `https://api.open-meteo.com/v1/forecast?latitude=${LATITUDE}&longitude=${LONGITUDE}&daily=weathercode,temperature_2m_max,temperature_2m_min&timezone=auto`;
// Append the temperature unit setting to the API URL if Fahrenheit is selected
if (TEMPERATURE_UNIT === 'F') {
apiUrl += '&temperature_unit=fahrenheit';
}
try {
const response = UrlFetchApp.fetch(apiUrl);
const data = JSON.parse(response.getContentText());
return data;
} catch (e) {
console.error("Failed to fetch weather data: " + e.toString());
return null;
}
}
/**
* Finds and removes any elements on the slide that were previously created by this script.
* We identify them by a special title we set when we create them.
* @param {GoogleAppsScript.Slides.Slide} slide The slide to clean up.
*/
function clearOldWeatherElements(slide) {
const pageElements = slide.getPageElements();
pageElements.forEach(element => {
// We "tag" our elements with this title so we can find them again.
if (element.getTitle() === 'weather_element') {
element.remove();
}
});
}
/**
* Draws the footer, icons, and text onto the slide.
* @param {GoogleAppsScript.Slides.Slide} slide The slide to draw on.
* @param {object} weatherData The weather data object from the API.
*/
function createWeatherDisplay(slide, weatherData) {
const presentationWidth = SlidesApp.getActivePresentation().getPageWidth();
const presentationHeight = SlidesApp.getActivePresentation().getPageHeight();
const footerHeight = 40;
const footerY = presentationHeight - footerHeight;
// Create the dark background rectangle for the footer
const footer = slide.insertShape(SlidesApp.ShapeType.RECTANGLE, 0, footerY, presentationWidth, footerHeight);
footer.getFill().setSolidFill(FOOTER_BACKGROUND_COLOR);
footer.getBorder().setTransparent();
footer.setTitle('weather_element');
// --- Display Location Name ---
const locationTextBox = slide.insertTextBox(
`${LOCATION_NAME} Forecast`, 15, footerY + 5, 170, 30
);
locationTextBox.getText().getTextStyle().setForegroundColor(PRIMARY_TEXT_COLOR).setFontSize(12).setBold(true);
locationTextBox.setTitle('weather_element');
// --- Display Daily Forecasts ---
const forecastStartX = 190;
const daysToShow = 5;
const forecastAreaWidth = presentationWidth - forecastStartX;
const dayWidth = forecastAreaWidth / daysToShow;
const unitSymbol = TEMPERATURE_UNIT === 'F' ? '°F' : '°C';
for (let i = 0; i < daysToShow && i < weatherData.daily.time.length; i++) {
const date = new Date(weatherData.daily.time[i] + 'T00:00:00');
const dayName = date.toLocaleDateString('en-US', { weekday: 'short' });
const weatherCode = weatherData.daily.weathercode[i];
const maxTemp = Math.round(weatherData.daily.temperature_2m_max[i]);
const minTemp = Math.round(weatherData.daily.temperature_2m_min[i]);
// Get the icon URL from the OpenWeatherMap API.
const finalIconUrl = getWeatherIconUrl(weatherCode);
// Calculate position for each day's forecast
const dayX = forecastStartX + (i * dayWidth);
const iconSize = 30;
// Insert the newly created image from the URL
const icon = slide.insertImage(finalIconUrl, dayX + 5, footerY + 5, iconSize, iconSize);
icon.setTitle('weather_element');
// --- Text Box for Day Name ---
const dayTextBox = slide.insertTextBox(dayName, dayX + 40, footerY + 5, dayWidth - 45, 15);
const dayTextStyle = dayTextBox.getText().getParagraphs()[0].getRange().getTextStyle();
dayTextStyle.setForegroundColor(PRIMARY_TEXT_COLOR).setFontSize(9).setBold(true);
dayTextBox.setTitle('weather_element');
// --- Text Box for Temperatures ---
const tempContent = `${maxTemp}${unitSymbol} / ${minTemp}${unitSymbol}`;
const tempTextBox = slide.insertTextBox(tempContent, dayX + 40, footerY + 17, dayWidth - 45, 15);
const tempTextStyle = tempTextBox.getText().getParagraphs()[0].getRange().getTextStyle();
tempTextStyle.setForegroundColor(SECONDARY_TEXT_COLOR).setFontSize(8);
tempTextBox.setTitle('weather_element');
}
}
/**
* Returns an OpenWeatherMap icon URL for a given weather code.
* Uses the "day" variants.
* @param {number} code The weather code from the API.
* @returns {string} The icon PNG URL.
*/
function getWeatherIconUrl(code) {
const baseUrl = 'https://openweathermap.org/img/wn/';
let iconCode;
switch (code) {
case 0: iconCode = '01d'; break; // Clear sky
case 1: iconCode = '02d'; break; // Mainly clear
case 2: iconCode = '03d'; break; // Partly cloudy
case 3: iconCode = '04d'; break; // Overcast
case 45:
case 48: iconCode = '50d'; break; // Fog
case 51:
case 53:
case 55: iconCode = '09d'; break; // Drizzle
case 61:
case 63:
case 65: iconCode = '10d'; break; // Rain
case 66:
case 67: iconCode = '13d'; break; // Freezing Rain (uses snow icon)
case 71:
case 73:
case 75: iconCode = '13d'; break; // Snow fall
case 80:
case 81:
case 82: iconCode = '09d'; break; // Rain showers
case 85:
case 86: iconCode = '13d'; break; // Snow showers
case 95:
case 96:
case 99: iconCode = '11d'; break; // Thunderstorm
default: iconCode = '01d'; break; // Default
}
// Return the full URL for the 2x resolution icon
return `${baseUrl}${iconCode}@2x.png`;
}
Customize the Script
In the code, locate the "CONFIGURATION SETTINGS" section in the first part of the code.
- Change the
latitudeandlongitudevalues to the desired location. A web search for "[City Name] latitude longitude" can provide these. Change the display name to your city or area. - Define whether the temperature should be shown in Celsius or Fahrenheit.
- Add your color-codes to better match your presentation.
Set Up a Trigger
To make the script run automatically, a trigger is needed.
- On the left side of the script editor, click the Triggers (clock) icon.
- Click the Add Trigger button in the bottom-right.
- Configure the trigger with the following settings:
- Function to run:
updateWeatherFooter - Select event source:
Time-driven - Select type of time-based trigger:
Hour timer(or another preferred frequency) - Select hour interval:
Every hour
- Function to run:
- Click Save.
- Google will request permission for the script to run. Review and accept the permissions to activate the trigger.
The script will now automatically update the weather on the slide every hour. To test it immediately, click the Run button at the top of the script editor.
Inspiration for Other Scripts
The same principles can be applied to display other types of live information. Consider creating scripts to show:
- Live news headlines from an RSS feed.
- Recent posts from a company's social media feed.
- The daily menu from a local canteen.
- Upcoming events from a public calendar.
- Key performance indicators from a business intelligence tool.