Keeping businesses’ opening hours up to date: with Github Actions, Strapi and Google Places API
What a disappointment it would be for a coffee lover to head to café promised to be “Open” by an app, only to find the lights are off.
Keeping businesses’ opening hours up to date: with Github Actions, Strapi and Google Places API

What a disappointment it would be for a coffee lover to head to café promised to be “Open” by an app, only to find the lights are off.
At Freddo Buddy, we opted to provide the user with some additional information for the listings apart from their location and the assurance that they serve our favorite iced cold coffee drink, the Freddo Espresso. The business hours of a listing is such information, that would naturally require additional manual work from either our team, or attempt to unload the burden to the business itself.
Fortunately, by taking as given that the business will at least make sure to keep up to date the opening hours on the google platforms, then we can come up with an easy solution that combines Google Places API access, Github Actions and the strapi API tokens for automating the desired process.
The Problem: Keep data fresh
Maintain the information provided through the Freddo Buddy app as accurate as possible is our goal. Whether it is the assurance that a café serves the Freddo Espresso or the business’s opening hours, we need to keep that data fresh and accurate.
Here the goal was simple:
- Fetch the latest information from Google
- Format it to match the database model
- Update the information regularly (weekly)
The solution: A serverless cron job
Although I maintain more than one VPS instances for serving my different applications, I opted to offload some of the work to an alternative and free option. I used Github Actions as a cron job scheduler, which when it gets triggered it executes a node.js script from the repository that takes care of the task.
Requirements
- Place ID: Finding and storing the Place ID for each business in your database.
- API Cost: Optimizing the usage of the free tier or subscribing to a premium tier for fetching the
opening_hoursfrom google’s API
Place ID This can be easily retrieved by searching for the business using the Google Maps Platform Place ID Finder.
Google’s Maps Platform API tiers
The opening_hours field is a premium one. For such premium fields there is a limit of 1000 free requests per month in total.
This means for my app that if I run the script 4 times per month, I can maintain up to 250 entries before I start adding costs.
- The script (node.js)
I wrote a custom node.js script using the @strapi/client SDK. The logic is straightforward:
- Fetch all cafés from the Strapi CMS
- Use each entry’s google place ID
- Fetch the latest information from the Google Places API for each entry
- Update each entry in the Strapi CMS with the latest information
Example of the code used:
const fetch_cafe_opening_hours = async (placeId) => {
// We use the 'fields' parameter to request ONLY opening_hours
// This is crucial for keeping API costs low (more on that below)
const url = `${GOOGLE_PLACES_URL}?place_id=${placeId}&fields=opening_hours&key=${GOOGLE_PLACES_API_KEY}`;
const r = await fetch(url);
const json = await r.json();
return json.result?.opening_hours;
};
A Note on Localization: The app supports both Hellenic and English languages. However, I only store the English version of the opening hours in the database. Since the data follows a standard structure (e.g., “Monday: 09:00–17:00”), we handle the translation of day names on the frontend. This keeps the backend data clean and simple.
- The Workflow (Github Actions)
The rest of the magic happens in the following github workflow configuration file.
name: Sync cafés Opening Hours
on:
schedule:
- cron: "0 7 * * 4" # Every Thursday at 07:00 UTC
workflow_dispatch: # Allows me to click "Run" manually if needed
jobs:
run-script:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: "24.x"
- run: npm install @strapi/client dotenv
- name: Run Sync Script
env:
STRAPI_URL: ${{ vars.STRAPI_URL }}
GOOGLE_PLACES_API_KEY: ${{ secrets.GOOGLE_PLACES_API_KEY }}
STRAPI_API_KEY: ${{ secrets.STRAPI_API_KEY }}
run: node .github/scripts/refresh-opening-hours/index.mjs
The Result
- Maintenance: Zero. The script runs silently in the background.
- Reliability: If a cafe changes its hours on Google Maps, my app reflects it within a week automatically.
- Scalability: As long as I stay under ~250 cafes, it is free. If I grow beyond that, the business will likely be generating enough revenue to cover the API costs.
By offloading the “boring” maintenance work to a script, I can focus on what actually matters: finding the next great espresso spot to add to the map.
Links

메타데이터
- post_id
- 2e72db23d6d5
- slug
- keeping-businesses-opening-hours-up-to-date-with-github-actions-strapi-and-google-places-api-2e72db23d6d5
- url
- https://medium.com/@spiros3p/keeping-businesses-opening-hours-up-to-date-with-github-actions-strapi-and-google-places-api-2e72db23d6d5
- canonical_url
- https://medium.com/@spiros3p/keeping-businesses-opening-hours-up-to-date-with-github-actions-strapi-and-google-places-api-2e72db23d6d5
- author_url
- https://medium.com/@spiros3p
- status
- ok
- fetched_at
- 2026-07-14 12:58:24