Skip to content

Commit 34c6a46

Browse files
committed
chore(files): integrate aligned foundation migration retirement
2 parents 05828cd + b676fc0 commit 34c6a46

96 files changed

Lines changed: 33215 additions & 4977 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/scripts/http-e2e.sh‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ case "$group" in
102102
# because they finish in seconds. Self-hosted without billing: hosted billing admits runs through
103103
# Redis, which the CLI app is not given.
104104
cli)
105+
GOOGLE_ADS_REPORT_PATH="$report_dir/google-ads.json" bun scripts/test-google-ads-e2e.ts
105106
for search in google-content lucid zoom google-meet; do
106107
report_var="SEARCH_$(echo "$search" | tr 'a-z-' 'A-Z_')_REPORT_PATH"
107108
env NEXT_PUBLIC_APP_URL=http://127.0.0.1:3040 NEXT_PUBLIC_FORCE_HOSTED=false \

‎apps/docs/content/docs/integrations/google_ads.mdx‎

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
1212

1313
{/* MANUAL-CONTENT-START:intro */}
1414
Use [Google Ads](https://ads.google.com) in Sim to list accessible accounts and campaigns, retrieve ad groups and performance metrics, and run custom Google Ads Query Language (GAQL) queries. These read operations support campaign reporting and budget monitoring workflows.
15+
16+
Connect your Google account and select a reporting operation. Google requires the `adwords` OAuth scope even for read-only reports; Sim's Google Ads operations do not create or modify ads, budgets, or billing.
17+
18+
Google Ads API access belongs to the Google Cloud project that owns the OAuth client. Self-hosted deployments must enable the Google Ads API and configure the project's access level in the [Google Ads API overview](https://console.cloud.google.com/google/ads-apis/overview). Test access works only with Google Ads test accounts; production accounts require an appropriate production access level. [Developer tokens were retired on September 9, 2026](https://developers.google.com/google-ads/api/docs/api-policy/developer-token) and are no longer needed.
19+
20+
Use the client account's Customer ID for reports. If your Google user accesses that account through a manager, set Manager Customer ID in the additional fields. List Customers returns accounts directly accessible to the signed-in user, which may include the manager rather than its client accounts. Test accounts do not serve ads and cannot demonstrate real impressions, clicks, or spend.
21+
All report operations return one page at a time (up to 10,000 rows). Use the returned `nextPageToken` in Page Token with unchanged query inputs to retrieve the next page. `totalCount` counts the current page. Custom Query also returns `totalResultsCount`, which ignores GAQL LIMIT. Daily performance reports return one row per entity and date; sum counts before computing ratios. Costs are in micros of the customer account currency.
1522
{/* MANUAL-CONTENT-END */}
1623

1724

@@ -25,19 +32,18 @@ Connect to Google Ads to list accessible accounts, list campaigns, view ad group
2532

2633
### List Google Ads Customers
2734

28-
List all Google Ads customer accounts accessible by the authenticated user
35+
List Google Ads accounts directly accessible by the authenticated user; query customer_client for manager subaccounts
2936

3037
#### Input
3138

3239
| Parameter | Type | Required | Description |
3340
| --------- | ---- | -------- | ----------- |
34-
| `developerToken` | string | Yes | Google Ads API developer token |
3541

3642
#### Output
3743

3844
| Parameter | Type | Description |
3945
| --------- | ---- | ----------- |
40-
| `customerIds` | array | List of accessible customer IDs |
46+
| `customerIds` | array | Customer IDs directly accessible by the user |
4147
| `totalCount` | number | Total number of accessible customer accounts |
4248

4349
### Google Ads Search (GAQL)
@@ -49,7 +55,6 @@ Run a custom Google Ads Query Language (GAQL) query
4955
| Parameter | Type | Required | Description |
5056
| --------- | ---- | -------- | ----------- |
5157
| `customerId` | string | Yes | Google Ads customer ID \(numeric, no dashes\) |
52-
| `developerToken` | string | Yes | Google Ads API developer token |
5358
| `managerCustomerId` | string | No | Manager account customer ID \(if accessing via manager account\) |
5459
| `query` | string | Yes | GAQL query to execute |
5560
| `pageToken` | string | No | Page token for pagination |
@@ -58,9 +63,9 @@ Run a custom Google Ads Query Language (GAQL) query
5863

5964
| Parameter | Type | Description |
6065
| --------- | ---- | ----------- |
61-
| `results` | json | Array of result objects from the GAQL query |
62-
| `totalResultsCount` | number | Total number of matching results |
63-
| `nextPageToken` | string | Token for the next page of results |
66+
| `results` | array | Rows containing only the fields selected by the GAQL query |
67+
| `totalResultsCount` | number | Total matching rows ignoring LIMIT, when returned by Google |
68+
| `nextPageToken` | string | Token for the next page; keep the same query and customer |
6469

6570
### List Google Ads Campaigns
6671

@@ -70,8 +75,8 @@ List campaigns in a Google Ads account with optional status filtering
7075

7176
| Parameter | Type | Required | Description |
7277
| --------- | ---- | -------- | ----------- |
78+
| `pageToken` | string | No | Continuation token from the previous page; keep the same customer and query inputs |
7379
| `customerId` | string | Yes | Google Ads customer ID \(numeric, no dashes\) |
74-
| `developerToken` | string | Yes | Google Ads API developer token |
7580
| `managerCustomerId` | string | No | Manager account customer ID \(if accessing via manager account\) |
7681
| `status` | string | No | Filter by campaign status \(ENABLED, PAUSED, REMOVED\) |
7782
| `limit` | number | No | Maximum number of campaigns to return |
@@ -80,6 +85,7 @@ List campaigns in a Google Ads account with optional status filtering
8085

8186
| Parameter | Type | Description |
8287
| --------- | ---- | ----------- |
88+
| `nextPageToken` | string | Continuation token, or null on the last page; reuse unchanged query inputs |
8389
| `campaigns` | array | List of campaigns in the account |
8490
| ↳ `id` | string | Campaign ID |
8591
| ↳ `name` | string | Campaign name |
@@ -88,7 +94,7 @@ List campaigns in a Google Ads account with optional status filtering
8894
| ↳ `startDate` | string | Campaign start date \(YYYY-MM-DD\) |
8995
| ↳ `endDate` | string | Campaign end date \(YYYY-MM-DD\) |
9096
| ↳ `budgetAmountMicros` | string | Daily budget in micros \(divide by 1,000,000 for currency value\) |
91-
| `totalCount` | number | Total number of campaigns returned |
97+
| `totalCount` | number | Number of campaigns in this page |
9298

9399
### Google Ads Campaign Performance
94100

@@ -98,8 +104,8 @@ Get performance metrics for Google Ads campaigns over a date range
98104

99105
| Parameter | Type | Required | Description |
100106
| --------- | ---- | -------- | ----------- |
107+
| `pageToken` | string | No | Continuation token from the previous page; keep the same customer and query inputs |
101108
| `customerId` | string | Yes | Google Ads customer ID \(numeric, no dashes\) |
102-
| `developerToken` | string | Yes | Google Ads API developer token |
103109
| `managerCustomerId` | string | No | Manager account customer ID \(if accessing via manager account\) |
104110
| `campaignId` | string | No | Filter by specific campaign ID |
105111
| `dateRange` | string | No | Predefined date range \(LAST_7_DAYS, LAST_30_DAYS, THIS_MONTH, LAST_MONTH, TODAY, YESTERDAY\) |
@@ -110,6 +116,7 @@ Get performance metrics for Google Ads campaigns over a date range
110116

111117
| Parameter | Type | Description |
112118
| --------- | ---- | ----------- |
119+
| `nextPageToken` | string | Continuation token, or null on the last page; reuse unchanged query inputs |
113120
| `campaigns` | array | Campaign performance data broken down by date |
114121
| ↳ `id` | string | Campaign ID |
115122
| ↳ `name` | string | Campaign name |
@@ -120,7 +127,7 @@ Get performance metrics for Google Ads campaigns over a date range
120127
| ↳ `ctr` | number | Click-through rate \(0.0 to 1.0\) |
121128
| ↳ `conversions` | number | Number of conversions |
122129
| ↳ `date` | string | Date for this row \(YYYY-MM-DD\) |
123-
| `totalCount` | number | Total number of result rows |
130+
| `totalCount` | number | Number of rows in this page |
124131

125132
### List Google Ads Ad Groups
126133

@@ -130,8 +137,8 @@ List ad groups in a Google Ads campaign
130137

131138
| Parameter | Type | Required | Description |
132139
| --------- | ---- | -------- | ----------- |
140+
| `pageToken` | string | No | Continuation token from the previous page; keep the same customer and query inputs |
133141
| `customerId` | string | Yes | Google Ads customer ID \(numeric, no dashes\) |
134-
| `developerToken` | string | Yes | Google Ads API developer token |
135142
| `managerCustomerId` | string | No | Manager account customer ID \(if accessing via manager account\) |
136143
| `campaignId` | string | Yes | Campaign ID to list ad groups for |
137144
| `status` | string | No | Filter by ad group status \(ENABLED, PAUSED, REMOVED\) |
@@ -141,14 +148,15 @@ List ad groups in a Google Ads campaign
141148

142149
| Parameter | Type | Description |
143150
| --------- | ---- | ----------- |
151+
| `nextPageToken` | string | Continuation token, or null on the last page; reuse unchanged query inputs |
144152
| `adGroups` | array | List of ad groups in the campaign |
145153
| ↳ `id` | string | Ad group ID |
146154
| ↳ `name` | string | Ad group name |
147155
| ↳ `status` | string | Ad group status \(ENABLED, PAUSED, REMOVED\) |
148156
| ↳ `type` | string | Ad group type \(SEARCH_STANDARD, DISPLAY_STANDARD, SHOPPING_PRODUCT_ADS\) |
149157
| ↳ `campaignId` | string | Parent campaign ID |
150158
| ↳ `campaignName` | string | Parent campaign name |
151-
| `totalCount` | number | Total number of ad groups returned |
159+
| `totalCount` | number | Number of ad groups in this page |
152160

153161
### Google Ads Ad Performance
154162

@@ -158,8 +166,8 @@ Get performance metrics for individual ads over a date range
158166

159167
| Parameter | Type | Required | Description |
160168
| --------- | ---- | -------- | ----------- |
169+
| `pageToken` | string | No | Continuation token from the previous page; keep the same customer and query inputs |
161170
| `customerId` | string | Yes | Google Ads customer ID \(numeric, no dashes\) |
162-
| `developerToken` | string | Yes | Google Ads API developer token |
163171
| `managerCustomerId` | string | No | Manager account customer ID \(if accessing via manager account\) |
164172
| `campaignId` | string | No | Filter by campaign ID |
165173
| `adGroupId` | string | No | Filter by ad group ID |
@@ -172,6 +180,7 @@ Get performance metrics for individual ads over a date range
172180

173181
| Parameter | Type | Description |
174182
| --------- | ---- | ----------- |
183+
| `nextPageToken` | string | Continuation token, or null on the last page; reuse unchanged query inputs |
175184
| `ads` | array | Ad performance data broken down by date |
176185
| ↳ `adId` | string | Ad ID |
177186
| ↳ `adGroupId` | string | Parent ad group ID |
@@ -185,7 +194,7 @@ Get performance metrics for individual ads over a date range
185194
| ↳ `ctr` | number | Click-through rate \(0.0 to 1.0\) |
186195
| ↳ `conversions` | number | Number of conversions |
187196
| ↳ `date` | string | Date for this row \(YYYY-MM-DD\) |
188-
| `totalCount` | number | Total number of result rows |
197+
| `totalCount` | number | Number of rows in this page |
189198

190199
## OAuth Scopes
191200

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { cn } from '@sim/emcn'
2+
import { EmptyState } from '@/components/empty-state/empty-state'
3+
import { HAIRLINE } from '@/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/hairline'
4+
import { MASK_NO_REPEAT } from '@/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/mask'
5+
6+
/**
7+
* Skeleton ink — see the `INK` note in `tables-empty-state.tsx` for why not the surface
8+
* ramp. `line` is the tables selection ring's opaque mix, so a chart stroke reads as the
9+
* one drawn mark rather than more placeholder.
10+
*/
11+
const INK = {
12+
strong: 'color-mix(in srgb, var(--text-secondary) 30%, transparent)',
13+
soft: 'color-mix(in srgb, var(--text-secondary) 15%, transparent)',
14+
area: 'color-mix(in srgb, var(--text-secondary) 7%, transparent)',
15+
line: 'color-mix(in srgb, var(--text-secondary) 46%, var(--bg))',
16+
} as const
17+
18+
/** The tables grid's corner fade: the trend panel keeps its meaning cropped. */
19+
const CORNER_FADE =
20+
'[-webkit-mask-image:linear-gradient(to_right,#000_62%,transparent_100%),linear-gradient(to_bottom,#000_56%,transparent_100%)] [mask-image:linear-gradient(to_right,#000_62%,transparent_100%),linear-gradient(to_bottom,#000_56%,transparent_100%)] [-webkit-mask-composite:source-in] [mask-composite:intersect]'
21+
22+
type Point = readonly [number, number]
23+
24+
const SPARKLINE = [
25+
[52, 62],
26+
[66, 56],
27+
[80, 59],
28+
[94, 50],
29+
[108, 53],
30+
[122, 44],
31+
[136, 47],
32+
[150, 40],
33+
] as const
34+
35+
const TREND = [
36+
[52, 140],
37+
[82, 128],
38+
[112, 133],
39+
[142, 112],
40+
[172, 118],
41+
[202, 98],
42+
[232, 104],
43+
[262, 86],
44+
[292, 92],
45+
[322, 76],
46+
] as const
47+
48+
const LEGEND = [
49+
{ y: 33, width: 34, fill: INK.strong },
50+
{ y: 42, width: 44, fill: INK.soft },
51+
{ y: 51, width: 28, fill: INK.soft },
52+
] as const
53+
54+
const DONUT = { cx: 202, cy: 44, r: 16, strokeWidth: 6 } as const
55+
56+
function toPath(points: readonly Point[]): string {
57+
return points.map(([x, y], i) => `${i === 0 ? 'M' : 'L'} ${x} ${y}`).join(' ')
58+
}
59+
60+
const CHART_STROKE = {
61+
stroke: INK.line,
62+
strokeLinecap: 'round',
63+
strokeLinejoin: 'round',
64+
} as const
65+
66+
/** A stat tile, a donut tile, and a wide trend panel running off two edges. */
67+
function DashboardGraphic() {
68+
const donutArc = {
69+
cx: DONUT.cx,
70+
cy: DONUT.cy,
71+
r: DONUT.r,
72+
strokeWidth: DONUT.strokeWidth,
73+
pathLength: 100,
74+
transform: `rotate(-90 ${DONUT.cx} ${DONUT.cy})`,
75+
}
76+
return (
77+
<svg
78+
viewBox='0 0 320 148'
79+
width={320}
80+
height={148}
81+
fill='none'
82+
aria-hidden='true'
83+
focusable='false'
84+
className={cn('block max-w-none shrink-0', CORNER_FADE, MASK_NO_REPEAT)}
85+
>
86+
<rect x='40' y='14' width='124' height='60' rx='6' fill='var(--surface-2)' {...HAIRLINE} />
87+
<rect x='52' y='24' width='30' height='4' rx='2' fill={INK.soft} />
88+
<rect x='52' y='33' width='48' height='8' rx='4' fill={INK.strong} />
89+
<path d={toPath(SPARKLINE)} strokeWidth={1.3} {...CHART_STROKE} />
90+
91+
<rect x='172' y='14' width='124' height='60' rx='6' fill='var(--surface-2)' {...HAIRLINE} />
92+
<circle
93+
cx={DONUT.cx}
94+
cy={DONUT.cy}
95+
r={DONUT.r}
96+
stroke={INK.soft}
97+
strokeWidth={DONUT.strokeWidth}
98+
/>
99+
<circle {...donutArc} stroke={INK.line} strokeDasharray='38 62' />
100+
<circle {...donutArc} stroke={INK.strong} strokeDasharray='24 76' strokeDashoffset={-40} />
101+
{LEGEND.map((line) => (
102+
<rect
103+
key={line.y}
104+
x='230'
105+
y={line.y}
106+
width={line.width}
107+
height='4'
108+
rx='2'
109+
fill={line.fill}
110+
/>
111+
))}
112+
113+
<rect x='40' y='82' width='300' height='90' rx='6' fill='var(--surface-2)' {...HAIRLINE} />
114+
<rect x='52' y='92' width='40' height='4' rx='2' fill={INK.strong} />
115+
<path d={`${toPath(TREND)} V 172 H 52 Z`} fill={INK.area} />
116+
<path d={toPath(TREND)} strokeWidth={1.4} {...CHART_STROKE} />
117+
</svg>
118+
)
119+
}
120+
121+
/** Empty state for a workspace whose dashboard Sim has not built yet. */
122+
export function DashboardEmptyState() {
123+
return (
124+
<EmptyState
125+
graphic={<DashboardGraphic />}
126+
title='Dashboard'
127+
description='Sim will build your dashboard here once your workspace is set up.'
128+
/>
129+
)
130+
}

‎apps/sim/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export { DashboardEmptyState } from '@/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/dashboard-empty-state'
12
export { DocumentsEmptyState } from '@/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/documents-empty-state'
23
export { FilesEmptyState } from '@/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/files-empty-state'
34
export { KnowledgeEmptyState } from '@/app/workspace/[workspaceId]/components/resource/components/resource-empty-state/knowledge-empty-state'

0 commit comments

Comments
 (0)