Automating Weekly Analytics Reports to Slack With a GitHub Action
Google Analytics access is often restricted to a handful of people, which means useful data rarely makes it to the wider team. A GitHub Action can change that by pulling page-view data from Google Analytics, comparing it week over week, and posting the results to a Slack channel on a schedule. This turns analytics into something anyone on the team can see, use, and share.
The workflow described here queries Google Analytics for the top ten most-viewed pages in the last seven days, then compares those numbers against the previous seven days. Each entry in the resulting report is labeled by trend: increased, decreased, unchanged, or new to the list. The report includes icons for each status and posts to a designated Slack channel every Friday at 10 AM.
The formatted output is easy to screenshot or copy into a slide for weekly meetings, so the data can be shared beyond Slack as well. The full repository is available on GitHub.
What You’ll Need
Setting this up requires admin access to Google Analytics and Slack, plus administrator privileges on a GitHub repository so you can configure Actions and Secrets.
Adjusting the Report to Your Needs
The code in the repository is intentionally left readable so it can be modified. The key areas are the Action’s schedule and naming, the Google Analytics query, and the Slack message layout.
Action Schedule and Naming
The Action file weekly-analytics.report.yml can be renamed without breaking anything. The name and jobs: values appear in the GitHub UI and workflow logs, so you’ll likely want to customize those to fit your project.
The cron expression controls when the Action runs. Schedules follow POSIX cron syntax, so editing the numbers changes the trigger time. You can also rename the secret variables, as long as you update them in the repository’s Settings.
# .github/workflows/weekly-analytics-report.yml
name: Weekly Analytics Report
on:
schedule:
- cron: '0 10 * * 5' # Runs every Friday at 10 AM UTC
workflow_dispatch: # Allows manual triggering
jobs:
analytics-report:
runs-on: ubuntu-latest
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
GA4_PROPERTY_ID: ${{ secrets.GA4_PROPERTY_ID }}
GOOGLE_APPLICATION_CREDENTIALS_BASE64: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_BASE64 }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: npm install
- name: Run the JavaScript script
run: node src/services/weekly-analytics.js
Google Analytics Query
The API request pulls the fullPageUrl and pageTitle for the totalUsers metric. One request covers the current seven-day window; a second covers the previous seven days. The results are aggregated and the response is limited to ten entries.
If you want a different metric or date range, use Google’s GA4 Query Explorer to construct your own query and replace the requests in the service file.
// src/services/weekly-analytics.js#L75
const [thisWeek] = await analyticsDataClient.runReport({
property: `properties/${process.env.GA4_PROPERTY_ID}`,
dateRanges: [
{
startDate: '7daysAgo',
endDate: 'today',
},
],
dimensions: [
{
name: 'fullPageUrl',
},
{
name: 'pageTitle',
},
],
metrics: [
{
name: 'totalUsers',
},
],
limit: reportLimit,
metricAggregations: ['MAXIMUM'],
});
How the Week-Over-Week Comparison Works
Three functions handle the comparison logic. The first uses a reduce operation to produce a list of URLs with their view counts. The second maps this week’s results against last week’s to pair them up. The final function assigns each pair a status: up, down, same, or new.
const lastWeekMap = lastWeekResults.reduce((items, item) => {
const { url, count } = item;
items[url] = count;
return items;
}, {});
// Generate the report for this week
const report = thisWeekResults.map((item, index) => {
const { url, title, count } = item;
const lastWeekCount = lastWeekMap[url];
const status = determineStatus(count, lastWeekCount);
return {
position: (index + 1).toString().padStart(2, '0'), // Format the position with leading zero if it's less than 10
url,
title,
count: { thisWeek: count, lastWeek: lastWeekCount || '0' }, // Ensure lastWeekCount is displayed as '0' if not found
status,
};
});
// Function to determine the status
const determineStatus = (count, lastWeekCount) => {
const thisCount = Number(count);
const previousCount = Number(lastWeekCount);
if (lastWeekCount === undefined || lastWeekCount === '0') {
return NEW;
}
if (thisCount > previousCount) {
return HIGHER;
}
if (thisCount < previousCount) {
return LOWER;
}
return SAME;
};
The code is deliberately verbose so you can drop in console.log statements and inspect what each function returns as it processes the data.
Designing the Slack Message
The Slack message configuration builds a header with an emoji, a divider, and a short description of the report content. A context object is used to iterate over the comparisons and output each item with an icon, the view count, the page name, and a link.
The Block Kit Builder is the best place to prototype a different message format if you want a different look or additional fields.
// src/services/weekly-analytics.js#151
const slackList = report.map((item, index) => {
const {
position,
url,
title,
count: { thisWeek, lastWeek },
status,
} = item;
return {
type: 'context',
elements: [
{
type: 'image',
image_url: `${reportConfig.url}/images/${status}`,
alt_text: 'icon',
},
{
type: 'mrkdwn',
text: `${position}. <${url}|${title}> | *\`${`x${thisWeek}`}\`* / x${lastWeek}`,
},
],
};
});
Setting Up the Google Cloud Side
Before the Action can run, you need to complete setup in Google Cloud, Google Analytics, Slack, and GitHub. Start with a new Google Cloud project.
In the Google Cloud console, open the project dropdown at the top and choose Select a project. In the modal, click NEW PROJECT and give it a name; the example uses smashing-weekly-analytics. Click CREATE.
Next, enable the Google Analytics Data API. From the sidebar, go to APIs & Services > Enable APIs & services, then click + ENABLE APIS & SERVICES. Search for “Google analytics data API,” select it, and click ENABLE.
Creating Service Account Credentials
With the API enabled, create credentials by clicking CREATE CREDENTIALS and choosing a Service account. This lets an application authenticate with the Google Analytics Data API using the credentials you’ll generate.
On the credential type screen, select Google Analytics Data API from the dropdown and choose Application data, then click NEXT.
Give the service account a name, ID, and optional description. The example uses smashing-weekly-analytics for both name and ID. Click CREATE AND CONTINUE.
On the next screen, set the Role to Owner and click CONTINUE. The final step can be left blank; click DONE.
Downloading the Key File
Navigate to Service Accounts from the left-hand menu, open the “more dots” menu for your account, and select Manage keys. Go to the KEYS tab, click ADD KEY, and choose Create new key. Select JSON as the key type and click CREATE to download the credentials file.
The downloaded .json file contains the credentials the app will use to authenticate.
Converting Credentials for Environment Variables
These credentials can’t be assigned directly as an object in an .env file. The entire JSON file needs to be converted to a base64 string first. Run the following command from the terminal, replacing name-of-creds-file.json with your actual file name:
cat name-of-creds-file.json | base64
If you’ve cloned the repository and followed the README’s getting-started steps, add the base64 output to the GOOGLE_APPLICATION_CREDENTIALS_BASE64 variable in your .env file. Wrap the string in double quotation marks.
GOOGLE_APPLICATION_CREDENTIALS_BASE64="abc123"
That finishes the Google Cloud configuration. The next steps involve adding the service account email to your Google Analytics property and locating your Property ID.
Wiring Up Your Google Analytics Property
Before your service account can query data, it needs permission inside Google Analytics itself. Start by locating your Property ID: open your Google Analytics account, confirm you're on the correct property, click the admin cog in the bottom left, and select Property details.
The PROPERTY ID appears in the top right corner. If you've cloned the repo and followed the README's getting-started steps, drop this value into the GA4_PROPERTY_ID variable in your .env file.
Granting Access to the Service Account
Next, open the Google application credential .json file you downloaded earlier and copy the client_email address. It will look something like smashing-weekly-analytics@smashing-weekly-analytics.iam.gserviceaccount.com.
In Google Analytics, go to Property access management, click the + in the top right, and choose Add users. Paste the client_email into the Email addresses field, untick Notify new users by email, assign the Viewer role under Direct roles and data restrictions, and click Add.
That's all the Google Analytics setup required. Your application now has API access via the service account credentials.
Creating the Slack Destination
You'll post the report to a dedicated Slack channel through an incoming webhook. First, create a new channel in your workspace — this example uses #weekly-analytics-report.
Building the Slack App
Go to the Slack API dashboard and click Create an App.
Choose From an app manifest, then select your workspace and click Next.
Give the app a name (e.g., Weekly Analytics Report) and click Next. On the confirmation screen, just click Done.
Setting Up the Webhook
From the left-hand navigation, open Incoming Webhooks, toggle the switch to On, and click Add New Webhook to Workspace.
Pick the workspace and the channel where messages should appear, then click Allow. You'll now see the webhook with a copy button — copy the Webhook URL and, if you've already cloned the repo, paste it into the SLACK_WEBHOOK_URL variable in your .env file.
Polishing the App
Under Basic Information, you can add an icon and description for the app. Click Save Changes when finished. You should now see the app listed in your Slack workspace.
Storing Secrets in GitHub
Open your repository's Settings tab, select Secrets and variables, then Actions. Add the three variables from your .env file as Repository secrets. One note on the base64 string: don't include the surrounding double quotes when you paste it.
Testing the Workflow
Head to the Actions tab, pick the Weekly Analytics Report job, and click Run workflow.
If everything is configured correctly, Slack will show a neatly formatted list of your top ten page views.
Done
That's it: a fully automated Google Analytics digest delivered straight to Slack. In teams where analytics access is restricted, this kind of routine sharing gives everyone — not just a few stakeholders — visibility into site performance without extra manual effort.




