AI campaign performance reporter in GA4 and Google Ads with a weekly summary

AI ideas DataGoogleIntegrationReportingComparison

Marketing teams often run into the same problem: data on campaign performance in Google Analytics 4 and Google Ads exists, but the regular weekly interpretation built on top of it is created manually, slowly, and inconsistently. One person pulls the numbers, another writes the commentary, and a third checks whether the cost-to-conversion ratio has worsened year over year or week over week. The result is often a report that arrives late and, on top of that, without clear recommendations.

In this article, we will build a feasible MVP of a project that automates this process. The goal is to download data from GA4 and Google Ads once a week, combine it into a shared data overview, calculate the basic metrics, have AI create an interpretation and specific recommendations, and send the finished output by email or to Slack. This will not be a theoretical overview, but a step-by-step process so that by completing the individual parts, the reader will have a working solution.

Introduction

Stock image

The practical value of a project like this is especially high where multiple campaigns, multiple accounts, or multiple countries are reported on every week. Automation here does not just mean saving time. It also brings a consistent output structure, stable metric calculations, and a traceable process that can be fine-tuned. In this scenario, AI does not replace the source of truth. Its role is different: to turn numerical data into an understandable summary, highlight deviations, and suggest next steps based on precisely defined rules and a prompt.

As a foundation, we will choose services that are commonly available and have official APIs: Google Analytics Data API for GA4, Google Ads API for ad performance, Google Sheets as simple storage and a control layer, Google Apps Script as orchestration, and the OpenAI API for interpretation. This keeps deployment relatively inexpensive, clear, and manageable even without a robust data warehouse.

Project goal

Try NordVPN

article-ai-1

The output will be an automated weekly report that every Friday at 8:00:

  • downloads GA4 data for the last 7 days and the previous 7 days,
  • downloads Google Ads data for the same period,
  • combines them by campaign or UTM structure into a single table,
  • calculates differences in key metrics,
  • generates an AI summary and recommendations,
  • sends the report by email or to Slack.

We will consider as the MVP a solution that works at least for one website, one GA4 property, and one Google Ads account, can handle weekly comparisons, and creates a consistent text summary over a clearly defined table.

Prerequisites

Try Semrush

Before you begin, prepare these access rights and settings:

  • GA4 property with at least Viewer permission and access to Google Analytics.
  • Google Ads account with Standard or Admin permission and access to Google Ads.
  • Google Cloud project for working with APIs in Google Cloud Console.
  • Google Sheets and Google Apps Script.
  • OpenAI API key from OpenAI Platform.
  • Basic familiarity with spreadsheets and the ability to copy a short script or JSON configuration.

If you do not have direct mapping between campaigns in GA4 and Google Ads, that is not a blocker. You just need to account for the limitation in matching accuracy, which I will describe in the Limitations section.

Implementation steps

Try Hostinger

Step 1: Design the data model and report structure

What and why: Before you start touching the APIs, you need to decide what one report row will look like and which metrics you will evaluate. Without this step, a common problem arises: you may download the data, but you will not be able to combine or explain it meaningfully. For a weekly report, it is ideal to have one row per campaign and period.

How exactly: In Google Sheets, create a file with the sheets config, ga4_raw, ads_raw, report_input, and ai_output. Insert the basic settings into the config sheet.

Specific input: config sheet with fields:

ga4_property_id | 123456789
ads_customer_id | 9876543210
report_day      | Friday
currency        | CZK
primary_kpi     | purchases
send_to_email   | marketing@example.cz
slack_webhook   | https://hooks.slack.com/services/...

Mini template of the report_input structure:

week_label | campaign_name | sessions | users | purchases | revenue | cost | clicks | impressions | ctr | cpc | roas | conv_rate

Specific output: a prepared Google Sheet with defined sheets and columns.

Success metric: you have precisely defined a maximum of 10 to 12 metrics that you will regularly use in the report, and each has a clear source in GA4 or Google Ads.

Once you know what you will compare, you can move on to the data sources. This will help you avoid a situation where, only when combining the data, you discover that you are missing a key field, such as the campaign name or period.

Step 2: Enable the APIs and prepare permissions

What and why: To download data automatically, the project must have the correct APIs enabled and the script must have permission to read the relevant accounts. This step is usually the least fun, but without it the next parts will not work.

How exactly:

  1. Open Google Cloud Console.
  2. Create a new project, for example ai-weekly-reporting.
  3. In the APIs & Services > Library menu, enable the Google Analytics Data API.
  4. If you will work through official access to the Google Ads API, also enable the related project and follow the documentation for the developer token. With Google Ads, you need to account for the fact that some access types are subject to approval: https://developers.google.com/google-ads/api/docs/first-call/dev-token.
  5. In Google Apps Script, open Services and add advanced services if needed, or use external HTTP calls via UrlFetchApp.

Specific input: GA4 property ID 123456789, Google Ads customer ID 9876543210, OAuth scope for the Analytics Data API.

Specific output: a working cloud project with an active API and a script that, after authorization, does not return a 403 or 401 error.

Success metric: a verification query to GA4 returns at least 1 row of data and does not fail on authorization; for Google Ads, access to the account is successfully verified.

Example of the expected verification output:

{
  "property": "properties/123456789",
  "rows": 12
}

Once you have permissions, it makes sense to test one source independently first. We will start with GA4, because it typically carries web conversions and revenue.

Step 3: Download weekly data from GA4

What and why: From GA4, we want to obtain traffic and conversion performance by campaign. For a weekly report, sessions, users, purchases, and revenue are usually enough. If your implementation uses different conversion events, adjust them in the configuration.

How exactly: In Apps Script, create a function that calls the Google Analytics Data API using the runReport method. In the script menu, open Project settings and save the property ID to a constant or load it from the config sheet.

Specific input: API parameter for date and dimensions:

{
  "dateRanges": [
    {"startDate": "7daysAgo", "endDate": "yesterday"}
  ],
  "dimensions": [
    {"name": "sessionCampaignName"}
  ],
  "metrics": [
    {"name": "sessions"},
    {"name": "totalUsers"},
    {"name": "purchaseRevenue"},
    {"name": "transactions"}
  ],
  "limit": 1000
}

Mini snippet in Apps Script:

function fetchGA4Week() {
  const propertyId = '123456789';
  const url = 'https://analyticsdata.googleapis.com/v1beta/properties/' + propertyId + ':runReport';
  const payload = {
    dateRanges: [{ startDate: '7daysAgo', endDate: 'yesterday' }],
    dimensions: [{ name: 'sessionCampaignName' }],
    metrics: [
      { name: 'sessions' },
      { name: 'totalUsers' },
      { name: 'purchaseRevenue' },
      { name: 'transactions' }
    ],
    limit: 1000
  };
  const token = ScriptApp.getOAuthToken();
  const response = UrlFetchApp.fetch(url, {
    method: 'post',
    contentType: 'application/json',
    headers: { Authorization: 'Bearer ' + token },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  });
  Logger.log(response.getContentText());
}

Example input: campaign Brand Search CZ.

Expected output:

campaign_name     | sessions | users | purchases | revenue
Brand Search CZ  | 1240     | 1011  | 37        | 58210.40

Success metric: at least 95% of the campaigns you expect in weekly performance are stored in the ga4_raw sheet, and session values are not zero for active campaigns.

Once you have the web part, you need to add ad costs and clicks. Only the combination of both sources allows you to calculate ROAS, CPC, or differences between traffic and ad performance.

Step 4: Download weekly data from Google Ads

What and why: Google Ads provides costs, clicks, impressions, and possibly ad conversions. For a weekly management report, you usually need at least campaign, cost_micros, clicks, impressions, and conversions. If you want to maintain a single source of truth for conversions, decide here whether you will interpret GA4 or Google Ads as the main KPI.

How exactly: For Google Ads, use the official Google Ads API and a query in GAQL. If you are just starting with it, stick to a simple campaign-level selection for the last 7 days. If needed, the implementation can be done outside Apps Script, for example in Cloud Run, but for an MVP the main thing is to obtain the data correctly and write it to the ads_raw sheet.

Specific input: GAQL query:

SELECT
  campaign.name,
  metrics.cost_micros,
  metrics.clicks,
  metrics.impressions,
  metrics.conversions,
  segments.date
FROM campaign
WHERE segments.date DURING LAST_7_DAYS

Example of cost_micros transformation: 125000000 means 125.00 in the account currency.

Specific output:

campaign_name     | cost  | clicks | impressions | conversions
Brand Search CZ  | 8420  | 913    | 12450       | 34

Success metric: the total cost in ads_raw differs from the display in the Google Ads interface for the same period by at most a few percent; ideally less than 1% if you use the same time zone and the same aggregation level.

Important note for less advanced users: differences between GA4 and Google Ads are not automatically an error. Each system may calculate sessions, conversions, or attribution differently. Therefore, we will first just download the data and only in the next step determine which metric comes from where.

Now you have both basic sources. The next logical step is to combine them into one table on which you can calculate changes and generate commentary.

Step 5: Combine the data and calculate key metrics

What and why: Separate tables are useful for control, but both AI and humans need one unified input. In this step, you will create the report_input sheet, where there will be one row per campaign with a combination of data from both sources. At the same time, you will calculate the basic indicators, such as CTR, CPC, ROAS, and conversion rate.

How exactly: If campaign names match between GA4 and Google Ads, you can match by campaign_name. If they do not match, create a mapping table campaign_map with the columns ga4_campaign_name and ads_campaign_name.

Specific input: columns:

campaign_name, sessions, purchases, revenue, cost, clicks, impressions

Mini formulas:

ctr = clicks / impressions
cpc = cost / clicks
roas = revenue / cost
conv_rate = purchases / sessions

Example input:

campaign_name    = Brand Search CZ
revenue          = 58210.40
cost             = 8420
clicks           = 913
impressions      = 12450
sessions         = 1240
purchases        = 37

Expected output:

campaign_name    | ctr   | cpc  | roas | conv_rate
Brand Search CZ | 7.33% | 9.22 | 6.91 | 2.98%

Success metric: at least 90% of rows from ads_raw or ga4_raw find a counterpart in the other source or are clearly marked as unmatched; none of the key calculations ends with a division-by-zero error.

Practical check: insert the values matched, ga4_only, or ads_only into the match_status column. This will let you see whether AI is commenting on complete data or a mix with gaps.

Now we have the numerical foundation. To make the weekly report more than just a table, we will add a comparison with the previous week and prepare a structured input for AI.

Step 6: Add week-over-week comparison and prepare the prompt for AI

What and why: Current numbers alone are not enough. A weekly report should answer the question of what changed compared to the previous week and what to do about it. Therefore, you will prepare two periods and derive both percentage and absolute differences from them.

How exactly: Repeat the collection from steps 3 and 4 for the period 14daysAgo to 8daysAgo as well. In the report_input sheet, add columns such as sessions_prev, cost_prev, revenue_prev, and calculations like wow_sessions_pct, wow_cost_pct, wow_roas_pct.

Specific input: prompt for the OpenAI API:

You are a marketing analyst. Explain campaign performance for the last 7 days against the previous 7 days.
Rules:
- Write in Czech.
- Work only with the provided data.
- State 3 main findings and 3 specific recommendations.
- If match_status != matched, point out the limitation.
- Do not infer causes that are not demonstrable from the data.

Data:
[{"campaign_name":"Brand Search CZ","revenue":58210.4,"revenue_prev":49780.1,"cost":8420,"cost_prev":9150,"roas":6.91,"roas_prev":5.44,"wow_revenue_pct":16.94}]

Specific output: JSON or text with sections summary, findings, recommendations.

Example of the expected output:

{
  "summary": "Campaign Brand Search CZ increased revenue by 16.9% week over week while costs fell by 8.0%, which led to an improvement in ROAS from 5.44 to 6.91.",
  "findings": [
    "Revenue grew faster than traffic.",
    "Costs fell, but the number of orders did not decline.",
    "The campaign is among the most efficient in the account."
  ],
  "recommendations": [
    "Check the possibility of increasing the budget by 10 to 15%.",
    "Review impression share for branded queries.",
    "Compare search terms with the previous week."
  ]
}

Success metric: the AI output is consistent, does not contain metrics that are not in the input, and in at least 90% of cases correctly reflects the direction of change in the main KPIs.

Important principle: the prompt must explicitly forbid assumptions. This significantly reduces the risk that AI will claim, for example, the impact of seasonality or changes in competition without support in the data.

At this point, you can already create the text itself. The last functional part of the MVP is automatic execution and distribution of the result without manual intervention.

Step 7: Automate report generation and delivery

What and why: A report is truly useful only when it is created regularly and reaches the right people at the same time. Automation also reduces the risk that someone forgets to run the script or export the table.

How exactly: In Apps Script, create a main function, for example runWeeklyReport(), which in the exact order calls data loading, calculations, AI interpretation, and sending. Then in the Triggers menu, set a time-based trigger for Friday at 8:00.

Specific input: function and trigger settings:

function runWeeklyReport() {
  fetchGA4Week();
  fetchAdsWeek();
  buildReportInput();
  generateAICommentary();
  sendEmailReport();
}

Example email subject: Weekly AI campaign report | 4 Mar 2026

Example Slack payload:

{
  "text": "The weekly AI report is ready. Main finding: total ROAS increased by 12.4% while costs fell by 3.1%."
}

Specific output: an email delivered to marketing@example.cz or a message in a Slack channel with a link to the Google Sheet.

Success metric: the report is sent automatically for at least 3 consecutive weeks without manual intervention and without a script error state.

At this point, you have a working MVP. Before going live, however, it is necessary to verify that the numbers match, the interpretation is factual, and distribution works even in the case of errors or incomplete data.

Recommended AI stack for implementation

Choose tools according to your budget and level of automation. Below is a direct overview of services for implementing the project.

Tool Offer
NordVPN Open offer
Semrush Open offer
Make Open offer
Hostinger Open offer
Fiverr Open offer
Adobe Open offer
Canva Open offer
Jasper Open offer

Testing

Try Fiverr

Divide testing into three layers.

  1. Data accuracy test: compare the totals of sessions, cost, clicks, and revenue with the GA4 and Google Ads interfaces for the same period. Ideally, create a control table for 3 to 5 campaigns.
  2. Calculation logic test: manually recalculate CTR, CPC, ROAS, and week-over-week changes for at least two rows. Also verify behavior when clicks or costs are zero.
  3. AI output quality test: check whether AI is adding non-existent metrics, mixing GA4 and Google Ads conversions without warning, and whether the recommendations correspond to the observed change.

Practical test scenario:

Input:
revenue = 30000
revenue_prev = 20000
cost = 10000
cost_prev = 8000

Expectation:
wow_revenue_pct = 50 %
roas = 3.0
roas_prev = 2.5
AI must mention revenue growth and ROAS improvement.

If AI writes that ROAS declined, you know there is a problem either in the calculations or in the prompt.

Deployment

Try Adobe

For small and medium use cases, it is usually enough to deploy the solution directly in Google Apps Script. The recommended operating mode looks like this:

  • Google Sheet serves as both simple storage and an audit trail.
  • Apps Script runs on a time-based trigger once a week.
  • Do not store API keys and sensitive data in cells unless necessary; it is better to use Script Properties.
  • In the ai_output sheet, store the run date, prompt version, and final report text.

Example of stored run metadata:

run_timestamp | 2026-03-04 08:00:14
prompt_version | v1.3
rows_reported | 18
status | success

For greater robustness, you can later move the Google Ads API integration or processing to Google Cloud Run or Cloud Functions. However, that goes beyond the MVP and is not necessary for the first working version.

Limitations

Try Canva

This project has several important limitations that need to be stated openly:

  • Attribution differences: GA4 and Google Ads may report different conversions and revenue. If you do not clarify this in the brief, AI may comment on numbers that are not directly comparable across systems.
  • Campaign matching: if campaign names are not standardized, matching by name will be inaccurate. In that case, a mapping table or a disciplined UTM structure is necessary.
  • AI output quality: AI may phrase things too confidently even where the data has gaps. Therefore, the prompt must require warnings about limitations and prohibit speculation.
  • APIs and permissions: the Google Ads API may require specific approval and proper developer token setup. Without it, automation will not be complete.
  • Scaling: Apps Script is suitable for an MVP, but with a large number of accounts or campaigns it may hit execution and call limits.

If any of these areas is not stable in your organization, treat it as a limitation of the solution, not as a detail that will “somehow be solved later.”

FAQ

Do I have to use both GA4 and Google Ads at the same time?

No, but the point of the project is precisely the combination of web and advertising data. Only then do you get a reasonable view of both costs and business results.

Is it better to take conversions from GA4 or from Google Ads?

It depends on your reporting standard. For business results, it is often useful to keep revenue and purchases from GA4, while costs, clicks, and impressions come from Google Ads. If you do it this way, state it explicitly in the report.

Can the report also be sent to Looker Studio?

Yes, but this guide is aimed at a text-based weekly summary with AI interpretation. You can add Looker Studio as an additional visualization layer.

How do I prevent AI from “hallucinating”?

A structured input, a ban on assumptions in the prompt, clear output rules, and storing only numbers that actually come from the report all help. It is also important to test the output on known scenarios.

Is it possible to expand this project to multiple accounts?

Yes, but for an MVP I recommend starting with one account. With multiple accounts, you will need to deal with configuration management, script limits, and separate report templates.

Conclusion

An automatic AI campaign performance reporter is not, in its first version, a complex data product. It is a disciplined process: a clear data model, two verified sources, simple calculations, a carefully designed prompt, and reliable distribution. It is precisely this combination that makes it a practical AI project with a fast return on investment.

If you go through the listed steps in order, you will end up with an MVP that independently prepares a campaign overview from GA4 and Google Ads every week, calculates the changes, adds interpretation, and sends it to the team. This is a sufficiently small yet useful foundation on which you can continue building. Typical next extensions include segmentation by country, device, or channel, introducing anomaly alerts, and moving from spreadsheets to a more robust data layer. Before you do that, however, make sure the first version reliably reports what it is supposed to report.

Recommended next step

Try NordVPN

Links in the article

Sources of illustrative images

The custom illustrative image was created using the OpenAI Images API.

Service Service description Offer
NordVPN VPN service for privacy protection and secure connections. Open offer
Semrush SEO and marketing platform for analysis and traffic growth. Open offer
Make Advanced visual automation for workflows and integrations. Open offer
Hostinger Web hosting and domains for fast website launch. Open offer
Fiverr Marketplace for freelancers and external specialists. Open offer
Adobe Creative tools for graphics, video, and digital content. Open offer
Canva Online design tool for graphics, presentations, and social media. Open offer
Jasper AI tool for marketing copy and content campaigns. Open offer

Note: We use affiliate links for listed services. If you purchase through them, we may earn a commission at no extra cost to you.