@tangle-network/agent-integrations 0.60.1 → 0.61.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/data/bundled-adapter-manifests.json +1 -1
- package/dist/{adapters-CqJ5RFh6.js → adapters-Dp5h7mF-.js} +3960 -107
- package/dist/{adapters-CqJ5RFh6.js.map → adapters-Dp5h7mF-.js.map} +1 -1
- package/dist/{bundled-manifest-data-DUWA4K9P.js → bundled-manifest-data-D8W3xNyQ.js} +5701 -1
- package/dist/{bundled-manifest-data-DUWA4K9P.js.map → bundled-manifest-data-D8W3xNyQ.js.map} +1 -1
- package/dist/connectors/adapters/index.d.ts +2 -2
- package/dist/connectors/adapters/index.js +2 -2
- package/dist/connectors/index.d.ts +3 -3
- package/dist/connectors/index.js +3 -3
- package/dist/{consumer-CcTc6QRQ.d.ts → consumer-DYpMLeNG.d.ts} +2 -2
- package/dist/{consumer-CcTc6QRQ.d.ts.map → consumer-DYpMLeNG.d.ts.map} +1 -1
- package/dist/consumer.d.ts +1 -1
- package/dist/consumer.js +2 -1
- package/dist/consumer.js.map +1 -1
- package/dist/coverage-catalog-DlfNsiGZ.d.ts.map +1 -1
- package/dist/coverage-catalog.js +74 -0
- package/dist/coverage-catalog.js.map +1 -1
- package/dist/{index-ClTbIO8u.d.ts → index-BXhHnxfA.d.ts} +155 -6
- package/dist/index-BXhHnxfA.d.ts.map +1 -0
- package/dist/{index-CgeaeuJe.d.ts → index-Bb---RDI.d.ts} +2 -2
- package/dist/{index-CgeaeuJe.d.ts.map → index-Bb---RDI.d.ts.map} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/internal/bundled-manifest-runtime.js +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +3 -2
- package/dist/mcp.js.map +1 -1
- package/dist/registry.js +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/sandbox.d.ts +1 -1
- package/dist/{specs-CFGt95KY.js → specs-ElJzHwc7.js} +2 -2
- package/dist/{specs-CFGt95KY.js.map → specs-ElJzHwc7.js.map} +1 -1
- package/dist/specs.js +1 -1
- package/dist/{src-yZCgbWPm.js → src-91m6v5vV.js} +7 -5
- package/dist/src-91m6v5vV.js.map +1 -0
- package/docs/amazon-ads.md +23 -0
- package/docs/linkedin-ads.md +25 -0
- package/docs/meta-ads.md +17 -0
- package/docs/microsoft-ads.md +21 -0
- package/docs/paid-advertising.md +26 -0
- package/docs/pinterest-ads.md +18 -0
- package/docs/reddit-ads.md +25 -0
- package/docs/snapchat-ads.md +18 -0
- package/docs/tiktok-ads.md +25 -0
- package/docs/x-ads.md +29 -0
- package/package.json +1 -1
- package/dist/index-ClTbIO8u.d.ts.map +0 -1
- package/dist/src-yZCgbWPm.js.map +0 -1
|
@@ -2,9 +2,9 @@ import { t as IntegrationRuntimeError } from "./errors-CvO_y8JO.js";
|
|
|
2
2
|
import { a as TangleIdentityUnreachableError, c as CredentialsExpired, d as ResourceContention, i as TANGLE_SERVICE_TOKEN_PREFIX, l as ProviderConfigError, n as TANGLE_API_KEY_PREFIX, o as createTangleIdentityClient, s as tangleIdentity, t as DEFAULT_TANGLE_PLATFORM_URL, u as ProviderRateLimited } from "./tangle-id-S6oooMWh.js";
|
|
3
3
|
import { createOAuthBasicAuthorizationHeader, exchangeAuthorizationCode, oauthClientCredentialRedactionValues, redactOAuthSensitiveText, refreshAccessToken } from "./connectors/oauth.js";
|
|
4
4
|
import { n as firstHeader, o as verifySlackSignature, s as verifyStripeSignature } from "./webhooks-FsjqRN_0.js";
|
|
5
|
-
import { i as retryAfterMs$6, n as record, r as requestJson, t as ProviderProtocolError } from "./response-json-BnUINkTL.js";
|
|
5
|
+
import { i as retryAfterMs$6, n as record$3, r as requestJson, t as ProviderProtocolError } from "./response-json-BnUINkTL.js";
|
|
6
6
|
import { t as linqWhatsappAttachmentUrl } from "./linq-whatsapp-attachment-url-C9jHVGw5.js";
|
|
7
|
-
import { createHash, createHmac, createSign, timingSafeEqual } from "node:crypto";
|
|
7
|
+
import { createHash, createHmac, createSign, randomBytes, timingSafeEqual } from "node:crypto";
|
|
8
8
|
import { decodeJwt } from "jose";
|
|
9
9
|
import { createHash as createHash$1, createHmac as createHmac$1 } from "crypto";
|
|
10
10
|
import { VoiceApiException, VoiceClient } from "@ph0ny/sdk";
|
|
@@ -934,6 +934,38 @@ const INGEST_FIELDS = [
|
|
|
934
934
|
"chunkOverlap"
|
|
935
935
|
];
|
|
936
936
|
//#endregion
|
|
937
|
+
//#region src/connectors/adapters/oauth1.ts
|
|
938
|
+
/** RFC 5849 signature over the final URL and, only for form requests, the body. */
|
|
939
|
+
function oauth1Authorization(input) {
|
|
940
|
+
const { credentials, url } = input;
|
|
941
|
+
const oauth = {
|
|
942
|
+
oauth_consumer_key: credentials.consumerKey,
|
|
943
|
+
oauth_nonce: input.nonce,
|
|
944
|
+
oauth_signature_method: "HMAC-SHA1",
|
|
945
|
+
oauth_timestamp: input.timestamp,
|
|
946
|
+
oauth_token: credentials.accessToken,
|
|
947
|
+
oauth_version: "1.0"
|
|
948
|
+
};
|
|
949
|
+
const parameters = [
|
|
950
|
+
...url.searchParams.entries(),
|
|
951
|
+
...new URLSearchParams(input.formBody).entries(),
|
|
952
|
+
...Object.entries(oauth)
|
|
953
|
+
].map(([key, value]) => [encode(key), encode(value)]);
|
|
954
|
+
parameters.sort(([ak, av], [bk, bv]) => ak < bk ? -1 : ak > bk ? 1 : av < bv ? -1 : av > bv ? 1 : 0);
|
|
955
|
+
const normalized = parameters.map(([key, value]) => `${key}=${value}`).join("&");
|
|
956
|
+
const base = [
|
|
957
|
+
input.method.toUpperCase(),
|
|
958
|
+
`${url.origin}${url.pathname}`,
|
|
959
|
+
normalized
|
|
960
|
+
].map(encode).join("&");
|
|
961
|
+
const key = `${encode(credentials.consumerSecret)}&${encode(credentials.accessTokenSecret)}`;
|
|
962
|
+
oauth.oauth_signature = createHmac("sha1", key).update(base).digest("base64");
|
|
963
|
+
return `OAuth ${Object.entries(oauth).map(([name, value]) => `${encode(name)}="${encode(value)}"`).join(", ")}`;
|
|
964
|
+
}
|
|
965
|
+
function encode(value) {
|
|
966
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
967
|
+
}
|
|
968
|
+
//#endregion
|
|
937
969
|
//#region src/connectors/adapters/aws-sigv4.ts
|
|
938
970
|
/**
|
|
939
971
|
* AWS Signature Version 4 (SigV4) request signer — self-contained, no SDK.
|
|
@@ -1286,8 +1318,10 @@ async function executeRestRequest(spec, request, inv, requiredArgs) {
|
|
|
1286
1318
|
const headers = {
|
|
1287
1319
|
accept: "application/json",
|
|
1288
1320
|
...renderHeaders(spec.defaultHeaders ?? {}, scope, true),
|
|
1289
|
-
...renderHeaders(renderableHeaders, scope, false, requiredArgs)
|
|
1321
|
+
...renderHeaders(renderableHeaders, scope, false, requiredArgs),
|
|
1322
|
+
...spec.credentialHeaders
|
|
1290
1323
|
};
|
|
1324
|
+
if (Object.values(spec.credentialHeaders ?? {}).some((value) => !value.trim())) throw new Error(`${spec.kind}: missing application credential header`);
|
|
1291
1325
|
const structuredCredentials = placement.kind === "structured-headers" || placement.kind === "structured-json-body" ? readStructuredCredentials(inv.source.credentials, placement.fields) : placement.kind === "basic-structured" ? readStructuredCredentials(inv.source.credentials, {
|
|
1292
1326
|
[placement.usernameField]: placement.usernameField,
|
|
1293
1327
|
[placement.passwordField]: placement.passwordField
|
|
@@ -1314,7 +1348,27 @@ async function executeRestRequest(spec, request, inv, requiredArgs) {
|
|
|
1314
1348
|
region: awsRegion,
|
|
1315
1349
|
bundle: aws
|
|
1316
1350
|
});
|
|
1317
|
-
else if (placement.kind === "
|
|
1351
|
+
else if (placement.kind === "oauth1") {
|
|
1352
|
+
const bundle = readStructuredCredentials(inv.source.credentials, {
|
|
1353
|
+
consumerKey: "",
|
|
1354
|
+
consumerSecret: "",
|
|
1355
|
+
accessToken: "",
|
|
1356
|
+
accessTokenSecret: ""
|
|
1357
|
+
});
|
|
1358
|
+
headers.authorization = oauth1Authorization({
|
|
1359
|
+
method: request.method,
|
|
1360
|
+
url,
|
|
1361
|
+
formBody: bodyEncoding === "form" ? bodyString : void 0,
|
|
1362
|
+
credentials: {
|
|
1363
|
+
consumerKey: bundle.consumerKey,
|
|
1364
|
+
consumerSecret: bundle.consumerSecret,
|
|
1365
|
+
accessToken: bundle.accessToken,
|
|
1366
|
+
accessTokenSecret: bundle.accessTokenSecret
|
|
1367
|
+
},
|
|
1368
|
+
nonce: randomBytes(24).toString("hex"),
|
|
1369
|
+
timestamp: String(Math.floor(Date.now() / 1e3))
|
|
1370
|
+
});
|
|
1371
|
+
} else if (placement.kind === "basic-structured") {
|
|
1318
1372
|
const username = structuredCredentials[placement.usernameField];
|
|
1319
1373
|
const password = structuredCredentials[placement.passwordField];
|
|
1320
1374
|
headers.authorization = `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`;
|
|
@@ -1327,7 +1381,7 @@ async function executeRestRequest(spec, request, inv, requiredArgs) {
|
|
|
1327
1381
|
});
|
|
1328
1382
|
if ((spec.credentialsExpiredStatuses ?? [401, 403]).includes(res.status)) throw new CredentialsExpired(`${spec.displayName} rejected credentials (${res.status})`, inv.source.id);
|
|
1329
1383
|
if (res.status === 409 || res.status === 412) {
|
|
1330
|
-
const text = redactCredentialText(await safeErrorText(res), inv.source.credentials, [getHeaderCI(headers, "authorization")]);
|
|
1384
|
+
const text = redactCredentialText(await safeErrorText(res), inv.source.credentials, [getHeaderCI(headers, "authorization"), ...Object.values(spec.credentialHeaders ?? {})]);
|
|
1331
1385
|
return {
|
|
1332
1386
|
data: parseBodyText(text),
|
|
1333
1387
|
outcome: "conflict",
|
|
@@ -1337,7 +1391,7 @@ async function executeRestRequest(spec, request, inv, requiredArgs) {
|
|
|
1337
1391
|
};
|
|
1338
1392
|
}
|
|
1339
1393
|
if (res.status === 429) {
|
|
1340
|
-
const text = redactCredentialText(await safeErrorText(res), inv.source.credentials, [getHeaderCI(headers, "authorization")]);
|
|
1394
|
+
const text = redactCredentialText(await safeErrorText(res), inv.source.credentials, [getHeaderCI(headers, "authorization"), ...Object.values(spec.credentialHeaders ?? {})]);
|
|
1341
1395
|
return {
|
|
1342
1396
|
data: parseBodyText(text),
|
|
1343
1397
|
outcome: "rate-limited",
|
|
@@ -1348,7 +1402,7 @@ async function executeRestRequest(spec, request, inv, requiredArgs) {
|
|
|
1348
1402
|
}
|
|
1349
1403
|
if (request.existenceCheck && (res.status === 204 || res.status === 404)) return { data: { exists: res.status === 204 } };
|
|
1350
1404
|
if (!res.ok) {
|
|
1351
|
-
const text = redactCredentialText(await safeErrorText(res), inv.source.credentials, [getHeaderCI(headers, "authorization")]);
|
|
1405
|
+
const text = redactCredentialText(await safeErrorText(res), inv.source.credentials, [getHeaderCI(headers, "authorization"), ...Object.values(spec.credentialHeaders ?? {})]);
|
|
1352
1406
|
throw new Error(`${spec.kind} ${request.method} ${url.pathname} HTTP ${res.status}: ${text.slice(0, 300)}`);
|
|
1353
1407
|
}
|
|
1354
1408
|
if (request.responseBody === "base64") return { data: {
|
|
@@ -1481,10 +1535,12 @@ function redactCredentialText(text, credentials, additionalSecrets = []) {
|
|
|
1481
1535
|
const candidates = credentials.kind === "oauth2" ? [credentials.accessToken, credentials.refreshToken] : credentials.kind === "api-key" ? [credentials.apiKey, ...jsonStringValues(credentials.apiKey)] : credentials.kind === "custom" ? Object.values(credentials.values) : [];
|
|
1482
1536
|
const authorizationSecrets = additionalSecrets.flatMap((secret) => {
|
|
1483
1537
|
if (typeof secret !== "string") return [];
|
|
1538
|
+
if (secret.startsWith("OAuth ")) return [secret, ...[...secret.matchAll(/oauth_(?:consumer_key|token|signature)="([^"]+)"/g)].map((match) => match[1])];
|
|
1484
1539
|
const credential = secret.match(/^(?:Basic|Bearer)\s+(.+)$/i)?.[1];
|
|
1485
1540
|
return credential ? [secret, credential] : [secret];
|
|
1486
1541
|
});
|
|
1487
|
-
|
|
1542
|
+
const secrets = [...candidates, ...authorizationSecrets].filter((secret) => typeof secret === "string" && secret.length > 0);
|
|
1543
|
+
return [...new Set(secrets.flatMap((secret) => [secret, encodeURIComponent(secret)]))].sort((a, b) => b.length - a.length).reduce((redacted, secret) => redacted.split(secret).join("[REDACTED]"), text);
|
|
1488
1544
|
}
|
|
1489
1545
|
function jsonStringValues(value) {
|
|
1490
1546
|
try {
|
|
@@ -1547,8 +1603,7 @@ function signAwsRequest(headers, url, opts) {
|
|
|
1547
1603
|
*/
|
|
1548
1604
|
function resolveBody(body, args, scope, requiredArgs) {
|
|
1549
1605
|
if (!body || body === "args") return args;
|
|
1550
|
-
|
|
1551
|
-
return renderObject(body, scope, requiredArgs);
|
|
1606
|
+
return renderValue(body, scope, requiredArgs);
|
|
1552
1607
|
}
|
|
1553
1608
|
/** Conservative wait when the upstream throttles without saying for how long. */
|
|
1554
1609
|
const DEFAULT_RETRY_AFTER_MS = 6e4;
|
|
@@ -7308,7 +7363,7 @@ const message = {
|
|
|
7308
7363
|
minLength: 1,
|
|
7309
7364
|
maxLength: 18e3
|
|
7310
7365
|
};
|
|
7311
|
-
const base$
|
|
7366
|
+
const base$9 = declarativeRestConnector({
|
|
7312
7367
|
kind: "contiguity",
|
|
7313
7368
|
displayName: "Contiguity",
|
|
7314
7369
|
category: "crm",
|
|
@@ -7568,14 +7623,14 @@ const base$3 = declarativeRestConnector({
|
|
|
7568
7623
|
]
|
|
7569
7624
|
});
|
|
7570
7625
|
const contiguityConnector = {
|
|
7571
|
-
...base$
|
|
7626
|
+
...base$9,
|
|
7572
7627
|
async executeMutation(inv) {
|
|
7573
|
-
if (inv.capabilityName !== "email.send") return base$
|
|
7628
|
+
if (inv.capabilityName !== "email.send") return base$9.executeMutation(inv);
|
|
7574
7629
|
const { body, contentType, ...args } = inv.args;
|
|
7575
7630
|
if (typeof body !== "string" || !body.length || contentType !== void 0 && contentType !== "text/plain" && contentType !== "text/html") throw new Error("Contiguity email requires a body and supported contentType");
|
|
7576
7631
|
delete args.text;
|
|
7577
7632
|
delete args.html;
|
|
7578
|
-
return base$
|
|
7633
|
+
return base$9.executeMutation({
|
|
7579
7634
|
...inv,
|
|
7580
7635
|
args: {
|
|
7581
7636
|
...args,
|
|
@@ -8074,12 +8129,12 @@ function privateAudio(args) {
|
|
|
8074
8129
|
};
|
|
8075
8130
|
}
|
|
8076
8131
|
function transcriptResponse(value) {
|
|
8077
|
-
if (!record(value) || !record(value.results) || !Array.isArray(value.results.channels)) throw new ProviderProtocolError("Deepgram returned no transcription channels", "invalid_response");
|
|
8132
|
+
if (!record$3(value) || !record$3(value.results) || !Array.isArray(value.results.channels)) throw new ProviderProtocolError("Deepgram returned no transcription channels", "invalid_response");
|
|
8078
8133
|
const channel = value.results.channels[0];
|
|
8079
|
-
if (!record(channel) || !Array.isArray(channel.alternatives) || !record(channel.alternatives[0])) throw new ProviderProtocolError("Deepgram returned no transcription alternative", "invalid_response");
|
|
8134
|
+
if (!record$3(channel) || !Array.isArray(channel.alternatives) || !record$3(channel.alternatives[0])) throw new ProviderProtocolError("Deepgram returned no transcription alternative", "invalid_response");
|
|
8080
8135
|
const text = channel.alternatives[0].transcript;
|
|
8081
8136
|
if (typeof text !== "string") throw new ProviderProtocolError("Deepgram returned an invalid transcript", "invalid_response");
|
|
8082
|
-
const rawRequestId = record(value.metadata) ? value.metadata.request_id : void 0;
|
|
8137
|
+
const rawRequestId = record$3(value.metadata) ? value.metadata.request_id : void 0;
|
|
8083
8138
|
return {
|
|
8084
8139
|
text,
|
|
8085
8140
|
requestId: typeof rawRequestId === "string" && rawRequestId.length > 0 && rawRequestId.length <= 256 ? rawRequestId : null,
|
|
@@ -8087,7 +8142,7 @@ function transcriptResponse(value) {
|
|
|
8087
8142
|
language: "multi"
|
|
8088
8143
|
};
|
|
8089
8144
|
}
|
|
8090
|
-
const base$
|
|
8145
|
+
const base$8 = declarativeRestConnector({
|
|
8091
8146
|
kind: "deepgram",
|
|
8092
8147
|
displayName: "Deepgram",
|
|
8093
8148
|
description: "Transcribe audio to text, synthesize text to speech, and analyze audio content with AI-powered speech recognition.",
|
|
@@ -8330,10 +8385,10 @@ const base$2 = declarativeRestConnector({
|
|
|
8330
8385
|
]
|
|
8331
8386
|
});
|
|
8332
8387
|
const deepgramConnector = {
|
|
8333
|
-
...base$
|
|
8388
|
+
...base$8,
|
|
8334
8389
|
manifest: {
|
|
8335
|
-
...base$
|
|
8336
|
-
capabilities: [...base$
|
|
8390
|
+
...base$8.manifest,
|
|
8391
|
+
capabilities: [...base$8.manifest.capabilities, {
|
|
8337
8392
|
name: "transcription.bytes",
|
|
8338
8393
|
class: "mutation",
|
|
8339
8394
|
cas: "none",
|
|
@@ -8360,7 +8415,7 @@ const deepgramConnector = {
|
|
|
8360
8415
|
}]
|
|
8361
8416
|
},
|
|
8362
8417
|
async executeMutation(inv) {
|
|
8363
|
-
if (inv.capabilityName !== "transcription.bytes") return base$
|
|
8418
|
+
if (inv.capabilityName !== "transcription.bytes") return base$8.executeMutation(inv);
|
|
8364
8419
|
const { bytes, contentType } = privateAudio(inv.args);
|
|
8365
8420
|
if (inv.source.credentials.kind !== "api-key" || !inv.source.credentials.apiKey || /[\u0000-\u0020\u007f]/.test(inv.source.credentials.apiKey)) throw new IntegrationRuntimeError({
|
|
8366
8421
|
code: "provider_auth_failed",
|
|
@@ -25968,7 +26023,7 @@ function arbitraryBodyParameters() {
|
|
|
25968
26023
|
}
|
|
25969
26024
|
//#endregion
|
|
25970
26025
|
//#region src/connectors/adapters/amplitude.ts
|
|
25971
|
-
const date$
|
|
26026
|
+
const date$4 = {
|
|
25972
26027
|
type: "string",
|
|
25973
26028
|
pattern: "^[0-9]{8}$",
|
|
25974
26029
|
description: "Inclusive date in YYYYMMDD format."
|
|
@@ -26085,8 +26140,8 @@ const amplitudeConnector = declarativeRestConnector({
|
|
|
26085
26140
|
type: "string",
|
|
26086
26141
|
enum: ["any", "active"]
|
|
26087
26142
|
},
|
|
26088
|
-
start: date$
|
|
26089
|
-
end: date$
|
|
26143
|
+
start: date$4,
|
|
26144
|
+
end: date$4,
|
|
26090
26145
|
interval: {
|
|
26091
26146
|
type: "integer",
|
|
26092
26147
|
enum: [
|
|
@@ -26152,8 +26207,8 @@ const amplitudeConnector = declarativeRestConnector({
|
|
|
26152
26207
|
parameters: {
|
|
26153
26208
|
type: "object",
|
|
26154
26209
|
properties: {
|
|
26155
|
-
start: date$
|
|
26156
|
-
end: date$
|
|
26210
|
+
start: date$4,
|
|
26211
|
+
end: date$4,
|
|
26157
26212
|
mode: {
|
|
26158
26213
|
type: "string",
|
|
26159
26214
|
enum: ["active", "new"]
|
|
@@ -26194,8 +26249,8 @@ const amplitudeConnector = declarativeRestConnector({
|
|
|
26194
26249
|
parameters: {
|
|
26195
26250
|
type: "object",
|
|
26196
26251
|
properties: {
|
|
26197
|
-
start: date$
|
|
26198
|
-
end: date$
|
|
26252
|
+
start: date$4,
|
|
26253
|
+
end: date$4
|
|
26199
26254
|
},
|
|
26200
26255
|
required: ["start", "end"]
|
|
26201
26256
|
},
|
|
@@ -36450,7 +36505,7 @@ const clickupConnector = declarativeRestConnector({
|
|
|
36450
36505
|
});
|
|
36451
36506
|
//#endregion
|
|
36452
36507
|
//#region src/connectors/adapters/cloudflare.ts
|
|
36453
|
-
const pagination$
|
|
36508
|
+
const pagination$5 = {
|
|
36454
36509
|
page: {
|
|
36455
36510
|
type: "integer",
|
|
36456
36511
|
minimum: 1
|
|
@@ -36599,7 +36654,7 @@ const cloudflareConnector = declarativeRestConnector({
|
|
|
36599
36654
|
parameters: {
|
|
36600
36655
|
type: "object",
|
|
36601
36656
|
properties: {
|
|
36602
|
-
...pagination$
|
|
36657
|
+
...pagination$5,
|
|
36603
36658
|
accountId: { type: "string" },
|
|
36604
36659
|
name: { type: "string" },
|
|
36605
36660
|
status: {
|
|
@@ -36706,7 +36761,7 @@ const cloudflareConnector = declarativeRestConnector({
|
|
|
36706
36761
|
type: "object",
|
|
36707
36762
|
properties: {
|
|
36708
36763
|
...zoneId,
|
|
36709
|
-
...pagination$
|
|
36764
|
+
...pagination$5,
|
|
36710
36765
|
type: { type: "string" },
|
|
36711
36766
|
name: {
|
|
36712
36767
|
type: "string",
|
|
@@ -39610,11 +39665,11 @@ const chargebeeConnector = declarativeRestConnector({
|
|
|
39610
39665
|
});
|
|
39611
39666
|
//#endregion
|
|
39612
39667
|
//#region src/connectors/adapters/recurly.ts
|
|
39613
|
-
const id$
|
|
39668
|
+
const id$15 = (description) => ({
|
|
39614
39669
|
type: "string",
|
|
39615
39670
|
description
|
|
39616
39671
|
});
|
|
39617
|
-
const pageQuery = {
|
|
39672
|
+
const pageQuery$2 = {
|
|
39618
39673
|
limit: {
|
|
39619
39674
|
type: "integer",
|
|
39620
39675
|
minimum: 1,
|
|
@@ -39670,7 +39725,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39670
39725
|
description: "List sites accessible to the supplied Recurly private API key.",
|
|
39671
39726
|
parameters: {
|
|
39672
39727
|
type: "object",
|
|
39673
|
-
properties: { limit: pageQuery.limit }
|
|
39728
|
+
properties: { limit: pageQuery$2.limit }
|
|
39674
39729
|
},
|
|
39675
39730
|
request: {
|
|
39676
39731
|
method: "GET",
|
|
@@ -39685,7 +39740,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39685
39740
|
parameters: {
|
|
39686
39741
|
type: "object",
|
|
39687
39742
|
properties: {
|
|
39688
|
-
...pageQuery,
|
|
39743
|
+
...pageQuery$2,
|
|
39689
39744
|
state: {
|
|
39690
39745
|
type: "string",
|
|
39691
39746
|
enum: [
|
|
@@ -39717,7 +39772,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39717
39772
|
description: "Read one billing account by UUID or code-prefixed identifier.",
|
|
39718
39773
|
parameters: {
|
|
39719
39774
|
type: "object",
|
|
39720
|
-
properties: { accountId: id$
|
|
39775
|
+
properties: { accountId: id$15("Account UUID or `code-<account code>`.") },
|
|
39721
39776
|
required: ["accountId"]
|
|
39722
39777
|
},
|
|
39723
39778
|
request: {
|
|
@@ -39762,7 +39817,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39762
39817
|
parameters: {
|
|
39763
39818
|
type: "object",
|
|
39764
39819
|
properties: {
|
|
39765
|
-
accountId: id$
|
|
39820
|
+
accountId: id$15("Account UUID or `code-<account code>`."),
|
|
39766
39821
|
email: { type: "string" },
|
|
39767
39822
|
first_name: { type: "string" },
|
|
39768
39823
|
last_name: { type: "string" },
|
|
@@ -39792,7 +39847,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39792
39847
|
parameters: {
|
|
39793
39848
|
type: "object",
|
|
39794
39849
|
properties: {
|
|
39795
|
-
...pageQuery,
|
|
39850
|
+
...pageQuery$2,
|
|
39796
39851
|
state: {
|
|
39797
39852
|
type: "string",
|
|
39798
39853
|
enum: ["active", "inactive"]
|
|
@@ -39819,7 +39874,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39819
39874
|
parameters: {
|
|
39820
39875
|
type: "object",
|
|
39821
39876
|
properties: {
|
|
39822
|
-
...pageQuery,
|
|
39877
|
+
...pageQuery$2,
|
|
39823
39878
|
state: {
|
|
39824
39879
|
type: "string",
|
|
39825
39880
|
enum: [
|
|
@@ -39853,8 +39908,8 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39853
39908
|
parameters: {
|
|
39854
39909
|
type: "object",
|
|
39855
39910
|
properties: {
|
|
39856
|
-
...pageQuery,
|
|
39857
|
-
accountId: id$
|
|
39911
|
+
...pageQuery$2,
|
|
39912
|
+
accountId: id$15("Account UUID or `code-<account code>`."),
|
|
39858
39913
|
state: {
|
|
39859
39914
|
type: "string",
|
|
39860
39915
|
enum: [
|
|
@@ -39888,7 +39943,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39888
39943
|
description: "Read one subscription by UUID.",
|
|
39889
39944
|
parameters: {
|
|
39890
39945
|
type: "object",
|
|
39891
|
-
properties: { subscriptionId: id$
|
|
39946
|
+
properties: { subscriptionId: id$15("Subscription UUID.") },
|
|
39892
39947
|
required: ["subscriptionId"]
|
|
39893
39948
|
},
|
|
39894
39949
|
request: {
|
|
@@ -39952,7 +40007,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39952
40007
|
description: "Schedule a subscription to cancel at its renewal date.",
|
|
39953
40008
|
parameters: {
|
|
39954
40009
|
type: "object",
|
|
39955
|
-
properties: { subscriptionId: id$
|
|
40010
|
+
properties: { subscriptionId: id$15("Subscription UUID.") },
|
|
39956
40011
|
required: ["subscriptionId"]
|
|
39957
40012
|
},
|
|
39958
40013
|
request: {
|
|
@@ -39969,7 +40024,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39969
40024
|
description: "Reactivate a subscription that is pending cancellation.",
|
|
39970
40025
|
parameters: {
|
|
39971
40026
|
type: "object",
|
|
39972
|
-
properties: { subscriptionId: id$
|
|
40027
|
+
properties: { subscriptionId: id$15("Subscription UUID.") },
|
|
39973
40028
|
required: ["subscriptionId"]
|
|
39974
40029
|
},
|
|
39975
40030
|
request: {
|
|
@@ -39987,7 +40042,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
39987
40042
|
parameters: {
|
|
39988
40043
|
type: "object",
|
|
39989
40044
|
properties: {
|
|
39990
|
-
subscriptionId: id$
|
|
40045
|
+
subscriptionId: id$15("Subscription UUID."),
|
|
39991
40046
|
refund: {
|
|
39992
40047
|
type: "string",
|
|
39993
40048
|
enum: [
|
|
@@ -40015,8 +40070,8 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
40015
40070
|
parameters: {
|
|
40016
40071
|
type: "object",
|
|
40017
40072
|
properties: {
|
|
40018
|
-
...pageQuery,
|
|
40019
|
-
accountId: id$
|
|
40073
|
+
...pageQuery$2,
|
|
40074
|
+
accountId: id$15("Optional account UUID or `code-<account code>`."),
|
|
40020
40075
|
state: {
|
|
40021
40076
|
type: "string",
|
|
40022
40077
|
enum: [
|
|
@@ -40059,7 +40114,7 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
40059
40114
|
description: "Read one invoice by UUID or number-prefixed identifier.",
|
|
40060
40115
|
parameters: {
|
|
40061
40116
|
type: "object",
|
|
40062
|
-
properties: { invoiceId: id$
|
|
40117
|
+
properties: { invoiceId: id$15("Invoice UUID or `number-<invoice number>`.") },
|
|
40063
40118
|
required: ["invoiceId"]
|
|
40064
40119
|
},
|
|
40065
40120
|
request: {
|
|
@@ -40074,8 +40129,8 @@ const recurlyConnector = declarativeRestConnector({
|
|
|
40074
40129
|
parameters: {
|
|
40075
40130
|
type: "object",
|
|
40076
40131
|
properties: {
|
|
40077
|
-
...pageQuery,
|
|
40078
|
-
accountId: id$
|
|
40132
|
+
...pageQuery$2,
|
|
40133
|
+
accountId: id$15("Account UUID or `code-<account code>`."),
|
|
40079
40134
|
state: {
|
|
40080
40135
|
type: "string",
|
|
40081
40136
|
enum: [
|
|
@@ -49900,35 +49955,35 @@ const googleAnalyticsConnector = declarativeRestConnector({
|
|
|
49900
49955
|
});
|
|
49901
49956
|
//#endregion
|
|
49902
49957
|
//#region src/connectors/adapters/google-ads.ts
|
|
49903
|
-
const scope = "https://www.googleapis.com/auth/adwords";
|
|
49904
|
-
const id$
|
|
49958
|
+
const scope$3 = "https://www.googleapis.com/auth/adwords";
|
|
49959
|
+
const id$14 = {
|
|
49905
49960
|
type: "string",
|
|
49906
49961
|
pattern: "^[0-9]+$",
|
|
49907
49962
|
description: "Numeric ID without hyphens."
|
|
49908
49963
|
};
|
|
49909
|
-
const text$
|
|
49964
|
+
const text$10 = {
|
|
49910
49965
|
type: "string",
|
|
49911
49966
|
minLength: 1
|
|
49912
49967
|
};
|
|
49913
|
-
const micros = {
|
|
49968
|
+
const micros$4 = {
|
|
49914
49969
|
type: "string",
|
|
49915
49970
|
pattern: "^[1-9][0-9]*$",
|
|
49916
49971
|
description: "Positive integer micros in the customer currency; 1000000 = one currency unit."
|
|
49917
49972
|
};
|
|
49918
|
-
const dateTime = {
|
|
49973
|
+
const dateTime$1 = {
|
|
49919
49974
|
type: "string",
|
|
49920
49975
|
pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
|
|
49921
49976
|
description: "yyyy-MM-dd HH:mm:ss in the customer timezone. Total-budget campaigns require a fixed end."
|
|
49922
49977
|
};
|
|
49923
49978
|
const campaign = "customers/{customerId}/campaigns/{campaignId}";
|
|
49924
49979
|
const adGroup = "customers/{customerId}/adGroups/{adGroupId}";
|
|
49925
|
-
function parameters(properties, required) {
|
|
49980
|
+
function parameters$9(properties, required) {
|
|
49926
49981
|
return {
|
|
49927
49982
|
type: "object",
|
|
49928
49983
|
properties: {
|
|
49929
|
-
customerId: id$
|
|
49984
|
+
customerId: id$14,
|
|
49930
49985
|
loginCustomerId: {
|
|
49931
|
-
...id$
|
|
49986
|
+
...id$14,
|
|
49932
49987
|
description: "Optional manager account ID when accessing a managed customer."
|
|
49933
49988
|
},
|
|
49934
49989
|
...properties
|
|
@@ -49937,15 +49992,15 @@ function parameters(properties, required) {
|
|
|
49937
49992
|
additionalProperties: false
|
|
49938
49993
|
};
|
|
49939
49994
|
}
|
|
49940
|
-
function mutation(name, description, properties, required, mutateOperations) {
|
|
49995
|
+
function mutation$3(name, description, properties, required, mutateOperations) {
|
|
49941
49996
|
return {
|
|
49942
49997
|
name,
|
|
49943
49998
|
description,
|
|
49944
49999
|
class: "mutation",
|
|
49945
50000
|
cas: "none",
|
|
49946
50001
|
externalEffect: true,
|
|
49947
|
-
requiredScopes: [scope],
|
|
49948
|
-
parameters: parameters({
|
|
50002
|
+
requiredScopes: [scope$3],
|
|
50003
|
+
parameters: parameters$9({
|
|
49949
50004
|
...properties,
|
|
49950
50005
|
validateOnly: {
|
|
49951
50006
|
type: "boolean",
|
|
@@ -49976,7 +50031,7 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
49976
50031
|
kind: "oauth2",
|
|
49977
50032
|
authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
49978
50033
|
tokenUrl: "https://oauth2.googleapis.com/token",
|
|
49979
|
-
scopes: [scope],
|
|
50034
|
+
scopes: [scope$3],
|
|
49980
50035
|
clientIdEnv: "GOOGLE_OAUTH_CLIENT_ID",
|
|
49981
50036
|
clientSecretEnv: "GOOGLE_OAUTH_CLIENT_SECRET",
|
|
49982
50037
|
extraAuthParams: {
|
|
@@ -49997,7 +50052,7 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
49997
50052
|
{
|
|
49998
50053
|
name: "customers.listAccessible",
|
|
49999
50054
|
class: "read",
|
|
50000
|
-
requiredScopes: [scope],
|
|
50055
|
+
requiredScopes: [scope$3],
|
|
50001
50056
|
description: "List directly accessible customer IDs. For managers, query customer_client to discover advertiser accounts.",
|
|
50002
50057
|
parameters: {
|
|
50003
50058
|
type: "object",
|
|
@@ -50012,11 +50067,11 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
50012
50067
|
{
|
|
50013
50068
|
name: "reports.search",
|
|
50014
50069
|
class: "read",
|
|
50015
|
-
requiredScopes: [scope],
|
|
50070
|
+
requiredScopes: [scope$3],
|
|
50016
50071
|
description: "Run GAQL for account currency/timezone, campaign budgets/status, ad review, billing readiness, spend, clicks, and configured conversion metrics. Follow nextPageToken.",
|
|
50017
|
-
parameters: parameters({
|
|
50072
|
+
parameters: parameters$9({
|
|
50018
50073
|
query: {
|
|
50019
|
-
...text$
|
|
50074
|
+
...text$10,
|
|
50020
50075
|
description: "Google Ads Query Language SELECT query. Monetary metrics use customer currency micros; conversion metrics require configured tracking."
|
|
50021
50076
|
},
|
|
50022
50077
|
pageToken: { type: "string" }
|
|
@@ -50031,11 +50086,11 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
50031
50086
|
}
|
|
50032
50087
|
}
|
|
50033
50088
|
},
|
|
50034
|
-
mutation("campaigns.createSearch", "Atomically create a PAUSED Search campaign and non-shared TOTAL budget. Verify customer currency/timezone first; configure targeting and ads before enabling.", {
|
|
50035
|
-
name: text$
|
|
50036
|
-
totalAmountMicros: micros,
|
|
50037
|
-
startDateTime: dateTime,
|
|
50038
|
-
endDateTime: dateTime,
|
|
50089
|
+
mutation$3("campaigns.createSearch", "Atomically create a PAUSED Search campaign and non-shared TOTAL budget. Verify customer currency/timezone first; configure targeting and ads before enabling.", {
|
|
50090
|
+
name: text$10,
|
|
50091
|
+
totalAmountMicros: micros$4,
|
|
50092
|
+
startDateTime: dateTime$1,
|
|
50093
|
+
endDateTime: dateTime$1,
|
|
50039
50094
|
containsEuPoliticalAdvertising: {
|
|
50040
50095
|
type: "string",
|
|
50041
50096
|
enum: ["DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING", "CONTAINS_EU_POLITICAL_ADVERTISING"]
|
|
@@ -50074,17 +50129,17 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
50074
50129
|
negativeGeoTargetType: "PRESENCE"
|
|
50075
50130
|
}
|
|
50076
50131
|
} } }]),
|
|
50077
|
-
...["ENABLED", "PAUSED"].map((status) => mutation(status === "ENABLED" ? "campaigns.enable" : "campaigns.pause", status === "ENABLED" ? "Launch a campaign. Verify authorization, total budget, end time, targeting, billing, and ad review first; enabling can spend immediately." : "Pause a campaign to stop serving ads. Read status and spend after pausing; reporting can lag.", { campaignId: id$
|
|
50132
|
+
...["ENABLED", "PAUSED"].map((status) => mutation$3(status === "ENABLED" ? "campaigns.enable" : "campaigns.pause", status === "ENABLED" ? "Launch a campaign. Verify authorization, total budget, end time, targeting, billing, and ad review first; enabling can spend immediately." : "Pause a campaign to stop serving ads. Read status and spend after pausing; reporting can lag.", { campaignId: id$14 }, ["campaignId"], [{ campaignOperation: {
|
|
50078
50133
|
update: {
|
|
50079
50134
|
resourceName: campaign,
|
|
50080
50135
|
status
|
|
50081
50136
|
},
|
|
50082
50137
|
updateMask: "status"
|
|
50083
50138
|
} }])),
|
|
50084
|
-
mutation("adGroups.create", "Create an enabled Search ad group with a maximum CPC bid. A paused parent campaign prevents serving until launched.", {
|
|
50085
|
-
campaignId: id$
|
|
50086
|
-
name: text$
|
|
50087
|
-
cpcBidMicros: micros
|
|
50139
|
+
mutation$3("adGroups.create", "Create an enabled Search ad group with a maximum CPC bid. A paused parent campaign prevents serving until launched.", {
|
|
50140
|
+
campaignId: id$14,
|
|
50141
|
+
name: text$10,
|
|
50142
|
+
cpcBidMicros: micros$4
|
|
50088
50143
|
}, [
|
|
50089
50144
|
"campaignId",
|
|
50090
50145
|
"name",
|
|
@@ -50096,9 +50151,9 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
50096
50151
|
status: "ENABLED",
|
|
50097
50152
|
cpcBidMicros: "{cpcBidMicros}"
|
|
50098
50153
|
} } }]),
|
|
50099
|
-
mutation("keywords.create", "Add a positive or negative keyword to an ad group. Exact and phrase match constrain search intent more tightly than broad match.", {
|
|
50100
|
-
adGroupId: id$
|
|
50101
|
-
text: text$
|
|
50154
|
+
mutation$3("keywords.create", "Add a positive or negative keyword to an ad group. Exact and phrase match constrain search intent more tightly than broad match.", {
|
|
50155
|
+
adGroupId: id$14,
|
|
50156
|
+
text: text$10,
|
|
50102
50157
|
matchType: {
|
|
50103
50158
|
type: "string",
|
|
50104
50159
|
enum: [
|
|
@@ -50121,8 +50176,8 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
50121
50176
|
matchType: "{matchType}"
|
|
50122
50177
|
}
|
|
50123
50178
|
} } }]),
|
|
50124
|
-
mutation("ads.createResponsiveSearch", "Create an enabled responsive Search ad. Supply 3–15 unique headlines and 2–4 descriptions; Google reviews the ad before serving.", {
|
|
50125
|
-
adGroupId: id$
|
|
50179
|
+
mutation$3("ads.createResponsiveSearch", "Create an enabled responsive Search ad. Supply 3–15 unique headlines and 2–4 descriptions; Google reviews the ad before serving.", {
|
|
50180
|
+
adGroupId: id$14,
|
|
50126
50181
|
finalUrls: {
|
|
50127
50182
|
type: "array",
|
|
50128
50183
|
minItems: 1,
|
|
@@ -50159,9 +50214,9 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
50159
50214
|
}
|
|
50160
50215
|
}
|
|
50161
50216
|
} } }]),
|
|
50162
|
-
...["ENABLED", "PAUSED"].map((status) => mutation(status === "ENABLED" ? "ads.enable" : "ads.pause", status === "ENABLED" ? "Enable a reviewed ad within its existing campaign and budget. An enabled parent campaign can serve it immediately." : "Pause one ad after creating a replacement, preserving the campaign total budget and other ads.", {
|
|
50163
|
-
adGroupId: id$
|
|
50164
|
-
adId: id$
|
|
50217
|
+
...["ENABLED", "PAUSED"].map((status) => mutation$3(status === "ENABLED" ? "ads.enable" : "ads.pause", status === "ENABLED" ? "Enable a reviewed ad within its existing campaign and budget. An enabled parent campaign can serve it immediately." : "Pause one ad after creating a replacement, preserving the campaign total budget and other ads.", {
|
|
50218
|
+
adGroupId: id$14,
|
|
50219
|
+
adId: id$14
|
|
50165
50220
|
}, ["adGroupId", "adId"], [{ adGroupAdOperation: {
|
|
50166
50221
|
update: {
|
|
50167
50222
|
resourceName: "customers/{customerId}/adGroupAds/{adGroupId}~{adId}",
|
|
@@ -50169,18 +50224,18 @@ const googleAdsConnector = declarativeRestConnector({
|
|
|
50169
50224
|
},
|
|
50170
50225
|
updateMask: "status"
|
|
50171
50226
|
} }])),
|
|
50172
|
-
mutation("campaigns.addLocation", "Target or exclude a geographic area. Discover geo_target_constant IDs with reports.search before adding targeting.", {
|
|
50173
|
-
campaignId: id$
|
|
50174
|
-
geoTargetConstantId: id$
|
|
50227
|
+
mutation$3("campaigns.addLocation", "Target or exclude a geographic area. Discover geo_target_constant IDs with reports.search before adding targeting.", {
|
|
50228
|
+
campaignId: id$14,
|
|
50229
|
+
geoTargetConstantId: id$14,
|
|
50175
50230
|
negative: { type: "boolean" }
|
|
50176
50231
|
}, ["campaignId", "geoTargetConstantId"], [{ campaignCriterionOperation: { create: {
|
|
50177
50232
|
campaign,
|
|
50178
50233
|
negative: "{negative}",
|
|
50179
50234
|
location: { geoTargetConstant: "geoTargetConstants/{geoTargetConstantId}" }
|
|
50180
50235
|
} } }]),
|
|
50181
|
-
mutation("campaigns.addLanguage", "Add a campaign language criterion. Discover language_constant IDs with reports.search.", {
|
|
50182
|
-
campaignId: id$
|
|
50183
|
-
languageConstantId: id$
|
|
50236
|
+
mutation$3("campaigns.addLanguage", "Add a campaign language criterion. Discover language_constant IDs with reports.search.", {
|
|
50237
|
+
campaignId: id$14,
|
|
50238
|
+
languageConstantId: id$14
|
|
50184
50239
|
}, ["campaignId", "languageConstantId"], [{ campaignCriterionOperation: { create: {
|
|
50185
50240
|
campaign,
|
|
50186
50241
|
language: { languageConstant: "languageConstants/{languageConstantId}" }
|
|
@@ -50195,7 +50250,7 @@ function textAssets(minItems, maxItems, maxLength) {
|
|
|
50195
50250
|
items: {
|
|
50196
50251
|
type: "object",
|
|
50197
50252
|
properties: { text: {
|
|
50198
|
-
...text$
|
|
50253
|
+
...text$10,
|
|
50199
50254
|
maxLength
|
|
50200
50255
|
} },
|
|
50201
50256
|
required: ["text"],
|
|
@@ -50204,6 +50259,3688 @@ function textAssets(minItems, maxItems, maxLength) {
|
|
|
50204
50259
|
};
|
|
50205
50260
|
}
|
|
50206
50261
|
//#endregion
|
|
50262
|
+
//#region src/connectors/adapters/meta-ads.ts
|
|
50263
|
+
const id$13 = {
|
|
50264
|
+
type: "string",
|
|
50265
|
+
pattern: "^[0-9]+$",
|
|
50266
|
+
description: "Numeric native ID. For accountId use account_id, without the act_ prefix."
|
|
50267
|
+
};
|
|
50268
|
+
const text$9 = {
|
|
50269
|
+
type: "string",
|
|
50270
|
+
minLength: 1
|
|
50271
|
+
};
|
|
50272
|
+
const money$4 = {
|
|
50273
|
+
type: "integer",
|
|
50274
|
+
minimum: 1,
|
|
50275
|
+
description: "Positive amount in the ad account currency minor units, e.g. 10000 = USD 100. Confirm account currency first."
|
|
50276
|
+
};
|
|
50277
|
+
const dateTime = {
|
|
50278
|
+
type: "string",
|
|
50279
|
+
format: "date-time"
|
|
50280
|
+
};
|
|
50281
|
+
const url$1 = {
|
|
50282
|
+
type: "string",
|
|
50283
|
+
format: "uri",
|
|
50284
|
+
pattern: "^https://"
|
|
50285
|
+
};
|
|
50286
|
+
const page$7 = {
|
|
50287
|
+
limit: {
|
|
50288
|
+
type: "integer",
|
|
50289
|
+
minimum: 1,
|
|
50290
|
+
maximum: 100
|
|
50291
|
+
},
|
|
50292
|
+
after: text$9
|
|
50293
|
+
};
|
|
50294
|
+
const pageQuery$1 = {
|
|
50295
|
+
limit: "{limit}",
|
|
50296
|
+
after: "{after}"
|
|
50297
|
+
};
|
|
50298
|
+
function parameters$8(properties, required = []) {
|
|
50299
|
+
return {
|
|
50300
|
+
type: "object",
|
|
50301
|
+
properties,
|
|
50302
|
+
required,
|
|
50303
|
+
additionalProperties: false
|
|
50304
|
+
};
|
|
50305
|
+
}
|
|
50306
|
+
function mutation$2(name, description, properties, required, path, body) {
|
|
50307
|
+
return {
|
|
50308
|
+
name,
|
|
50309
|
+
description,
|
|
50310
|
+
class: "mutation",
|
|
50311
|
+
cas: "none",
|
|
50312
|
+
externalEffect: true,
|
|
50313
|
+
requiredScopes: ["ads_management"],
|
|
50314
|
+
parameters: parameters$8(properties, required),
|
|
50315
|
+
request: {
|
|
50316
|
+
method: "POST",
|
|
50317
|
+
path,
|
|
50318
|
+
bodyEncoding: "form",
|
|
50319
|
+
body
|
|
50320
|
+
}
|
|
50321
|
+
};
|
|
50322
|
+
}
|
|
50323
|
+
const base$7 = declarativeRestConnector({
|
|
50324
|
+
kind: "meta-ads",
|
|
50325
|
+
displayName: "Meta Ads",
|
|
50326
|
+
description: "Manage Facebook and Instagram paid traffic campaigns, bounded budgets, ad sets, link creatives, delivery status and insights.",
|
|
50327
|
+
category: "other",
|
|
50328
|
+
defaultConsistencyModel: "cache",
|
|
50329
|
+
auth: {
|
|
50330
|
+
kind: "oauth2",
|
|
50331
|
+
authorizationUrl: "https://www.facebook.com/v25.0/dialog/oauth",
|
|
50332
|
+
tokenUrl: "https://graph.facebook.com/v25.0/oauth/access_token",
|
|
50333
|
+
scopes: [
|
|
50334
|
+
"ads_read",
|
|
50335
|
+
"ads_management",
|
|
50336
|
+
"pages_show_list",
|
|
50337
|
+
"pages_read_engagement"
|
|
50338
|
+
],
|
|
50339
|
+
pkce: "unsupported",
|
|
50340
|
+
clientIdEnv: "META_ADS_OAUTH_CLIENT_ID",
|
|
50341
|
+
clientSecretEnv: "META_ADS_OAUTH_CLIENT_SECRET"
|
|
50342
|
+
},
|
|
50343
|
+
baseUrl: "https://graph.facebook.com/v25.0",
|
|
50344
|
+
credentialsExpiredStatuses: [401],
|
|
50345
|
+
test: {
|
|
50346
|
+
method: "GET",
|
|
50347
|
+
path: "/me/adaccounts",
|
|
50348
|
+
query: {
|
|
50349
|
+
fields: "id,account_id,name,account_status,currency,timezone_name",
|
|
50350
|
+
limit: 1
|
|
50351
|
+
}
|
|
50352
|
+
},
|
|
50353
|
+
capabilities: [
|
|
50354
|
+
{
|
|
50355
|
+
name: "accounts.list",
|
|
50356
|
+
class: "read",
|
|
50357
|
+
description: "Discover permitted ad accounts, currencies, timezones and readiness. Follow paging.cursors.after.",
|
|
50358
|
+
requiredScopes: ["ads_read"],
|
|
50359
|
+
parameters: parameters$8(page$7),
|
|
50360
|
+
request: {
|
|
50361
|
+
method: "GET",
|
|
50362
|
+
path: "/me/adaccounts",
|
|
50363
|
+
query: {
|
|
50364
|
+
fields: "id,account_id,name,account_status,currency,timezone_name,amount_spent,spend_cap",
|
|
50365
|
+
...pageQuery$1
|
|
50366
|
+
}
|
|
50367
|
+
}
|
|
50368
|
+
},
|
|
50369
|
+
{
|
|
50370
|
+
name: "pages.list",
|
|
50371
|
+
class: "read",
|
|
50372
|
+
description: "Discover Pages and their linked Instagram business identities for ad creatives. Page access tokens are deliberately not requested.",
|
|
50373
|
+
requiredScopes: ["pages_show_list"],
|
|
50374
|
+
parameters: parameters$8(page$7),
|
|
50375
|
+
request: {
|
|
50376
|
+
method: "GET",
|
|
50377
|
+
path: "/me/accounts",
|
|
50378
|
+
query: {
|
|
50379
|
+
fields: "id,name,instagram_business_account{id,username}",
|
|
50380
|
+
...pageQuery$1
|
|
50381
|
+
}
|
|
50382
|
+
}
|
|
50383
|
+
},
|
|
50384
|
+
...[
|
|
50385
|
+
["campaigns", "id,name,status,effective_status,objective,spend_cap,budget_remaining"],
|
|
50386
|
+
["adsets", "id,name,campaign_id,status,effective_status,lifetime_budget,budget_remaining,start_time,end_time,targeting"],
|
|
50387
|
+
["ads", "id,name,campaign_id,adset_id,status,effective_status,creative,issues_info"],
|
|
50388
|
+
["adcreatives", "id,name,object_story_spec,thumbnail_url"]
|
|
50389
|
+
].map(([edge, fields]) => ({
|
|
50390
|
+
name: `${edge === "adsets" ? "adSets" : edge === "adcreatives" ? "creatives" : edge}.list`,
|
|
50391
|
+
class: "read",
|
|
50392
|
+
requiredScopes: ["ads_read"],
|
|
50393
|
+
description: `Read ${edge} in an ad account, including native IDs and readiness. Follow paging.cursors.after.`,
|
|
50394
|
+
parameters: parameters$8({
|
|
50395
|
+
accountId: id$13,
|
|
50396
|
+
...page$7
|
|
50397
|
+
}, ["accountId"]),
|
|
50398
|
+
request: {
|
|
50399
|
+
method: "GET",
|
|
50400
|
+
path: `/act_{accountId}/${edge}`,
|
|
50401
|
+
query: {
|
|
50402
|
+
fields,
|
|
50403
|
+
...pageQuery$1
|
|
50404
|
+
}
|
|
50405
|
+
}
|
|
50406
|
+
})),
|
|
50407
|
+
mutation$2("campaigns.createTraffic", "Create a PAUSED auction traffic campaign with an explicit campaign spend cap across all its ad sets. The cap is not a daily budget; configure bounded ad sets before enabling.", {
|
|
50408
|
+
accountId: id$13,
|
|
50409
|
+
name: text$9,
|
|
50410
|
+
spendCap: money$4,
|
|
50411
|
+
specialAdCategories: {
|
|
50412
|
+
type: "array",
|
|
50413
|
+
items: {
|
|
50414
|
+
type: "string",
|
|
50415
|
+
enum: [
|
|
50416
|
+
"HOUSING",
|
|
50417
|
+
"EMPLOYMENT",
|
|
50418
|
+
"FINANCIAL_PRODUCTS_SERVICES",
|
|
50419
|
+
"ISSUES_ELECTIONS_POLITICS"
|
|
50420
|
+
]
|
|
50421
|
+
},
|
|
50422
|
+
uniqueItems: true
|
|
50423
|
+
}
|
|
50424
|
+
}, [
|
|
50425
|
+
"accountId",
|
|
50426
|
+
"name",
|
|
50427
|
+
"spendCap",
|
|
50428
|
+
"specialAdCategories"
|
|
50429
|
+
], "/act_{accountId}/campaigns", {
|
|
50430
|
+
name: "{name}",
|
|
50431
|
+
objective: "OUTCOME_TRAFFIC",
|
|
50432
|
+
buying_type: "AUCTION",
|
|
50433
|
+
status: "PAUSED",
|
|
50434
|
+
spend_cap: "{spendCap}",
|
|
50435
|
+
special_ad_categories: "{specialAdCategoriesJson}",
|
|
50436
|
+
is_adset_budget_sharing_enabled: false
|
|
50437
|
+
}),
|
|
50438
|
+
mutation$2("adSets.createTraffic", "Create a PAUSED website-link-click ad set with a lifetime budget and fixed flight. Meta validates targeting and regional disclosure requirements; use a campaign spend cap as the aggregate limit.", {
|
|
50439
|
+
accountId: id$13,
|
|
50440
|
+
campaignId: id$13,
|
|
50441
|
+
name: text$9,
|
|
50442
|
+
lifetimeBudget: money$4,
|
|
50443
|
+
startTime: dateTime,
|
|
50444
|
+
endTime: dateTime,
|
|
50445
|
+
countries: {
|
|
50446
|
+
type: "array",
|
|
50447
|
+
minItems: 1,
|
|
50448
|
+
items: {
|
|
50449
|
+
type: "string",
|
|
50450
|
+
pattern: "^[A-Z]{2}$"
|
|
50451
|
+
},
|
|
50452
|
+
uniqueItems: true
|
|
50453
|
+
},
|
|
50454
|
+
ageMin: {
|
|
50455
|
+
type: "integer",
|
|
50456
|
+
minimum: 18,
|
|
50457
|
+
maximum: 65
|
|
50458
|
+
},
|
|
50459
|
+
ageMax: {
|
|
50460
|
+
type: "integer",
|
|
50461
|
+
minimum: 18,
|
|
50462
|
+
maximum: 65
|
|
50463
|
+
},
|
|
50464
|
+
dsaBeneficiary: text$9,
|
|
50465
|
+
dsaPayor: text$9
|
|
50466
|
+
}, [
|
|
50467
|
+
"accountId",
|
|
50468
|
+
"campaignId",
|
|
50469
|
+
"name",
|
|
50470
|
+
"lifetimeBudget",
|
|
50471
|
+
"startTime",
|
|
50472
|
+
"endTime",
|
|
50473
|
+
"countries"
|
|
50474
|
+
], "/act_{accountId}/adsets", {
|
|
50475
|
+
name: "{name}",
|
|
50476
|
+
campaign_id: "{campaignId}",
|
|
50477
|
+
status: "PAUSED",
|
|
50478
|
+
lifetime_budget: "{lifetimeBudget}",
|
|
50479
|
+
start_time: "{startTime}",
|
|
50480
|
+
end_time: "{endTime}",
|
|
50481
|
+
billing_event: "IMPRESSIONS",
|
|
50482
|
+
optimization_goal: "LINK_CLICKS",
|
|
50483
|
+
bid_strategy: "LOWEST_COST_WITHOUT_CAP",
|
|
50484
|
+
destination_type: "WEBSITE",
|
|
50485
|
+
targeting: "{targetingJson}",
|
|
50486
|
+
dsa_beneficiary: "{dsaBeneficiary}",
|
|
50487
|
+
dsa_payor: "{dsaPayor}"
|
|
50488
|
+
}),
|
|
50489
|
+
mutation$2("creatives.createLink", "Create a website link creative from a Page identity and a public HTTPS image. Supply instagramUserId for the Instagram identity. Provider review still applies.", {
|
|
50490
|
+
accountId: id$13,
|
|
50491
|
+
name: text$9,
|
|
50492
|
+
pageId: id$13,
|
|
50493
|
+
instagramUserId: id$13,
|
|
50494
|
+
link: url$1,
|
|
50495
|
+
imageUrl: url$1,
|
|
50496
|
+
message: text$9,
|
|
50497
|
+
headline: text$9,
|
|
50498
|
+
callToAction: {
|
|
50499
|
+
type: "string",
|
|
50500
|
+
enum: [
|
|
50501
|
+
"LEARN_MORE",
|
|
50502
|
+
"SIGN_UP",
|
|
50503
|
+
"SHOP_NOW",
|
|
50504
|
+
"CONTACT_US",
|
|
50505
|
+
"BOOK_TRAVEL",
|
|
50506
|
+
"GET_QUOTE"
|
|
50507
|
+
]
|
|
50508
|
+
}
|
|
50509
|
+
}, [
|
|
50510
|
+
"accountId",
|
|
50511
|
+
"name",
|
|
50512
|
+
"pageId",
|
|
50513
|
+
"link",
|
|
50514
|
+
"imageUrl",
|
|
50515
|
+
"message",
|
|
50516
|
+
"headline",
|
|
50517
|
+
"callToAction"
|
|
50518
|
+
], "/act_{accountId}/adcreatives", {
|
|
50519
|
+
name: "{name}",
|
|
50520
|
+
object_story_spec: "{storyJson}"
|
|
50521
|
+
}),
|
|
50522
|
+
mutation$2("ads.create", "Create a PAUSED ad using an existing creative and ad set; this does not launch the ad.", {
|
|
50523
|
+
accountId: id$13,
|
|
50524
|
+
name: text$9,
|
|
50525
|
+
adSetId: id$13,
|
|
50526
|
+
creativeId: id$13
|
|
50527
|
+
}, [
|
|
50528
|
+
"accountId",
|
|
50529
|
+
"name",
|
|
50530
|
+
"adSetId",
|
|
50531
|
+
"creativeId"
|
|
50532
|
+
], "/act_{accountId}/ads", {
|
|
50533
|
+
name: "{name}",
|
|
50534
|
+
adset_id: "{adSetId}",
|
|
50535
|
+
creative: "{creativeJson}",
|
|
50536
|
+
status: "PAUSED"
|
|
50537
|
+
}),
|
|
50538
|
+
...[
|
|
50539
|
+
"campaigns",
|
|
50540
|
+
"adSets",
|
|
50541
|
+
"ads"
|
|
50542
|
+
].flatMap((entity) => ["ACTIVE", "PAUSED"].map((status) => mutation$2(`${entity}.${status === "ACTIVE" ? "enable" : "pause"}`, status === "ACTIVE" ? "Enable delivery of this object. Verify approved spending authority, parent campaign cap, flight, billing, targeting and review status first; all ancestors must be active to serve." : "Pause delivery of this object without changing budgets or creatives. Re-read effective status and spend afterward.", { objectId: id$13 }, ["objectId"], "/{objectId}", { status }))),
|
|
50543
|
+
{
|
|
50544
|
+
name: "reports.insights",
|
|
50545
|
+
class: "read",
|
|
50546
|
+
requiredScopes: ["ads_read"],
|
|
50547
|
+
description: "Read account, campaign, ad set or ad performance for an inclusive date range. Spend is in account currency units; actions require configured attribution and are not verified sales.",
|
|
50548
|
+
parameters: parameters$8({
|
|
50549
|
+
accountId: id$13,
|
|
50550
|
+
since: {
|
|
50551
|
+
type: "string",
|
|
50552
|
+
format: "date"
|
|
50553
|
+
},
|
|
50554
|
+
until: {
|
|
50555
|
+
type: "string",
|
|
50556
|
+
format: "date"
|
|
50557
|
+
},
|
|
50558
|
+
level: {
|
|
50559
|
+
type: "string",
|
|
50560
|
+
enum: [
|
|
50561
|
+
"account",
|
|
50562
|
+
"campaign",
|
|
50563
|
+
"adset",
|
|
50564
|
+
"ad"
|
|
50565
|
+
]
|
|
50566
|
+
},
|
|
50567
|
+
...page$7
|
|
50568
|
+
}, [
|
|
50569
|
+
"accountId",
|
|
50570
|
+
"since",
|
|
50571
|
+
"until",
|
|
50572
|
+
"level"
|
|
50573
|
+
]),
|
|
50574
|
+
request: {
|
|
50575
|
+
method: "GET",
|
|
50576
|
+
path: "/act_{accountId}/insights",
|
|
50577
|
+
query: {
|
|
50578
|
+
fields: "account_id,account_currency,campaign_id,campaign_name,adset_id,ad_id,impressions,clicks,spend,actions,action_values",
|
|
50579
|
+
level: "{level}",
|
|
50580
|
+
time_range: "{timeRangeJson}",
|
|
50581
|
+
...pageQuery$1
|
|
50582
|
+
}
|
|
50583
|
+
}
|
|
50584
|
+
}
|
|
50585
|
+
]
|
|
50586
|
+
});
|
|
50587
|
+
function prepare$2(inv) {
|
|
50588
|
+
const a = inv.args;
|
|
50589
|
+
if (inv.capabilityName === "campaigns.createTraffic" && (!Number.isSafeInteger(a.spendCap) || Number(a.spendCap) <= 0)) throw new Error("meta-ads: spendCap must be a positive safe integer");
|
|
50590
|
+
if (inv.capabilityName === "adSets.createTraffic") {
|
|
50591
|
+
if (!Number.isSafeInteger(a.lifetimeBudget) || Number(a.lifetimeBudget) <= 0) throw new Error("meta-ads: lifetimeBudget must be a positive safe integer");
|
|
50592
|
+
if (!(Date.parse(String(a.endTime)) > Date.parse(String(a.startTime)))) throw new Error("meta-ads: endTime must be after startTime");
|
|
50593
|
+
}
|
|
50594
|
+
return {
|
|
50595
|
+
...inv,
|
|
50596
|
+
args: {
|
|
50597
|
+
...a,
|
|
50598
|
+
specialAdCategoriesJson: JSON.stringify(a.specialAdCategories),
|
|
50599
|
+
targetingJson: JSON.stringify({
|
|
50600
|
+
geo_locations: { countries: a.countries },
|
|
50601
|
+
age_min: a.ageMin,
|
|
50602
|
+
age_max: a.ageMax
|
|
50603
|
+
}),
|
|
50604
|
+
storyJson: JSON.stringify({
|
|
50605
|
+
page_id: a.pageId,
|
|
50606
|
+
instagram_user_id: a.instagramUserId,
|
|
50607
|
+
link_data: {
|
|
50608
|
+
link: a.link,
|
|
50609
|
+
picture: a.imageUrl,
|
|
50610
|
+
message: a.message,
|
|
50611
|
+
name: a.headline,
|
|
50612
|
+
call_to_action: {
|
|
50613
|
+
type: a.callToAction,
|
|
50614
|
+
value: { link: a.link }
|
|
50615
|
+
}
|
|
50616
|
+
}
|
|
50617
|
+
}),
|
|
50618
|
+
creativeJson: JSON.stringify({ creative_id: a.creativeId }),
|
|
50619
|
+
timeRangeJson: JSON.stringify({
|
|
50620
|
+
since: a.since,
|
|
50621
|
+
until: a.until
|
|
50622
|
+
})
|
|
50623
|
+
}
|
|
50624
|
+
};
|
|
50625
|
+
}
|
|
50626
|
+
const metaAdsConnector = {
|
|
50627
|
+
...base$7,
|
|
50628
|
+
async executeRead(inv) {
|
|
50629
|
+
const result = await base$7.executeRead(prepare$2(inv));
|
|
50630
|
+
if (isPlainRecord(result.data) && isPlainRecord(result.data.paging)) {
|
|
50631
|
+
const { next: _next, previous: _previous, ...paging } = result.data.paging;
|
|
50632
|
+
return {
|
|
50633
|
+
...result,
|
|
50634
|
+
data: {
|
|
50635
|
+
...result.data,
|
|
50636
|
+
paging
|
|
50637
|
+
}
|
|
50638
|
+
};
|
|
50639
|
+
}
|
|
50640
|
+
return result;
|
|
50641
|
+
},
|
|
50642
|
+
async executeMutation(inv) {
|
|
50643
|
+
const result = await base$7.executeMutation(prepare$2(inv));
|
|
50644
|
+
if (result.status !== "committed") return result;
|
|
50645
|
+
const data = result.data;
|
|
50646
|
+
if (!(isPlainRecord(data) && !("error" in data) && (inv.capabilityName.includes(".create") ? typeof data.id === "string" && data.id.trim().length > 0 : data.success === true))) throw new Error("meta-ads: missing native mutation receipt; reconcile provider state before retrying");
|
|
50647
|
+
return result;
|
|
50648
|
+
}
|
|
50649
|
+
};
|
|
50650
|
+
//#endregion
|
|
50651
|
+
//#region src/connectors/adapters/x-ads.ts
|
|
50652
|
+
const id$12 = {
|
|
50653
|
+
type: "string",
|
|
50654
|
+
pattern: "^[a-zA-Z0-9]+$"
|
|
50655
|
+
};
|
|
50656
|
+
const text$8 = {
|
|
50657
|
+
type: "string",
|
|
50658
|
+
minLength: 1,
|
|
50659
|
+
maxLength: 255
|
|
50660
|
+
};
|
|
50661
|
+
const micros$3 = {
|
|
50662
|
+
type: "string",
|
|
50663
|
+
pattern: "^[1-9][0-9]*$",
|
|
50664
|
+
description: "Positive integer microcurrency in the funding instrument currency; 1000000 = one currency unit."
|
|
50665
|
+
};
|
|
50666
|
+
const time$4 = {
|
|
50667
|
+
type: "string",
|
|
50668
|
+
format: "date-time"
|
|
50669
|
+
};
|
|
50670
|
+
const page$6 = {
|
|
50671
|
+
cursor: { type: "string" },
|
|
50672
|
+
count: {
|
|
50673
|
+
type: "integer",
|
|
50674
|
+
minimum: 1,
|
|
50675
|
+
maximum: 1e3
|
|
50676
|
+
}
|
|
50677
|
+
};
|
|
50678
|
+
const accountPath$1 = "/accounts/{accountId}";
|
|
50679
|
+
function parameters$7(properties, required = []) {
|
|
50680
|
+
return {
|
|
50681
|
+
type: "object",
|
|
50682
|
+
properties,
|
|
50683
|
+
required,
|
|
50684
|
+
additionalProperties: false
|
|
50685
|
+
};
|
|
50686
|
+
}
|
|
50687
|
+
function write$5(name, description, path, properties, required, body, method = "POST") {
|
|
50688
|
+
return {
|
|
50689
|
+
name,
|
|
50690
|
+
description,
|
|
50691
|
+
class: "mutation",
|
|
50692
|
+
cas: "none",
|
|
50693
|
+
externalEffect: true,
|
|
50694
|
+
parameters: parameters$7({
|
|
50695
|
+
accountId: id$12,
|
|
50696
|
+
...properties
|
|
50697
|
+
}, ["accountId", ...required]),
|
|
50698
|
+
request: {
|
|
50699
|
+
method,
|
|
50700
|
+
path: accountPath$1 + path,
|
|
50701
|
+
bodyEncoding: "form",
|
|
50702
|
+
body
|
|
50703
|
+
}
|
|
50704
|
+
};
|
|
50705
|
+
}
|
|
50706
|
+
const base$6 = declarativeRestConnector({
|
|
50707
|
+
kind: "x-ads",
|
|
50708
|
+
displayName: "X Ads",
|
|
50709
|
+
description: "Manage X paid campaigns with total budgets, scheduled line items, targeting, promoted posts, and spend reports.",
|
|
50710
|
+
auth: {
|
|
50711
|
+
kind: "api-key",
|
|
50712
|
+
hint: "JSON OAuth 1.0a credential bundle: consumerKey, consumerSecret, accessToken, accessTokenSecret. Requires an Ads API approved application and advertiser user access. Twitter OAuth 2.0 tokens do not work."
|
|
50713
|
+
},
|
|
50714
|
+
credentialPlacement: { kind: "oauth1" },
|
|
50715
|
+
category: "other",
|
|
50716
|
+
defaultConsistencyModel: "cache",
|
|
50717
|
+
baseUrl: "https://ads-api.x.com/12",
|
|
50718
|
+
credentialsExpiredStatuses: [401],
|
|
50719
|
+
test: {
|
|
50720
|
+
method: "GET",
|
|
50721
|
+
path: "/accounts",
|
|
50722
|
+
query: { count: 1 }
|
|
50723
|
+
},
|
|
50724
|
+
capabilities: [
|
|
50725
|
+
{
|
|
50726
|
+
name: "accounts.list",
|
|
50727
|
+
class: "read",
|
|
50728
|
+
description: "Discover accessible advertising accounts, approval status and timezone. Follow next_cursor.",
|
|
50729
|
+
parameters: parameters$7(page$6),
|
|
50730
|
+
request: {
|
|
50731
|
+
method: "GET",
|
|
50732
|
+
path: "/accounts",
|
|
50733
|
+
query: {
|
|
50734
|
+
count: "{count}",
|
|
50735
|
+
cursor: "{cursor}"
|
|
50736
|
+
}
|
|
50737
|
+
}
|
|
50738
|
+
},
|
|
50739
|
+
...[
|
|
50740
|
+
"funding_instruments",
|
|
50741
|
+
"campaigns",
|
|
50742
|
+
"line_items",
|
|
50743
|
+
"promoted_tweets",
|
|
50744
|
+
"promotable_users",
|
|
50745
|
+
"authenticated_user_access"
|
|
50746
|
+
].map((resource) => ({
|
|
50747
|
+
name: {
|
|
50748
|
+
funding_instruments: "fundingInstruments.list",
|
|
50749
|
+
campaigns: "campaigns.list",
|
|
50750
|
+
line_items: "lineItems.list",
|
|
50751
|
+
promoted_tweets: "ads.list",
|
|
50752
|
+
promotable_users: "accounts.promotableUsers",
|
|
50753
|
+
authenticated_user_access: "accounts.authenticatedUserAccess"
|
|
50754
|
+
}[resource],
|
|
50755
|
+
class: "read",
|
|
50756
|
+
description: `Read ${resource} with native IDs, status, budget and pagination. Funding instruments include currency and funding readiness.`,
|
|
50757
|
+
parameters: parameters$7({
|
|
50758
|
+
accountId: id$12,
|
|
50759
|
+
...page$6
|
|
50760
|
+
}, ["accountId"]),
|
|
50761
|
+
request: {
|
|
50762
|
+
method: "GET",
|
|
50763
|
+
path: `${accountPath$1}/${resource}`,
|
|
50764
|
+
query: {
|
|
50765
|
+
count: "{count}",
|
|
50766
|
+
cursor: "{cursor}"
|
|
50767
|
+
}
|
|
50768
|
+
}
|
|
50769
|
+
})),
|
|
50770
|
+
{
|
|
50771
|
+
name: "campaigns.get",
|
|
50772
|
+
class: "read",
|
|
50773
|
+
description: "Read the campaign budget and status before launch and after changes.",
|
|
50774
|
+
parameters: parameters$7({
|
|
50775
|
+
accountId: id$12,
|
|
50776
|
+
campaignId: id$12
|
|
50777
|
+
}, ["accountId", "campaignId"]),
|
|
50778
|
+
request: {
|
|
50779
|
+
method: "GET",
|
|
50780
|
+
path: `${accountPath$1}/campaigns/{campaignId}`
|
|
50781
|
+
}
|
|
50782
|
+
},
|
|
50783
|
+
write$5("campaigns.create", "Create a PAUSED campaign with a required total budget. Verify currency and funding first. Line items own the serving schedule.", "/campaigns", {
|
|
50784
|
+
name: text$8,
|
|
50785
|
+
fundingInstrumentId: id$12,
|
|
50786
|
+
totalBudgetMicros: micros$3,
|
|
50787
|
+
dailyBudgetMicros: micros$3
|
|
50788
|
+
}, [
|
|
50789
|
+
"name",
|
|
50790
|
+
"fundingInstrumentId",
|
|
50791
|
+
"totalBudgetMicros",
|
|
50792
|
+
"dailyBudgetMicros"
|
|
50793
|
+
], {
|
|
50794
|
+
name: "{name}",
|
|
50795
|
+
funding_instrument_id: "{fundingInstrumentId}",
|
|
50796
|
+
total_budget_amount_local_micro: "{totalBudgetMicros}",
|
|
50797
|
+
daily_budget_amount_local_micro: "{dailyBudgetMicros}",
|
|
50798
|
+
budget_optimization: "LINE_ITEM",
|
|
50799
|
+
entity_status: "PAUSED"
|
|
50800
|
+
}),
|
|
50801
|
+
write$5("campaigns.enable", "Launch a campaign under an explicit cumulative total budget and daily budget. Active line items may spend immediately. Verify all line-item schedules, targeting, creative review and authorization first.", "/campaigns/{campaignId}", {
|
|
50802
|
+
campaignId: id$12,
|
|
50803
|
+
totalBudgetMicros: micros$3,
|
|
50804
|
+
dailyBudgetMicros: micros$3
|
|
50805
|
+
}, [
|
|
50806
|
+
"campaignId",
|
|
50807
|
+
"totalBudgetMicros",
|
|
50808
|
+
"dailyBudgetMicros"
|
|
50809
|
+
], {
|
|
50810
|
+
entity_status: "ACTIVE",
|
|
50811
|
+
total_budget_amount_local_micro: "{totalBudgetMicros}",
|
|
50812
|
+
daily_budget_amount_local_micro: "{dailyBudgetMicros}"
|
|
50813
|
+
}, "PUT"),
|
|
50814
|
+
write$5("campaigns.pause", "Pause the campaign. Read back status and reporting; billing metrics can lag.", "/campaigns/{campaignId}", { campaignId: id$12 }, ["campaignId"], { entity_status: "PAUSED" }, "PUT"),
|
|
50815
|
+
write$5("lineItems.createTraffic", "Create a PAUSED website-clicks line item with a fixed schedule, total budget and maximum CPC bid. The parent campaign budget also constrains spend.", "/line_items", {
|
|
50816
|
+
campaignId: id$12,
|
|
50817
|
+
name: text$8,
|
|
50818
|
+
startTime: time$4,
|
|
50819
|
+
endTime: time$4,
|
|
50820
|
+
totalBudgetMicros: micros$3,
|
|
50821
|
+
bidMicros: micros$3
|
|
50822
|
+
}, [
|
|
50823
|
+
"campaignId",
|
|
50824
|
+
"name",
|
|
50825
|
+
"startTime",
|
|
50826
|
+
"endTime",
|
|
50827
|
+
"totalBudgetMicros",
|
|
50828
|
+
"bidMicros"
|
|
50829
|
+
], {
|
|
50830
|
+
campaign_id: "{campaignId}",
|
|
50831
|
+
name: "{name}",
|
|
50832
|
+
start_time: "{startTime}",
|
|
50833
|
+
end_time: "{endTime}",
|
|
50834
|
+
total_budget_amount_local_micro: "{totalBudgetMicros}",
|
|
50835
|
+
bid_amount_local_micro: "{bidMicros}",
|
|
50836
|
+
product_type: "PROMOTED_TWEETS",
|
|
50837
|
+
objective: "WEBSITE_CLICKS",
|
|
50838
|
+
placements: "ALL_ON_TWITTER",
|
|
50839
|
+
goal: "LINK_CLICKS",
|
|
50840
|
+
bid_strategy: "MAX",
|
|
50841
|
+
standard_delivery: true,
|
|
50842
|
+
entity_status: "PAUSED"
|
|
50843
|
+
}),
|
|
50844
|
+
...["ACTIVE", "PAUSED"].map((status) => write$5(status === "ACTIVE" ? "lineItems.enable" : "lineItems.pause", status === "ACTIVE" ? "Enable a line item; can spend immediately if the campaign is active. Confirm its native total budget and fixed schedule first." : "Pause a line item.", "/line_items/{lineItemId}", { lineItemId: id$12 }, ["lineItemId"], { entity_status: status }, "PUT")),
|
|
50845
|
+
{
|
|
50846
|
+
name: "targeting.locations",
|
|
50847
|
+
class: "read",
|
|
50848
|
+
description: "Find geographic targeting IDs. Use returned targeting_value in targeting.add.",
|
|
50849
|
+
parameters: parameters$7({
|
|
50850
|
+
query: text$8,
|
|
50851
|
+
locationType: {
|
|
50852
|
+
type: "string",
|
|
50853
|
+
enum: [
|
|
50854
|
+
"COUNTRIES",
|
|
50855
|
+
"REGIONS",
|
|
50856
|
+
"METROS",
|
|
50857
|
+
"CITIES",
|
|
50858
|
+
"POSTAL_CODES"
|
|
50859
|
+
]
|
|
50860
|
+
}
|
|
50861
|
+
}, ["query"]),
|
|
50862
|
+
request: {
|
|
50863
|
+
method: "GET",
|
|
50864
|
+
path: "/targeting_criteria/locations",
|
|
50865
|
+
query: {
|
|
50866
|
+
q: "{query}",
|
|
50867
|
+
location_type: "{locationType}"
|
|
50868
|
+
}
|
|
50869
|
+
}
|
|
50870
|
+
},
|
|
50871
|
+
write$5("targeting.add", "Add a location, keyword, language, or follower targeting criterion to a line item. Use discovered native values.", "/targeting_criteria", {
|
|
50872
|
+
lineItemId: id$12,
|
|
50873
|
+
targetingType: {
|
|
50874
|
+
type: "string",
|
|
50875
|
+
enum: [
|
|
50876
|
+
"LOCATION",
|
|
50877
|
+
"PHRASE_KEYWORD",
|
|
50878
|
+
"EXACT_KEYWORD",
|
|
50879
|
+
"BROAD_KEYWORD",
|
|
50880
|
+
"LANGUAGE",
|
|
50881
|
+
"FOLLOWERS_OF_USER"
|
|
50882
|
+
]
|
|
50883
|
+
},
|
|
50884
|
+
targetingValue: {
|
|
50885
|
+
type: "string",
|
|
50886
|
+
minLength: 1
|
|
50887
|
+
}
|
|
50888
|
+
}, [
|
|
50889
|
+
"lineItemId",
|
|
50890
|
+
"targetingType",
|
|
50891
|
+
"targetingValue"
|
|
50892
|
+
], {
|
|
50893
|
+
line_item_id: "{lineItemId}",
|
|
50894
|
+
targeting_type: "{targetingType}",
|
|
50895
|
+
targeting_value: "{targetingValue}"
|
|
50896
|
+
}),
|
|
50897
|
+
write$5("posts.createPromotedOnly", "Create a promoted-only post with text and an optional pre-uploaded card or media. It does not appear on the organic timeline; attach it to a paused line item next.", "/tweet", {
|
|
50898
|
+
advertiserUserId: {
|
|
50899
|
+
type: "string",
|
|
50900
|
+
pattern: "^[0-9]+$",
|
|
50901
|
+
description: "Promotable advertiser user ID from accounts.promotableUsers. The connected user needs TWEET_COMPOSER permission."
|
|
50902
|
+
},
|
|
50903
|
+
text: {
|
|
50904
|
+
type: "string",
|
|
50905
|
+
minLength: 1,
|
|
50906
|
+
maxLength: 280
|
|
50907
|
+
},
|
|
50908
|
+
cardUri: { type: "string" },
|
|
50909
|
+
mediaKeys: {
|
|
50910
|
+
type: "string",
|
|
50911
|
+
pattern: "^[0-9]+_[0-9]+(,[0-9]+_[0-9]+){0,3}$",
|
|
50912
|
+
description: "Comma-separated media keys already uploaded for the advertiser."
|
|
50913
|
+
}
|
|
50914
|
+
}, ["advertiserUserId", "text"], {
|
|
50915
|
+
as_user_id: "{advertiserUserId}",
|
|
50916
|
+
text: "{text}",
|
|
50917
|
+
card_uri: "{cardUri}",
|
|
50918
|
+
media_keys: "{mediaKeys}",
|
|
50919
|
+
nullcast: true
|
|
50920
|
+
}),
|
|
50921
|
+
write$5("ads.promotePost", "Attach one existing or promoted-only post to a line item. Keep the parent paused while preparing; an active line item can serve this immediately.", "/promoted_tweets", {
|
|
50922
|
+
lineItemId: id$12,
|
|
50923
|
+
tweetId: {
|
|
50924
|
+
type: "string",
|
|
50925
|
+
pattern: "^[0-9]+$"
|
|
50926
|
+
}
|
|
50927
|
+
}, ["lineItemId", "tweetId"], {
|
|
50928
|
+
line_item_id: "{lineItemId}",
|
|
50929
|
+
tweet_ids: "{tweetId}"
|
|
50930
|
+
}),
|
|
50931
|
+
{
|
|
50932
|
+
name: "reports.stats",
|
|
50933
|
+
class: "read",
|
|
50934
|
+
description: "Read synchronous campaign, line-item or promoted-post spend, engagement and web conversion metrics. Use ranges of at most 7 days; billing metrics can be revised for three days.",
|
|
50935
|
+
parameters: parameters$7({
|
|
50936
|
+
accountId: id$12,
|
|
50937
|
+
entity: {
|
|
50938
|
+
type: "string",
|
|
50939
|
+
enum: [
|
|
50940
|
+
"CAMPAIGN",
|
|
50941
|
+
"LINE_ITEM",
|
|
50942
|
+
"PROMOTED_TWEET"
|
|
50943
|
+
]
|
|
50944
|
+
},
|
|
50945
|
+
entityIds: {
|
|
50946
|
+
type: "string",
|
|
50947
|
+
pattern: "^[a-zA-Z0-9]+(,[a-zA-Z0-9]+){0,19}$"
|
|
50948
|
+
},
|
|
50949
|
+
startTime: time$4,
|
|
50950
|
+
endTime: time$4,
|
|
50951
|
+
granularity: {
|
|
50952
|
+
type: "string",
|
|
50953
|
+
enum: [
|
|
50954
|
+
"TOTAL",
|
|
50955
|
+
"DAY",
|
|
50956
|
+
"HOUR"
|
|
50957
|
+
]
|
|
50958
|
+
}
|
|
50959
|
+
}, [
|
|
50960
|
+
"accountId",
|
|
50961
|
+
"entity",
|
|
50962
|
+
"entityIds",
|
|
50963
|
+
"startTime",
|
|
50964
|
+
"endTime",
|
|
50965
|
+
"granularity"
|
|
50966
|
+
]),
|
|
50967
|
+
request: {
|
|
50968
|
+
method: "GET",
|
|
50969
|
+
path: "/stats/accounts/{accountId}",
|
|
50970
|
+
query: {
|
|
50971
|
+
entity: "{entity}",
|
|
50972
|
+
entity_ids: "{entityIds}",
|
|
50973
|
+
start_time: "{startTime}",
|
|
50974
|
+
end_time: "{endTime}",
|
|
50975
|
+
granularity: "{granularity}",
|
|
50976
|
+
placement: "ALL_ON_TWITTER",
|
|
50977
|
+
metric_groups: "ENGAGEMENT,BILLING,WEB_CONVERSION"
|
|
50978
|
+
}
|
|
50979
|
+
}
|
|
50980
|
+
}
|
|
50981
|
+
]
|
|
50982
|
+
});
|
|
50983
|
+
const xAdsConnector = {
|
|
50984
|
+
...base$6,
|
|
50985
|
+
async executeMutation(inv) {
|
|
50986
|
+
for (const key of [
|
|
50987
|
+
"totalBudgetMicros",
|
|
50988
|
+
"dailyBudgetMicros",
|
|
50989
|
+
"bidMicros"
|
|
50990
|
+
]) if (inv.args[key] !== void 0 && (typeof inv.args[key] !== "string" || !/^[1-9][0-9]*$/.test(inv.args[key]))) throw new Error(`x-ads: ${key} must be positive integer microcurrency`);
|
|
50991
|
+
if (typeof inv.args.dailyBudgetMicros === "string" && typeof inv.args.totalBudgetMicros === "string" && BigInt(inv.args.dailyBudgetMicros) > BigInt(inv.args.totalBudgetMicros)) throw new Error("x-ads: daily budget exceeds total budget");
|
|
50992
|
+
if (inv.capabilityName === "lineItems.createTraffic" && !(typeof inv.args.startTime === "string" && typeof inv.args.endTime === "string" && Date.parse(inv.args.endTime) > Date.parse(inv.args.startTime))) throw new Error("x-ads: endTime must be after startTime");
|
|
50993
|
+
const result = await base$6.executeMutation(inv);
|
|
50994
|
+
if (result.status === "committed") {
|
|
50995
|
+
const envelope = result.data;
|
|
50996
|
+
const records = isPlainRecord(envelope) ? Array.isArray(envelope.data) ? envelope.data : [envelope.data] : [];
|
|
50997
|
+
if (!isPlainRecord(envelope) || envelope.errors || records.length === 0 || !records.every((item) => isPlainRecord(item) && (typeof item.id === "string" && item.id.length > 0 || typeof item.id_str === "string" && item.id_str.length > 0))) throw new Error("x-ads: missing native mutation receipt or provider error; reconcile state before retrying");
|
|
50998
|
+
}
|
|
50999
|
+
return result;
|
|
51000
|
+
}
|
|
51001
|
+
};
|
|
51002
|
+
//#endregion
|
|
51003
|
+
//#region src/connectors/adapters/tiktok-ads.ts
|
|
51004
|
+
const id$11 = {
|
|
51005
|
+
type: "string",
|
|
51006
|
+
pattern: "^[0-9]+$"
|
|
51007
|
+
};
|
|
51008
|
+
const text$7 = {
|
|
51009
|
+
type: "string",
|
|
51010
|
+
minLength: 1
|
|
51011
|
+
};
|
|
51012
|
+
const budget = {
|
|
51013
|
+
type: "number",
|
|
51014
|
+
exclusiveMinimum: 0,
|
|
51015
|
+
description: "Total budget in advertiser currency units, not cents or micros. TikTok minimums depend on currency and flight length."
|
|
51016
|
+
};
|
|
51017
|
+
const time$3 = {
|
|
51018
|
+
type: "string",
|
|
51019
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
|
|
51020
|
+
description: "yyyy-MM-dd HH:mm:ss in the advertiser timezone."
|
|
51021
|
+
};
|
|
51022
|
+
const ids = {
|
|
51023
|
+
type: "array",
|
|
51024
|
+
minItems: 1,
|
|
51025
|
+
maxItems: 100,
|
|
51026
|
+
items: id$11
|
|
51027
|
+
};
|
|
51028
|
+
const pagination$4 = {
|
|
51029
|
+
page: {
|
|
51030
|
+
type: "integer",
|
|
51031
|
+
minimum: 1
|
|
51032
|
+
},
|
|
51033
|
+
pageSize: {
|
|
51034
|
+
type: "integer",
|
|
51035
|
+
minimum: 1,
|
|
51036
|
+
maximum: 100
|
|
51037
|
+
}
|
|
51038
|
+
};
|
|
51039
|
+
function parameters$6(properties, required = []) {
|
|
51040
|
+
return {
|
|
51041
|
+
type: "object",
|
|
51042
|
+
properties,
|
|
51043
|
+
required,
|
|
51044
|
+
additionalProperties: false
|
|
51045
|
+
};
|
|
51046
|
+
}
|
|
51047
|
+
function mutation$1(name, description, properties, required, path, body) {
|
|
51048
|
+
return {
|
|
51049
|
+
name,
|
|
51050
|
+
description,
|
|
51051
|
+
class: "mutation",
|
|
51052
|
+
cas: "none",
|
|
51053
|
+
externalEffect: true,
|
|
51054
|
+
parameters: parameters$6({
|
|
51055
|
+
advertiserId: id$11,
|
|
51056
|
+
...properties
|
|
51057
|
+
}, ["advertiserId", ...required]),
|
|
51058
|
+
request: {
|
|
51059
|
+
method: "POST",
|
|
51060
|
+
path,
|
|
51061
|
+
body: {
|
|
51062
|
+
advertiser_id: "{advertiserId}",
|
|
51063
|
+
...body
|
|
51064
|
+
}
|
|
51065
|
+
}
|
|
51066
|
+
};
|
|
51067
|
+
}
|
|
51068
|
+
const base$5 = declarativeRestConnector({
|
|
51069
|
+
kind: "tiktok-ads",
|
|
51070
|
+
displayName: "TikTok Ads",
|
|
51071
|
+
description: "Operate TikTok Marketing API traffic campaigns, lifetime budgets, targeted ad groups, video ads and paid performance reports.",
|
|
51072
|
+
auth: {
|
|
51073
|
+
kind: "api-key",
|
|
51074
|
+
hint: "JSON secret bundle with accessToken, appId and appSecret from your approved TikTok API for Business app. This is separate from TikTok creator OAuth. Keep all three in this secret field."
|
|
51075
|
+
},
|
|
51076
|
+
category: "other",
|
|
51077
|
+
defaultConsistencyModel: "cache",
|
|
51078
|
+
baseUrl: "https://business-api.tiktok.com/open_api/v1.3",
|
|
51079
|
+
credentialPlacement: {
|
|
51080
|
+
kind: "structured-headers",
|
|
51081
|
+
fields: { accessToken: "Access-Token" }
|
|
51082
|
+
},
|
|
51083
|
+
credentialsExpiredStatuses: [401],
|
|
51084
|
+
capabilities: [
|
|
51085
|
+
{
|
|
51086
|
+
name: "advertisers.list",
|
|
51087
|
+
class: "read",
|
|
51088
|
+
description: "Discover advertisers that granted this Business API app access. Uses app credentials only from the encrypted connection secret.",
|
|
51089
|
+
parameters: parameters$6({}),
|
|
51090
|
+
request: {
|
|
51091
|
+
method: "GET",
|
|
51092
|
+
path: "/oauth2/advertiser/get/"
|
|
51093
|
+
}
|
|
51094
|
+
},
|
|
51095
|
+
{
|
|
51096
|
+
name: "advertisers.get",
|
|
51097
|
+
class: "read",
|
|
51098
|
+
description: "Read advertiser currency, timezone and account details before choosing budgets or schedules.",
|
|
51099
|
+
parameters: parameters$6({ advertiserIds: ids }, ["advertiserIds"]),
|
|
51100
|
+
request: {
|
|
51101
|
+
method: "GET",
|
|
51102
|
+
path: "/advertiser/info/",
|
|
51103
|
+
query: { advertiser_ids: "{advertiserIdsJson}" }
|
|
51104
|
+
}
|
|
51105
|
+
},
|
|
51106
|
+
...[
|
|
51107
|
+
"campaign",
|
|
51108
|
+
"adgroup",
|
|
51109
|
+
"ad"
|
|
51110
|
+
].map((entity) => ({
|
|
51111
|
+
name: `${entity}s.list`,
|
|
51112
|
+
class: "read",
|
|
51113
|
+
description: `Read ${entity} IDs, provider status and setup. Follow page_info; filters are deliberately bounded to a single optional native ID.`,
|
|
51114
|
+
parameters: parameters$6({
|
|
51115
|
+
advertiserId: id$11,
|
|
51116
|
+
objectId: id$11,
|
|
51117
|
+
...pagination$4
|
|
51118
|
+
}, ["advertiserId"]),
|
|
51119
|
+
request: {
|
|
51120
|
+
method: "GET",
|
|
51121
|
+
path: `/${entity}/get/`,
|
|
51122
|
+
query: {
|
|
51123
|
+
advertiser_id: "{advertiserId}",
|
|
51124
|
+
filtering: "{filteringJson}",
|
|
51125
|
+
page: "{page}",
|
|
51126
|
+
page_size: "{pageSize}"
|
|
51127
|
+
}
|
|
51128
|
+
}
|
|
51129
|
+
})),
|
|
51130
|
+
{
|
|
51131
|
+
name: "identities.list",
|
|
51132
|
+
class: "read",
|
|
51133
|
+
description: "Discover authorized advertiser identities for video creatives. A Business Center identity additionally needs identityAuthorizedBcId.",
|
|
51134
|
+
parameters: parameters$6({
|
|
51135
|
+
advertiserId: id$11,
|
|
51136
|
+
identityType: {
|
|
51137
|
+
type: "string",
|
|
51138
|
+
enum: [
|
|
51139
|
+
"CUSTOMIZED_USER",
|
|
51140
|
+
"AUTH_CODE",
|
|
51141
|
+
"TT_USER",
|
|
51142
|
+
"BC_AUTH_TT"
|
|
51143
|
+
]
|
|
51144
|
+
},
|
|
51145
|
+
identityAuthorizedBcId: id$11,
|
|
51146
|
+
...pagination$4
|
|
51147
|
+
}, ["advertiserId"]),
|
|
51148
|
+
request: {
|
|
51149
|
+
method: "GET",
|
|
51150
|
+
path: "/identity/get/",
|
|
51151
|
+
query: {
|
|
51152
|
+
advertiser_id: "{advertiserId}",
|
|
51153
|
+
identity_type: "{identityType}",
|
|
51154
|
+
identity_authorized_bc_id: "{identityAuthorizedBcId}",
|
|
51155
|
+
page: "{page}",
|
|
51156
|
+
page_size: "{pageSize}"
|
|
51157
|
+
}
|
|
51158
|
+
}
|
|
51159
|
+
},
|
|
51160
|
+
{
|
|
51161
|
+
name: "targeting.locations",
|
|
51162
|
+
class: "read",
|
|
51163
|
+
description: "Discover location IDs available for this advertiser before creating an ad group.",
|
|
51164
|
+
parameters: parameters$6({ advertiserId: id$11 }, ["advertiserId"]),
|
|
51165
|
+
request: {
|
|
51166
|
+
method: "GET",
|
|
51167
|
+
path: "/search/region/",
|
|
51168
|
+
query: { advertiser_id: "{advertiserId}" }
|
|
51169
|
+
}
|
|
51170
|
+
},
|
|
51171
|
+
{
|
|
51172
|
+
name: "videos.list",
|
|
51173
|
+
class: "read",
|
|
51174
|
+
description: "Read available advertiser video assets and their provider video IDs. Follow page_info.",
|
|
51175
|
+
parameters: parameters$6({
|
|
51176
|
+
advertiserId: id$11,
|
|
51177
|
+
...pagination$4
|
|
51178
|
+
}, ["advertiserId"]),
|
|
51179
|
+
request: {
|
|
51180
|
+
method: "GET",
|
|
51181
|
+
path: "/file/video/ad/search/",
|
|
51182
|
+
query: {
|
|
51183
|
+
advertiser_id: "{advertiserId}",
|
|
51184
|
+
page: "{page}",
|
|
51185
|
+
page_size: "{pageSize}"
|
|
51186
|
+
}
|
|
51187
|
+
}
|
|
51188
|
+
},
|
|
51189
|
+
mutation$1("videos.uploadFromUrl", "Ask TikTok to import a video from a public HTTPS URL into the advertiser Asset Library. Check videos.list for processing/availability before creating an ad.", {
|
|
51190
|
+
filename: text$7,
|
|
51191
|
+
videoUrl: {
|
|
51192
|
+
type: "string",
|
|
51193
|
+
format: "uri",
|
|
51194
|
+
pattern: "^https://"
|
|
51195
|
+
}
|
|
51196
|
+
}, ["filename", "videoUrl"], "/file/video/ad/upload/", {}),
|
|
51197
|
+
mutation$1("campaigns.createTraffic", "Create a DISABLED traffic campaign with a total (lifetime) budget. No automatic budget increase. Verify provider minimums and account currency before creation.", {
|
|
51198
|
+
name: text$7,
|
|
51199
|
+
totalBudget: budget
|
|
51200
|
+
}, ["name", "totalBudget"], "/campaign/create/", {
|
|
51201
|
+
campaign_name: "{name}",
|
|
51202
|
+
objective_type: "TRAFFIC",
|
|
51203
|
+
budget_mode: "BUDGET_MODE_TOTAL",
|
|
51204
|
+
budget: "{totalBudget}",
|
|
51205
|
+
operation_status: "DISABLE",
|
|
51206
|
+
budget_optimize_on: false
|
|
51207
|
+
}),
|
|
51208
|
+
mutation$1("adgroups.createTraffic", "Create a DISABLED website-traffic ad group using a fixed lifetime budget, start/end, approved location IDs and TikTok placement. Keep its parent campaign disabled until review.", {
|
|
51209
|
+
campaignId: id$11,
|
|
51210
|
+
name: text$7,
|
|
51211
|
+
totalBudget: budget,
|
|
51212
|
+
startTime: time$3,
|
|
51213
|
+
endTime: time$3,
|
|
51214
|
+
locationIds: ids,
|
|
51215
|
+
bidPrice: {
|
|
51216
|
+
type: "number",
|
|
51217
|
+
exclusiveMinimum: 0,
|
|
51218
|
+
description: "Maximum CPC bid in advertiser currency units."
|
|
51219
|
+
}
|
|
51220
|
+
}, [
|
|
51221
|
+
"campaignId",
|
|
51222
|
+
"name",
|
|
51223
|
+
"totalBudget",
|
|
51224
|
+
"startTime",
|
|
51225
|
+
"endTime",
|
|
51226
|
+
"locationIds",
|
|
51227
|
+
"bidPrice"
|
|
51228
|
+
], "/adgroup/create/", {
|
|
51229
|
+
campaign_id: "{campaignId}",
|
|
51230
|
+
adgroup_name: "{name}",
|
|
51231
|
+
operation_status: "DISABLE",
|
|
51232
|
+
promotion_type: "WEBSITE",
|
|
51233
|
+
placement_type: "PLACEMENT_TYPE_NORMAL",
|
|
51234
|
+
placements: ["PLACEMENT_TIKTOK"],
|
|
51235
|
+
location_ids: "{locationIds}",
|
|
51236
|
+
budget_mode: "BUDGET_MODE_TOTAL",
|
|
51237
|
+
budget: "{totalBudget}",
|
|
51238
|
+
schedule_type: "SCHEDULE_START_END",
|
|
51239
|
+
schedule_start_time: "{startTime}",
|
|
51240
|
+
schedule_end_time: "{endTime}",
|
|
51241
|
+
optimization_goal: "CLICK",
|
|
51242
|
+
billing_event: "CPC",
|
|
51243
|
+
bid_type: "BID_TYPE_CUSTOM",
|
|
51244
|
+
bid_price: "{bidPrice}",
|
|
51245
|
+
pacing: "PACING_MODE_SMOOTH"
|
|
51246
|
+
}),
|
|
51247
|
+
mutation$1("ads.createVideo", "Create one DISABLED video ad from an existing advertiser video asset and authorized identity. Import media with videos.uploadFromUrl first; review and active ancestors are required to serve.", {
|
|
51248
|
+
adgroupId: id$11,
|
|
51249
|
+
name: text$7,
|
|
51250
|
+
adText: {
|
|
51251
|
+
...text$7,
|
|
51252
|
+
maxLength: 100
|
|
51253
|
+
},
|
|
51254
|
+
videoId: text$7,
|
|
51255
|
+
identityId: text$7,
|
|
51256
|
+
identityType: {
|
|
51257
|
+
type: "string",
|
|
51258
|
+
enum: [
|
|
51259
|
+
"CUSTOMIZED_USER",
|
|
51260
|
+
"AUTH_CODE",
|
|
51261
|
+
"TT_USER",
|
|
51262
|
+
"BC_AUTH_TT"
|
|
51263
|
+
]
|
|
51264
|
+
},
|
|
51265
|
+
identityAuthorizedBcId: id$11,
|
|
51266
|
+
landingPageUrl: {
|
|
51267
|
+
type: "string",
|
|
51268
|
+
format: "uri",
|
|
51269
|
+
pattern: "^https://"
|
|
51270
|
+
},
|
|
51271
|
+
callToAction: {
|
|
51272
|
+
type: "string",
|
|
51273
|
+
enum: [
|
|
51274
|
+
"LEARN_MORE",
|
|
51275
|
+
"SIGN_UP",
|
|
51276
|
+
"SHOP_NOW",
|
|
51277
|
+
"CONTACT_US",
|
|
51278
|
+
"DOWNLOAD",
|
|
51279
|
+
"BOOK_NOW",
|
|
51280
|
+
"APPLY_NOW"
|
|
51281
|
+
]
|
|
51282
|
+
}
|
|
51283
|
+
}, [
|
|
51284
|
+
"adgroupId",
|
|
51285
|
+
"name",
|
|
51286
|
+
"adText",
|
|
51287
|
+
"videoId",
|
|
51288
|
+
"identityId",
|
|
51289
|
+
"identityType",
|
|
51290
|
+
"landingPageUrl",
|
|
51291
|
+
"callToAction"
|
|
51292
|
+
], "/ad/create/", {
|
|
51293
|
+
adgroup_id: "{adgroupId}",
|
|
51294
|
+
creatives: [{
|
|
51295
|
+
ad_name: "{name}",
|
|
51296
|
+
ad_text: "{adText}",
|
|
51297
|
+
ad_format: "SINGLE_VIDEO",
|
|
51298
|
+
video_id: "{videoId}",
|
|
51299
|
+
identity_id: "{identityId}",
|
|
51300
|
+
identity_type: "{identityType}",
|
|
51301
|
+
identity_authorized_bc_id: "{identityAuthorizedBcId}",
|
|
51302
|
+
landing_page_url: "{landingPageUrl}",
|
|
51303
|
+
call_to_action: "{callToAction}",
|
|
51304
|
+
operation_status: "DISABLE"
|
|
51305
|
+
}]
|
|
51306
|
+
}),
|
|
51307
|
+
...[
|
|
51308
|
+
"campaign",
|
|
51309
|
+
"adgroup",
|
|
51310
|
+
"ad"
|
|
51311
|
+
].flatMap((entity) => ["ENABLE", "DISABLE"].map((status) => mutation$1(`${entity}s.${status === "ENABLE" ? "enable" : "pause"}`, status === "ENABLE" ? "Enable delivery after checking approval, billing, review, targeting, total budget and flight. This can immediately spend within active ancestors." : "Disable delivery without changing the budget. Re-read status and report after stopping.", { objectId: id$11 }, ["objectId"], `/${entity}/status/update/`, {
|
|
51312
|
+
[`${entity}_ids`]: ["{objectId}"],
|
|
51313
|
+
operation_status: status
|
|
51314
|
+
}))),
|
|
51315
|
+
{
|
|
51316
|
+
name: "reports.integrated",
|
|
51317
|
+
class: "read",
|
|
51318
|
+
description: "Read paginated BASIC campaign, ad-group or ad performance with spend, clicks and configured conversion metrics. Amounts use advertiser currency; attributed conversions are not confirmed revenue.",
|
|
51319
|
+
parameters: parameters$6({
|
|
51320
|
+
advertiserId: id$11,
|
|
51321
|
+
dataLevel: {
|
|
51322
|
+
type: "string",
|
|
51323
|
+
enum: [
|
|
51324
|
+
"AUCTION_CAMPAIGN",
|
|
51325
|
+
"AUCTION_ADGROUP",
|
|
51326
|
+
"AUCTION_AD"
|
|
51327
|
+
]
|
|
51328
|
+
},
|
|
51329
|
+
startDate: {
|
|
51330
|
+
type: "string",
|
|
51331
|
+
format: "date"
|
|
51332
|
+
},
|
|
51333
|
+
endDate: {
|
|
51334
|
+
type: "string",
|
|
51335
|
+
format: "date"
|
|
51336
|
+
},
|
|
51337
|
+
metrics: {
|
|
51338
|
+
type: "array",
|
|
51339
|
+
minItems: 1,
|
|
51340
|
+
maxItems: 20,
|
|
51341
|
+
items: {
|
|
51342
|
+
type: "string",
|
|
51343
|
+
enum: [
|
|
51344
|
+
"spend",
|
|
51345
|
+
"impressions",
|
|
51346
|
+
"clicks",
|
|
51347
|
+
"ctr",
|
|
51348
|
+
"cpc",
|
|
51349
|
+
"cpm",
|
|
51350
|
+
"conversion",
|
|
51351
|
+
"cost_per_conversion",
|
|
51352
|
+
"conversion_rate"
|
|
51353
|
+
]
|
|
51354
|
+
}
|
|
51355
|
+
},
|
|
51356
|
+
...pagination$4
|
|
51357
|
+
}, [
|
|
51358
|
+
"advertiserId",
|
|
51359
|
+
"dataLevel",
|
|
51360
|
+
"startDate",
|
|
51361
|
+
"endDate",
|
|
51362
|
+
"metrics"
|
|
51363
|
+
]),
|
|
51364
|
+
request: {
|
|
51365
|
+
method: "GET",
|
|
51366
|
+
path: "/report/integrated/get/",
|
|
51367
|
+
query: {
|
|
51368
|
+
advertiser_id: "{advertiserId}",
|
|
51369
|
+
report_type: "BASIC",
|
|
51370
|
+
data_level: "{dataLevel}",
|
|
51371
|
+
dimensions: "{dimensionsJson}",
|
|
51372
|
+
metrics: "{metricsJson}",
|
|
51373
|
+
start_date: "{startDate}",
|
|
51374
|
+
end_date: "{endDate}",
|
|
51375
|
+
page: "{page}",
|
|
51376
|
+
page_size: "{pageSize}"
|
|
51377
|
+
}
|
|
51378
|
+
}
|
|
51379
|
+
}
|
|
51380
|
+
]
|
|
51381
|
+
});
|
|
51382
|
+
function prepare$1(inv) {
|
|
51383
|
+
const a = inv.args;
|
|
51384
|
+
if (inv.capabilityName.endsWith(".createTraffic")) {
|
|
51385
|
+
if (typeof a.totalBudget !== "number" || !Number.isFinite(a.totalBudget) || a.totalBudget <= 0) throw new Error("tiktok-ads: totalBudget must be positive and finite");
|
|
51386
|
+
if (inv.capabilityName === "adgroups.createTraffic" && !(String(a.endTime) > String(a.startTime))) throw new Error("tiktok-ads: endTime must be after startTime");
|
|
51387
|
+
}
|
|
51388
|
+
if (inv.capabilityName === "ads.createVideo" && a.identityType === "BC_AUTH_TT" && !a.identityAuthorizedBcId) throw new Error("tiktok-ads: Business Center identity requires identityAuthorizedBcId");
|
|
51389
|
+
const entity = inv.capabilityName.split(".")[0].replace(/s$/, "");
|
|
51390
|
+
const dimension = a.dataLevel === "AUCTION_CAMPAIGN" ? "campaign_id" : a.dataLevel === "AUCTION_ADGROUP" ? "adgroup_id" : "ad_id";
|
|
51391
|
+
return {
|
|
51392
|
+
...inv,
|
|
51393
|
+
args: {
|
|
51394
|
+
...a,
|
|
51395
|
+
advertiserIdsJson: JSON.stringify(a.advertiserIds),
|
|
51396
|
+
metricsJson: JSON.stringify(a.metrics),
|
|
51397
|
+
dimensionsJson: JSON.stringify([dimension]),
|
|
51398
|
+
filteringJson: a.objectId ? JSON.stringify({ [`${entity}_ids`]: [a.objectId] }) : void 0
|
|
51399
|
+
}
|
|
51400
|
+
};
|
|
51401
|
+
}
|
|
51402
|
+
function assertEnvelope$1(value, allowArrayData = false) {
|
|
51403
|
+
if (!isPlainRecord(value) || typeof value.code !== "number") throw new Error("tiktok-ads: malformed provider response (missing numeric code)");
|
|
51404
|
+
if (value.code !== 0) throw new Error(`tiktok-ads: provider rejected request (code ${value.code})`);
|
|
51405
|
+
if (!isPlainRecord(value.data) && !(allowArrayData && Array.isArray(value.data) && value.data.every(isPlainRecord))) throw new Error("tiktok-ads: malformed provider response (missing data)");
|
|
51406
|
+
}
|
|
51407
|
+
function assertMutationReceipt$1(value, capability) {
|
|
51408
|
+
assertEnvelope$1(value, capability === "videos.uploadFromUrl");
|
|
51409
|
+
const data = value.data;
|
|
51410
|
+
const validId = (id) => typeof id === "string" && id.trim().length > 0;
|
|
51411
|
+
let valid = true;
|
|
51412
|
+
if (capability === "videos.uploadFromUrl") {
|
|
51413
|
+
const videos = Array.isArray(data) ? data : [data];
|
|
51414
|
+
valid = videos.length > 0 && videos.every((video) => isPlainRecord(video) && validId(video.video_id));
|
|
51415
|
+
} else if (isPlainRecord(data)) {
|
|
51416
|
+
if (capability === "campaigns.createTraffic") valid = validId(data.campaign_id);
|
|
51417
|
+
if (capability === "adgroups.createTraffic") valid = validId(data.adgroup_id);
|
|
51418
|
+
if (capability === "ads.createVideo") valid = Array.isArray(data.ad_ids) && data.ad_ids.length === 1 && data.ad_ids.every(validId);
|
|
51419
|
+
}
|
|
51420
|
+
if (!valid) throw new Error("tiktok-ads: missing native entity ID in mutation receipt; reconcile provider state before retrying");
|
|
51421
|
+
}
|
|
51422
|
+
function credentials(value) {
|
|
51423
|
+
let data = value.kind === "custom" ? value.values : void 0;
|
|
51424
|
+
if (value.kind === "api-key") try {
|
|
51425
|
+
data = JSON.parse(value.apiKey);
|
|
51426
|
+
} catch {
|
|
51427
|
+
throw new Error("tiktok-ads: connection secret must be a JSON bundle");
|
|
51428
|
+
}
|
|
51429
|
+
if (!isPlainRecord(data) || ![
|
|
51430
|
+
"accessToken",
|
|
51431
|
+
"appId",
|
|
51432
|
+
"appSecret"
|
|
51433
|
+
].every((key) => typeof data[key] === "string" && data[key].length > 0)) throw new Error("tiktok-ads: connection secret requires accessToken, appId and appSecret");
|
|
51434
|
+
return {
|
|
51435
|
+
accessToken: String(data.accessToken),
|
|
51436
|
+
appId: String(data.appId),
|
|
51437
|
+
appSecret: String(data.appSecret)
|
|
51438
|
+
};
|
|
51439
|
+
}
|
|
51440
|
+
async function discover(inv) {
|
|
51441
|
+
const secret = credentials(inv.source.credentials);
|
|
51442
|
+
const endpoint = new URL("https://business-api.tiktok.com/open_api/v1.3/oauth2/advertiser/get/");
|
|
51443
|
+
endpoint.searchParams.set("app_id", secret.appId);
|
|
51444
|
+
endpoint.searchParams.set("secret", secret.appSecret);
|
|
51445
|
+
const response = await fetch(endpoint, {
|
|
51446
|
+
headers: { "Access-Token": secret.accessToken },
|
|
51447
|
+
redirect: "error",
|
|
51448
|
+
signal: AbortSignal.timeout(2e4)
|
|
51449
|
+
}).catch(() => {
|
|
51450
|
+
throw new Error("tiktok-ads: advertiser discovery transport failed");
|
|
51451
|
+
});
|
|
51452
|
+
if (response.status === 401) throw new CredentialsExpired("TikTok Ads rejected credentials (401)", inv.source.id);
|
|
51453
|
+
if (response.status === 429) throw new ProviderRateLimited("TikTok Ads advertiser discovery rate limited", inv.source.id, {
|
|
51454
|
+
status: 429,
|
|
51455
|
+
retryAfterMs: 6e4
|
|
51456
|
+
});
|
|
51457
|
+
if (!response.ok) throw new Error(`tiktok-ads: advertiser discovery HTTP ${response.status}`);
|
|
51458
|
+
const data = await response.json().catch(() => null);
|
|
51459
|
+
assertEnvelope$1(data);
|
|
51460
|
+
return {
|
|
51461
|
+
data,
|
|
51462
|
+
fetchedAt: Date.now()
|
|
51463
|
+
};
|
|
51464
|
+
}
|
|
51465
|
+
async function uploadVideo(inv) {
|
|
51466
|
+
const secret = credentials(inv.source.credentials);
|
|
51467
|
+
const { advertiserId, filename, videoUrl } = inv.args;
|
|
51468
|
+
if (typeof advertiserId !== "string" || !/^[0-9]+$/.test(advertiserId) || typeof filename !== "string" || !filename) throw new Error("tiktok-ads: advertiserId and filename are required");
|
|
51469
|
+
let url;
|
|
51470
|
+
try {
|
|
51471
|
+
url = new URL(String(videoUrl));
|
|
51472
|
+
} catch {
|
|
51473
|
+
throw new Error("tiktok-ads: videoUrl must be a public HTTPS URL");
|
|
51474
|
+
}
|
|
51475
|
+
if (url.protocol !== "https:" || url.username || url.password) throw new Error("tiktok-ads: videoUrl must be a public HTTPS URL without credentials");
|
|
51476
|
+
const form = new FormData();
|
|
51477
|
+
form.set("advertiser_id", advertiserId);
|
|
51478
|
+
form.set("file_name", filename);
|
|
51479
|
+
form.set("upload_type", "UPLOAD_BY_URL");
|
|
51480
|
+
form.set("video_url", url.href);
|
|
51481
|
+
const response = await fetch("https://business-api.tiktok.com/open_api/v1.3/file/video/ad/upload/", {
|
|
51482
|
+
method: "POST",
|
|
51483
|
+
headers: { "Access-Token": secret.accessToken },
|
|
51484
|
+
body: form,
|
|
51485
|
+
redirect: "error",
|
|
51486
|
+
signal: AbortSignal.timeout(3e4)
|
|
51487
|
+
}).catch(() => {
|
|
51488
|
+
throw new Error("tiktok-ads: video upload transport failed");
|
|
51489
|
+
});
|
|
51490
|
+
if (response.status === 401) throw new CredentialsExpired("TikTok Ads rejected credentials (401)", inv.source.id);
|
|
51491
|
+
if (response.status === 429) return {
|
|
51492
|
+
status: "rate-limited",
|
|
51493
|
+
retryAfterMs: 6e4,
|
|
51494
|
+
message: "TikTok Ads video upload rate limited"
|
|
51495
|
+
};
|
|
51496
|
+
if (!response.ok) throw new Error(`tiktok-ads: video upload HTTP ${response.status}`);
|
|
51497
|
+
const data = await response.json().catch(() => null);
|
|
51498
|
+
assertMutationReceipt$1(data, inv.capabilityName);
|
|
51499
|
+
return {
|
|
51500
|
+
status: "committed",
|
|
51501
|
+
data,
|
|
51502
|
+
committedAt: Date.now(),
|
|
51503
|
+
idempotentReplay: false
|
|
51504
|
+
};
|
|
51505
|
+
}
|
|
51506
|
+
const tiktokAdsConnector = {
|
|
51507
|
+
...base$5,
|
|
51508
|
+
async executeRead(inv) {
|
|
51509
|
+
if (inv.capabilityName === "advertisers.list") return discover(inv);
|
|
51510
|
+
credentials(inv.source.credentials);
|
|
51511
|
+
const result = await base$5.executeRead(prepare$1(inv));
|
|
51512
|
+
assertEnvelope$1(result.data);
|
|
51513
|
+
return result;
|
|
51514
|
+
},
|
|
51515
|
+
async executeMutation(inv) {
|
|
51516
|
+
if (inv.capabilityName === "videos.uploadFromUrl") return uploadVideo(inv);
|
|
51517
|
+
credentials(inv.source.credentials);
|
|
51518
|
+
const result = await base$5.executeMutation(prepare$1(inv));
|
|
51519
|
+
if (result.status === "committed") assertMutationReceipt$1(result.data, inv.capabilityName);
|
|
51520
|
+
return result;
|
|
51521
|
+
},
|
|
51522
|
+
async test(source) {
|
|
51523
|
+
try {
|
|
51524
|
+
await discover({
|
|
51525
|
+
source,
|
|
51526
|
+
capabilityName: "advertisers.list",
|
|
51527
|
+
args: {},
|
|
51528
|
+
idempotencyKey: "test"
|
|
51529
|
+
});
|
|
51530
|
+
return { ok: true };
|
|
51531
|
+
} catch (error) {
|
|
51532
|
+
return {
|
|
51533
|
+
ok: false,
|
|
51534
|
+
reason: error instanceof Error ? error.message : "TikTok Ads connection failed"
|
|
51535
|
+
};
|
|
51536
|
+
}
|
|
51537
|
+
}
|
|
51538
|
+
};
|
|
51539
|
+
//#endregion
|
|
51540
|
+
//#region src/connectors/adapters/linkedin-ads.ts
|
|
51541
|
+
const id$10 = {
|
|
51542
|
+
type: "string",
|
|
51543
|
+
pattern: "^[0-9]+$"
|
|
51544
|
+
};
|
|
51545
|
+
const text$6 = {
|
|
51546
|
+
type: "string",
|
|
51547
|
+
minLength: 1,
|
|
51548
|
+
maxLength: 255
|
|
51549
|
+
};
|
|
51550
|
+
const money$3 = {
|
|
51551
|
+
type: "string",
|
|
51552
|
+
pattern: "^(?:[1-9][0-9]*(?:\\.[0-9]{1,2})?|0\\.(?:0[1-9]|[1-9][0-9]?))$",
|
|
51553
|
+
description: "Positive decimal amount in account currency, not micros."
|
|
51554
|
+
};
|
|
51555
|
+
const currency = {
|
|
51556
|
+
type: "string",
|
|
51557
|
+
pattern: "^[A-Z]{3}$"
|
|
51558
|
+
};
|
|
51559
|
+
const time$2 = {
|
|
51560
|
+
type: "integer",
|
|
51561
|
+
minimum: 1,
|
|
51562
|
+
description: "Unix epoch milliseconds."
|
|
51563
|
+
};
|
|
51564
|
+
const facets = [
|
|
51565
|
+
"interfaceLocales",
|
|
51566
|
+
"locations",
|
|
51567
|
+
"industries",
|
|
51568
|
+
"employers",
|
|
51569
|
+
"jobFunctions",
|
|
51570
|
+
"seniorities",
|
|
51571
|
+
"titles",
|
|
51572
|
+
"skills",
|
|
51573
|
+
"staffCountRanges",
|
|
51574
|
+
"interests"
|
|
51575
|
+
];
|
|
51576
|
+
const facetValues = Object.fromEntries(facets.map((facet) => [facet, {
|
|
51577
|
+
type: "array",
|
|
51578
|
+
minItems: 1,
|
|
51579
|
+
maxItems: 100,
|
|
51580
|
+
items: {
|
|
51581
|
+
type: "string",
|
|
51582
|
+
pattern: "^urn:li:"
|
|
51583
|
+
}
|
|
51584
|
+
}]));
|
|
51585
|
+
const targeting = {
|
|
51586
|
+
type: "object",
|
|
51587
|
+
properties: {
|
|
51588
|
+
include: {
|
|
51589
|
+
type: "object",
|
|
51590
|
+
properties: { and: {
|
|
51591
|
+
type: "array",
|
|
51592
|
+
minItems: 1,
|
|
51593
|
+
maxItems: 9,
|
|
51594
|
+
items: {
|
|
51595
|
+
type: "object",
|
|
51596
|
+
properties: { or: {
|
|
51597
|
+
type: "object",
|
|
51598
|
+
minProperties: 1,
|
|
51599
|
+
properties: facetValues,
|
|
51600
|
+
additionalProperties: false
|
|
51601
|
+
} },
|
|
51602
|
+
required: ["or"],
|
|
51603
|
+
additionalProperties: false
|
|
51604
|
+
}
|
|
51605
|
+
} },
|
|
51606
|
+
required: ["and"],
|
|
51607
|
+
additionalProperties: false
|
|
51608
|
+
},
|
|
51609
|
+
exclude: {
|
|
51610
|
+
type: "object",
|
|
51611
|
+
properties: { or: {
|
|
51612
|
+
type: "object",
|
|
51613
|
+
minProperties: 1,
|
|
51614
|
+
properties: facetValues,
|
|
51615
|
+
additionalProperties: false
|
|
51616
|
+
} },
|
|
51617
|
+
required: ["or"],
|
|
51618
|
+
additionalProperties: false
|
|
51619
|
+
}
|
|
51620
|
+
},
|
|
51621
|
+
required: ["include"],
|
|
51622
|
+
additionalProperties: false,
|
|
51623
|
+
description: "Targeting criteria with short facet names (locations, interfaceLocales, etc.). Include a locations facet using current Bing geo URNs discovered through targeting.search. OR within a facet, AND between groups."
|
|
51624
|
+
};
|
|
51625
|
+
function nativeTargeting(value) {
|
|
51626
|
+
if (!isPlainRecord(value) || !isPlainRecord(value.include) || !Array.isArray(value.include.and) || value.include.and.length === 0) throw new Error("linkedin-ads: targetingCriteria.include.and is required");
|
|
51627
|
+
const group = (entry) => {
|
|
51628
|
+
if (!isPlainRecord(entry) || !isPlainRecord(entry.or) || Object.keys(entry.or).length === 0) throw new Error("linkedin-ads: targeting group requires facets");
|
|
51629
|
+
return { or: Object.fromEntries(Object.entries(entry.or).map(([facet, values]) => {
|
|
51630
|
+
if (!facets.includes(facet) || !Array.isArray(values) || values.length === 0 || values.some((item) => typeof item !== "string" || !item.startsWith("urn:li:"))) throw new Error("linkedin-ads: unknown targeting facet or invalid URN values");
|
|
51631
|
+
return [`urn:li:adTargetingFacet:${facet}`, values];
|
|
51632
|
+
})) };
|
|
51633
|
+
};
|
|
51634
|
+
return {
|
|
51635
|
+
include: { and: value.include.and.map(group) },
|
|
51636
|
+
...value.exclude === void 0 ? {} : { exclude: group(value.exclude) }
|
|
51637
|
+
};
|
|
51638
|
+
}
|
|
51639
|
+
const account$1 = "/adAccounts/{accountId}";
|
|
51640
|
+
const page$5 = {
|
|
51641
|
+
pageSize: {
|
|
51642
|
+
type: "integer",
|
|
51643
|
+
minimum: 1,
|
|
51644
|
+
maximum: 100
|
|
51645
|
+
},
|
|
51646
|
+
pageToken: { type: "string" }
|
|
51647
|
+
};
|
|
51648
|
+
function parameters$5(properties, required = []) {
|
|
51649
|
+
return {
|
|
51650
|
+
type: "object",
|
|
51651
|
+
properties,
|
|
51652
|
+
required,
|
|
51653
|
+
additionalProperties: false
|
|
51654
|
+
};
|
|
51655
|
+
}
|
|
51656
|
+
function write$4(name, description, path, properties, required, body, create = false) {
|
|
51657
|
+
return {
|
|
51658
|
+
name,
|
|
51659
|
+
description,
|
|
51660
|
+
class: "mutation",
|
|
51661
|
+
cas: "none",
|
|
51662
|
+
externalEffect: true,
|
|
51663
|
+
requiredScopes: ["rw_ads"],
|
|
51664
|
+
parameters: parameters$5({
|
|
51665
|
+
accountId: id$10,
|
|
51666
|
+
...properties
|
|
51667
|
+
}, ["accountId", ...required]),
|
|
51668
|
+
request: {
|
|
51669
|
+
method: "POST",
|
|
51670
|
+
path: account$1 + path,
|
|
51671
|
+
body,
|
|
51672
|
+
...create ? { resultFromHeader: {
|
|
51673
|
+
header: "x-restli-id",
|
|
51674
|
+
field: "id"
|
|
51675
|
+
} } : { headers: { "X-RestLi-Method": "PARTIAL_UPDATE" } }
|
|
51676
|
+
}
|
|
51677
|
+
};
|
|
51678
|
+
}
|
|
51679
|
+
const base$4 = declarativeRestConnector({
|
|
51680
|
+
kind: "linkedin-ads",
|
|
51681
|
+
displayName: "LinkedIn Ads",
|
|
51682
|
+
description: "Discover advertiser accounts, prepare lifetime-budget sponsored campaigns, target professional audiences, sponsor existing posts, and measure results.",
|
|
51683
|
+
auth: {
|
|
51684
|
+
kind: "oauth2",
|
|
51685
|
+
authorizationUrl: "https://www.linkedin.com/oauth/v2/authorization",
|
|
51686
|
+
tokenUrl: "https://www.linkedin.com/oauth/v2/accessToken",
|
|
51687
|
+
scopes: ["rw_ads", "r_ads_reporting"],
|
|
51688
|
+
clientIdEnv: "LINKEDIN_OAUTH_CLIENT_ID",
|
|
51689
|
+
clientSecretEnv: "LINKEDIN_OAUTH_CLIENT_SECRET"
|
|
51690
|
+
},
|
|
51691
|
+
category: "other",
|
|
51692
|
+
defaultConsistencyModel: "cache",
|
|
51693
|
+
baseUrl: "https://api.linkedin.com/rest",
|
|
51694
|
+
credentialsExpiredStatuses: [401],
|
|
51695
|
+
defaultHeaders: {
|
|
51696
|
+
"LinkedIn-Version": "202609",
|
|
51697
|
+
"X-Restli-Protocol-Version": "2.0.0"
|
|
51698
|
+
},
|
|
51699
|
+
test: {
|
|
51700
|
+
method: "GET",
|
|
51701
|
+
path: "/adAccounts",
|
|
51702
|
+
query: {
|
|
51703
|
+
q: "search",
|
|
51704
|
+
pageSize: 1
|
|
51705
|
+
}
|
|
51706
|
+
},
|
|
51707
|
+
capabilities: [
|
|
51708
|
+
{
|
|
51709
|
+
name: "accounts.list",
|
|
51710
|
+
class: "read",
|
|
51711
|
+
requiredScopes: ["rw_ads"],
|
|
51712
|
+
description: "List accessible advertiser accounts, currency, account status and native nextPageToken. Includes test accounts.",
|
|
51713
|
+
parameters: parameters$5(page$5),
|
|
51714
|
+
request: {
|
|
51715
|
+
method: "GET",
|
|
51716
|
+
path: "/adAccounts",
|
|
51717
|
+
query: {
|
|
51718
|
+
q: "search",
|
|
51719
|
+
pageSize: "{pageSize}",
|
|
51720
|
+
pageToken: "{pageToken}"
|
|
51721
|
+
}
|
|
51722
|
+
}
|
|
51723
|
+
},
|
|
51724
|
+
...["adCampaignGroups", "adCampaigns"].flatMap((resource) => {
|
|
51725
|
+
const name = resource === "adCampaignGroups" ? "campaignGroups" : "campaigns";
|
|
51726
|
+
return [{
|
|
51727
|
+
name: `${name}.list`,
|
|
51728
|
+
class: "read",
|
|
51729
|
+
requiredScopes: ["rw_ads"],
|
|
51730
|
+
description: "Read campaigns or groups with native budgets, serving holds and nextPageToken.",
|
|
51731
|
+
parameters: parameters$5({
|
|
51732
|
+
accountId: id$10,
|
|
51733
|
+
...page$5
|
|
51734
|
+
}, ["accountId"]),
|
|
51735
|
+
request: {
|
|
51736
|
+
method: "GET",
|
|
51737
|
+
path: `${account$1}/${resource}`,
|
|
51738
|
+
query: {
|
|
51739
|
+
q: "search",
|
|
51740
|
+
search: resource === "adCampaignGroups" ? "(status:(values:List(ACTIVE,PAUSED,DRAFT,ARCHIVED)))" : "(status:(values:List(ACTIVE,PAUSED,DRAFT,COMPLETED,ARCHIVED)))",
|
|
51741
|
+
pageSize: "{pageSize}",
|
|
51742
|
+
pageToken: "{pageToken}"
|
|
51743
|
+
}
|
|
51744
|
+
}
|
|
51745
|
+
}, {
|
|
51746
|
+
name: `${name}.get`,
|
|
51747
|
+
class: "read",
|
|
51748
|
+
requiredScopes: ["rw_ads"],
|
|
51749
|
+
description: "Inspect a native campaign or group budget, schedule and serving status.",
|
|
51750
|
+
parameters: parameters$5({
|
|
51751
|
+
accountId: id$10,
|
|
51752
|
+
id: id$10
|
|
51753
|
+
}, ["accountId", "id"]),
|
|
51754
|
+
request: {
|
|
51755
|
+
method: "GET",
|
|
51756
|
+
path: `${account$1}/${resource}/{id}`
|
|
51757
|
+
}
|
|
51758
|
+
}];
|
|
51759
|
+
}),
|
|
51760
|
+
write$4("campaignGroups.create", "Create a DRAFT campaign group with a cumulative total budget and fixed schedule. New groups only accept DRAFT or ACTIVE at creation.", "/adCampaignGroups", {
|
|
51761
|
+
name: text$6,
|
|
51762
|
+
totalBudget: money$3,
|
|
51763
|
+
currencyCode: currency,
|
|
51764
|
+
startTime: time$2,
|
|
51765
|
+
endTime: time$2
|
|
51766
|
+
}, [
|
|
51767
|
+
"name",
|
|
51768
|
+
"totalBudget",
|
|
51769
|
+
"currencyCode",
|
|
51770
|
+
"startTime",
|
|
51771
|
+
"endTime"
|
|
51772
|
+
], {
|
|
51773
|
+
account: "urn:li:sponsoredAccount:{accountId}",
|
|
51774
|
+
name: "{name}",
|
|
51775
|
+
status: "DRAFT",
|
|
51776
|
+
totalBudget: {
|
|
51777
|
+
amount: "{totalBudget}",
|
|
51778
|
+
currencyCode: "{currencyCode}"
|
|
51779
|
+
},
|
|
51780
|
+
runSchedule: {
|
|
51781
|
+
start: "{startTime}",
|
|
51782
|
+
end: "{endTime}"
|
|
51783
|
+
}
|
|
51784
|
+
}, true),
|
|
51785
|
+
...["ACTIVE", "PAUSED"].map((status) => write$4(status === "ACTIVE" ? "campaignGroups.enable" : "campaignGroups.pause", status === "ACTIVE" ? "Enable a campaign group. Active children can spend immediately; verify the group total budget and schedule first." : "Pause the entire campaign group.", "/adCampaignGroups/{groupId}", { groupId: id$10 }, ["groupId"], { patch: { $set: { status } } })),
|
|
51786
|
+
write$4("campaigns.createSponsored", "Create a PAUSED sponsored-content campaign with lifetime pacing, a total budget, fixed schedule and maximum CPC bid. Include geographic targeting. Reuse existing LinkedIn posts for creatives.", "/adCampaigns", {
|
|
51787
|
+
name: text$6,
|
|
51788
|
+
groupId: id$10,
|
|
51789
|
+
associatedEntity: {
|
|
51790
|
+
type: "string",
|
|
51791
|
+
pattern: "^urn:li:(organization:[0-9]+|person:[A-Za-z0-9_-]+)$",
|
|
51792
|
+
description: "Beneficiary organization or member URN with sponsorship rights for this campaign."
|
|
51793
|
+
},
|
|
51794
|
+
totalBudget: money$3,
|
|
51795
|
+
currencyCode: currency,
|
|
51796
|
+
bidAmount: money$3,
|
|
51797
|
+
startTime: time$2,
|
|
51798
|
+
endTime: time$2,
|
|
51799
|
+
targetingCriteria: targeting,
|
|
51800
|
+
localeCountry: {
|
|
51801
|
+
type: "string",
|
|
51802
|
+
pattern: "^[A-Z]{2}$"
|
|
51803
|
+
},
|
|
51804
|
+
localeLanguage: {
|
|
51805
|
+
type: "string",
|
|
51806
|
+
pattern: "^[a-z]{2}$"
|
|
51807
|
+
},
|
|
51808
|
+
politicalIntent: {
|
|
51809
|
+
type: "string",
|
|
51810
|
+
enum: [
|
|
51811
|
+
"NOT_POLITICAL",
|
|
51812
|
+
"POLITICAL",
|
|
51813
|
+
"NOT_DECLARED"
|
|
51814
|
+
],
|
|
51815
|
+
description: "For EU targeting the advertiser must provide the LinkedIn political advertising declaration before submission."
|
|
51816
|
+
}
|
|
51817
|
+
}, [
|
|
51818
|
+
"name",
|
|
51819
|
+
"groupId",
|
|
51820
|
+
"associatedEntity",
|
|
51821
|
+
"totalBudget",
|
|
51822
|
+
"currencyCode",
|
|
51823
|
+
"bidAmount",
|
|
51824
|
+
"startTime",
|
|
51825
|
+
"endTime",
|
|
51826
|
+
"targetingCriteria",
|
|
51827
|
+
"localeCountry",
|
|
51828
|
+
"localeLanguage",
|
|
51829
|
+
"politicalIntent"
|
|
51830
|
+
], {
|
|
51831
|
+
account: "urn:li:sponsoredAccount:{accountId}",
|
|
51832
|
+
campaignGroup: "urn:li:sponsoredCampaignGroup:{groupId}",
|
|
51833
|
+
associatedEntity: "{associatedEntity}",
|
|
51834
|
+
name: "{name}",
|
|
51835
|
+
type: "SPONSORED_UPDATES",
|
|
51836
|
+
objectiveType: "WEBSITE_VISIT",
|
|
51837
|
+
status: "PAUSED",
|
|
51838
|
+
pacingStrategy: "LIFETIME",
|
|
51839
|
+
totalBudget: {
|
|
51840
|
+
amount: "{totalBudget}",
|
|
51841
|
+
currencyCode: "{currencyCode}"
|
|
51842
|
+
},
|
|
51843
|
+
unitCost: {
|
|
51844
|
+
amount: "{bidAmount}",
|
|
51845
|
+
currencyCode: "{currencyCode}"
|
|
51846
|
+
},
|
|
51847
|
+
costType: "CPC",
|
|
51848
|
+
optimizationTargetType: "NONE",
|
|
51849
|
+
runSchedule: {
|
|
51850
|
+
start: "{startTime}",
|
|
51851
|
+
end: "{endTime}"
|
|
51852
|
+
},
|
|
51853
|
+
targetingCriteria: "{targetingCriteria}",
|
|
51854
|
+
locale: {
|
|
51855
|
+
country: "{localeCountry}",
|
|
51856
|
+
language: "{localeLanguage}"
|
|
51857
|
+
},
|
|
51858
|
+
audienceExpansionEnabled: false,
|
|
51859
|
+
offsiteDeliveryEnabled: false,
|
|
51860
|
+
creativeSelection: "OPTIMIZED",
|
|
51861
|
+
politicalIntent: "{politicalIntent}"
|
|
51862
|
+
}, true),
|
|
51863
|
+
...["ACTIVE", "PAUSED"].map((status) => write$4(status === "ACTIVE" ? "campaigns.enable" : "campaigns.pause", status === "ACTIVE" ? "Enable an existing lifetime-budget campaign. Verify total budget, end date, targeting, ad review, funding and authorization first; this can spend immediately." : "Pause the campaign and stop delivery.", "/adCampaigns/{campaignId}", { campaignId: id$10 }, ["campaignId"], { patch: { $set: { status } } })),
|
|
51864
|
+
{
|
|
51865
|
+
name: "targeting.search",
|
|
51866
|
+
class: "read",
|
|
51867
|
+
requiredScopes: ["rw_ads"],
|
|
51868
|
+
description: "Find current native targeting URNs by facet and text. Geographic results use Bing geo; do not reuse obsolete geo IDs.",
|
|
51869
|
+
parameters: parameters$5({
|
|
51870
|
+
facet: {
|
|
51871
|
+
type: "string",
|
|
51872
|
+
enum: [
|
|
51873
|
+
"locations",
|
|
51874
|
+
"industries",
|
|
51875
|
+
"employers",
|
|
51876
|
+
"titles",
|
|
51877
|
+
"skills",
|
|
51878
|
+
"interests"
|
|
51879
|
+
]
|
|
51880
|
+
},
|
|
51881
|
+
query: text$6
|
|
51882
|
+
}, ["facet", "query"]),
|
|
51883
|
+
request: {
|
|
51884
|
+
method: "GET",
|
|
51885
|
+
path: "/adTargetingEntities",
|
|
51886
|
+
query: {
|
|
51887
|
+
q: "typeahead",
|
|
51888
|
+
facet: "urn:li:adTargetingFacet:{facet}",
|
|
51889
|
+
query: "{query}",
|
|
51890
|
+
queryVersion: "QUERY_USES_URNS"
|
|
51891
|
+
}
|
|
51892
|
+
}
|
|
51893
|
+
},
|
|
51894
|
+
{
|
|
51895
|
+
name: "targeting.listFacet",
|
|
51896
|
+
class: "read",
|
|
51897
|
+
requiredScopes: ["rw_ads"],
|
|
51898
|
+
description: "List professional targeting facet values for job function, seniority and company size.",
|
|
51899
|
+
parameters: parameters$5({ facet: {
|
|
51900
|
+
type: "string",
|
|
51901
|
+
enum: [
|
|
51902
|
+
"jobFunctions",
|
|
51903
|
+
"seniorities",
|
|
51904
|
+
"staffCountRanges"
|
|
51905
|
+
]
|
|
51906
|
+
} }, ["facet"]),
|
|
51907
|
+
request: {
|
|
51908
|
+
method: "GET",
|
|
51909
|
+
path: "/adTargetingEntities",
|
|
51910
|
+
query: {
|
|
51911
|
+
q: "adTargetingFacet",
|
|
51912
|
+
facet: "urn:li:adTargetingFacet:{facet}",
|
|
51913
|
+
queryVersion: "QUERY_USES_URNS"
|
|
51914
|
+
}
|
|
51915
|
+
}
|
|
51916
|
+
},
|
|
51917
|
+
write$4("creatives.createFromPost", "Create a PAUSED sponsored creative referencing a share or UGC post. Author content using the existing LinkedIn publishing connector; the advertiser must have sponsorship rights.", "/creatives", {
|
|
51918
|
+
campaignId: id$10,
|
|
51919
|
+
postUrn: {
|
|
51920
|
+
type: "string",
|
|
51921
|
+
pattern: "^urn:li:(share|ugcPost):[0-9]+$"
|
|
51922
|
+
},
|
|
51923
|
+
name: text$6
|
|
51924
|
+
}, [
|
|
51925
|
+
"campaignId",
|
|
51926
|
+
"postUrn",
|
|
51927
|
+
"name"
|
|
51928
|
+
], {
|
|
51929
|
+
campaign: "urn:li:sponsoredCampaign:{campaignId}",
|
|
51930
|
+
content: { reference: "{postUrn}" },
|
|
51931
|
+
intendedStatus: "PAUSED",
|
|
51932
|
+
name: "{name}"
|
|
51933
|
+
}, true),
|
|
51934
|
+
{
|
|
51935
|
+
name: "creatives.get",
|
|
51936
|
+
class: "read",
|
|
51937
|
+
requiredScopes: ["rw_ads"],
|
|
51938
|
+
description: "Read ad review, serving holds and effective serving state using the returned creative URN.",
|
|
51939
|
+
parameters: parameters$5({
|
|
51940
|
+
accountId: id$10,
|
|
51941
|
+
creativeUrn: {
|
|
51942
|
+
type: "string",
|
|
51943
|
+
pattern: "^urn:li:sponsoredCreative:[0-9]+$"
|
|
51944
|
+
}
|
|
51945
|
+
}, ["accountId", "creativeUrn"]),
|
|
51946
|
+
request: {
|
|
51947
|
+
method: "GET",
|
|
51948
|
+
path: `${account$1}/creatives/{creativeUrn}`
|
|
51949
|
+
}
|
|
51950
|
+
},
|
|
51951
|
+
...["ACTIVE", "PAUSED"].map((status) => write$4(status === "ACTIVE" ? "creatives.enable" : "creatives.pause", status === "ACTIVE" ? "Activate a creative for review and serving within its campaign budget; an active parent may spend immediately." : "Pause a creative. LinkedIn may reject pausing a creative currently under review; pause its campaign instead.", "/creatives/{creativeUrn}", { creativeUrn: {
|
|
51952
|
+
type: "string",
|
|
51953
|
+
pattern: "^urn:li:sponsoredCreative:[0-9]+$"
|
|
51954
|
+
} }, ["creativeUrn"], { patch: { $set: { intendedStatus: status } } })),
|
|
51955
|
+
{
|
|
51956
|
+
name: "reports.analytics",
|
|
51957
|
+
class: "read",
|
|
51958
|
+
requiredScopes: ["r_ads_reporting"],
|
|
51959
|
+
description: "Read campaign spend in account currency, impressions, clicks and configured website conversions for an inclusive UTC date range. Provider attribution is not proof of revenue.",
|
|
51960
|
+
parameters: parameters$5({
|
|
51961
|
+
accountId: id$10,
|
|
51962
|
+
startYear: {
|
|
51963
|
+
type: "integer",
|
|
51964
|
+
minimum: 2e3
|
|
51965
|
+
},
|
|
51966
|
+
startMonth: {
|
|
51967
|
+
type: "integer",
|
|
51968
|
+
minimum: 1,
|
|
51969
|
+
maximum: 12
|
|
51970
|
+
},
|
|
51971
|
+
startDay: {
|
|
51972
|
+
type: "integer",
|
|
51973
|
+
minimum: 1,
|
|
51974
|
+
maximum: 31
|
|
51975
|
+
},
|
|
51976
|
+
endYear: {
|
|
51977
|
+
type: "integer",
|
|
51978
|
+
minimum: 2e3
|
|
51979
|
+
},
|
|
51980
|
+
endMonth: {
|
|
51981
|
+
type: "integer",
|
|
51982
|
+
minimum: 1,
|
|
51983
|
+
maximum: 12
|
|
51984
|
+
},
|
|
51985
|
+
endDay: {
|
|
51986
|
+
type: "integer",
|
|
51987
|
+
minimum: 1,
|
|
51988
|
+
maximum: 31
|
|
51989
|
+
}
|
|
51990
|
+
}, [
|
|
51991
|
+
"accountId",
|
|
51992
|
+
"startYear",
|
|
51993
|
+
"startMonth",
|
|
51994
|
+
"startDay",
|
|
51995
|
+
"endYear",
|
|
51996
|
+
"endMonth",
|
|
51997
|
+
"endDay"
|
|
51998
|
+
]),
|
|
51999
|
+
request: {
|
|
52000
|
+
method: "GET",
|
|
52001
|
+
path: "/adAnalytics",
|
|
52002
|
+
query: {
|
|
52003
|
+
q: "analytics",
|
|
52004
|
+
pivot: "CAMPAIGN",
|
|
52005
|
+
accounts: "List(urn:li:sponsoredAccount:{accountId})",
|
|
52006
|
+
timeGranularity: "DAILY",
|
|
52007
|
+
dateRange: "(start:(year:{startYear},month:{startMonth},day:{startDay}),end:(year:{endYear},month:{endMonth},day:{endDay}))",
|
|
52008
|
+
fields: "dateRange,pivotValues,impressions,clicks,landingPageClicks,costInLocalCurrency,externalWebsiteConversions"
|
|
52009
|
+
}
|
|
52010
|
+
}
|
|
52011
|
+
}
|
|
52012
|
+
]
|
|
52013
|
+
});
|
|
52014
|
+
const linkedinAdsConnector = {
|
|
52015
|
+
...base$4,
|
|
52016
|
+
async executeMutation(inv) {
|
|
52017
|
+
for (const key of ["totalBudget", "bidAmount"]) if (inv.args[key] !== void 0 && (typeof inv.args[key] !== "string" || !new RegExp(money$3.pattern).test(inv.args[key]))) throw new Error(`linkedin-ads: ${key} must be positive decimal currency`);
|
|
52018
|
+
if (inv.capabilityName === "campaignGroups.create" || inv.capabilityName === "campaigns.createSponsored") {
|
|
52019
|
+
if (!(typeof inv.args.startTime === "number" && typeof inv.args.endTime === "number" && Number.isSafeInteger(inv.args.startTime) && Number.isSafeInteger(inv.args.endTime) && Number(inv.args.startTime) > 0 && Number(inv.args.endTime) > Number(inv.args.startTime))) throw new Error("linkedin-ads: endTime must be after startTime in epoch milliseconds");
|
|
52020
|
+
}
|
|
52021
|
+
if (inv.capabilityName === "campaigns.createSponsored") inv = {
|
|
52022
|
+
...inv,
|
|
52023
|
+
args: {
|
|
52024
|
+
...inv.args,
|
|
52025
|
+
targetingCriteria: nativeTargeting(inv.args.targetingCriteria)
|
|
52026
|
+
}
|
|
52027
|
+
};
|
|
52028
|
+
const result = await base$4.executeMutation(inv);
|
|
52029
|
+
if (result.status === "committed") {
|
|
52030
|
+
if ([
|
|
52031
|
+
"campaignGroups.create",
|
|
52032
|
+
"campaigns.createSponsored",
|
|
52033
|
+
"creatives.createFromPost"
|
|
52034
|
+
].includes(inv.capabilityName) ? !(isPlainRecord(result.data) && typeof result.data.id === "string" && result.data.id.length > 0) : result.data !== null) throw new Error("linkedin-ads: unexpected mutation receipt; reconcile provider state before retrying");
|
|
52035
|
+
}
|
|
52036
|
+
return result;
|
|
52037
|
+
}
|
|
52038
|
+
};
|
|
52039
|
+
//#endregion
|
|
52040
|
+
//#region src/connectors/adapters/reddit-ads.ts
|
|
52041
|
+
const id$9 = {
|
|
52042
|
+
type: "string",
|
|
52043
|
+
pattern: "^[a-zA-Z0-9_-]+$"
|
|
52044
|
+
};
|
|
52045
|
+
const text$5 = {
|
|
52046
|
+
type: "string",
|
|
52047
|
+
minLength: 1,
|
|
52048
|
+
maxLength: 255
|
|
52049
|
+
};
|
|
52050
|
+
const time$1 = {
|
|
52051
|
+
type: "string",
|
|
52052
|
+
format: "date-time"
|
|
52053
|
+
};
|
|
52054
|
+
const url = {
|
|
52055
|
+
type: "string",
|
|
52056
|
+
format: "uri",
|
|
52057
|
+
pattern: "^https://"
|
|
52058
|
+
};
|
|
52059
|
+
const micros$2 = {
|
|
52060
|
+
type: "integer",
|
|
52061
|
+
minimum: 1,
|
|
52062
|
+
maximum: Number.MAX_SAFE_INTEGER,
|
|
52063
|
+
description: "Positive integer microcurrency in the advertiser account currency; 1000000 = one currency unit."
|
|
52064
|
+
};
|
|
52065
|
+
const page$4 = {
|
|
52066
|
+
pageToken: { type: "string" },
|
|
52067
|
+
pageSize: {
|
|
52068
|
+
type: "integer",
|
|
52069
|
+
minimum: 1,
|
|
52070
|
+
maximum: 100
|
|
52071
|
+
}
|
|
52072
|
+
};
|
|
52073
|
+
const pageQuery = {
|
|
52074
|
+
"page.token": "{pageToken}",
|
|
52075
|
+
"page.size": "{pageSize}"
|
|
52076
|
+
};
|
|
52077
|
+
const account = "/ad_accounts/{accountId}";
|
|
52078
|
+
function parameters$4(properties, required = []) {
|
|
52079
|
+
return {
|
|
52080
|
+
type: "object",
|
|
52081
|
+
properties,
|
|
52082
|
+
required,
|
|
52083
|
+
additionalProperties: false
|
|
52084
|
+
};
|
|
52085
|
+
}
|
|
52086
|
+
function strings$1(maxItems) {
|
|
52087
|
+
return {
|
|
52088
|
+
type: "array",
|
|
52089
|
+
minItems: 1,
|
|
52090
|
+
maxItems,
|
|
52091
|
+
items: {
|
|
52092
|
+
type: "string",
|
|
52093
|
+
minLength: 1
|
|
52094
|
+
}
|
|
52095
|
+
};
|
|
52096
|
+
}
|
|
52097
|
+
function write$3(name, description, path, properties, required, data, method = "POST") {
|
|
52098
|
+
return {
|
|
52099
|
+
name,
|
|
52100
|
+
description,
|
|
52101
|
+
class: "mutation",
|
|
52102
|
+
cas: "none",
|
|
52103
|
+
externalEffect: true,
|
|
52104
|
+
requiredScopes: ["adsedit"],
|
|
52105
|
+
parameters: parameters$4(properties, required),
|
|
52106
|
+
request: {
|
|
52107
|
+
method,
|
|
52108
|
+
path,
|
|
52109
|
+
body: { data }
|
|
52110
|
+
}
|
|
52111
|
+
};
|
|
52112
|
+
}
|
|
52113
|
+
const base$3 = declarativeRestConnector({
|
|
52114
|
+
kind: "reddit-ads",
|
|
52115
|
+
displayName: "Reddit Ads",
|
|
52116
|
+
description: "Prepare lifetime-budget Reddit traffic campaigns, target communities and geographies, create ad creatives, launch or pause, and measure spend and conversions.",
|
|
52117
|
+
auth: {
|
|
52118
|
+
kind: "oauth2",
|
|
52119
|
+
authorizationUrl: "https://www.reddit.com/api/v1/authorize",
|
|
52120
|
+
tokenUrl: "https://www.reddit.com/api/v1/access_token",
|
|
52121
|
+
scopes: ["adsread", "adsedit"],
|
|
52122
|
+
pkce: "unsupported",
|
|
52123
|
+
tokenClientAuthMethod: "client_secret_basic",
|
|
52124
|
+
extraAuthParams: { duration: "permanent" },
|
|
52125
|
+
clientIdEnv: "REDDIT_ADS_OAUTH_CLIENT_ID",
|
|
52126
|
+
clientSecretEnv: "REDDIT_ADS_OAUTH_CLIENT_SECRET",
|
|
52127
|
+
tokenRequestHeaders: { "User-Agent": "web:tools.tangle.integration-hub:v1.0 (contact: https://tangle.tools)" }
|
|
52128
|
+
},
|
|
52129
|
+
category: "other",
|
|
52130
|
+
defaultConsistencyModel: "cache",
|
|
52131
|
+
baseUrl: "https://ads-api.reddit.com/api/v3",
|
|
52132
|
+
credentialsExpiredStatuses: [401],
|
|
52133
|
+
defaultHeaders: { "User-Agent": "web:tools.tangle.integration-hub:v1.0 (contact: https://tangle.tools)" },
|
|
52134
|
+
test: {
|
|
52135
|
+
method: "GET",
|
|
52136
|
+
path: "/me/businesses",
|
|
52137
|
+
query: { "page.size": 1 }
|
|
52138
|
+
},
|
|
52139
|
+
capabilities: [
|
|
52140
|
+
{
|
|
52141
|
+
name: "businesses.list",
|
|
52142
|
+
class: "read",
|
|
52143
|
+
requiredScopes: ["adsread"],
|
|
52144
|
+
description: "Discover advertiser businesses available to the connected user. Follow pagination tokens.",
|
|
52145
|
+
parameters: parameters$4(page$4),
|
|
52146
|
+
request: {
|
|
52147
|
+
method: "GET",
|
|
52148
|
+
path: "/me/businesses",
|
|
52149
|
+
query: pageQuery
|
|
52150
|
+
}
|
|
52151
|
+
},
|
|
52152
|
+
{
|
|
52153
|
+
name: "accounts.list",
|
|
52154
|
+
class: "read",
|
|
52155
|
+
requiredScopes: ["adsread"],
|
|
52156
|
+
description: "List advertiser accounts in one accessible business. Use account currency and billing readiness before budgeting.",
|
|
52157
|
+
parameters: parameters$4({
|
|
52158
|
+
businessId: id$9,
|
|
52159
|
+
...page$4
|
|
52160
|
+
}, ["businessId"]),
|
|
52161
|
+
request: {
|
|
52162
|
+
method: "GET",
|
|
52163
|
+
path: "/businesses/{businessId}/ad_accounts",
|
|
52164
|
+
query: pageQuery
|
|
52165
|
+
}
|
|
52166
|
+
},
|
|
52167
|
+
{
|
|
52168
|
+
name: "accounts.get",
|
|
52169
|
+
class: "read",
|
|
52170
|
+
requiredScopes: ["adsread"],
|
|
52171
|
+
description: "Read advertiser account currency, funding and serving status.",
|
|
52172
|
+
parameters: parameters$4({ accountId: id$9 }, ["accountId"]),
|
|
52173
|
+
request: {
|
|
52174
|
+
method: "GET",
|
|
52175
|
+
path: account
|
|
52176
|
+
}
|
|
52177
|
+
},
|
|
52178
|
+
...[
|
|
52179
|
+
"campaigns",
|
|
52180
|
+
"ad_groups",
|
|
52181
|
+
"ads",
|
|
52182
|
+
"pixels",
|
|
52183
|
+
"profiles"
|
|
52184
|
+
].map((resource) => ({
|
|
52185
|
+
name: `${resource === "ad_groups" ? "adGroups" : resource}.list`,
|
|
52186
|
+
class: "read",
|
|
52187
|
+
requiredScopes: ["adsread"],
|
|
52188
|
+
description: `List ${resource} under this advertiser account. Retain provider IDs and pagination.`,
|
|
52189
|
+
parameters: parameters$4({
|
|
52190
|
+
accountId: id$9,
|
|
52191
|
+
...page$4
|
|
52192
|
+
}, ["accountId"]),
|
|
52193
|
+
request: {
|
|
52194
|
+
method: "GET",
|
|
52195
|
+
path: `${account}/${resource}`,
|
|
52196
|
+
query: pageQuery
|
|
52197
|
+
}
|
|
52198
|
+
})),
|
|
52199
|
+
...[
|
|
52200
|
+
"campaigns",
|
|
52201
|
+
"ad_groups",
|
|
52202
|
+
"ads"
|
|
52203
|
+
].flatMap((resource) => {
|
|
52204
|
+
const name = resource === "ad_groups" ? "adGroups" : resource;
|
|
52205
|
+
return [{
|
|
52206
|
+
name: `${name}.get`,
|
|
52207
|
+
class: "read",
|
|
52208
|
+
requiredScopes: ["adsread"],
|
|
52209
|
+
description: "Read native budget, schedule, configured status and effective serving status.",
|
|
52210
|
+
parameters: parameters$4({ id: id$9 }, ["id"]),
|
|
52211
|
+
request: {
|
|
52212
|
+
method: "GET",
|
|
52213
|
+
path: `/${resource}/{id}`
|
|
52214
|
+
}
|
|
52215
|
+
}, ...["ACTIVE", "PAUSED"].map((status) => write$3(`${name}.${status === "ACTIVE" ? "enable" : "pause"}`, status === "ACTIVE" ? "Enable this entity; delivery may start immediately if its parents are active. Verify lifetime campaign budget, schedule, creative review, targeting and authorization first." : "Pause this entity. Check effective status and reporting after the write.", `/${resource}/{id}`, { id: id$9 }, ["id"], { configured_status: status }, "PATCH"))];
|
|
52216
|
+
}),
|
|
52217
|
+
write$3("campaigns.createTraffic", "Create a PAUSED Standard traffic campaign with campaign budget optimization and a lifetime spending budget. A conversion pixel is required by Reddit, including traffic campaigns.", `${account}/campaigns`, {
|
|
52218
|
+
accountId: id$9,
|
|
52219
|
+
name: text$5,
|
|
52220
|
+
totalBudgetMicros: micros$2,
|
|
52221
|
+
startTime: time$1,
|
|
52222
|
+
endTime: time$1,
|
|
52223
|
+
pixelId: id$9
|
|
52224
|
+
}, [
|
|
52225
|
+
"accountId",
|
|
52226
|
+
"name",
|
|
52227
|
+
"totalBudgetMicros",
|
|
52228
|
+
"startTime",
|
|
52229
|
+
"endTime",
|
|
52230
|
+
"pixelId"
|
|
52231
|
+
], {
|
|
52232
|
+
name: "{name}",
|
|
52233
|
+
configured_status: "PAUSED",
|
|
52234
|
+
objective: "CLICKS",
|
|
52235
|
+
is_campaign_budget_optimization: true,
|
|
52236
|
+
goal_type: "LIFETIME_SPEND",
|
|
52237
|
+
goal_value: "{totalBudgetMicros}",
|
|
52238
|
+
start_time: "{startTime}",
|
|
52239
|
+
end_time: "{endTime}",
|
|
52240
|
+
bid_strategy: "BIDLESS",
|
|
52241
|
+
bid_type: "CPC",
|
|
52242
|
+
conversion_pixel_id: "{pixelId}"
|
|
52243
|
+
}),
|
|
52244
|
+
write$3("adGroups.createTraffic", "Create a PAUSED traffic ad group inheriting the CBO campaign lifetime budget and bid strategy. Match campaign schedule and pixel. Targeting expansion is disabled.", `${account}/ad_groups`, {
|
|
52245
|
+
accountId: id$9,
|
|
52246
|
+
campaignId: id$9,
|
|
52247
|
+
name: text$5,
|
|
52248
|
+
startTime: time$1,
|
|
52249
|
+
endTime: time$1,
|
|
52250
|
+
pixelId: id$9,
|
|
52251
|
+
geolocations: strings$1(100),
|
|
52252
|
+
communities: strings$1(100),
|
|
52253
|
+
keywords: strings$1(1e3),
|
|
52254
|
+
excludedCommunities: strings$1(100)
|
|
52255
|
+
}, [
|
|
52256
|
+
"accountId",
|
|
52257
|
+
"campaignId",
|
|
52258
|
+
"name",
|
|
52259
|
+
"startTime",
|
|
52260
|
+
"endTime",
|
|
52261
|
+
"pixelId",
|
|
52262
|
+
"geolocations"
|
|
52263
|
+
], {
|
|
52264
|
+
campaign_id: "{campaignId}",
|
|
52265
|
+
name: "{name}",
|
|
52266
|
+
configured_status: "PAUSED",
|
|
52267
|
+
start_time: "{startTime}",
|
|
52268
|
+
end_time: "{endTime}",
|
|
52269
|
+
bid_type: "CPC",
|
|
52270
|
+
bid_strategy: null,
|
|
52271
|
+
bid_value: null,
|
|
52272
|
+
conversion_pixel_id: "{pixelId}",
|
|
52273
|
+
targeting: {
|
|
52274
|
+
geolocations: "{geolocations}",
|
|
52275
|
+
communities: "{communities}",
|
|
52276
|
+
keywords: "{keywords}",
|
|
52277
|
+
excluded_communities: "{excludedCommunities}",
|
|
52278
|
+
expand_targeting: false
|
|
52279
|
+
}
|
|
52280
|
+
}),
|
|
52281
|
+
{
|
|
52282
|
+
name: "targeting.communities",
|
|
52283
|
+
class: "read",
|
|
52284
|
+
requiredScopes: ["adsread"],
|
|
52285
|
+
description: "Search targetable communities by name or topic. Use returned community names in ad-group targeting.",
|
|
52286
|
+
parameters: parameters$4({
|
|
52287
|
+
query: text$5,
|
|
52288
|
+
...page$4
|
|
52289
|
+
}, ["query"]),
|
|
52290
|
+
request: {
|
|
52291
|
+
method: "GET",
|
|
52292
|
+
path: "/targeting/communities/search",
|
|
52293
|
+
query: {
|
|
52294
|
+
query: "{query}",
|
|
52295
|
+
...pageQuery
|
|
52296
|
+
}
|
|
52297
|
+
}
|
|
52298
|
+
},
|
|
52299
|
+
{
|
|
52300
|
+
name: "targeting.geolocations",
|
|
52301
|
+
class: "read",
|
|
52302
|
+
requiredScopes: ["adsread"],
|
|
52303
|
+
description: "Find country or city geolocation IDs for targeting.",
|
|
52304
|
+
parameters: parameters$4({
|
|
52305
|
+
country: {
|
|
52306
|
+
type: "string",
|
|
52307
|
+
pattern: "^[A-Z]{2}$"
|
|
52308
|
+
},
|
|
52309
|
+
city: text$5
|
|
52310
|
+
}, ["country"]),
|
|
52311
|
+
request: {
|
|
52312
|
+
method: "GET",
|
|
52313
|
+
path: "/targeting/geolocations",
|
|
52314
|
+
query: {
|
|
52315
|
+
country: "{country}",
|
|
52316
|
+
cities_search: "{city}"
|
|
52317
|
+
}
|
|
52318
|
+
}
|
|
52319
|
+
},
|
|
52320
|
+
write$3("posts.createImage", "Submit a structured image-post creation job using provider-fetchable public HTTPS media. A committed result means job submission; poll posts.getJob until SUCCESS and use its resulting post ID.", "/profiles/{profileId}/structured_posts/jobs", {
|
|
52321
|
+
profileId: id$9,
|
|
52322
|
+
headline: {
|
|
52323
|
+
type: "string",
|
|
52324
|
+
minLength: 1,
|
|
52325
|
+
maxLength: 300
|
|
52326
|
+
},
|
|
52327
|
+
destinationUrl: url,
|
|
52328
|
+
imageUrl: url,
|
|
52329
|
+
thumbnailUrl: url,
|
|
52330
|
+
allowComments: { type: "boolean" }
|
|
52331
|
+
}, [
|
|
52332
|
+
"profileId",
|
|
52333
|
+
"headline",
|
|
52334
|
+
"destinationUrl",
|
|
52335
|
+
"imageUrl",
|
|
52336
|
+
"thumbnailUrl",
|
|
52337
|
+
"allowComments"
|
|
52338
|
+
], {
|
|
52339
|
+
allow_comments: "{allowComments}",
|
|
52340
|
+
creative: {
|
|
52341
|
+
type: "IMAGE",
|
|
52342
|
+
headline: "{headline}",
|
|
52343
|
+
destination: {
|
|
52344
|
+
type: "URL",
|
|
52345
|
+
url: "{destinationUrl}"
|
|
52346
|
+
},
|
|
52347
|
+
image: { media: {
|
|
52348
|
+
type: "URL",
|
|
52349
|
+
url: "{imageUrl}"
|
|
52350
|
+
} },
|
|
52351
|
+
thumbnail: { media: {
|
|
52352
|
+
type: "URL",
|
|
52353
|
+
url: "{thumbnailUrl}"
|
|
52354
|
+
} }
|
|
52355
|
+
}
|
|
52356
|
+
}),
|
|
52357
|
+
write$3("posts.createText", "Submit a structured free-form text-post creation job. Poll posts.getJob before treating the creative as available.", "/profiles/{profileId}/structured_posts/jobs", {
|
|
52358
|
+
profileId: id$9,
|
|
52359
|
+
headline: {
|
|
52360
|
+
type: "string",
|
|
52361
|
+
minLength: 1,
|
|
52362
|
+
maxLength: 300
|
|
52363
|
+
},
|
|
52364
|
+
body: {
|
|
52365
|
+
type: "string",
|
|
52366
|
+
minLength: 1,
|
|
52367
|
+
maxLength: 4e4
|
|
52368
|
+
},
|
|
52369
|
+
allowComments: { type: "boolean" }
|
|
52370
|
+
}, [
|
|
52371
|
+
"profileId",
|
|
52372
|
+
"headline",
|
|
52373
|
+
"body",
|
|
52374
|
+
"allowComments"
|
|
52375
|
+
], {
|
|
52376
|
+
allow_comments: "{allowComments}",
|
|
52377
|
+
creative: {
|
|
52378
|
+
type: "TEXT",
|
|
52379
|
+
headline: "{headline}",
|
|
52380
|
+
body: "{body}",
|
|
52381
|
+
text_format: "PLAIN_TEXT"
|
|
52382
|
+
}
|
|
52383
|
+
}),
|
|
52384
|
+
{
|
|
52385
|
+
name: "posts.getJob",
|
|
52386
|
+
class: "read",
|
|
52387
|
+
requiredScopes: ["adsread"],
|
|
52388
|
+
description: "Read creative job status and output. PROCESSING/QUEUED are unfinished; CLIENT_ERROR/SERVER_ERROR are failures, not created ads.",
|
|
52389
|
+
parameters: parameters$4({ jobId: id$9 }, ["jobId"]),
|
|
52390
|
+
request: {
|
|
52391
|
+
method: "GET",
|
|
52392
|
+
path: "/structured_posts/jobs/{jobId}"
|
|
52393
|
+
}
|
|
52394
|
+
},
|
|
52395
|
+
write$3("ads.create", "Create a PAUSED ad with an existing successful post and HTTPS landing URL. For image ads, clickUrl must match the post destination.", `${account}/ads`, {
|
|
52396
|
+
accountId: id$9,
|
|
52397
|
+
adGroupId: id$9,
|
|
52398
|
+
name: text$5,
|
|
52399
|
+
postId: {
|
|
52400
|
+
type: "string",
|
|
52401
|
+
pattern: "^t3_[a-zA-Z0-9]+$"
|
|
52402
|
+
},
|
|
52403
|
+
clickUrl: url
|
|
52404
|
+
}, [
|
|
52405
|
+
"accountId",
|
|
52406
|
+
"adGroupId",
|
|
52407
|
+
"name",
|
|
52408
|
+
"postId",
|
|
52409
|
+
"clickUrl"
|
|
52410
|
+
], {
|
|
52411
|
+
ad_group_id: "{adGroupId}",
|
|
52412
|
+
name: "{name}",
|
|
52413
|
+
post_id: "{postId}",
|
|
52414
|
+
click_url: "{clickUrl}",
|
|
52415
|
+
configured_status: "PAUSED"
|
|
52416
|
+
}),
|
|
52417
|
+
{
|
|
52418
|
+
name: "reports.get",
|
|
52419
|
+
class: "read",
|
|
52420
|
+
requiredScopes: ["adsread"],
|
|
52421
|
+
description: "Read daily campaign spend, impressions, clicks and configured conversion metrics. Spend is microcurrency; conversion values are cents. Reporting may take six hours to stabilize.",
|
|
52422
|
+
parameters: parameters$4({
|
|
52423
|
+
accountId: id$9,
|
|
52424
|
+
startTime: time$1,
|
|
52425
|
+
endTime: time$1,
|
|
52426
|
+
fields: {
|
|
52427
|
+
type: "array",
|
|
52428
|
+
minItems: 1,
|
|
52429
|
+
maxItems: 20,
|
|
52430
|
+
uniqueItems: true,
|
|
52431
|
+
items: {
|
|
52432
|
+
type: "string",
|
|
52433
|
+
enum: [
|
|
52434
|
+
"SPEND",
|
|
52435
|
+
"IMPRESSIONS",
|
|
52436
|
+
"CLICKS",
|
|
52437
|
+
"CTR",
|
|
52438
|
+
"CPC",
|
|
52439
|
+
"CURRENCY",
|
|
52440
|
+
"CONVERSION_PAGE_VISIT_CLICKS",
|
|
52441
|
+
"CONVERSION_SIGN_UP_CLICKS",
|
|
52442
|
+
"CONVERSION_LEAD_CLICKS",
|
|
52443
|
+
"CONVERSION_PURCHASE_CLICKS",
|
|
52444
|
+
"CONVERSION_PURCHASE_TOTAL_VALUE"
|
|
52445
|
+
]
|
|
52446
|
+
}
|
|
52447
|
+
}
|
|
52448
|
+
}, [
|
|
52449
|
+
"accountId",
|
|
52450
|
+
"startTime",
|
|
52451
|
+
"endTime",
|
|
52452
|
+
"fields"
|
|
52453
|
+
]),
|
|
52454
|
+
request: {
|
|
52455
|
+
method: "POST",
|
|
52456
|
+
path: `${account}/reports`,
|
|
52457
|
+
body: { data: {
|
|
52458
|
+
starts_at: "{startTime}",
|
|
52459
|
+
ends_at: "{endTime}",
|
|
52460
|
+
fields: "{fields}",
|
|
52461
|
+
breakdowns: ["CAMPAIGN_ID", "DATE"]
|
|
52462
|
+
} }
|
|
52463
|
+
}
|
|
52464
|
+
}
|
|
52465
|
+
]
|
|
52466
|
+
});
|
|
52467
|
+
const redditAdsConnector = {
|
|
52468
|
+
...base$3,
|
|
52469
|
+
async executeMutation(inv) {
|
|
52470
|
+
if (inv.args.totalBudgetMicros !== void 0 && !(typeof inv.args.totalBudgetMicros === "number" && Number.isSafeInteger(inv.args.totalBudgetMicros) && Number(inv.args.totalBudgetMicros) > 0)) throw new Error("reddit-ads: totalBudgetMicros must be positive safe integer microcurrency");
|
|
52471
|
+
if (inv.capabilityName === "campaigns.createTraffic" || inv.capabilityName === "adGroups.createTraffic") {
|
|
52472
|
+
if (!(typeof inv.args.startTime === "string" && typeof inv.args.endTime === "string" && Date.parse(inv.args.endTime) > Date.parse(inv.args.startTime))) throw new Error("reddit-ads: endTime must be after startTime");
|
|
52473
|
+
}
|
|
52474
|
+
const result = await base$3.executeMutation(inv);
|
|
52475
|
+
if (result.status === "committed") {
|
|
52476
|
+
const envelope = result.data;
|
|
52477
|
+
if (!isPlainRecord(envelope) || envelope.error || envelope.errors || !isPlainRecord(envelope.data) || typeof envelope.data.id !== "string" || !envelope.data.id) throw new Error("reddit-ads: missing native mutation receipt or provider error; reconcile state before retrying");
|
|
52478
|
+
if (inv.capabilityName === "posts.createImage" || inv.capabilityName === "posts.createText") {
|
|
52479
|
+
if (![
|
|
52480
|
+
"QUEUED",
|
|
52481
|
+
"PROCESSING",
|
|
52482
|
+
"SUCCESS"
|
|
52483
|
+
].includes(String(envelope.data.status))) throw new Error("reddit-ads: post creation job failed or returned unknown status");
|
|
52484
|
+
}
|
|
52485
|
+
}
|
|
52486
|
+
return result;
|
|
52487
|
+
}
|
|
52488
|
+
};
|
|
52489
|
+
//#endregion
|
|
52490
|
+
//#region src/connectors/adapters/snapchat-ads.ts
|
|
52491
|
+
const scope$2 = "snapchat-marketing-api";
|
|
52492
|
+
const id$8 = {
|
|
52493
|
+
type: "string",
|
|
52494
|
+
format: "uuid"
|
|
52495
|
+
};
|
|
52496
|
+
const text$4 = {
|
|
52497
|
+
type: "string",
|
|
52498
|
+
minLength: 1
|
|
52499
|
+
};
|
|
52500
|
+
const micros$1 = {
|
|
52501
|
+
type: "integer",
|
|
52502
|
+
minimum: 1,
|
|
52503
|
+
maximum: Number.MAX_SAFE_INTEGER,
|
|
52504
|
+
description: "Positive micro-currency units in the ad account currency. 1000000 = one currency unit."
|
|
52505
|
+
};
|
|
52506
|
+
const time = {
|
|
52507
|
+
type: "string",
|
|
52508
|
+
format: "date-time"
|
|
52509
|
+
};
|
|
52510
|
+
const pagination$3 = {
|
|
52511
|
+
limit: {
|
|
52512
|
+
type: "integer",
|
|
52513
|
+
minimum: 50,
|
|
52514
|
+
maximum: 100
|
|
52515
|
+
},
|
|
52516
|
+
cursor: text$4
|
|
52517
|
+
};
|
|
52518
|
+
function parameters$3(properties, required = []) {
|
|
52519
|
+
return {
|
|
52520
|
+
type: "object",
|
|
52521
|
+
properties,
|
|
52522
|
+
required,
|
|
52523
|
+
additionalProperties: false
|
|
52524
|
+
};
|
|
52525
|
+
}
|
|
52526
|
+
function mutation(name, description, properties, required, path, body) {
|
|
52527
|
+
return {
|
|
52528
|
+
name,
|
|
52529
|
+
description,
|
|
52530
|
+
class: "mutation",
|
|
52531
|
+
cas: "none",
|
|
52532
|
+
externalEffect: true,
|
|
52533
|
+
requiredScopes: [scope$2],
|
|
52534
|
+
parameters: parameters$3(properties, required),
|
|
52535
|
+
request: {
|
|
52536
|
+
method: "POST",
|
|
52537
|
+
path,
|
|
52538
|
+
body
|
|
52539
|
+
}
|
|
52540
|
+
};
|
|
52541
|
+
}
|
|
52542
|
+
const base$2 = declarativeRestConnector({
|
|
52543
|
+
kind: "snapchat-ads",
|
|
52544
|
+
displayName: "Snapchat Ads",
|
|
52545
|
+
description: "Create bounded Snapchat campaigns, targeted ad squads, uploaded media and website creatives; control delivery and read spend and conversions.",
|
|
52546
|
+
auth: {
|
|
52547
|
+
kind: "oauth2",
|
|
52548
|
+
authorizationUrl: "https://accounts.snapchat.com/login/oauth2/authorize",
|
|
52549
|
+
tokenUrl: "https://accounts.snapchat.com/login/oauth2/access_token",
|
|
52550
|
+
scopes: [scope$2],
|
|
52551
|
+
pkce: "unsupported",
|
|
52552
|
+
clientIdEnv: "SNAPCHAT_ADS_OAUTH_CLIENT_ID",
|
|
52553
|
+
clientSecretEnv: "SNAPCHAT_ADS_OAUTH_CLIENT_SECRET"
|
|
52554
|
+
},
|
|
52555
|
+
category: "other",
|
|
52556
|
+
defaultConsistencyModel: "cache",
|
|
52557
|
+
baseUrl: "https://adsapi.snapchat.com/v1",
|
|
52558
|
+
credentialsExpiredStatuses: [401],
|
|
52559
|
+
capabilities: [
|
|
52560
|
+
{
|
|
52561
|
+
name: "accounts.list",
|
|
52562
|
+
class: "read",
|
|
52563
|
+
requiredScopes: [scope$2],
|
|
52564
|
+
description: "Discover organizations and their ad accounts, including native IDs and account currency. Follow the returned paging cursor.",
|
|
52565
|
+
parameters: parameters$3(pagination$3),
|
|
52566
|
+
request: {
|
|
52567
|
+
method: "GET",
|
|
52568
|
+
path: "/me/organizations",
|
|
52569
|
+
query: {
|
|
52570
|
+
with_ad_accounts: true,
|
|
52571
|
+
limit: "{limit}",
|
|
52572
|
+
cursor: "{cursor}"
|
|
52573
|
+
}
|
|
52574
|
+
}
|
|
52575
|
+
},
|
|
52576
|
+
...[
|
|
52577
|
+
"campaigns",
|
|
52578
|
+
"adsquads",
|
|
52579
|
+
"ads",
|
|
52580
|
+
"creatives",
|
|
52581
|
+
"media"
|
|
52582
|
+
].map((entity) => ({
|
|
52583
|
+
name: `${entity}.list`,
|
|
52584
|
+
class: "read",
|
|
52585
|
+
requiredScopes: [scope$2],
|
|
52586
|
+
description: `Read ${entity} for an ad account, including provider delivery, review or processing state. Follow paging.next_link's cursor using this same action.`,
|
|
52587
|
+
parameters: parameters$3({
|
|
52588
|
+
accountId: id$8,
|
|
52589
|
+
...pagination$3
|
|
52590
|
+
}, ["accountId"]),
|
|
52591
|
+
request: {
|
|
52592
|
+
method: "GET",
|
|
52593
|
+
path: `/adaccounts/{accountId}/${entity}`,
|
|
52594
|
+
query: {
|
|
52595
|
+
limit: "{limit}",
|
|
52596
|
+
cursor: "{cursor}"
|
|
52597
|
+
}
|
|
52598
|
+
}
|
|
52599
|
+
})),
|
|
52600
|
+
mutation("campaigns.createTraffic", "Create a PAUSED auction traffic campaign with a required lifetime spend cap and fixed flight. This aggregate cap bounds all ad squads in this campaign.", {
|
|
52601
|
+
accountId: id$8,
|
|
52602
|
+
name: text$4,
|
|
52603
|
+
lifetimeSpendCapMicro: micros$1,
|
|
52604
|
+
startTime: time,
|
|
52605
|
+
endTime: time
|
|
52606
|
+
}, [
|
|
52607
|
+
"accountId",
|
|
52608
|
+
"name",
|
|
52609
|
+
"lifetimeSpendCapMicro",
|
|
52610
|
+
"startTime",
|
|
52611
|
+
"endTime"
|
|
52612
|
+
], "/adaccounts/{accountId}/campaigns", { campaigns: [{
|
|
52613
|
+
ad_account_id: "{accountId}",
|
|
52614
|
+
name: "{name}",
|
|
52615
|
+
status: "PAUSED",
|
|
52616
|
+
buy_model: "AUCTION",
|
|
52617
|
+
objective_v2_properties: { objective_v2_type: "TRAFFIC" },
|
|
52618
|
+
lifetime_spend_cap_micro: "{lifetimeSpendCapMicro}",
|
|
52619
|
+
start_time: "{startTime}",
|
|
52620
|
+
end_time: "{endTime}"
|
|
52621
|
+
}] }),
|
|
52622
|
+
mutation("adsquads.createTraffic", "Create a PAUSED website-traffic ad squad with a lifetime budget, fixed flight, explicit countries and maximum bid. The campaign lifetime cap remains the aggregate limit.", {
|
|
52623
|
+
campaignId: id$8,
|
|
52624
|
+
name: text$4,
|
|
52625
|
+
lifetimeBudgetMicro: micros$1,
|
|
52626
|
+
bidMicro: micros$1,
|
|
52627
|
+
startTime: time,
|
|
52628
|
+
endTime: time,
|
|
52629
|
+
countries: {
|
|
52630
|
+
type: "array",
|
|
52631
|
+
minItems: 1,
|
|
52632
|
+
items: {
|
|
52633
|
+
type: "string",
|
|
52634
|
+
pattern: "^[a-z]{2}$"
|
|
52635
|
+
},
|
|
52636
|
+
uniqueItems: true
|
|
52637
|
+
}
|
|
52638
|
+
}, [
|
|
52639
|
+
"campaignId",
|
|
52640
|
+
"name",
|
|
52641
|
+
"lifetimeBudgetMicro",
|
|
52642
|
+
"bidMicro",
|
|
52643
|
+
"startTime",
|
|
52644
|
+
"endTime",
|
|
52645
|
+
"countries"
|
|
52646
|
+
], "/campaigns/{campaignId}/adsquads", { adsquads: [{
|
|
52647
|
+
campaign_id: "{campaignId}",
|
|
52648
|
+
name: "{name}",
|
|
52649
|
+
status: "PAUSED",
|
|
52650
|
+
type: "SNAP_ADS",
|
|
52651
|
+
placement_v2: { config: "AUTOMATIC" },
|
|
52652
|
+
optimization_goal: "SWIPES",
|
|
52653
|
+
bid_strategy: "LOWEST_COST_WITH_MAX_BID",
|
|
52654
|
+
billing_event: "IMPRESSION",
|
|
52655
|
+
bid_micro: "{bidMicro}",
|
|
52656
|
+
lifetime_budget_micro: "{lifetimeBudgetMicro}",
|
|
52657
|
+
delivery_constraint: "LIFETIME_BUDGET",
|
|
52658
|
+
pacing_type: "STANDARD",
|
|
52659
|
+
start_time: "{startTime}",
|
|
52660
|
+
end_time: "{endTime}",
|
|
52661
|
+
targeting: "{targeting}"
|
|
52662
|
+
}] }),
|
|
52663
|
+
mutation("media.create", "Create an IMAGE or VIDEO media container. Upload bytes using media.upload and read media.list until READY before using it in a creative.", {
|
|
52664
|
+
accountId: id$8,
|
|
52665
|
+
name: text$4,
|
|
52666
|
+
type: {
|
|
52667
|
+
type: "string",
|
|
52668
|
+
enum: ["IMAGE", "VIDEO"]
|
|
52669
|
+
}
|
|
52670
|
+
}, [
|
|
52671
|
+
"accountId",
|
|
52672
|
+
"name",
|
|
52673
|
+
"type"
|
|
52674
|
+
], "/adaccounts/{accountId}/media", { media: [{
|
|
52675
|
+
ad_account_id: "{accountId}",
|
|
52676
|
+
name: "{name}",
|
|
52677
|
+
type: "{type}"
|
|
52678
|
+
}] }),
|
|
52679
|
+
mutation("media.upload", "Upload a canonical base64 image or video to a previously created media container, up to 10 MiB. Provider dimension/duration rules still apply; wait for READY. Larger uploads require Snap native chunked upload.", {
|
|
52680
|
+
mediaId: id$8,
|
|
52681
|
+
fileBase64: {
|
|
52682
|
+
...text$4,
|
|
52683
|
+
maxLength: Math.ceil(MAX_FILE_BYTES / 3) * 4
|
|
52684
|
+
},
|
|
52685
|
+
filename: text$4,
|
|
52686
|
+
mimeType: {
|
|
52687
|
+
type: "string",
|
|
52688
|
+
enum: [
|
|
52689
|
+
"image/jpeg",
|
|
52690
|
+
"image/png",
|
|
52691
|
+
"video/mp4",
|
|
52692
|
+
"video/quicktime"
|
|
52693
|
+
]
|
|
52694
|
+
}
|
|
52695
|
+
}, [
|
|
52696
|
+
"mediaId",
|
|
52697
|
+
"fileBase64",
|
|
52698
|
+
"filename",
|
|
52699
|
+
"mimeType"
|
|
52700
|
+
], "/media/{mediaId}/upload", {}),
|
|
52701
|
+
mutation("creatives.createWebsite", "Create a WEB_VIEW creative from READY media, a public profile, headline and HTTPS destination. Read review_status before serving.", {
|
|
52702
|
+
accountId: id$8,
|
|
52703
|
+
name: text$4,
|
|
52704
|
+
mediaId: id$8,
|
|
52705
|
+
profileId: id$8,
|
|
52706
|
+
headline: {
|
|
52707
|
+
...text$4,
|
|
52708
|
+
maxLength: 34
|
|
52709
|
+
},
|
|
52710
|
+
brandName: {
|
|
52711
|
+
...text$4,
|
|
52712
|
+
maxLength: 32
|
|
52713
|
+
},
|
|
52714
|
+
url: {
|
|
52715
|
+
type: "string",
|
|
52716
|
+
format: "uri",
|
|
52717
|
+
pattern: "^https://"
|
|
52718
|
+
},
|
|
52719
|
+
callToAction: {
|
|
52720
|
+
type: "string",
|
|
52721
|
+
enum: [
|
|
52722
|
+
"MORE",
|
|
52723
|
+
"SIGN_UP",
|
|
52724
|
+
"SHOP_NOW",
|
|
52725
|
+
"BOOK_NOW",
|
|
52726
|
+
"TRY",
|
|
52727
|
+
"APPLY_NOW",
|
|
52728
|
+
"DOWNLOAD"
|
|
52729
|
+
]
|
|
52730
|
+
}
|
|
52731
|
+
}, [
|
|
52732
|
+
"accountId",
|
|
52733
|
+
"name",
|
|
52734
|
+
"mediaId",
|
|
52735
|
+
"profileId",
|
|
52736
|
+
"headline",
|
|
52737
|
+
"url",
|
|
52738
|
+
"callToAction"
|
|
52739
|
+
], "/adaccounts/{accountId}/creatives", { creatives: [{
|
|
52740
|
+
ad_account_id: "{accountId}",
|
|
52741
|
+
name: "{name}",
|
|
52742
|
+
type: "WEB_VIEW",
|
|
52743
|
+
top_snap_media_id: "{mediaId}",
|
|
52744
|
+
headline: "{headline}",
|
|
52745
|
+
brand_name: "{brandName}",
|
|
52746
|
+
profile_properties: { profile_id: "{profileId}" },
|
|
52747
|
+
web_view_properties: { url: "{url}" },
|
|
52748
|
+
call_to_action: "{callToAction}"
|
|
52749
|
+
}] }),
|
|
52750
|
+
mutation("ads.create", "Create a PAUSED ad linking a reviewed website creative to an ad squad.", {
|
|
52751
|
+
adSquadId: id$8,
|
|
52752
|
+
creativeId: id$8,
|
|
52753
|
+
name: text$4
|
|
52754
|
+
}, [
|
|
52755
|
+
"adSquadId",
|
|
52756
|
+
"creativeId",
|
|
52757
|
+
"name"
|
|
52758
|
+
], "/adsquads/{adSquadId}/ads", { ads: [{
|
|
52759
|
+
ad_squad_id: "{adSquadId}",
|
|
52760
|
+
creative_id: "{creativeId}",
|
|
52761
|
+
name: "{name}",
|
|
52762
|
+
type: "REMOTE_WEBPAGE",
|
|
52763
|
+
status: "PAUSED"
|
|
52764
|
+
}] }),
|
|
52765
|
+
...[
|
|
52766
|
+
[
|
|
52767
|
+
"campaigns",
|
|
52768
|
+
"/adaccounts/{accountId}/campaigns/{objectId}",
|
|
52769
|
+
"accountId"
|
|
52770
|
+
],
|
|
52771
|
+
[
|
|
52772
|
+
"adsquads",
|
|
52773
|
+
"/campaigns/{campaignId}/adsquads/{objectId}",
|
|
52774
|
+
"campaignId"
|
|
52775
|
+
],
|
|
52776
|
+
[
|
|
52777
|
+
"ads",
|
|
52778
|
+
"/adsquads/{adSquadId}/ads/{objectId}",
|
|
52779
|
+
"adSquadId"
|
|
52780
|
+
]
|
|
52781
|
+
].flatMap(([entity, path, parent]) => ["ACTIVE", "PAUSED"].map((status) => ({
|
|
52782
|
+
name: `${entity}.${status === "ACTIVE" ? "enable" : "pause"}`,
|
|
52783
|
+
class: "mutation",
|
|
52784
|
+
cas: "none",
|
|
52785
|
+
externalEffect: true,
|
|
52786
|
+
requiredScopes: [scope$2],
|
|
52787
|
+
description: status === "ACTIVE" ? "Enable delivery using a status-only PATCH. Verify spend authorization, campaign cap, billing, targeting, flight and review first; active ancestors can spend immediately." : "Pause delivery with a status-only PATCH; retain all budgets, targeting and creatives.",
|
|
52788
|
+
parameters: parameters$3({
|
|
52789
|
+
[parent]: id$8,
|
|
52790
|
+
objectId: id$8
|
|
52791
|
+
}, [parent, "objectId"]),
|
|
52792
|
+
request: {
|
|
52793
|
+
method: "PATCH",
|
|
52794
|
+
path,
|
|
52795
|
+
headers: { "content-type": "application/json-patch+json" },
|
|
52796
|
+
body: "{statusPatch}"
|
|
52797
|
+
}
|
|
52798
|
+
}))),
|
|
52799
|
+
{
|
|
52800
|
+
name: "reports.campaign",
|
|
52801
|
+
class: "read",
|
|
52802
|
+
requiredScopes: [scope$2],
|
|
52803
|
+
description: "Read campaign spend, impressions, swipes and configured purchases/signup attribution for a fixed time range. Spend is micro-currency; stats are delayed and may be revised.",
|
|
52804
|
+
parameters: parameters$3({
|
|
52805
|
+
campaignId: id$8,
|
|
52806
|
+
startTime: time,
|
|
52807
|
+
endTime: time,
|
|
52808
|
+
granularity: {
|
|
52809
|
+
type: "string",
|
|
52810
|
+
enum: [
|
|
52811
|
+
"TOTAL",
|
|
52812
|
+
"DAY",
|
|
52813
|
+
"HOUR"
|
|
52814
|
+
]
|
|
52815
|
+
}
|
|
52816
|
+
}, [
|
|
52817
|
+
"campaignId",
|
|
52818
|
+
"startTime",
|
|
52819
|
+
"endTime",
|
|
52820
|
+
"granularity"
|
|
52821
|
+
]),
|
|
52822
|
+
request: {
|
|
52823
|
+
method: "GET",
|
|
52824
|
+
path: "/campaigns/{campaignId}/stats",
|
|
52825
|
+
query: {
|
|
52826
|
+
granularity: "{granularity}",
|
|
52827
|
+
start_time: "{startTime}",
|
|
52828
|
+
end_time: "{endTime}",
|
|
52829
|
+
fields: "impressions,swipes,spend,conversion_purchases,conversion_sign_ups"
|
|
52830
|
+
}
|
|
52831
|
+
}
|
|
52832
|
+
}
|
|
52833
|
+
]
|
|
52834
|
+
});
|
|
52835
|
+
function assertEnvelope(value) {
|
|
52836
|
+
if (!isPlainRecord(value) || typeof value.request_status !== "string") throw new Error("snapchat-ads: malformed provider response (missing request_status)");
|
|
52837
|
+
if (value.request_status.toUpperCase() !== "SUCCESS") throw new Error("snapchat-ads: provider rejected request");
|
|
52838
|
+
for (const entries of Object.values(value)) {
|
|
52839
|
+
if (!Array.isArray(entries)) continue;
|
|
52840
|
+
for (const entry of entries) if (isPlainRecord(entry) && typeof entry.sub_request_status === "string" && entry.sub_request_status.toUpperCase() !== "SUCCESS") throw new Error("snapchat-ads: provider rejected a sub-request; inspect native status before retrying");
|
|
52841
|
+
}
|
|
52842
|
+
}
|
|
52843
|
+
function assertMutationReceipt(value, capability) {
|
|
52844
|
+
assertEnvelope(value);
|
|
52845
|
+
let entity;
|
|
52846
|
+
if (capability === "media.upload") entity = value.result;
|
|
52847
|
+
else {
|
|
52848
|
+
const resource = capability.split(".")[0];
|
|
52849
|
+
const entities = value[resource];
|
|
52850
|
+
const receipt = Array.isArray(entities) && entities.length === 1 ? entities[0] : void 0;
|
|
52851
|
+
if (!isPlainRecord(receipt) || typeof receipt.sub_request_status !== "string" || receipt.sub_request_status.toUpperCase() !== "SUCCESS") throw new Error("snapchat-ads: missing successful entity sub-request; reconcile provider state before retrying");
|
|
52852
|
+
entity = receipt[resource === "media" ? "media" : resource.slice(0, -1)];
|
|
52853
|
+
}
|
|
52854
|
+
if (!isPlainRecord(entity) || typeof entity.id !== "string" || !entity.id.trim()) throw new Error("snapchat-ads: missing native entity ID in mutation receipt; reconcile provider state before retrying");
|
|
52855
|
+
}
|
|
52856
|
+
function prepare(inv) {
|
|
52857
|
+
const a = inv.args;
|
|
52858
|
+
if (inv.capabilityName.endsWith(".createTraffic")) {
|
|
52859
|
+
for (const key of inv.capabilityName === "campaigns.createTraffic" ? ["lifetimeSpendCapMicro"] : ["lifetimeBudgetMicro", "bidMicro"]) if (!Number.isSafeInteger(a[key]) || Number(a[key]) <= 0) throw new Error(`snapchat-ads: ${key} must be a positive safe integer`);
|
|
52860
|
+
if (!(Date.parse(String(a.endTime)) > Date.parse(String(a.startTime)))) throw new Error("snapchat-ads: endTime must be after startTime");
|
|
52861
|
+
}
|
|
52862
|
+
return {
|
|
52863
|
+
...inv,
|
|
52864
|
+
args: {
|
|
52865
|
+
...a,
|
|
52866
|
+
targeting: { geos: Array.isArray(a.countries) ? a.countries.map((country_code) => ({ country_code })) : void 0 },
|
|
52867
|
+
statusPatch: [{
|
|
52868
|
+
op: "replace",
|
|
52869
|
+
path: "/status",
|
|
52870
|
+
value: inv.capabilityName.endsWith(".enable") ? "ACTIVE" : "PAUSED"
|
|
52871
|
+
}]
|
|
52872
|
+
}
|
|
52873
|
+
};
|
|
52874
|
+
}
|
|
52875
|
+
async function upload(inv) {
|
|
52876
|
+
const credentials = inv.source.credentials;
|
|
52877
|
+
if (credentials.kind !== "oauth2") throw new Error("snapchat-ads: OAuth credentials required");
|
|
52878
|
+
const { mediaId, filename, mimeType } = inv.args;
|
|
52879
|
+
if (typeof mediaId !== "string" || !/^[0-9a-f-]{36}$/i.test(mediaId)) throw new Error("snapchat-ads: mediaId must be a UUID");
|
|
52880
|
+
if (typeof filename !== "string" || !filename || typeof mimeType !== "string" || ![
|
|
52881
|
+
"image/jpeg",
|
|
52882
|
+
"image/png",
|
|
52883
|
+
"video/mp4",
|
|
52884
|
+
"video/quicktime"
|
|
52885
|
+
].includes(mimeType)) throw new Error("snapchat-ads: filename and supported mimeType are required");
|
|
52886
|
+
const bytes = readBase64File(inv.args.fileBase64);
|
|
52887
|
+
const form = new FormData();
|
|
52888
|
+
form.set("file", new Blob([new Uint8Array(bytes)], { type: mimeType }), filename);
|
|
52889
|
+
const response = await fetch(`https://adsapi.snapchat.com/v1/media/${encodeURIComponent(mediaId)}/upload`, {
|
|
52890
|
+
method: "POST",
|
|
52891
|
+
headers: { authorization: `Bearer ${credentials.accessToken}` },
|
|
52892
|
+
body: form,
|
|
52893
|
+
redirect: "error",
|
|
52894
|
+
signal: AbortSignal.timeout(3e4)
|
|
52895
|
+
});
|
|
52896
|
+
if (response.status === 401) throw new CredentialsExpired("Snapchat Ads rejected credentials (401)", inv.source.id);
|
|
52897
|
+
if (response.status === 429) return {
|
|
52898
|
+
status: "rate-limited",
|
|
52899
|
+
retryAfterMs: 6e4,
|
|
52900
|
+
message: "Snapchat Ads upload rate limited"
|
|
52901
|
+
};
|
|
52902
|
+
if (!response.ok) throw new Error(`snapchat-ads: media upload HTTP ${response.status}`);
|
|
52903
|
+
const data = await response.json().catch(() => null);
|
|
52904
|
+
assertMutationReceipt(data, inv.capabilityName);
|
|
52905
|
+
return {
|
|
52906
|
+
status: "committed",
|
|
52907
|
+
data,
|
|
52908
|
+
committedAt: Date.now(),
|
|
52909
|
+
idempotentReplay: false
|
|
52910
|
+
};
|
|
52911
|
+
}
|
|
52912
|
+
const snapchatAdsConnector = {
|
|
52913
|
+
...base$2,
|
|
52914
|
+
async executeRead(inv) {
|
|
52915
|
+
const result = await base$2.executeRead(prepare(inv));
|
|
52916
|
+
assertEnvelope(result.data);
|
|
52917
|
+
return result;
|
|
52918
|
+
},
|
|
52919
|
+
async executeMutation(inv) {
|
|
52920
|
+
if (inv.capabilityName === "media.upload") return upload(inv);
|
|
52921
|
+
const result = await base$2.executeMutation(prepare(inv));
|
|
52922
|
+
if (result.status === "committed") assertMutationReceipt(result.data, inv.capabilityName);
|
|
52923
|
+
return result;
|
|
52924
|
+
},
|
|
52925
|
+
async test(source) {
|
|
52926
|
+
try {
|
|
52927
|
+
assertEnvelope((await base$2.executeRead({
|
|
52928
|
+
source,
|
|
52929
|
+
capabilityName: "accounts.list",
|
|
52930
|
+
args: {},
|
|
52931
|
+
idempotencyKey: "test"
|
|
52932
|
+
})).data);
|
|
52933
|
+
return { ok: true };
|
|
52934
|
+
} catch (error) {
|
|
52935
|
+
return {
|
|
52936
|
+
ok: false,
|
|
52937
|
+
reason: error instanceof Error ? error.message : "Snapchat Ads connection failed"
|
|
52938
|
+
};
|
|
52939
|
+
}
|
|
52940
|
+
}
|
|
52941
|
+
};
|
|
52942
|
+
//#endregion
|
|
52943
|
+
//#region src/connectors/adapters/pinterest-ads.ts
|
|
52944
|
+
const text$3 = {
|
|
52945
|
+
type: "string",
|
|
52946
|
+
minLength: 1
|
|
52947
|
+
};
|
|
52948
|
+
const id$7 = {
|
|
52949
|
+
...text$3,
|
|
52950
|
+
pattern: "^\\d+$"
|
|
52951
|
+
};
|
|
52952
|
+
const micros = {
|
|
52953
|
+
type: "integer",
|
|
52954
|
+
minimum: 1,
|
|
52955
|
+
maximum: Number.MAX_SAFE_INTEGER,
|
|
52956
|
+
description: "Microcurrency in the ad account currency: 1000000 = one currency unit."
|
|
52957
|
+
};
|
|
52958
|
+
const timestamp = {
|
|
52959
|
+
type: "integer",
|
|
52960
|
+
minimum: 1,
|
|
52961
|
+
description: "Unix timestamp in seconds."
|
|
52962
|
+
};
|
|
52963
|
+
const strings = {
|
|
52964
|
+
type: "array",
|
|
52965
|
+
minItems: 1,
|
|
52966
|
+
items: text$3
|
|
52967
|
+
};
|
|
52968
|
+
const accountPath = "/ad_accounts/{adAccountId}";
|
|
52969
|
+
function parameters$2(properties, required = []) {
|
|
52970
|
+
return {
|
|
52971
|
+
type: "object",
|
|
52972
|
+
properties: {
|
|
52973
|
+
adAccountId: id$7,
|
|
52974
|
+
...properties
|
|
52975
|
+
},
|
|
52976
|
+
required: ["adAccountId", ...required],
|
|
52977
|
+
additionalProperties: false
|
|
52978
|
+
};
|
|
52979
|
+
}
|
|
52980
|
+
function write$2(name, description, resource, properties, required, body, method = "POST") {
|
|
52981
|
+
return {
|
|
52982
|
+
name,
|
|
52983
|
+
description,
|
|
52984
|
+
class: "mutation",
|
|
52985
|
+
cas: "none",
|
|
52986
|
+
externalEffect: true,
|
|
52987
|
+
requiredScopes: ["ads:write"],
|
|
52988
|
+
parameters: parameters$2(properties, required),
|
|
52989
|
+
request: {
|
|
52990
|
+
method,
|
|
52991
|
+
path: `${accountPath}/${resource}`,
|
|
52992
|
+
body: [body]
|
|
52993
|
+
}
|
|
52994
|
+
};
|
|
52995
|
+
}
|
|
52996
|
+
const rest = declarativeRestConnector({
|
|
52997
|
+
kind: "pinterest-ads",
|
|
52998
|
+
displayName: "Pinterest Ads",
|
|
52999
|
+
description: "Manage Pinterest consideration campaigns, targeted ad groups, existing-Pin ads and spend reports.",
|
|
53000
|
+
auth: {
|
|
53001
|
+
kind: "oauth2",
|
|
53002
|
+
authorizationUrl: "https://www.pinterest.com/oauth/",
|
|
53003
|
+
tokenUrl: "https://api.pinterest.com/v5/oauth/token",
|
|
53004
|
+
scopes: ["ads:read", "ads:write"],
|
|
53005
|
+
clientIdEnv: "PINTEREST_ADS_CLIENT_ID",
|
|
53006
|
+
clientSecretEnv: "PINTEREST_ADS_CLIENT_SECRET",
|
|
53007
|
+
tokenClientAuthMethod: "client_secret_basic"
|
|
53008
|
+
},
|
|
53009
|
+
category: "other",
|
|
53010
|
+
defaultConsistencyModel: "cache",
|
|
53011
|
+
baseUrl: "https://api.pinterest.com/v5",
|
|
53012
|
+
credentialsExpiredStatuses: [401],
|
|
53013
|
+
test: {
|
|
53014
|
+
method: "GET",
|
|
53015
|
+
path: "/ad_accounts",
|
|
53016
|
+
query: { page_size: 1 }
|
|
53017
|
+
},
|
|
53018
|
+
capabilities: [
|
|
53019
|
+
{
|
|
53020
|
+
name: "accounts.list",
|
|
53021
|
+
class: "read",
|
|
53022
|
+
description: "List accessible ad accounts, currency, and account status. Follow bookmark for further pages.",
|
|
53023
|
+
requiredScopes: ["ads:read"],
|
|
53024
|
+
parameters: {
|
|
53025
|
+
type: "object",
|
|
53026
|
+
properties: { bookmark: text$3 },
|
|
53027
|
+
additionalProperties: false
|
|
53028
|
+
},
|
|
53029
|
+
request: {
|
|
53030
|
+
method: "GET",
|
|
53031
|
+
path: "/ad_accounts",
|
|
53032
|
+
query: {
|
|
53033
|
+
bookmark: "{bookmark}",
|
|
53034
|
+
page_size: 100
|
|
53035
|
+
}
|
|
53036
|
+
}
|
|
53037
|
+
},
|
|
53038
|
+
...[
|
|
53039
|
+
"campaigns",
|
|
53040
|
+
"ad_groups",
|
|
53041
|
+
"ads"
|
|
53042
|
+
].map((resource) => ({
|
|
53043
|
+
name: `${resource === "ad_groups" ? "adGroups" : resource}.list`,
|
|
53044
|
+
class: "read",
|
|
53045
|
+
requiredScopes: ["ads:read"],
|
|
53046
|
+
description: `List ${resource} and their provider statuses; follow bookmark for additional pages.`,
|
|
53047
|
+
parameters: parameters$2({ bookmark: text$3 }),
|
|
53048
|
+
request: {
|
|
53049
|
+
method: "GET",
|
|
53050
|
+
path: `${accountPath}/${resource}`,
|
|
53051
|
+
query: {
|
|
53052
|
+
bookmark: "{bookmark}",
|
|
53053
|
+
page_size: 100
|
|
53054
|
+
}
|
|
53055
|
+
}
|
|
53056
|
+
})),
|
|
53057
|
+
write$2("campaigns.createConsideration", "Create a PAUSED consideration campaign with a lifetime campaign budget in microcurrency and a required end time. Ad groups inherit this budget; daily budgets and Performance+ are disabled.", "campaigns", {
|
|
53058
|
+
name: text$3,
|
|
53059
|
+
lifetimeSpendCap: micros,
|
|
53060
|
+
startTime: timestamp,
|
|
53061
|
+
endTime: timestamp
|
|
53062
|
+
}, [
|
|
53063
|
+
"name",
|
|
53064
|
+
"lifetimeSpendCap",
|
|
53065
|
+
"startTime",
|
|
53066
|
+
"endTime"
|
|
53067
|
+
], {
|
|
53068
|
+
name: "{name}",
|
|
53069
|
+
objective_type: "CONSIDERATION",
|
|
53070
|
+
status: "PAUSED",
|
|
53071
|
+
is_campaign_budget_optimization: true,
|
|
53072
|
+
is_flexible_daily_budgets: false,
|
|
53073
|
+
is_performance_plus: false,
|
|
53074
|
+
is_automated_campaign: false,
|
|
53075
|
+
lifetime_spend_cap: "{lifetimeSpendCap}",
|
|
53076
|
+
start_time: "{startTime}",
|
|
53077
|
+
end_time: "{endTime}"
|
|
53078
|
+
}),
|
|
53079
|
+
write$2("adGroups.create", "Create a PAUSED clickthrough ad group inside a consideration campaign using campaign budget optimization. Explicit location targeting and a maximum CPC bid are required; automatic targeting expansion is disabled.", "ad_groups", {
|
|
53080
|
+
campaignId: id$7,
|
|
53081
|
+
name: text$3,
|
|
53082
|
+
bidMicros: micros,
|
|
53083
|
+
locations: {
|
|
53084
|
+
...strings,
|
|
53085
|
+
description: "Pinterest LOCATION codes, such as US or CA."
|
|
53086
|
+
},
|
|
53087
|
+
interests: strings,
|
|
53088
|
+
locales: strings
|
|
53089
|
+
}, [
|
|
53090
|
+
"campaignId",
|
|
53091
|
+
"name",
|
|
53092
|
+
"bidMicros",
|
|
53093
|
+
"locations"
|
|
53094
|
+
], {
|
|
53095
|
+
campaign_id: "{campaignId}",
|
|
53096
|
+
name: "{name}",
|
|
53097
|
+
status: "PAUSED",
|
|
53098
|
+
billable_event: "CLICKTHROUGH",
|
|
53099
|
+
bid_strategy_type: "MAX_BID",
|
|
53100
|
+
bid_in_micro_currency: "{bidMicros}",
|
|
53101
|
+
auto_targeting_enabled: false,
|
|
53102
|
+
targeting_spec: {
|
|
53103
|
+
LOCATION: "{locations}",
|
|
53104
|
+
INTEREST: "{interests}",
|
|
53105
|
+
LOCALE: "{locales}"
|
|
53106
|
+
}
|
|
53107
|
+
}),
|
|
53108
|
+
write$2("ads.createFromPin", "Create a PAUSED regular image ad from an existing eligible Pin. Pin creation and media upload are separate Pinterest operations; ad review still applies.", "ads", {
|
|
53109
|
+
adGroupId: id$7,
|
|
53110
|
+
pinId: id$7,
|
|
53111
|
+
name: text$3,
|
|
53112
|
+
destinationUrl: {
|
|
53113
|
+
type: "string",
|
|
53114
|
+
format: "uri"
|
|
53115
|
+
}
|
|
53116
|
+
}, [
|
|
53117
|
+
"adGroupId",
|
|
53118
|
+
"pinId",
|
|
53119
|
+
"name",
|
|
53120
|
+
"destinationUrl"
|
|
53121
|
+
], {
|
|
53122
|
+
ad_group_id: "{adGroupId}",
|
|
53123
|
+
pin_id: "{pinId}",
|
|
53124
|
+
name: "{name}",
|
|
53125
|
+
destination_url: "{destinationUrl}",
|
|
53126
|
+
creative_type: "REGULAR",
|
|
53127
|
+
status: "PAUSED"
|
|
53128
|
+
}),
|
|
53129
|
+
...[
|
|
53130
|
+
"campaigns",
|
|
53131
|
+
"ad_groups",
|
|
53132
|
+
"ads"
|
|
53133
|
+
].flatMap((resource) => ["ACTIVE", "PAUSED"].map((status) => write$2(`${resource === "ad_groups" ? "adGroups" : resource}.${status === "ACTIVE" ? "enable" : "pause"}`, status === "ACTIVE" ? "Enable the entity. Serving can spend immediately when its parents are active; verify billing, lifetime budget, targeting and authorization first." : "Pause the entity, then read status and delayed spend to confirm.", resource, { entityId: id$7 }, ["entityId"], {
|
|
53134
|
+
id: "{entityId}",
|
|
53135
|
+
status
|
|
53136
|
+
}, "PATCH"))),
|
|
53137
|
+
{
|
|
53138
|
+
name: "reports.account",
|
|
53139
|
+
class: "read",
|
|
53140
|
+
requiredScopes: ["ads:read"],
|
|
53141
|
+
description: "Read daily account impressions, paid clicks and spend in microcurrency. Attribution and reporting lag apply; no unconfigured conversion outcomes are inferred.",
|
|
53142
|
+
parameters: parameters$2({
|
|
53143
|
+
startDate: {
|
|
53144
|
+
type: "string",
|
|
53145
|
+
format: "date"
|
|
53146
|
+
},
|
|
53147
|
+
endDate: {
|
|
53148
|
+
type: "string",
|
|
53149
|
+
format: "date"
|
|
53150
|
+
}
|
|
53151
|
+
}, ["startDate", "endDate"]),
|
|
53152
|
+
request: {
|
|
53153
|
+
method: "GET",
|
|
53154
|
+
path: `${accountPath}/analytics`,
|
|
53155
|
+
query: {
|
|
53156
|
+
start_date: "{startDate}",
|
|
53157
|
+
end_date: "{endDate}",
|
|
53158
|
+
granularity: "DAY",
|
|
53159
|
+
columns: "SPEND_IN_MICRO_DOLLAR,PAID_IMPRESSION,TOTAL_CLICKTHROUGH"
|
|
53160
|
+
}
|
|
53161
|
+
}
|
|
53162
|
+
}
|
|
53163
|
+
]
|
|
53164
|
+
});
|
|
53165
|
+
const pinterestAdsConnector = {
|
|
53166
|
+
...rest,
|
|
53167
|
+
async executeMutation(inv) {
|
|
53168
|
+
const result = await rest.executeMutation(inv);
|
|
53169
|
+
if (result.status !== "committed") return result;
|
|
53170
|
+
const items = record$2(result.data)?.items;
|
|
53171
|
+
const item = Array.isArray(items) && items.length === 1 ? record$2(items[0]) : void 0;
|
|
53172
|
+
if (!item) throw new Error("pinterest-ads returned no single-item receipt; reconcile provider state before retrying");
|
|
53173
|
+
if (item.exceptions != null && !Array.isArray(item.exceptions)) throw new Error("pinterest-ads returned an invalid exception receipt; reconcile provider state before retrying");
|
|
53174
|
+
if (Array.isArray(item.exceptions) && item.exceptions.length) throw new Error(`pinterest-ads rejected the item (${item.exceptions.length} provider exceptions); inspect account permissions and field constraints before retrying`);
|
|
53175
|
+
const entity = record$2(item.data);
|
|
53176
|
+
if (!entity || typeof entity.id !== "string" || !entity.id.trim()) throw new Error("pinterest-ads returned no entity ID; reconcile provider state before retrying");
|
|
53177
|
+
return result;
|
|
53178
|
+
}
|
|
53179
|
+
};
|
|
53180
|
+
function record$2(value) {
|
|
53181
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
53182
|
+
}
|
|
53183
|
+
//#endregion
|
|
53184
|
+
//#region src/connectors/adapters/microsoft-ads.ts
|
|
53185
|
+
const scope$1 = "https://ads.microsoft.com/msads.manage";
|
|
53186
|
+
const text$2 = {
|
|
53187
|
+
type: "string",
|
|
53188
|
+
minLength: 1
|
|
53189
|
+
};
|
|
53190
|
+
const id$6 = {
|
|
53191
|
+
...text$2,
|
|
53192
|
+
pattern: "^[0-9]+$"
|
|
53193
|
+
};
|
|
53194
|
+
const money$2 = {
|
|
53195
|
+
type: "number",
|
|
53196
|
+
exclusiveMinimum: 0,
|
|
53197
|
+
description: "Amount in the advertising account currency, not micros or cents."
|
|
53198
|
+
};
|
|
53199
|
+
const date$3 = {
|
|
53200
|
+
type: "object",
|
|
53201
|
+
properties: {
|
|
53202
|
+
Year: {
|
|
53203
|
+
type: "integer",
|
|
53204
|
+
minimum: 2020
|
|
53205
|
+
},
|
|
53206
|
+
Month: {
|
|
53207
|
+
type: "integer",
|
|
53208
|
+
minimum: 1,
|
|
53209
|
+
maximum: 12
|
|
53210
|
+
},
|
|
53211
|
+
Day: {
|
|
53212
|
+
type: "integer",
|
|
53213
|
+
minimum: 1,
|
|
53214
|
+
maximum: 31
|
|
53215
|
+
}
|
|
53216
|
+
},
|
|
53217
|
+
required: [
|
|
53218
|
+
"Year",
|
|
53219
|
+
"Month",
|
|
53220
|
+
"Day"
|
|
53221
|
+
],
|
|
53222
|
+
additionalProperties: false
|
|
53223
|
+
};
|
|
53224
|
+
const accountHeaders = {
|
|
53225
|
+
CustomerAccountId: "{accountId}",
|
|
53226
|
+
CustomerId: "{customerId}"
|
|
53227
|
+
};
|
|
53228
|
+
const customerService = "https://clientcenter.api.bingads.microsoft.com/CustomerManagement/v13";
|
|
53229
|
+
const reportService = "https://reporting.api.bingads.microsoft.com/Reporting/v13";
|
|
53230
|
+
const createdIds = {
|
|
53231
|
+
"campaigns.createSearch": "CampaignIds",
|
|
53232
|
+
"adGroups.create": "AdGroupIds",
|
|
53233
|
+
"keywords.create": "KeywordIds",
|
|
53234
|
+
"campaigns.addLocation": "CampaignCriterionIds",
|
|
53235
|
+
"ads.createResponsiveSearch": "AdIds"
|
|
53236
|
+
};
|
|
53237
|
+
function record$1(value) {
|
|
53238
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
53239
|
+
}
|
|
53240
|
+
function validId(value) {
|
|
53241
|
+
return typeof value === "string" ? /^[1-9][0-9]*$/.test(value) : typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
53242
|
+
}
|
|
53243
|
+
function parameters$1(properties, required = []) {
|
|
53244
|
+
return {
|
|
53245
|
+
type: "object",
|
|
53246
|
+
properties: {
|
|
53247
|
+
accountId: id$6,
|
|
53248
|
+
customerId: id$6,
|
|
53249
|
+
...properties
|
|
53250
|
+
},
|
|
53251
|
+
required: [
|
|
53252
|
+
"accountId",
|
|
53253
|
+
"customerId",
|
|
53254
|
+
...required
|
|
53255
|
+
],
|
|
53256
|
+
additionalProperties: false
|
|
53257
|
+
};
|
|
53258
|
+
}
|
|
53259
|
+
function write$1(name, description, path, properties, required, body, method = "POST") {
|
|
53260
|
+
return {
|
|
53261
|
+
name,
|
|
53262
|
+
description,
|
|
53263
|
+
class: "mutation",
|
|
53264
|
+
cas: "none",
|
|
53265
|
+
externalEffect: true,
|
|
53266
|
+
requiredScopes: [scope$1],
|
|
53267
|
+
parameters: parameters$1(properties, required),
|
|
53268
|
+
request: {
|
|
53269
|
+
method,
|
|
53270
|
+
path,
|
|
53271
|
+
headers: accountHeaders,
|
|
53272
|
+
body
|
|
53273
|
+
}
|
|
53274
|
+
};
|
|
53275
|
+
}
|
|
53276
|
+
function createMicrosoftAdsConnector(options) {
|
|
53277
|
+
if (!options.developerToken?.trim()) throw new Error("Microsoft Ads requires an approved developerToken");
|
|
53278
|
+
const rest = declarativeRestConnector({
|
|
53279
|
+
kind: "microsoft-ads",
|
|
53280
|
+
displayName: "Microsoft Advertising",
|
|
53281
|
+
description: "Microsoft Advertising REST v13 Search campaigns, keyword and location targeting, responsive search ads and asynchronous reports.",
|
|
53282
|
+
auth: {
|
|
53283
|
+
kind: "oauth2",
|
|
53284
|
+
authorizationUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
|
53285
|
+
tokenUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
|
53286
|
+
scopes: [scope$1, "offline_access"],
|
|
53287
|
+
clientIdEnv: "MICROSOFT_ADS_CLIENT_ID",
|
|
53288
|
+
clientSecretEnv: "MICROSOFT_ADS_CLIENT_SECRET"
|
|
53289
|
+
},
|
|
53290
|
+
category: "other",
|
|
53291
|
+
defaultConsistencyModel: "cache",
|
|
53292
|
+
baseUrl: "https://campaign.api.bingads.microsoft.com/CampaignManagement/v13",
|
|
53293
|
+
credentialsExpiredStatuses: [401],
|
|
53294
|
+
credentialHeaders: { DeveloperToken: options.developerToken },
|
|
53295
|
+
test: {
|
|
53296
|
+
method: "POST",
|
|
53297
|
+
path: `${customerService}/User/Query`,
|
|
53298
|
+
body: {}
|
|
53299
|
+
},
|
|
53300
|
+
capabilities: [
|
|
53301
|
+
{
|
|
53302
|
+
name: "users.getCurrent",
|
|
53303
|
+
class: "read",
|
|
53304
|
+
requiredScopes: [scope$1],
|
|
53305
|
+
description: "Get the authenticated user ID and customer roles before account discovery.",
|
|
53306
|
+
parameters: {
|
|
53307
|
+
type: "object",
|
|
53308
|
+
properties: {},
|
|
53309
|
+
additionalProperties: false
|
|
53310
|
+
},
|
|
53311
|
+
request: {
|
|
53312
|
+
method: "POST",
|
|
53313
|
+
path: `${customerService}/User/Query`,
|
|
53314
|
+
body: {}
|
|
53315
|
+
}
|
|
53316
|
+
},
|
|
53317
|
+
{
|
|
53318
|
+
name: "accounts.list",
|
|
53319
|
+
class: "read",
|
|
53320
|
+
requiredScopes: [scope$1],
|
|
53321
|
+
description: "Search accounts accessible to the user returned by users.getCurrent, including currency, timezone, status and parent customer ID. Page index is zero-based.",
|
|
53322
|
+
parameters: {
|
|
53323
|
+
type: "object",
|
|
53324
|
+
properties: {
|
|
53325
|
+
userId: id$6,
|
|
53326
|
+
pageIndex: {
|
|
53327
|
+
type: "integer",
|
|
53328
|
+
minimum: 0
|
|
53329
|
+
}
|
|
53330
|
+
},
|
|
53331
|
+
required: ["userId", "pageIndex"],
|
|
53332
|
+
additionalProperties: false
|
|
53333
|
+
},
|
|
53334
|
+
request: {
|
|
53335
|
+
method: "POST",
|
|
53336
|
+
path: `${customerService}/Accounts/Search`,
|
|
53337
|
+
body: {
|
|
53338
|
+
Predicates: [{
|
|
53339
|
+
Field: "UserId",
|
|
53340
|
+
Operator: "Equals",
|
|
53341
|
+
Value: "{userId}"
|
|
53342
|
+
}],
|
|
53343
|
+
PageInfo: {
|
|
53344
|
+
Index: "{pageIndex}",
|
|
53345
|
+
Size: 100
|
|
53346
|
+
}
|
|
53347
|
+
}
|
|
53348
|
+
}
|
|
53349
|
+
},
|
|
53350
|
+
{
|
|
53351
|
+
name: "campaigns.list",
|
|
53352
|
+
class: "read",
|
|
53353
|
+
requiredScopes: [scope$1],
|
|
53354
|
+
description: "Read Search campaigns, budgets and status for the selected account.",
|
|
53355
|
+
parameters: parameters$1({}),
|
|
53356
|
+
request: {
|
|
53357
|
+
method: "POST",
|
|
53358
|
+
path: "/Campaigns/QueryByAccountId",
|
|
53359
|
+
headers: accountHeaders,
|
|
53360
|
+
body: {
|
|
53361
|
+
AccountId: "{accountId}",
|
|
53362
|
+
CampaignType: "Search"
|
|
53363
|
+
}
|
|
53364
|
+
}
|
|
53365
|
+
},
|
|
53366
|
+
write$1("campaigns.createSearch", "Create a PAUSED Search campaign with a DAILY budget in account currency and MaxClicks bidding capped by maximum CPC. This is not a lifetime spend cap. Configure dated ad groups, location targeting and ads before enabling.", "/Campaigns", {
|
|
53367
|
+
name: text$2,
|
|
53368
|
+
dailyBudget: money$2,
|
|
53369
|
+
maxCpc: money$2,
|
|
53370
|
+
languages: {
|
|
53371
|
+
type: "array",
|
|
53372
|
+
minItems: 1,
|
|
53373
|
+
items: text$2
|
|
53374
|
+
},
|
|
53375
|
+
isPolitical: { type: "boolean" }
|
|
53376
|
+
}, [
|
|
53377
|
+
"name",
|
|
53378
|
+
"dailyBudget",
|
|
53379
|
+
"maxCpc",
|
|
53380
|
+
"languages",
|
|
53381
|
+
"isPolitical"
|
|
53382
|
+
], {
|
|
53383
|
+
AccountId: "{accountId}",
|
|
53384
|
+
Campaigns: [{
|
|
53385
|
+
Name: "{name}",
|
|
53386
|
+
CampaignType: "Search",
|
|
53387
|
+
Status: "Paused",
|
|
53388
|
+
BudgetType: "DailyBudgetStandard",
|
|
53389
|
+
DailyBudget: "{dailyBudget}",
|
|
53390
|
+
BiddingScheme: {
|
|
53391
|
+
Type: "MaxClicks",
|
|
53392
|
+
MaxCpc: { Amount: "{maxCpc}" }
|
|
53393
|
+
},
|
|
53394
|
+
Languages: "{languages}",
|
|
53395
|
+
IsPolitical: "{isPolitical}"
|
|
53396
|
+
}]
|
|
53397
|
+
}),
|
|
53398
|
+
write$1("adGroups.create", "Create a PAUSED Search ad group with explicit start/end dates and currency CPC bid. Serving is limited to Microsoft owned and operated networks; the parent daily budget is not a total cap.", "/AdGroups", {
|
|
53399
|
+
campaignId: id$6,
|
|
53400
|
+
name: text$2,
|
|
53401
|
+
cpcBid: money$2,
|
|
53402
|
+
startDate: date$3,
|
|
53403
|
+
endDate: date$3
|
|
53404
|
+
}, [
|
|
53405
|
+
"campaignId",
|
|
53406
|
+
"name",
|
|
53407
|
+
"cpcBid",
|
|
53408
|
+
"startDate",
|
|
53409
|
+
"endDate"
|
|
53410
|
+
], {
|
|
53411
|
+
CampaignId: "{campaignId}",
|
|
53412
|
+
AdGroups: [{
|
|
53413
|
+
Name: "{name}",
|
|
53414
|
+
Status: "Paused",
|
|
53415
|
+
Network: "OwnedAndOperatedOnly",
|
|
53416
|
+
CpcBid: { Amount: "{cpcBid}" },
|
|
53417
|
+
StartDate: "{startDate}",
|
|
53418
|
+
EndDate: "{endDate}"
|
|
53419
|
+
}]
|
|
53420
|
+
}),
|
|
53421
|
+
write$1("keywords.create", "Create an active Search keyword with an explicit match type and currency bid. Create under a paused ad group before launch.", "/Keywords", {
|
|
53422
|
+
adGroupId: id$6,
|
|
53423
|
+
text: text$2,
|
|
53424
|
+
matchType: {
|
|
53425
|
+
type: "string",
|
|
53426
|
+
enum: [
|
|
53427
|
+
"Exact",
|
|
53428
|
+
"Phrase",
|
|
53429
|
+
"Broad"
|
|
53430
|
+
]
|
|
53431
|
+
},
|
|
53432
|
+
bid: money$2
|
|
53433
|
+
}, [
|
|
53434
|
+
"adGroupId",
|
|
53435
|
+
"text",
|
|
53436
|
+
"matchType",
|
|
53437
|
+
"bid"
|
|
53438
|
+
], {
|
|
53439
|
+
AdGroupId: "{adGroupId}",
|
|
53440
|
+
Keywords: [{
|
|
53441
|
+
Text: "{text}",
|
|
53442
|
+
MatchType: "{matchType}",
|
|
53443
|
+
Bid: { Amount: "{bid}" },
|
|
53444
|
+
Status: "Active"
|
|
53445
|
+
}]
|
|
53446
|
+
}),
|
|
53447
|
+
write$1("campaigns.addLocation", "Add a positive geographic criterion using a Microsoft location ID. Location IDs come from Microsoft geographic location codes; verify location intent settings and targeting before launch.", "/CampaignCriterions", {
|
|
53448
|
+
campaignId: id$6,
|
|
53449
|
+
locationId: id$6
|
|
53450
|
+
}, ["campaignId", "locationId"], {
|
|
53451
|
+
CampaignCriterions: [{
|
|
53452
|
+
CampaignId: "{campaignId}",
|
|
53453
|
+
Type: "BiddableCampaignCriterion",
|
|
53454
|
+
Criterion: {
|
|
53455
|
+
Type: "LocationCriterion",
|
|
53456
|
+
LocationId: "{locationId}"
|
|
53457
|
+
},
|
|
53458
|
+
CriterionBid: {
|
|
53459
|
+
Type: "BidMultiplier",
|
|
53460
|
+
Multiplier: 0
|
|
53461
|
+
}
|
|
53462
|
+
}],
|
|
53463
|
+
CriterionType: "Targets"
|
|
53464
|
+
}),
|
|
53465
|
+
write$1("ads.createResponsiveSearch", "Create a PAUSED responsive Search ad, subject to editorial review. Supply 3–15 headlines and 2–4 descriptions, with at least one final URL.", "/Ads", {
|
|
53466
|
+
adGroupId: id$6,
|
|
53467
|
+
headlines: {
|
|
53468
|
+
type: "array",
|
|
53469
|
+
minItems: 3,
|
|
53470
|
+
maxItems: 15,
|
|
53471
|
+
items: {
|
|
53472
|
+
...text$2,
|
|
53473
|
+
maxLength: 30
|
|
53474
|
+
}
|
|
53475
|
+
},
|
|
53476
|
+
descriptions: {
|
|
53477
|
+
type: "array",
|
|
53478
|
+
minItems: 2,
|
|
53479
|
+
maxItems: 4,
|
|
53480
|
+
items: {
|
|
53481
|
+
...text$2,
|
|
53482
|
+
maxLength: 90
|
|
53483
|
+
}
|
|
53484
|
+
},
|
|
53485
|
+
finalUrls: {
|
|
53486
|
+
type: "array",
|
|
53487
|
+
minItems: 1,
|
|
53488
|
+
items: {
|
|
53489
|
+
type: "string",
|
|
53490
|
+
format: "uri"
|
|
53491
|
+
}
|
|
53492
|
+
}
|
|
53493
|
+
}, [
|
|
53494
|
+
"adGroupId",
|
|
53495
|
+
"headlines",
|
|
53496
|
+
"descriptions",
|
|
53497
|
+
"finalUrls"
|
|
53498
|
+
], {
|
|
53499
|
+
AdGroupId: "{adGroupId}",
|
|
53500
|
+
Ads: [{
|
|
53501
|
+
Type: "ResponsiveSearch",
|
|
53502
|
+
Status: "Paused",
|
|
53503
|
+
Headlines: "{headlines}",
|
|
53504
|
+
Descriptions: "{descriptions}",
|
|
53505
|
+
FinalUrls: "{finalUrls}"
|
|
53506
|
+
}]
|
|
53507
|
+
}),
|
|
53508
|
+
...["Active", "Paused"].flatMap((status) => [
|
|
53509
|
+
write$1(`campaigns.${status === "Active" ? "enable" : "pause"}`, status === "Active" ? "Enable the campaign. Active child entities can spend immediately; confirm billing, daily budget, dated ad groups, targeting and authorization." : "Pause campaign delivery and verify provider status and delayed spend.", "/Campaigns", { campaignId: id$6 }, ["campaignId"], {
|
|
53510
|
+
AccountId: "{accountId}",
|
|
53511
|
+
Campaigns: [{
|
|
53512
|
+
Id: "{campaignId}",
|
|
53513
|
+
Status: status
|
|
53514
|
+
}]
|
|
53515
|
+
}, "PUT"),
|
|
53516
|
+
write$1(`adGroups.${status === "Active" ? "enable" : "pause"}`, "Set the ad group serving state. Enabling under an active campaign can spend immediately.", "/AdGroups", {
|
|
53517
|
+
campaignId: id$6,
|
|
53518
|
+
adGroupId: id$6
|
|
53519
|
+
}, ["campaignId", "adGroupId"], {
|
|
53520
|
+
CampaignId: "{campaignId}",
|
|
53521
|
+
AdGroups: [{
|
|
53522
|
+
Id: "{adGroupId}",
|
|
53523
|
+
Status: status
|
|
53524
|
+
}]
|
|
53525
|
+
}, "PUT"),
|
|
53526
|
+
write$1(`ads.${status === "Active" ? "enable" : "pause"}`, "Set a responsive Search ad serving state. Enabling under active parents can spend immediately.", "/Ads", {
|
|
53527
|
+
adGroupId: id$6,
|
|
53528
|
+
adId: id$6
|
|
53529
|
+
}, ["adGroupId", "adId"], {
|
|
53530
|
+
AdGroupId: "{adGroupId}",
|
|
53531
|
+
Ads: [{
|
|
53532
|
+
Id: "{adId}",
|
|
53533
|
+
Type: "ResponsiveSearch",
|
|
53534
|
+
Status: status
|
|
53535
|
+
}]
|
|
53536
|
+
}, "PUT")
|
|
53537
|
+
]),
|
|
53538
|
+
{
|
|
53539
|
+
name: "reports.requestCampaigns",
|
|
53540
|
+
class: "read",
|
|
53541
|
+
requiredScopes: [scope$1],
|
|
53542
|
+
description: "Submit a daily campaign performance CSV report for a closed date range. Returns ReportRequestId; poll reports.get. Spend is in account currency and attribution can lag.",
|
|
53543
|
+
parameters: parameters$1({
|
|
53544
|
+
startDate: date$3,
|
|
53545
|
+
endDate: date$3
|
|
53546
|
+
}, ["startDate", "endDate"]),
|
|
53547
|
+
request: {
|
|
53548
|
+
method: "POST",
|
|
53549
|
+
path: `${reportService}/GenerateReport/Submit`,
|
|
53550
|
+
headers: accountHeaders,
|
|
53551
|
+
body: { ReportRequest: {
|
|
53552
|
+
Type: "CampaignPerformanceReportRequest",
|
|
53553
|
+
Format: "Csv",
|
|
53554
|
+
Aggregation: "Daily",
|
|
53555
|
+
ReturnOnlyCompleteData: true,
|
|
53556
|
+
Columns: [
|
|
53557
|
+
"TimePeriod",
|
|
53558
|
+
"AccountId",
|
|
53559
|
+
"CampaignId",
|
|
53560
|
+
"CampaignName",
|
|
53561
|
+
"Impressions",
|
|
53562
|
+
"Clicks",
|
|
53563
|
+
"Spend",
|
|
53564
|
+
"Conversions"
|
|
53565
|
+
],
|
|
53566
|
+
Scope: { AccountIds: ["{accountId}"] },
|
|
53567
|
+
Time: {
|
|
53568
|
+
CustomDateRangeStart: "{startDate}",
|
|
53569
|
+
CustomDateRangeEnd: "{endDate}"
|
|
53570
|
+
}
|
|
53571
|
+
} }
|
|
53572
|
+
}
|
|
53573
|
+
},
|
|
53574
|
+
{
|
|
53575
|
+
name: "reports.get",
|
|
53576
|
+
class: "read",
|
|
53577
|
+
requiredScopes: [scope$1],
|
|
53578
|
+
description: "Poll report status and retrieve its expiring download URL. Download without forwarding advertising credentials; never interpret Pending as completed data.",
|
|
53579
|
+
parameters: parameters$1({ reportRequestId: text$2 }, ["reportRequestId"]),
|
|
53580
|
+
request: {
|
|
53581
|
+
method: "POST",
|
|
53582
|
+
path: `${reportService}/GenerateReport/Poll`,
|
|
53583
|
+
headers: accountHeaders,
|
|
53584
|
+
body: { ReportRequestId: "{reportRequestId}" }
|
|
53585
|
+
}
|
|
53586
|
+
}
|
|
53587
|
+
]
|
|
53588
|
+
});
|
|
53589
|
+
return {
|
|
53590
|
+
...rest,
|
|
53591
|
+
async executeRead(inv) {
|
|
53592
|
+
const result = await rest.executeRead(inv);
|
|
53593
|
+
if (inv.capabilityName !== "users.getCurrent") return result;
|
|
53594
|
+
const data = record$1(result.data), user = record$1(data?.User);
|
|
53595
|
+
if (!user || !validId(user.Id)) throw new Error("microsoft-ads returned no current user identity");
|
|
53596
|
+
const name = record$1(user.Name);
|
|
53597
|
+
return {
|
|
53598
|
+
...result,
|
|
53599
|
+
data: {
|
|
53600
|
+
User: {
|
|
53601
|
+
Id: user.Id,
|
|
53602
|
+
CustomerId: user.CustomerId,
|
|
53603
|
+
UserName: user.UserName,
|
|
53604
|
+
UserLifeCycleStatus: user.UserLifeCycleStatus,
|
|
53605
|
+
...name ? { Name: {
|
|
53606
|
+
FirstName: name.FirstName,
|
|
53607
|
+
LastName: name.LastName,
|
|
53608
|
+
MiddleInitial: name.MiddleInitial
|
|
53609
|
+
} } : {}
|
|
53610
|
+
},
|
|
53611
|
+
CustomerRoles: data?.CustomerRoles
|
|
53612
|
+
}
|
|
53613
|
+
};
|
|
53614
|
+
},
|
|
53615
|
+
async executeMutation(inv) {
|
|
53616
|
+
if (inv.capabilityName === "ads.createResponsiveSearch") {
|
|
53617
|
+
const assets = (value) => {
|
|
53618
|
+
if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) throw new Error("Microsoft Search ad assets must be arrays of text");
|
|
53619
|
+
return value.map((Text) => ({ Asset: {
|
|
53620
|
+
Type: "TextAsset",
|
|
53621
|
+
Text
|
|
53622
|
+
} }));
|
|
53623
|
+
};
|
|
53624
|
+
inv = {
|
|
53625
|
+
...inv,
|
|
53626
|
+
args: {
|
|
53627
|
+
...inv.args,
|
|
53628
|
+
headlines: assets(inv.args.headlines),
|
|
53629
|
+
descriptions: assets(inv.args.descriptions)
|
|
53630
|
+
}
|
|
53631
|
+
};
|
|
53632
|
+
}
|
|
53633
|
+
const result = await rest.executeMutation(inv);
|
|
53634
|
+
if (result.status !== "committed") return result;
|
|
53635
|
+
const idField = createdIds[inv.capabilityName], data = record$1(result.data);
|
|
53636
|
+
if (result.data === null && !idField) return result;
|
|
53637
|
+
if (!data || "raw" in data) throw new Error("microsoft-ads returned an invalid mutation receipt; reconcile provider state before retrying");
|
|
53638
|
+
for (const field of ["PartialErrors", "NestedPartialErrors"]) {
|
|
53639
|
+
const errors = data[field];
|
|
53640
|
+
if (errors != null && !Array.isArray(errors)) throw new Error("microsoft-ads returned an invalid error receipt; reconcile provider state before retrying");
|
|
53641
|
+
if (Array.isArray(errors) && errors.some((error) => error != null)) throw new Error(`microsoft-ads rejected the item (${errors.length} provider errors); inspect account permissions and field constraints before retrying`);
|
|
53642
|
+
}
|
|
53643
|
+
if (idField) {
|
|
53644
|
+
const ids = data[idField];
|
|
53645
|
+
if (!Array.isArray(ids) || ids.length !== 1 || !validId(ids[0])) throw new Error("microsoft-ads returned no created entity ID; reconcile provider state before retrying");
|
|
53646
|
+
}
|
|
53647
|
+
return result;
|
|
53648
|
+
}
|
|
53649
|
+
};
|
|
53650
|
+
}
|
|
53651
|
+
//#endregion
|
|
53652
|
+
//#region src/connectors/adapters/amazon-ads.ts
|
|
53653
|
+
const scope = "advertising::campaign_management";
|
|
53654
|
+
const text$1 = {
|
|
53655
|
+
type: "string",
|
|
53656
|
+
minLength: 1
|
|
53657
|
+
};
|
|
53658
|
+
const id$5 = {
|
|
53659
|
+
...text$1,
|
|
53660
|
+
pattern: "^[0-9]+$"
|
|
53661
|
+
};
|
|
53662
|
+
const money$1 = {
|
|
53663
|
+
type: "number",
|
|
53664
|
+
exclusiveMinimum: 0,
|
|
53665
|
+
description: "Amount in the profile currency, not micros or cents. Provider marketplace minimums apply."
|
|
53666
|
+
};
|
|
53667
|
+
const date$2 = {
|
|
53668
|
+
type: "string",
|
|
53669
|
+
format: "date",
|
|
53670
|
+
description: "YYYY-MM-DD in the advertiser marketplace timezone."
|
|
53671
|
+
};
|
|
53672
|
+
const resources = {
|
|
53673
|
+
campaigns: ["spCampaign", "campaignId"],
|
|
53674
|
+
adGroups: ["spAdGroup", "adGroupId"],
|
|
53675
|
+
keywords: ["spKeyword", "keywordId"],
|
|
53676
|
+
productAds: ["spProductAd", "adId"]
|
|
53677
|
+
};
|
|
53678
|
+
function record(value) {
|
|
53679
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
53680
|
+
}
|
|
53681
|
+
function parameters(properties, required = []) {
|
|
53682
|
+
return {
|
|
53683
|
+
type: "object",
|
|
53684
|
+
properties: {
|
|
53685
|
+
profileId: id$5,
|
|
53686
|
+
...properties
|
|
53687
|
+
},
|
|
53688
|
+
required: ["profileId", ...required],
|
|
53689
|
+
additionalProperties: false
|
|
53690
|
+
};
|
|
53691
|
+
}
|
|
53692
|
+
function headers(resource) {
|
|
53693
|
+
const media = `application/vnd.${resources[resource][0]}.v3+json`;
|
|
53694
|
+
return {
|
|
53695
|
+
"Amazon-Advertising-API-Scope": "{profileId}",
|
|
53696
|
+
accept: media,
|
|
53697
|
+
"content-type": media
|
|
53698
|
+
};
|
|
53699
|
+
}
|
|
53700
|
+
function write(name, description, resource, properties, required, item, method = "POST") {
|
|
53701
|
+
return {
|
|
53702
|
+
name,
|
|
53703
|
+
description,
|
|
53704
|
+
class: "mutation",
|
|
53705
|
+
cas: "none",
|
|
53706
|
+
externalEffect: true,
|
|
53707
|
+
requiredScopes: [scope],
|
|
53708
|
+
parameters: parameters(properties, required),
|
|
53709
|
+
request: {
|
|
53710
|
+
method,
|
|
53711
|
+
path: `/sp/${resource}`,
|
|
53712
|
+
headers: headers(resource),
|
|
53713
|
+
body: { [resource]: [item] }
|
|
53714
|
+
}
|
|
53715
|
+
};
|
|
53716
|
+
}
|
|
53717
|
+
/** Application identity stays in trusted runtime configuration, never tool args. */
|
|
53718
|
+
function createAmazonAdsConnector(options) {
|
|
53719
|
+
if (!options.clientId?.trim()) throw new Error("Amazon Ads requires its approved application clientId");
|
|
53720
|
+
const rest = declarativeRestConnector({
|
|
53721
|
+
kind: "amazon-ads",
|
|
53722
|
+
displayName: "Amazon Ads",
|
|
53723
|
+
description: "Manage Sponsored Products for eligible Amazon sellers/vendors, marketplace profiles and campaign reports. Not a general SaaS display-ad connector.",
|
|
53724
|
+
auth: {
|
|
53725
|
+
kind: "oauth2",
|
|
53726
|
+
authorizationUrl: "https://www.amazon.com/ap/oa",
|
|
53727
|
+
tokenUrl: "https://api.amazon.com/auth/o2",
|
|
53728
|
+
scopes: [scope],
|
|
53729
|
+
clientIdEnv: "AMAZON_ADS_CLIENT_ID",
|
|
53730
|
+
clientSecretEnv: "AMAZON_ADS_CLIENT_SECRET"
|
|
53731
|
+
},
|
|
53732
|
+
category: "other",
|
|
53733
|
+
defaultConsistencyModel: "cache",
|
|
53734
|
+
credentialsExpiredStatuses: [401],
|
|
53735
|
+
baseUrl: {
|
|
53736
|
+
metadataKey: "apiBaseUrl",
|
|
53737
|
+
fallback: "https://advertising-api.amazon.com"
|
|
53738
|
+
},
|
|
53739
|
+
allowedBaseUrls: [
|
|
53740
|
+
"https://advertising-api.amazon.com",
|
|
53741
|
+
"https://advertising-api-eu.amazon.com",
|
|
53742
|
+
"https://advertising-api-fe.amazon.com"
|
|
53743
|
+
],
|
|
53744
|
+
credentialHeaders: { "Amazon-Advertising-API-ClientId": options.clientId },
|
|
53745
|
+
test: {
|
|
53746
|
+
method: "GET",
|
|
53747
|
+
path: "/v2/profiles"
|
|
53748
|
+
},
|
|
53749
|
+
capabilities: [
|
|
53750
|
+
{
|
|
53751
|
+
name: "profiles.list",
|
|
53752
|
+
class: "read",
|
|
53753
|
+
requiredScopes: [scope],
|
|
53754
|
+
description: "Discover authorized marketplace profiles, currency, timezone, and seller/vendor account type on the configured regional endpoint.",
|
|
53755
|
+
parameters: {
|
|
53756
|
+
type: "object",
|
|
53757
|
+
properties: {},
|
|
53758
|
+
additionalProperties: false
|
|
53759
|
+
},
|
|
53760
|
+
request: {
|
|
53761
|
+
method: "GET",
|
|
53762
|
+
path: "/v2/profiles"
|
|
53763
|
+
}
|
|
53764
|
+
},
|
|
53765
|
+
...Object.keys(resources).map((resourceName) => {
|
|
53766
|
+
const resource = resourceName;
|
|
53767
|
+
return {
|
|
53768
|
+
name: `${resource}.list`,
|
|
53769
|
+
class: "read",
|
|
53770
|
+
requiredScopes: [scope],
|
|
53771
|
+
description: `List Sponsored Products ${resource} and native statuses; use nextToken for pagination.`,
|
|
53772
|
+
parameters: parameters({ nextToken: text$1 }),
|
|
53773
|
+
request: {
|
|
53774
|
+
method: "POST",
|
|
53775
|
+
path: `/sp/${resource}/list`,
|
|
53776
|
+
headers: headers(resource),
|
|
53777
|
+
body: {
|
|
53778
|
+
nextToken: "{nextToken}",
|
|
53779
|
+
maxResults: 100
|
|
53780
|
+
}
|
|
53781
|
+
}
|
|
53782
|
+
};
|
|
53783
|
+
}),
|
|
53784
|
+
write("campaigns.createSponsoredProducts", "Create a PAUSED manual Sponsored Products campaign. DAILY budget is in profile currency and is an average daily budget, not a hard daily or lifetime spend cap. Required end date bounds the schedule; only eligible products may advertise.", "campaigns", {
|
|
53785
|
+
name: text$1,
|
|
53786
|
+
dailyBudget: money$1,
|
|
53787
|
+
startDate: date$2,
|
|
53788
|
+
endDate: date$2
|
|
53789
|
+
}, [
|
|
53790
|
+
"name",
|
|
53791
|
+
"dailyBudget",
|
|
53792
|
+
"startDate",
|
|
53793
|
+
"endDate"
|
|
53794
|
+
], {
|
|
53795
|
+
name: "{name}",
|
|
53796
|
+
state: "PAUSED",
|
|
53797
|
+
targetingType: "MANUAL",
|
|
53798
|
+
budget: {
|
|
53799
|
+
budgetType: "DAILY",
|
|
53800
|
+
budget: "{dailyBudget}"
|
|
53801
|
+
},
|
|
53802
|
+
startDate: "{startDate}",
|
|
53803
|
+
endDate: "{endDate}",
|
|
53804
|
+
dynamicBidding: { strategy: "LEGACY_FOR_SALES" }
|
|
53805
|
+
}),
|
|
53806
|
+
write("adGroups.create", "Create a PAUSED Sponsored Products ad group with a default bid in profile currency.", "adGroups", {
|
|
53807
|
+
campaignId: id$5,
|
|
53808
|
+
name: text$1,
|
|
53809
|
+
defaultBid: money$1
|
|
53810
|
+
}, [
|
|
53811
|
+
"campaignId",
|
|
53812
|
+
"name",
|
|
53813
|
+
"defaultBid"
|
|
53814
|
+
], {
|
|
53815
|
+
campaignId: "{campaignId}",
|
|
53816
|
+
name: "{name}",
|
|
53817
|
+
defaultBid: "{defaultBid}",
|
|
53818
|
+
state: "PAUSED"
|
|
53819
|
+
}),
|
|
53820
|
+
write("keywords.create", "Create a PAUSED keyword target in a manual Sponsored Products campaign. Bid is in profile currency; explicitly enable after review.", "keywords", {
|
|
53821
|
+
campaignId: id$5,
|
|
53822
|
+
adGroupId: id$5,
|
|
53823
|
+
keywordText: text$1,
|
|
53824
|
+
matchType: {
|
|
53825
|
+
type: "string",
|
|
53826
|
+
enum: [
|
|
53827
|
+
"EXACT",
|
|
53828
|
+
"PHRASE",
|
|
53829
|
+
"BROAD"
|
|
53830
|
+
]
|
|
53831
|
+
},
|
|
53832
|
+
bid: money$1
|
|
53833
|
+
}, [
|
|
53834
|
+
"campaignId",
|
|
53835
|
+
"adGroupId",
|
|
53836
|
+
"keywordText",
|
|
53837
|
+
"matchType",
|
|
53838
|
+
"bid"
|
|
53839
|
+
], {
|
|
53840
|
+
campaignId: "{campaignId}",
|
|
53841
|
+
adGroupId: "{adGroupId}",
|
|
53842
|
+
keywordText: "{keywordText}",
|
|
53843
|
+
matchType: "{matchType}",
|
|
53844
|
+
bid: "{bid}",
|
|
53845
|
+
state: "PAUSED"
|
|
53846
|
+
}),
|
|
53847
|
+
...["sku", "asin"].map((productKey) => write(productKey === "sku" ? "productAds.createSellerProduct" : "productAds.createVendorProduct", `Create a PAUSED product ad for an eligible ${productKey === "sku" ? "seller SKU" : "vendor ASIN"}. Product availability, account eligibility and Amazon review still apply; this cannot advertise arbitrary SaaS URLs.`, "productAds", {
|
|
53848
|
+
campaignId: id$5,
|
|
53849
|
+
adGroupId: id$5,
|
|
53850
|
+
[productKey]: text$1
|
|
53851
|
+
}, [
|
|
53852
|
+
"campaignId",
|
|
53853
|
+
"adGroupId",
|
|
53854
|
+
productKey
|
|
53855
|
+
], {
|
|
53856
|
+
campaignId: "{campaignId}",
|
|
53857
|
+
adGroupId: "{adGroupId}",
|
|
53858
|
+
[productKey]: `{${productKey}}`,
|
|
53859
|
+
state: "PAUSED"
|
|
53860
|
+
})),
|
|
53861
|
+
...Object.entries(resources).flatMap(([resourceName, [, entityKey]]) => ["ENABLED", "PAUSED"].map((state) => write(`${resourceName}.${state === "ENABLED" ? "enable" : "pause"}`, state === "ENABLED" ? "Enable the entity. When parents and targets are enabled this can spend immediately; verify product eligibility, budget, end date and authorization first." : "Pause the entity; confirm provider status and delayed spend afterward.", resourceName, { entityId: id$5 }, ["entityId"], {
|
|
53862
|
+
[entityKey]: "{entityId}",
|
|
53863
|
+
state
|
|
53864
|
+
}, "PUT"))),
|
|
53865
|
+
{
|
|
53866
|
+
name: "reports.requestCampaigns",
|
|
53867
|
+
class: "read",
|
|
53868
|
+
requiredScopes: [scope],
|
|
53869
|
+
description: "Request a daily Sponsored Products campaign report. Returns reportId; poll reports.get until COMPLETED. Costs are profile currency; attribution and reporting lag apply.",
|
|
53870
|
+
parameters: parameters({
|
|
53871
|
+
startDate: date$2,
|
|
53872
|
+
endDate: date$2
|
|
53873
|
+
}, ["startDate", "endDate"]),
|
|
53874
|
+
request: {
|
|
53875
|
+
method: "POST",
|
|
53876
|
+
path: "/reporting/reports",
|
|
53877
|
+
headers: {
|
|
53878
|
+
"Amazon-Advertising-API-Scope": "{profileId}",
|
|
53879
|
+
"content-type": "application/vnd.createasyncreportrequest.v3+json"
|
|
53880
|
+
},
|
|
53881
|
+
body: {
|
|
53882
|
+
startDate: "{startDate}",
|
|
53883
|
+
endDate: "{endDate}",
|
|
53884
|
+
configuration: {
|
|
53885
|
+
adProduct: "SPONSORED_PRODUCTS",
|
|
53886
|
+
groupBy: ["campaign"],
|
|
53887
|
+
columns: [
|
|
53888
|
+
"date",
|
|
53889
|
+
"campaignId",
|
|
53890
|
+
"campaignName",
|
|
53891
|
+
"impressions",
|
|
53892
|
+
"clicks",
|
|
53893
|
+
"cost"
|
|
53894
|
+
],
|
|
53895
|
+
reportTypeId: "spCampaigns",
|
|
53896
|
+
timeUnit: "DAILY",
|
|
53897
|
+
format: "GZIP_JSON"
|
|
53898
|
+
}
|
|
53899
|
+
}
|
|
53900
|
+
}
|
|
53901
|
+
},
|
|
53902
|
+
{
|
|
53903
|
+
name: "reports.get",
|
|
53904
|
+
class: "read",
|
|
53905
|
+
requiredScopes: [scope],
|
|
53906
|
+
description: "Read asynchronous report status and its expiring download URL. Download completed GZIP_JSON without forwarding advertising credentials to the download host.",
|
|
53907
|
+
parameters: parameters({ reportId: text$1 }, ["reportId"]),
|
|
53908
|
+
request: {
|
|
53909
|
+
method: "GET",
|
|
53910
|
+
path: "/reporting/reports/{reportId}",
|
|
53911
|
+
headers: { "Amazon-Advertising-API-Scope": "{profileId}" }
|
|
53912
|
+
}
|
|
53913
|
+
}
|
|
53914
|
+
]
|
|
53915
|
+
});
|
|
53916
|
+
return {
|
|
53917
|
+
...rest,
|
|
53918
|
+
async executeMutation(inv) {
|
|
53919
|
+
const result = await rest.executeMutation(inv);
|
|
53920
|
+
if (result.status !== "committed") return result;
|
|
53921
|
+
const resource = inv.capabilityName.split(".")[0];
|
|
53922
|
+
const receipt = record(record(result.data)?.[resource]);
|
|
53923
|
+
if (!receipt) throw new Error("amazon-ads returned no resource receipt; reconcile provider state before retrying");
|
|
53924
|
+
if (receipt.error != null && !Array.isArray(receipt.error)) throw new Error("amazon-ads returned an invalid error receipt; reconcile provider state before retrying");
|
|
53925
|
+
if (Array.isArray(receipt.error) && receipt.error.length) throw new Error(`amazon-ads rejected the item (${receipt.error.length} provider errors); inspect profile eligibility and field constraints before retrying`);
|
|
53926
|
+
const success = Array.isArray(receipt.success) && receipt.success.length === 1 ? record(receipt.success[0]) : void 0;
|
|
53927
|
+
if (!success || success.index !== 0) throw new Error("amazon-ads returned no single-item success receipt; reconcile provider state before retrying");
|
|
53928
|
+
if (inv.capabilityName.includes(".create")) {
|
|
53929
|
+
const [, idKey] = resources[resource];
|
|
53930
|
+
const entityKey = {
|
|
53931
|
+
campaigns: "campaign",
|
|
53932
|
+
adGroups: "adGroup",
|
|
53933
|
+
keywords: "keyword",
|
|
53934
|
+
productAds: "productAd"
|
|
53935
|
+
}[resource];
|
|
53936
|
+
const entityId = success[idKey] ?? record(success[entityKey])?.[idKey];
|
|
53937
|
+
if (typeof entityId !== "string" || !entityId.trim()) throw new Error("amazon-ads returned no created entity ID; reconcile provider state before retrying");
|
|
53938
|
+
}
|
|
53939
|
+
return result;
|
|
53940
|
+
}
|
|
53941
|
+
};
|
|
53942
|
+
}
|
|
53943
|
+
//#endregion
|
|
50207
53944
|
//#region src/connectors/adapters/google-cloud-storage.ts
|
|
50208
53945
|
/**
|
|
50209
53946
|
* Google Cloud Storage connector — buckets, objects, and ACLs.
|
|
@@ -91547,8 +95284,8 @@ async function call$1(source, path, init) {
|
|
|
91547
95284
|
});
|
|
91548
95285
|
throw error;
|
|
91549
95286
|
}
|
|
91550
|
-
if (record(result) && result.success === false) throw new ProviderProtocolError("Cloudbeds rejected the request", "provider_rejected", 422, true);
|
|
91551
|
-
if (!record(result) || result.success !== true) throw new ProviderProtocolError("Cloudbeds returned an unsuccessful or malformed response", "invalid_response");
|
|
95287
|
+
if (record$3(result) && result.success === false) throw new ProviderProtocolError("Cloudbeds rejected the request", "provider_rejected", 422, true);
|
|
95288
|
+
if (!record$3(result) || result.success !== true) throw new ProviderProtocolError("Cloudbeds returned an unsuccessful or malformed response", "invalid_response");
|
|
91552
95289
|
return result;
|
|
91553
95290
|
}
|
|
91554
95291
|
function date$1(value, label) {
|
|
@@ -91590,7 +95327,7 @@ function reservationQuery(args, property) {
|
|
|
91590
95327
|
function reservations(result, property, query) {
|
|
91591
95328
|
if (!Array.isArray(result.data) || !Number.isSafeInteger(result.count) || !Number.isSafeInteger(result.total) || result.count < 0 || result.total < 0 || result.count !== result.data.length || result.total < result.count || result.count > Number(query.get("pageSize"))) throw new ProviderProtocolError("Cloudbeds returned malformed reservation pagination", "invalid_response");
|
|
91592
95329
|
const items = result.data.map((raw) => {
|
|
91593
|
-
if (!record(raw) || raw.propertyID !== property || typeof raw.reservationID !== "string" || !raw.reservationID || typeof raw.startDate !== "string" || typeof raw.endDate !== "string" || typeof raw.status !== "string" || !STATUSES.has(raw.status)) throw new ProviderProtocolError("Cloudbeds returned a reservation outside the connected property or with invalid fields", "invalid_response");
|
|
95330
|
+
if (!record$3(raw) || raw.propertyID !== property || typeof raw.reservationID !== "string" || !raw.reservationID || typeof raw.startDate !== "string" || typeof raw.endDate !== "string" || typeof raw.status !== "string" || !STATUSES.has(raw.status)) throw new ProviderProtocolError("Cloudbeds returned a reservation outside the connected property or with invalid fields", "invalid_response");
|
|
91594
95331
|
try {
|
|
91595
95332
|
date$1(raw.startDate, "provider startDate");
|
|
91596
95333
|
date$1(raw.endDate, "provider endDate");
|
|
@@ -91640,9 +95377,9 @@ function roomAvailabilityQuery(args, property) {
|
|
|
91640
95377
|
function roomAvailability(result, property, query) {
|
|
91641
95378
|
if (!Array.isArray(result.data) || !Number.isSafeInteger(result.count) || !Number.isSafeInteger(result.total) || !Number.isSafeInteger(result.roomCount) || result.count < 0 || result.count > 1 || result.total < result.count || result.count !== result.data.length || result.roomCount < 0 || result.count > Number(query.get("pageSize"))) throw new ProviderProtocolError("Cloudbeds returned malformed room availability pagination", "invalid_response");
|
|
91642
95379
|
const roomTypes = result.data.flatMap((raw) => {
|
|
91643
|
-
if (!record(raw) || raw.propertyID !== property || !Array.isArray(raw.propertyRooms)) throw new ProviderProtocolError("Cloudbeds returned availability outside the connected property", "invalid_response");
|
|
95380
|
+
if (!record$3(raw) || raw.propertyID !== property || !Array.isArray(raw.propertyRooms)) throw new ProviderProtocolError("Cloudbeds returned availability outside the connected property", "invalid_response");
|
|
91644
95381
|
return raw.propertyRooms.map((room) => {
|
|
91645
|
-
if (!record(room) || typeof room.roomTypeID !== "string" || !room.roomTypeID || !Number.isSafeInteger(room.roomsAvailable) || room.roomsAvailable < 0 || room.roomRate !== void 0 && (typeof room.roomRate !== "number" || !Number.isFinite(room.roomRate) || room.roomRate < 0)) throw new ProviderProtocolError("Cloudbeds returned malformed room-type availability", "invalid_response");
|
|
95382
|
+
if (!record$3(room) || typeof room.roomTypeID !== "string" || !room.roomTypeID || !Number.isSafeInteger(room.roomsAvailable) || room.roomsAvailable < 0 || room.roomRate !== void 0 && (typeof room.roomRate !== "number" || !Number.isFinite(room.roomRate) || room.roomRate < 0)) throw new ProviderProtocolError("Cloudbeds returned malformed room-type availability", "invalid_response");
|
|
91646
95383
|
return {
|
|
91647
95384
|
roomTypeId: room.roomTypeID,
|
|
91648
95385
|
roomTypeName: providerText$1(room.roomTypeName),
|
|
@@ -91687,7 +95424,7 @@ function formForItem(inv, property) {
|
|
|
91687
95424
|
itemPaid: "false"
|
|
91688
95425
|
});
|
|
91689
95426
|
args.taxes.forEach((tax, index) => {
|
|
91690
|
-
if (!record(tax)) throw new Error("cloudbeds: invalid tax");
|
|
95427
|
+
if (!record$3(tax)) throw new Error("cloudbeds: invalid tax");
|
|
91691
95428
|
form.set(`items[0][itemTaxes][${index}][taxName]`, boundedString(tax.taxName, "taxName"));
|
|
91692
95429
|
form.set(`items[0][itemTaxes][${index}][taxValue]`, money(tax.taxValue, "taxValue", true).toFixed(2));
|
|
91693
95430
|
});
|
|
@@ -91893,13 +95630,13 @@ const cloudbedsConnector = {
|
|
|
91893
95630
|
reservationID: reservationId
|
|
91894
95631
|
});
|
|
91895
95632
|
const reservation = await call$1(inv.source, `getReservation?${query}`, { method: "GET" });
|
|
91896
|
-
if (!record(reservation.data) || reservation.data.propertyID !== property || reservation.data.reservationID !== reservationId) throw new ProviderProtocolError("Cloudbeds could not verify the reservation belongs to the connected property", "invalid_response");
|
|
95633
|
+
if (!record$3(reservation.data) || reservation.data.propertyID !== property || reservation.data.reservationID !== reservationId) throw new ProviderProtocolError("Cloudbeds could not verify the reservation belongs to the connected property", "invalid_response");
|
|
91897
95634
|
const result = await call$1(inv.source, "postCustomItem", {
|
|
91898
95635
|
method: "POST",
|
|
91899
95636
|
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
91900
95637
|
body: form.toString()
|
|
91901
95638
|
});
|
|
91902
|
-
if (!record(result.data)) throw new ProviderProtocolError("Cloudbeds returned a malformed folio item receipt", "invalid_response");
|
|
95639
|
+
if (!record$3(result.data)) throw new ProviderProtocolError("Cloudbeds returned a malformed folio item receipt", "invalid_response");
|
|
91903
95640
|
const soldProductId = typeof result.data.soldProductID === "string" && result.data.soldProductID ? result.data.soldProductID : null;
|
|
91904
95641
|
const notice = providerText$1(result.data.notice);
|
|
91905
95642
|
const duplicate = soldProductId === null && notice !== null && /referenceid/i.test(notice) && /nothing was created/i.test(notice);
|
|
@@ -91954,7 +95691,7 @@ function selectedListings(source) {
|
|
|
91954
95691
|
if (!Array.isArray(value) || value.length < 1 || value.length > 100) throw new Error("pricelabs: connection requires one or more pinned listings");
|
|
91955
95692
|
const seen = /* @__PURE__ */ new Set();
|
|
91956
95693
|
return value.map((raw) => {
|
|
91957
|
-
if (!record(raw)) throw new Error("pricelabs: invalid pinned listing");
|
|
95694
|
+
if (!record$3(raw)) throw new Error("pricelabs: invalid pinned listing");
|
|
91958
95695
|
const id = identifier(raw.id, "pinned listing id");
|
|
91959
95696
|
const pms = identifier(raw.pms, "pinned listing pms");
|
|
91960
95697
|
const key = JSON.stringify([id, pms]);
|
|
@@ -91996,7 +95733,7 @@ function date(value, label) {
|
|
|
91996
95733
|
return value;
|
|
91997
95734
|
}
|
|
91998
95735
|
function readPrice(row, from, to) {
|
|
91999
|
-
if (!record(row) || typeof row.date !== "string" || !DATE.test(row.date) || row.date < from || row.date > to || typeof row.price !== "number" || !Number.isFinite(row.price) || row.price < 0 || row.min_stay !== void 0 && (!Number.isSafeInteger(row.min_stay) || row.min_stay < 1) || row.unbookable !== void 0 && row.unbookable !== 0 && row.unbookable !== 1 && row.unbookable !== true && row.unbookable !== false) throw new ProviderProtocolError("PriceLabs returned a malformed daily price", "invalid_response");
|
|
95736
|
+
if (!record$3(row) || typeof row.date !== "string" || !DATE.test(row.date) || row.date < from || row.date > to || typeof row.price !== "number" || !Number.isFinite(row.price) || row.price < 0 || row.min_stay !== void 0 && (!Number.isSafeInteger(row.min_stay) || row.min_stay < 1) || row.unbookable !== void 0 && row.unbookable !== 0 && row.unbookable !== 1 && row.unbookable !== true && row.unbookable !== false) throw new ProviderProtocolError("PriceLabs returned a malformed daily price", "invalid_response");
|
|
92000
95737
|
try {
|
|
92001
95738
|
date(row.date, "provider date");
|
|
92002
95739
|
} catch {
|
|
@@ -92073,7 +95810,7 @@ const pricelabsConnector = {
|
|
|
92073
95810
|
dateTo
|
|
92074
95811
|
}] })
|
|
92075
95812
|
});
|
|
92076
|
-
if (!Array.isArray(result) || result.length !== 1 || !record(result[0]) || result[0].id !== id || result[0].pms !== pms) throw new ProviderProtocolError("PriceLabs returned malformed or mismatched listing prices", "invalid_response");
|
|
95813
|
+
if (!Array.isArray(result) || result.length !== 1 || !record$3(result[0]) || result[0].id !== id || result[0].pms !== pms) throw new ProviderProtocolError("PriceLabs returned malformed or mismatched listing prices", "invalid_response");
|
|
92077
95814
|
const listing = result[0];
|
|
92078
95815
|
const failures = {
|
|
92079
95816
|
LISTING_NOT_PRESENT: "PriceLabs listing is no longer present",
|
|
@@ -92098,8 +95835,8 @@ const pricelabsConnector = {
|
|
|
92098
95835
|
try {
|
|
92099
95836
|
const listings = selectedListings(source);
|
|
92100
95837
|
const result = await call(source, "listings", { method: "GET" });
|
|
92101
|
-
if (!record(result) || !Array.isArray(result.listings)) throw new ProviderProtocolError("PriceLabs returned malformed listing inventory", "invalid_response");
|
|
92102
|
-
const available = new Set(result.listings.filter(record).map((row) => JSON.stringify([row.id, row.pms])));
|
|
95838
|
+
if (!record$3(result) || !Array.isArray(result.listings)) throw new ProviderProtocolError("PriceLabs returned malformed listing inventory", "invalid_response");
|
|
95839
|
+
const available = new Set(result.listings.filter(record$3).map((row) => JSON.stringify([row.id, row.pms])));
|
|
92103
95840
|
if (listings.some((listing) => !available.has(JSON.stringify([listing.id, listing.pms])))) throw new Error("pricelabs: a pinned listing is unavailable to this API key");
|
|
92104
95841
|
return { ok: true };
|
|
92105
95842
|
} catch (error) {
|
|
@@ -104146,6 +107883,37 @@ const CONNECTOR_ADAPTER_FACTORIES = [
|
|
|
104146
107883
|
defineFactoryAdapter(() => googleTasksConnector, googleOAuthEnvMap),
|
|
104147
107884
|
defineFactoryAdapter(() => googleAnalyticsConnector, googleOAuthEnvMap),
|
|
104148
107885
|
defineFactoryAdapter(() => googleAdsConnector, googleOAuthEnvMap),
|
|
107886
|
+
defineFactoryAdapter(() => metaAdsConnector, {
|
|
107887
|
+
clientId: "META_ADS_OAUTH_CLIENT_ID",
|
|
107888
|
+
clientSecret: "META_ADS_OAUTH_CLIENT_SECRET"
|
|
107889
|
+
}),
|
|
107890
|
+
defineFactoryAdapter(() => xAdsConnector, {}),
|
|
107891
|
+
defineFactoryAdapter(() => tiktokAdsConnector, {}),
|
|
107892
|
+
defineFactoryAdapter(() => linkedinAdsConnector, {
|
|
107893
|
+
clientId: "LINKEDIN_OAUTH_CLIENT_ID",
|
|
107894
|
+
clientSecret: "LINKEDIN_OAUTH_CLIENT_SECRET"
|
|
107895
|
+
}),
|
|
107896
|
+
defineFactoryAdapter(() => redditAdsConnector, {
|
|
107897
|
+
clientId: "REDDIT_ADS_OAUTH_CLIENT_ID",
|
|
107898
|
+
clientSecret: "REDDIT_ADS_OAUTH_CLIENT_SECRET"
|
|
107899
|
+
}),
|
|
107900
|
+
defineFactoryAdapter(() => snapchatAdsConnector, {
|
|
107901
|
+
clientId: "SNAPCHAT_ADS_OAUTH_CLIENT_ID",
|
|
107902
|
+
clientSecret: "SNAPCHAT_ADS_OAUTH_CLIENT_SECRET"
|
|
107903
|
+
}),
|
|
107904
|
+
defineFactoryAdapter(() => pinterestAdsConnector, {
|
|
107905
|
+
clientId: "PINTEREST_ADS_CLIENT_ID",
|
|
107906
|
+
clientSecret: "PINTEREST_ADS_CLIENT_SECRET"
|
|
107907
|
+
}),
|
|
107908
|
+
defineFactoryAdapter(createMicrosoftAdsConnector, {
|
|
107909
|
+
clientId: "MICROSOFT_ADS_CLIENT_ID",
|
|
107910
|
+
clientSecret: "MICROSOFT_ADS_CLIENT_SECRET",
|
|
107911
|
+
developerToken: "MICROSOFT_ADS_DEVELOPER_TOKEN"
|
|
107912
|
+
}),
|
|
107913
|
+
defineFactoryAdapter(createAmazonAdsConnector, {
|
|
107914
|
+
clientId: "AMAZON_ADS_CLIENT_ID",
|
|
107915
|
+
clientSecret: "AMAZON_ADS_CLIENT_SECRET"
|
|
107916
|
+
}),
|
|
104149
107917
|
defineFactoryAdapter(() => googleMeetConnector, googleOAuthEnvMap),
|
|
104150
107918
|
defineFactoryAdapter(() => googleMyBusinessConnector, googleOAuthEnvMap),
|
|
104151
107919
|
defineFactoryAdapter(() => googleSearchConsoleConnector, googleOAuthEnvMap),
|
|
@@ -105449,6 +109217,82 @@ const githubConnector = declarativeRestConnector({
|
|
|
105449
109217
|
}
|
|
105450
109218
|
}
|
|
105451
109219
|
},
|
|
109220
|
+
{
|
|
109221
|
+
name: "repos.getCombinedStatusForRef",
|
|
109222
|
+
class: "read",
|
|
109223
|
+
description: "Read the combined commit status for a ref (a SHA, branch or tag): its overall state and every status context, such as CI jobs or deploy receipts. Page with per_page.",
|
|
109224
|
+
parameters: {
|
|
109225
|
+
type: "object",
|
|
109226
|
+
properties: {
|
|
109227
|
+
owner: { type: "string" },
|
|
109228
|
+
repo: { type: "string" },
|
|
109229
|
+
ref: {
|
|
109230
|
+
type: "string",
|
|
109231
|
+
description: "A commit SHA, branch name or tag name."
|
|
109232
|
+
},
|
|
109233
|
+
per_page: {
|
|
109234
|
+
type: "integer",
|
|
109235
|
+
minimum: 1,
|
|
109236
|
+
maximum: 100
|
|
109237
|
+
},
|
|
109238
|
+
page: {
|
|
109239
|
+
type: "integer",
|
|
109240
|
+
minimum: 1
|
|
109241
|
+
}
|
|
109242
|
+
},
|
|
109243
|
+
required: [
|
|
109244
|
+
"owner",
|
|
109245
|
+
"repo",
|
|
109246
|
+
"ref"
|
|
109247
|
+
]
|
|
109248
|
+
},
|
|
109249
|
+
request: {
|
|
109250
|
+
method: "GET",
|
|
109251
|
+
path: "/repos/{owner}/{repo}/commits/{ref}/status",
|
|
109252
|
+
query: {
|
|
109253
|
+
per_page: "{per_page}",
|
|
109254
|
+
page: "{page}"
|
|
109255
|
+
}
|
|
109256
|
+
}
|
|
109257
|
+
},
|
|
109258
|
+
{
|
|
109259
|
+
name: "checks.listForRef",
|
|
109260
|
+
class: "read",
|
|
109261
|
+
description: "List the check runs (for example GitHub Actions jobs) reported on a ref, with their status and conclusion. Page with per_page.",
|
|
109262
|
+
parameters: {
|
|
109263
|
+
type: "object",
|
|
109264
|
+
properties: {
|
|
109265
|
+
owner: { type: "string" },
|
|
109266
|
+
repo: { type: "string" },
|
|
109267
|
+
ref: {
|
|
109268
|
+
type: "string",
|
|
109269
|
+
description: "A commit SHA, branch name or tag name."
|
|
109270
|
+
},
|
|
109271
|
+
per_page: {
|
|
109272
|
+
type: "integer",
|
|
109273
|
+
minimum: 1,
|
|
109274
|
+
maximum: 100
|
|
109275
|
+
},
|
|
109276
|
+
page: {
|
|
109277
|
+
type: "integer",
|
|
109278
|
+
minimum: 1
|
|
109279
|
+
}
|
|
109280
|
+
},
|
|
109281
|
+
required: [
|
|
109282
|
+
"owner",
|
|
109283
|
+
"repo",
|
|
109284
|
+
"ref"
|
|
109285
|
+
]
|
|
109286
|
+
},
|
|
109287
|
+
request: {
|
|
109288
|
+
method: "GET",
|
|
109289
|
+
path: "/repos/{owner}/{repo}/commits/{ref}/check-runs",
|
|
109290
|
+
query: {
|
|
109291
|
+
per_page: "{per_page}",
|
|
109292
|
+
page: "{page}"
|
|
109293
|
+
}
|
|
109294
|
+
}
|
|
109295
|
+
},
|
|
105452
109296
|
{
|
|
105453
109297
|
name: "issues.get",
|
|
105454
109298
|
class: "read",
|
|
@@ -188756,8 +192600,10 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
188756
192600
|
copperConnector: () => copperConnector,
|
|
188757
192601
|
copyAiConnector: () => copyAiConnector,
|
|
188758
192602
|
couchbaseConnector: () => couchbaseConnector,
|
|
192603
|
+
createAmazonAdsConnector: () => createAmazonAdsConnector,
|
|
188759
192604
|
createKafkaConnector: () => createKafkaConnector,
|
|
188760
192605
|
createLinkedinConnector: () => createLinkedinConnector,
|
|
192606
|
+
createMicrosoftAdsConnector: () => createMicrosoftAdsConnector,
|
|
188761
192607
|
createMongoDbConnector: () => createMongoDbConnector,
|
|
188762
192608
|
createMySqlConnector: () => createMySqlConnector,
|
|
188763
192609
|
createPhonyConnector: () => createPhonyConnector,
|
|
@@ -188968,6 +192814,7 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
188968
192814
|
lightfunnelsConnector: () => lightfunnelsConnector,
|
|
188969
192815
|
linearConnector: () => linearConnector,
|
|
188970
192816
|
linkaConnector: () => linkaConnector,
|
|
192817
|
+
linkedinAdsConnector: () => linkedinAdsConnector,
|
|
188971
192818
|
linkedinConnector: () => linkedinConnector,
|
|
188972
192819
|
linkupConnector: () => linkupConnector,
|
|
188973
192820
|
linqConnector: () => linqConnector,
|
|
@@ -189002,6 +192849,7 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
189002
192849
|
meetgeekAiConnector: () => meetgeekAiConnector,
|
|
189003
192850
|
memConnector: () => memConnector,
|
|
189004
192851
|
messagebirdConnector: () => messagebirdConnector,
|
|
192852
|
+
metaAdsConnector: () => metaAdsConnector,
|
|
189005
192853
|
metabaseConnector: () => metabaseConnector,
|
|
189006
192854
|
microsoft365PeopleConnector: () => microsoft365PeopleConnector,
|
|
189007
192855
|
microsoft365PlannerConnector: () => microsoft365PlannerConnector,
|
|
@@ -189076,6 +192924,7 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
189076
192924
|
pinchPaymentsConnector: () => pinchPaymentsConnector,
|
|
189077
192925
|
pineconeConnector: () => pineconeConnector,
|
|
189078
192926
|
pingIdentityConnector: () => pingIdentityConnector,
|
|
192927
|
+
pinterestAdsConnector: () => pinterestAdsConnector,
|
|
189079
192928
|
pipedreamConnector: () => pipedreamConnector,
|
|
189080
192929
|
pipedriveConnector: () => pipedriveConnector,
|
|
189081
192930
|
placidConnector: () => placidConnector,
|
|
@@ -189108,6 +192957,7 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
189108
192957
|
recallAiConnector: () => recallAiConnector,
|
|
189109
192958
|
recurlyConnector: () => recurlyConnector,
|
|
189110
192959
|
reddit: () => reddit,
|
|
192960
|
+
redditAdsConnector: () => redditAdsConnector,
|
|
189111
192961
|
redditConnector: () => redditConnector,
|
|
189112
192962
|
redisConnector: () => redisConnector,
|
|
189113
192963
|
redshiftConnector: () => redshiftConnector,
|
|
@@ -189166,6 +193016,7 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
189166
193016
|
smartsuiteConnector: () => smartsuiteConnector,
|
|
189167
193017
|
smooveConnector: () => smooveConnector,
|
|
189168
193018
|
smsmodeConnector: () => smsmodeConnector,
|
|
193019
|
+
snapchatAdsConnector: () => snapchatAdsConnector,
|
|
189169
193020
|
snovIoConnector: () => snovIoConnector,
|
|
189170
193021
|
snowflakeConnector: () => snowflakeConnector,
|
|
189171
193022
|
socialkitConnector: () => socialkitConnector,
|
|
@@ -189190,6 +193041,7 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
189190
193041
|
theirstackConnector: () => theirstackConnector,
|
|
189191
193042
|
ticktickConnector: () => ticktickConnector,
|
|
189192
193043
|
tiktok: () => tiktok,
|
|
193044
|
+
tiktokAdsConnector: () => tiktokAdsConnector,
|
|
189193
193045
|
tiktokConnector: () => tiktokConnector,
|
|
189194
193046
|
timeOpsConnector: () => timeOpsConnector,
|
|
189195
193047
|
timelinesAiConnector: () => timelinesAiConnector,
|
|
@@ -189241,6 +193093,7 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
189241
193093
|
wrikeConnector: () => wrikeConnector,
|
|
189242
193094
|
writesonicBulkConnector: () => writesonicBulkConnector,
|
|
189243
193095
|
wufooConnector: () => wufooConnector,
|
|
193096
|
+
xAdsConnector: () => xAdsConnector,
|
|
189244
193097
|
xeroConnector: () => xeroConnector,
|
|
189245
193098
|
youcanbookmeConnector: () => youcanbookmeConnector,
|
|
189246
193099
|
youtubeDataConnector: () => youtubeDataConnector,
|
|
@@ -189263,6 +193116,6 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
189263
193116
|
zuoraConnector: () => zuoraConnector
|
|
189264
193117
|
});
|
|
189265
193118
|
//#endregion
|
|
189266
|
-
export { uscreenConnector as $, openaiConnector as $a, harvestConnector as $c, buttondownConnector as $d, campaignMonitorConnector as $i, codaConnector as $l, mailerooConnector as $n, zohoBooksConnector as $o, mailercheckConnector as $r, parquetFilesConnector as $s, postizConnector as $t, opsgenieConnector as $u, bettercontactConnector as A, altTextAiConnector as Aa, microsoftCalendar as Ac, elevenlabsConnector as Ad, copyAiConnector as Ai, flowluConnector as Al, instasentConnector as An, digitalOceanConnector as Ao, joggAiConnector as Ar, sageIntacctConnector as As, sendinblueConnector as At, amazonCloudWatchConnector as Au, woocommerceConnector as B, airOpsConnector as Ba, kafkaConnector as Bc, contiguityConnector as Bd, clockifyConnector as Bi, dialpadConnector as Bl, gptzeroDetectAiConnector as Bn, smartleadConnector as Bo, hashiCorpVaultConnector as Br, rssConnector as Bs, retableConnector as Bt, videoaskConnector as Bu, serperConnector as C, apitableConnector as Ca, microsoftPowerBiConnector as Cc, genderApiConnector as Cd, descriptConnector as Ci, googleApiError as Cl, nocodbConnector as Cn, createMySqlConnector as Co, koFiConnector as Cr, todoistConnector as Cs, simplybookmeConnector as Ct, auth0Connector as Cu, snovIoConnector as D, amazonTextractConnector as Da, microsoftExcel365Connector as Dc, featheryConnector as Dd, customgptConnector as Di, freshsalesConnector as Dl, loopsConnector as Dn, googleBigqueryConnector as Do, kimaiConnector as Dr, stripePackConnector as Ds, serviceNowConnector as Dt, amazonSnsConnector as Du, wizaConnector as E, apitemplateIoConnector as Ea, microsoftGraph as Ec, fellowConnector as Ed, deepseekConnector as Ei, frontConnector as El, mailchainConnector as En, hightouchConnector as Eo, kissflowConnector as Er, tallyConnector as Es, signrequestConnector as Et, amazonSqsConnector as Eu, zeplinConnector as F, aipriseConnector as Fa, linkedinConnector as Fc, digitalPilotConnector as Fd, cometapiConnector as Fi, fireberryConnector as Fl, humeAiConnector as Fn, TELEGRAM_FILE_DOWNLOAD_ROOT as Fo, instantlyAiConnector as Fr, savvycalConnector as Fs, sardisConnector as Ft, adobeSignConnector as Fu, webscrapingAiConnector as G, bamboohrConnector as Ga, ironcladConnector as Gc, claudeConnector as Gd, chatbaseConnector as Gi, circleConnector as Gl, missiveConnector as Gn, lemlistConnector as Go, greenptConnector as Gr, postgresConnector as Gs, raiaAiConnector as Gt, sendpulseConnector as Gu, wonderchatConnector as H, activecampaignConnector as Ha, justcallConnector as Hc, codyConnector as Hd, chatnodeConnector as Hi, docuseal as Hl, glideConnector as Hn, outreachConnector as Ho, hastewireConnector as Hr, rampConnector as Hs, reoonVerifierConnector as Ht, tenzoConnector as Hu, youcanbookmeConnector as I, acumbamailConnector as Ia, linearConnector as Ic, detectingAiConnector as Id, cohereConnector as Ii, fathomConnector as Il, hedyConnector as In, telegramConnector as Io, huggingFaceConnector as Ir, saleorConnector as Is, saasticConnector as It, zuoraConnector as Iu, vtigerConnector as J, weaviateConnector as Ja, instagramBusinessConnector as Jc, chaindeskConnector as Jd, cannyConnector as Ji, recurlyConnector as Jl, mindeeConnector as Jn, brazeConnector as Jo, ghostcmsConnector as Jr, createRedisConnector as Js, pushoverConnector as Jt, reddit as Ju, whatConvertsConnector as K, qdrantConnector as Ka, invoiceninjaConnector as Kc, chatsistantConnector as Kd, chatlingConnector as Ki, cashfreePaymentsConnector as Kl, mixpanelConnector as Kn, klaviyoConnector as Ko, googleSearchConnector as Kr, createRedshiftConnector as Ks, quadernoConnector as Kt, sanityConnector as Ku, wufooConnector as L, aidbaseConnector as La, lemonSqueezyConnector as Lc, deepgramConnector as Ld, cognitoFormsConnector as Li, etsyConnector as Ll, heartbeatConnector as Ln, mattermostConnector as Lo, influencersClubConnector as Lr, createSftpConnector as Ls, runwareConnector as Lt, zoominfoConnector as Lu, lagrowthmachineConnector as M, airtopConnector as Ma, microsoft365PeopleConnector as Mc, dripConnector as Md, convertkitConnector as Mi, figmaConnector as Ml, imapConnector as Mn, datadogConnector as Mo, jiraDataCenterConnector as Mr, signNowConnector as Ms, seekTableConnector as Mt, amplitudeConnector as Mu, heyreachConnector as N, amazonSecretsManagerConnector as Na, makeConnector as Nc, docsbotConnector as Nd, crispConnector as Ni, figjamConnector as Nl, ibmCognoseConnector as Nn, baserowConnector as No, jinaAiConnector as Nr, shippoConnector as Ns, scrapelessConnector as Nt, affinityConnector as Nu, findymailConnector as O, amazonSesConnector as Oa, microsoftDynamicsCrmConnector as Oc, everhourConnector as Od, cryptolensConnector as Oi, freshdeskConnector as Ol, knockConnector as On, firebaseConnector as Oo, kapsoConnector as Or, squareConnector as Os, serpstatConnector as Ot, amazonS3Connector as Ou, amplemarketConnector as P, amazonBedrockConnector as Pa, createLinkedinConnector as Pc, duckdbConnector as Pd, comfyicuConnector as Pi, firefliesAiConnector as Pl, hystructConnector as Pn, airtableConnector as Po, imageRouterConnector as Pr, sharepoint as Ps, scrapegraphaiConnector as Pt, aircallConnector as Pu, vboutConnector as Q, anthropicConnector as Qa, helpscoutConnector as Qc, cambAiConnector as Qd, braveSearchConnector as Qi, confluenceConnector as Ql, messagebirdConnector as Qn, zohoCampaignsConnector as Qo, frameConnector as Qr, quickbooksConnector as Qs, posthogConnector as Qt, pagerdutyConnector as Qu, writesonicBulkConnector as R, afforaiConnector as Ra, leadConnectorConnector as Rc, dappierConnector as Rd, clearoutConnector as Ri, ebayConnector as Rl, griptapeConnector as Rn, matrixConnector as Ro, housecallProConnector as Rr, sftpConnector as Rs, robollyConnector as Rt, workdayConnector as Ru, warmlyConnector as S, aminosConnector as Sa, microsoftTodoConnector as Sc, generatebannersConnector as Sd, datocmsConnector as Si, classifyGoogleReason as Sl, ntfyConnector as Sn, segmentConnector as So, kudosityConnector as Sr, trelloConnector as Ss, smartsheetConnector as St, acuitySchedulingConnector as Su, commonRoomConnector as T, ampecoConnector as Ta, microsoftTeams as Tc, flowParserConnector as Td, denserAiConnector as Ti, googleTestFailureReason as Tl, medullarConnector as Tn, metabaseConnector as To, klentyConnector as Tr, ticktickConnector as Ts, shortIoConnector as Tt, asanaConnector as Tu, whatsscaleConnector as U, smooveConnector as Ua, jotformConnector as Uc, clickfunnelsConnector as Ud, chatDataConnector as Ui, chessComConnector as Ul, googleVertexaiConnector as Un, marketoConnector as Uo, guideliteConnector as Ur, recallAiConnector as Us, reachinboxConnector as Ut, teableConnector as Uu, woodpeckerConnector as V, kustomerConnector as Va, publicKafkaSocketFactory as Vc, contextualAiConnector as Vd, clockodoConnector as Vi, docusignConnector as Vl, gotifyConnector as Vn, salesloftConnector as Vo, heygenConnector as Vr, ringcentralConnector as Vs, replyIoConnector as Vt, vercelConnector as Vu, whatsappConnector as W, greenhouseConnector as Wa, jiraCloudConnector as Wc, clearoutphoneConnector as Wd, chartlyConnector as Wi, checkoutConnector as Wl, exaConnector as Wn, mailchimpConnector as Wo, greipConnector as Wr, createPostgresConnector as Ws, rapidtextAiConnector as Wt, snowflakeConnector as Wu, vlmRunConnector as X, geminiConnector as Xa, httpConnector as Xc, csvFilesConnector as Xd, certopusConnector as Xi, copperConnector as Xl, memConnector as Xn, zohoMailConnector as Xo, gameballConnector as Xr, createRabbitMqConnector as Xs, productboardConnector as Xt, pushbulletConnector as Xu, vtexConnector as Y, huggingfaceConnector as Ya, intercomConnector as Yc, chainAwareConnector as Yd, chainalysisApiConnector as Yi, chargebeeConnector as Yl, millionverifierConnector as Yn, apolloConnector as Yo, freshserviceConnector as Yr, redisConnector as Ys, proxycurlConnector as Yt, redditConnector as Yu, vidlab7Connector as Z, googleGeminiConnector as Za, hubspot as Zc, cartloomConnector as Zd, captainDataConnector as Zi, contentfulConnector as Zl, mauticConnector as Zn, zohoInvoiceConnector as Zo, fragmentConnector as Zr, rabbitMqConnector as Zs, predictLeadsConnector as Zt, paychexConnector as Zu, phantombusterConnector as _, ashbyConnector as _a, mondayConnector as _c, bexioConnector as _d, phonyConnector as _f, dubConnector as _i, googleCalendar as _l, opportifyConnector as _n, neverbounceConnector as _o, linkupConnector as _r, tiktokConnector as _s, swarmnodeConnector as _t, azureEventGridConnector as _u, linqConnector as a, bonjoroConnector as aa, outlookMail as ac, gustoConnector as ad, apifyConnector as af, facebookLeadsConnector as ai, googleSheets as al, perplexityAiConnector as an, quickzuConnector as ao, mailerLiteConnector as ar, zoomConnector as as, twinLabsConnector as at, calendlyConnector as au, crustdataConnector as b, semrushConnector as ba, meetgeekAiConnector as bc, modelslabConnector as bd, documergeConnector as bi, gmail as bl, omniCoConnector as bn, builtwithConnector as bo, kommoConnector as br, typeformConnector as bs, smsmodeConnector as bt, avalaraConnector as bu, factorsAiConnector as c, bettermodeConnector as ca, openPhoneConnector as cc, formstackConnector as cd, aianswerConnector as cf, firecrawlConnector as ci, googleMeetConnector as cl, parseurConnector as cn, githubConnector as co, logsnagConnector as cr, youtubeDataConnector as cs, togglTrackConnector as ct, billplzConnector as cu, signwellConnector as d, barcodeLookupConnector as da, n8nConnector as dc, constantContactConnector as dd, pingIdentityConnector as df, emailoctopusConnector as di, googleDocs as dl, pastefyConnector as dn, gtmAgentConnector as do, magicalApiConnector as dr, webflowConnector as ds, textcortexAiConnector as dt, baremetricsConnector as du, brilliantDirectoriesConnector as ea, pipedriveConnector as ec, niftyConnector as ed, bikaConnector as ef, fountainConnector as ei, hellosign as el, pollybotAiConnector as en, sentryConnector as eo, mailgunConnector as er, zohoCrmConnector as es, umamiConnector as et, cloudinaryConnector as eu, polytomicConnector as f, autocallsConnector as fa, notion as fc, cloudconvertConnector as fd, oneloginConnector as ff, dustConnector as fi, googleContactsConnector as fl, paperformConnector as fn, webhookConnector as fo, llmrailsConnector as fr, xeroConnector as fs, telnyxConnector as ft, boxConnector as fu, zenrowsConnector as g, assemblyaiConnector as ga, mongodbConnector as gc, bigcommerceConnector as gd, createPhonyConnector as gf, documentproConnector as gi, googleAnalyticsConnector as gl, openmicAiConnector as gn, theirstackConnector as go, letsCalendarConnector as gr, tiktok as gs, stripeConnector as gt, azureServiceBusConnector as gu, oceanIoConnector as h, avianConnector as ha, createMongoDbConnector as hc, canvaConnector as hd, declarativeRestConnector as hf, elasticEmailConnector as hi, googleAdsConnector as hl, opnformConnector as hn, zerobounceConnector as ho, linkaConnector as hr, twilioSmsConnector as hs, systemeIoConnector as ht, basecampConnector as hu, linqWhatsappConnector as i, blueskyConnector as ia, pandadoc as ic, instaChartsConnector as id, askHandleConnector as if, flowiseConnector as ii, googleSlidesConnector as il, personalAiConnector as in, zagomailConnector as io, luxuryPresenceConnector as ir, zohoBookingsConnector as is, twilioConnector as it, capsuleCrmConnector as iu, saleshandyConnector as j, alaiConnector as ja, microsoft365PlannerConnector as jc, echowinConnector as jd, dashworksConnector as ji, filloutFormsConnector as jl, insightoAiConnector as jn, discourseConnector as jo, justInvoiceConnector as jr, slack as js, skyprepConnector as jt, amazonEventBridgeConnector as ju, contactoutConnector as k, alttextifyConnector as ka, microsoftDynamics365BusinessCentralConnector as kc, excelFilesConnector as kd, datafuelConnector as ki, folkConnector as kl, kallabotAiConnector as kn, clicksendConnector as ko, kizeoFormsConnector as kr, shopifyConnector as ks, senjaConnector as kt, amazonLambdaConnector as ku, modjoConnector as l, beamerConnector as la, ninjapipeConnector as lc, discordConnector as ld, actualbudgetConnector as lf, esignaturesConnector as li, googleForms as ll, paywhirlConnector as ln, slackEventsConnector as lo, logrocketConnector as lr, wrikeConnector as ls, timelinesAiConnector as lt, billComConnector as lu, seamlessAiConnector as m, asknewsConnector as ma, mycaseConnector as mc, clicdataConnector as md, oktaConnector as mf, edenAiConnector as mi, googleCloudStorageConnector as ml, orimonConnector as mn, resolveConnectorAdapterFactoryOptions as mo, localaiConnector as mr, voucheryIoConnector as ms, tableauConnector as mt, backblazeConnector as mu, sendblueConnector as n, bookedinConnector as na, plaidConnector as nc, lightfunnelsConnector as nd, base44Connector as nf, formbricksConnector as ni, googlechatConnector as nl, plausibleConnector as nn, sendgridConnector as no, matomoConnector as nr, pricelabsConnector as ns, vapiConnector as nt, clickupConnector as nu, inkboxConnector as o, bitlyConnector as oa, oneSpanSignConnector as oc, giteaConnector as od, anyhookWebsocketConnector as of, enrichlayerConnector as oi, googleSearchConsoleConnector as ol, peekshotConnector as on, facebookPagesConnector as oo, lushaConnector as or, zendeskConnector as os, typefullyConnector as ot, calCom as ou, usergemsConnector as p, azureCommunicationServicesConnector as pa, notionConnector as pc, clioConnector as pd, clientCredentialsRestConnector as pf, easyPeasyAiConnector as pi, googlePubSubConnector as pl, oracleDatabaseConnector as pn, CONNECTOR_ADAPTER_FACTORIES as po, lobstermailConnector as pr, whatsappBusiness as ps, talkableConnector as pt, biginByZohoConnector as pu, wafeqConnector as q, pineconeConnector as qa, insightlyConnector as qc, chatAidConnector as qd, chargekeepConnector as qi, taxjarConnector as ql, mixmaxConnector as qn, customerIoConnector as qo, gistlyConnector as qr, redshiftConnector as qs, qawafelConnector as qt, ripplingConnector as qu, resendConnector as r, bolnaConnector as ra, paddleConnector as rc, leverConnector as rd, bannerbearConnector as rf, flipandoConnector as ri, googleTasksConnector as rl, placidConnector as rn, zendeskSellConnector as ro, lucidyaConnector as rr, cloudbedsConnector as rs, upgradechatConnector as rt, closeConnector as ru, getresponseConnector as s, blandAiConnector as sa, oneDrive as sc, freeAgentConnector as sd, airparserConnector as sf, fathomAnalyticsConnector as si, googleMyBusinessConnector as sl, pdfmonkeyConnector as sn, gitlabConnector as so, loftyConnector as sr, zapierConnector as ss, totalcmsConnector as st, calComConnector as su, adapters_exports as t, browseAiConnector as ta, pipedreamConnector as tc, netlifyConnector as td, beehiivConnector as tf, foreplayCoConnector as ti, granolaConnector as tl, pocketbaseConnector as tn, postmarkConnector as to, manychatConnector as tr, zohoDeskConnector as ts, validatedmailsConnector as tt, cloudflareConnector as tu, nooksConnector as u, azureOpenaiConnector as ua, netsuiteConnector as uc, demandbaseConnector as ud, scimConnector as uf, emailitConnector as ui, googleDrive as ul, pinchPaymentsConnector as un, stripeWebhookReceiverConnector as uo, lokaliseConnector as ur, wordpressConnector as us, timeOpsConnector as ut, brexConnector as uu, brightdataConnector as v, clayConnector as va, miroConnector as vc, adpConnector as vd, dumplingAiConnector as vi, gorgiasConnector as vl, openRouterConnector as vn, hunterConnector as vo, lettaConnector as vr, twitter as vs, supadataConnector as vt, azureBlobStorageConnector as vu, leadfeederConnector as w, appfollowConnector as wa, microsoftOnenoteConnector as wc, gammaConnector as wd, devinConnector as wi, googleErrorReason as wl, mindStudioConnector as wn, mysqlConnector as wo, knackConnector as wr, tlDvConnector as ws, simplirouteConnector as wt, attioConnector as wu, autoboundConnector as x, similarwebConnector as xa, mastodonConnector as xc, giftbitConnector as xd, dittofeedConnector as xi, classifyGoogleError as xl, odooConnector as xn, supabaseConnector as xo, leapAiConnector as xr, twentyConnector as xs, smartsuiteConnector as xt, avomaConnector as xu, leadmagicConnector as y, cognismConnector as ya, mollieConnector as yc, adobeCreativeCloudConnector as yd, doctlyConnector as yi, gongConnector as yl, omnihrConnector as yn, fullenrichConnector as yo, leexiConnector as yr, twitterConnector as ys, socialkitConnector as yt, azureAdConnector as yu, workableConnector as z, agentxConnector as za, createKafkaConnector as zc, couchbaseConnector as zd, cloutlyConnector as zi, dropboxConnector as zl, gristConnector as zn, chatwootConnector as zo, heymarketSmsConnector as zr, salesforceConnector as zs, retellAiConnector as zt, wootricConnector as zu };
|
|
193119
|
+
export { uscreenConnector as $, openaiConnector as $a, harvestConnector as $c, clearoutphoneConnector as $d, campaignMonitorConnector as $i, checkoutConnector as $l, mailerooConnector as $n, zohoBooksConnector as $o, mailercheckConnector as $r, parquetFilesConnector as $s, postizConnector as $t, snowflakeConnector as $u, bettercontactConnector as A, altTextAiConnector as Aa, microsoftCalendar as Ac, giftbitConnector as Ad, copyAiConnector as Ai, classifyGoogleError as Al, instasentConnector as An, digitalOceanConnector as Ao, joggAiConnector as Ar, sageIntacctConnector as As, sendinblueConnector as At, avomaConnector as Au, woocommerceConnector as B, airOpsConnector as Ba, kafkaConnector as Bc, echowinConnector as Bd, clockifyConnector as Bi, filloutFormsConnector as Bl, gptzeroDetectAiConnector as Bn, smartleadConnector as Bo, hashiCorpVaultConnector as Br, rssConnector as Bs, retableConnector as Bt, amazonEventBridgeConnector as Bu, serperConnector as C, apitableConnector as Ca, microsoftPowerBiConnector as Cc, clicdataConnector as Cd, oktaConnector as Cf, descriptConnector as Ci, metaAdsConnector as Cl, nocodbConnector as Cn, createMySqlConnector as Co, koFiConnector as Cr, todoistConnector as Cs, simplybookmeConnector as Ct, backblazeConnector as Cu, snovIoConnector as D, amazonTextractConnector as Da, microsoftExcel365Connector as Dc, adpConnector as Dd, customgptConnector as Di, gorgiasConnector as Dl, loopsConnector as Dn, googleBigqueryConnector as Do, kimaiConnector as Dr, stripePackConnector as Ds, serviceNowConnector as Dt, azureBlobStorageConnector as Du, wizaConnector as E, apitemplateIoConnector as Ea, microsoftGraph as Ec, bexioConnector as Ed, phonyConnector as Ef, deepseekConnector as Ei, googleCalendar as El, mailchainConnector as En, hightouchConnector as Eo, kissflowConnector as Er, tallyConnector as Es, signrequestConnector as Et, azureEventGridConnector as Eu, zeplinConnector as F, aipriseConnector as Fa, linkedinConnector as Fc, fellowConnector as Fd, cometapiConnector as Fi, frontConnector as Fl, humeAiConnector as Fn, TELEGRAM_FILE_DOWNLOAD_ROOT as Fo, instantlyAiConnector as Fr, savvycalConnector as Fs, sardisConnector as Ft, amazonSqsConnector as Fu, webscrapingAiConnector as G, bamboohrConnector as Ga, ironcladConnector as Gc, detectingAiConnector as Gd, chatbaseConnector as Gi, fathomConnector as Gl, missiveConnector as Gn, lemlistConnector as Go, greenptConnector as Gr, postgresConnector as Gs, raiaAiConnector as Gt, zuoraConnector as Gu, wonderchatConnector as H, activecampaignConnector as Ha, justcallConnector as Hc, docsbotConnector as Hd, chatnodeConnector as Hi, figjamConnector as Hl, glideConnector as Hn, outreachConnector as Ho, hastewireConnector as Hr, rampConnector as Hs, reoonVerifierConnector as Ht, affinityConnector as Hu, youcanbookmeConnector as I, acumbamailConnector as Ia, linearConnector as Ic, featheryConnector as Id, cohereConnector as Ii, freshsalesConnector as Il, hedyConnector as In, telegramConnector as Io, huggingFaceConnector as Ir, saleorConnector as Is, saasticConnector as It, amazonSnsConnector as Iu, vtigerConnector as J, weaviateConnector as Ja, instagramBusinessConnector as Jc, couchbaseConnector as Jd, cannyConnector as Ji, dropboxConnector as Jl, mindeeConnector as Jn, brazeConnector as Jo, ghostcmsConnector as Jr, createRedisConnector as Js, pushoverConnector as Jt, wootricConnector as Ju, whatConvertsConnector as K, qdrantConnector as Ka, invoiceninjaConnector as Kc, deepgramConnector as Kd, chatlingConnector as Ki, etsyConnector as Kl, mixpanelConnector as Kn, klaviyoConnector as Ko, googleSearchConnector as Kr, createRedshiftConnector as Ks, quadernoConnector as Kt, zoominfoConnector as Ku, wufooConnector as L, aidbaseConnector as La, lemonSqueezyConnector as Lc, everhourConnector as Ld, cognitoFormsConnector as Li, freshdeskConnector as Ll, heartbeatConnector as Ln, mattermostConnector as Lo, influencersClubConnector as Lr, createSftpConnector as Ls, runwareConnector as Lt, amazonS3Connector as Lu, lagrowthmachineConnector as M, airtopConnector as Ma, microsoft365PeopleConnector as Mc, genderApiConnector as Md, convertkitConnector as Mi, googleApiError as Ml, imapConnector as Mn, datadogConnector as Mo, jiraDataCenterConnector as Mr, signNowConnector as Ms, seekTableConnector as Mt, auth0Connector as Mu, heyreachConnector as N, amazonSecretsManagerConnector as Na, makeConnector as Nc, gammaConnector as Nd, crispConnector as Ni, googleErrorReason as Nl, ibmCognoseConnector as Nn, baserowConnector as No, jinaAiConnector as Nr, shippoConnector as Ns, scrapelessConnector as Nt, attioConnector as Nu, findymailConnector as O, amazonSesConnector as Oa, microsoftDynamicsCrmConnector as Oc, adobeCreativeCloudConnector as Od, cryptolensConnector as Oi, gongConnector as Ol, knockConnector as On, firebaseConnector as Oo, kapsoConnector as Or, squareConnector as Os, serpstatConnector as Ot, azureAdConnector as Ou, amplemarketConnector as P, amazonBedrockConnector as Pa, createLinkedinConnector as Pc, flowParserConnector as Pd, comfyicuConnector as Pi, googleTestFailureReason as Pl, hystructConnector as Pn, airtableConnector as Po, imageRouterConnector as Pr, sharepoint as Ps, scrapegraphaiConnector as Pt, asanaConnector as Pu, vboutConnector as Q, anthropicConnector as Qa, helpscoutConnector as Qc, clickfunnelsConnector as Qd, braveSearchConnector as Qi, chessComConnector as Ql, messagebirdConnector as Qn, zohoCampaignsConnector as Qo, frameConnector as Qr, quickbooksConnector as Qs, posthogConnector as Qt, teableConnector as Qu, writesonicBulkConnector as R, afforaiConnector as Ra, leadConnectorConnector as Rc, excelFilesConnector as Rd, clearoutConnector as Ri, folkConnector as Rl, griptapeConnector as Rn, matrixConnector as Ro, housecallProConnector as Rr, sftpConnector as Rs, robollyConnector as Rt, amazonLambdaConnector as Ru, warmlyConnector as S, aminosConnector as Sa, microsoftTodoConnector as Sc, clioConnector as Sd, clientCredentialsRestConnector as Sf, datocmsConnector as Si, xAdsConnector as Sl, ntfyConnector as Sn, segmentConnector as So, kudosityConnector as Sr, trelloConnector as Ss, smartsheetConnector as St, biginByZohoConnector as Su, commonRoomConnector as T, ampecoConnector as Ta, microsoftTeams as Tc, bigcommerceConnector as Td, createPhonyConnector as Tf, denserAiConnector as Ti, googleAnalyticsConnector as Tl, medullarConnector as Tn, metabaseConnector as To, klentyConnector as Tr, ticktickConnector as Ts, shortIoConnector as Tt, azureServiceBusConnector as Tu, whatsscaleConnector as U, smooveConnector as Ua, jotformConnector as Uc, duckdbConnector as Ud, chatDataConnector as Ui, firefliesAiConnector as Ul, googleVertexaiConnector as Un, marketoConnector as Uo, guideliteConnector as Ur, recallAiConnector as Us, reachinboxConnector as Ut, aircallConnector as Uu, woodpeckerConnector as V, kustomerConnector as Va, publicKafkaSocketFactory as Vc, dripConnector as Vd, clockodoConnector as Vi, figmaConnector as Vl, gotifyConnector as Vn, salesloftConnector as Vo, heygenConnector as Vr, ringcentralConnector as Vs, replyIoConnector as Vt, amplitudeConnector as Vu, whatsappConnector as W, greenhouseConnector as Wa, jiraCloudConnector as Wc, digitalPilotConnector as Wd, chartlyConnector as Wi, fireberryConnector as Wl, exaConnector as Wn, mailchimpConnector as Wo, greipConnector as Wr, createPostgresConnector as Ws, rapidtextAiConnector as Wt, adobeSignConnector as Wu, vlmRunConnector as X, geminiConnector as Xa, httpConnector as Xc, contextualAiConnector as Xd, certopusConnector as Xi, docusignConnector as Xl, memConnector as Xn, zohoMailConnector as Xo, gameballConnector as Xr, createRabbitMqConnector as Xs, productboardConnector as Xt, vercelConnector as Xu, vtexConnector as Y, huggingfaceConnector as Ya, intercomConnector as Yc, contiguityConnector as Yd, chainalysisApiConnector as Yi, dialpadConnector as Yl, millionverifierConnector as Yn, apolloConnector as Yo, freshserviceConnector as Yr, redisConnector as Ys, proxycurlConnector as Yt, videoaskConnector as Yu, vidlab7Connector as Z, googleGeminiConnector as Za, hubspot as Zc, codyConnector as Zd, captainDataConnector as Zi, docuseal as Zl, mauticConnector as Zn, zohoInvoiceConnector as Zo, fragmentConnector as Zr, rabbitMqConnector as Zs, predictLeadsConnector as Zt, tenzoConnector as Zu, phantombusterConnector as _, ashbyConnector as _a, mondayConnector as _c, formstackConnector as _d, aianswerConnector as _f, dubConnector as _i, pinterestAdsConnector as _l, opportifyConnector as _n, neverbounceConnector as _o, linkupConnector as _r, tiktokConnector as _s, swarmnodeConnector as _t, billplzConnector as _u, linqConnector as a, bonjoroConnector as aa, outlookMail as ac, pushbulletConnector as ad, csvFilesConnector as af, facebookLeadsConnector as ai, googleSheets as al, perplexityAiConnector as an, quickzuConnector as ao, mailerLiteConnector as ar, zoomConnector as as, twinLabsConnector as at, copperConnector as au, crustdataConnector as b, semrushConnector as ba, meetgeekAiConnector as bc, constantContactConnector as bd, pingIdentityConnector as bf, documergeConnector as bi, linkedinAdsConnector as bl, omniCoConnector as bn, builtwithConnector as bo, kommoConnector as br, typeformConnector as bs, smsmodeConnector as bt, baremetricsConnector as bu, factorsAiConnector as c, bettermodeConnector as ca, openPhoneConnector as cc, opsgenieConnector as cd, buttondownConnector as cf, firecrawlConnector as ci, googleMeetConnector as cl, parseurConnector as cn, githubConnector as co, logsnagConnector as cr, youtubeDataConnector as cs, togglTrackConnector as ct, codaConnector as cu, signwellConnector as d, barcodeLookupConnector as da, n8nConnector as dc, lightfunnelsConnector as dd, base44Connector as df, emailoctopusConnector as di, googleDocs as dl, pastefyConnector as dn, gtmAgentConnector as do, magicalApiConnector as dr, webflowConnector as ds, textcortexAiConnector as dt, clickupConnector as du, brilliantDirectoriesConnector as ea, pipedriveConnector as ec, sendpulseConnector as ed, claudeConnector as ef, fountainConnector as ei, hellosign as el, pollybotAiConnector as en, sentryConnector as eo, mailgunConnector as er, zohoCrmConnector as es, umamiConnector as et, circleConnector as eu, polytomicConnector as f, autocallsConnector as fa, notion as fc, leverConnector as fd, bannerbearConnector as ff, dustConnector as fi, googleContactsConnector as fl, paperformConnector as fn, webhookConnector as fo, llmrailsConnector as fr, xeroConnector as fs, telnyxConnector as ft, closeConnector as fu, zenrowsConnector as g, assemblyaiConnector as ga, mongodbConnector as gc, freeAgentConnector as gd, airparserConnector as gf, documentproConnector as gi, createMicrosoftAdsConnector as gl, openmicAiConnector as gn, theirstackConnector as go, letsCalendarConnector as gr, tiktok as gs, stripeConnector as gt, calComConnector as gu, oceanIoConnector as h, avianConnector as ha, createMongoDbConnector as hc, giteaConnector as hd, anyhookWebsocketConnector as hf, elasticEmailConnector as hi, createAmazonAdsConnector as hl, opnformConnector as hn, zerobounceConnector as ho, linkaConnector as hr, twilioSmsConnector as hs, systemeIoConnector as ht, calCom as hu, linqWhatsappConnector as i, blueskyConnector as ia, pandadoc as ic, redditConnector as id, chainAwareConnector as if, flowiseConnector as ii, googleSlidesConnector as il, personalAiConnector as in, zagomailConnector as io, luxuryPresenceConnector as ir, zohoBookingsConnector as is, twilioConnector as it, chargebeeConnector as iu, saleshandyConnector as j, alaiConnector as ja, microsoft365PlannerConnector as jc, generatebannersConnector as jd, dashworksConnector as ji, classifyGoogleReason as jl, insightoAiConnector as jn, discourseConnector as jo, justInvoiceConnector as jr, slack as js, skyprepConnector as jt, acuitySchedulingConnector as ju, contactoutConnector as k, alttextifyConnector as ka, microsoftDynamics365BusinessCentralConnector as kc, modelslabConnector as kd, datafuelConnector as ki, gmail as kl, kallabotAiConnector as kn, clicksendConnector as ko, kizeoFormsConnector as kr, shopifyConnector as ks, senjaConnector as kt, avalaraConnector as ku, modjoConnector as l, beamerConnector as la, ninjapipeConnector as lc, niftyConnector as ld, bikaConnector as lf, esignaturesConnector as li, googleForms as ll, paywhirlConnector as ln, slackEventsConnector as lo, logrocketConnector as lr, wrikeConnector as ls, timelinesAiConnector as lt, cloudinaryConnector as lu, seamlessAiConnector as m, asknewsConnector as ma, mycaseConnector as mc, gustoConnector as md, apifyConnector as mf, edenAiConnector as mi, googleCloudStorageConnector as ml, orimonConnector as mn, resolveConnectorAdapterFactoryOptions as mo, localaiConnector as mr, voucheryIoConnector as ms, tableauConnector as mt, calendlyConnector as mu, sendblueConnector as n, bookedinConnector as na, plaidConnector as nc, ripplingConnector as nd, chatAidConnector as nf, formbricksConnector as ni, googlechatConnector as nl, plausibleConnector as nn, sendgridConnector as no, matomoConnector as nr, pricelabsConnector as ns, vapiConnector as nt, taxjarConnector as nu, inkboxConnector as o, bitlyConnector as oa, oneSpanSignConnector as oc, paychexConnector as od, cartloomConnector as of, enrichlayerConnector as oi, googleSearchConsoleConnector as ol, peekshotConnector as on, facebookPagesConnector as oo, lushaConnector as or, zendeskConnector as os, typefullyConnector as ot, contentfulConnector as ou, usergemsConnector as p, azureCommunicationServicesConnector as pa, notionConnector as pc, instaChartsConnector as pd, askHandleConnector as pf, easyPeasyAiConnector as pi, googlePubSubConnector as pl, oracleDatabaseConnector as pn, CONNECTOR_ADAPTER_FACTORIES as po, lobstermailConnector as pr, whatsappBusiness as ps, talkableConnector as pt, capsuleCrmConnector as pu, wafeqConnector as q, pineconeConnector as qa, insightlyConnector as qc, dappierConnector as qd, chargekeepConnector as qi, ebayConnector as ql, mixmaxConnector as qn, customerIoConnector as qo, gistlyConnector as qr, redshiftConnector as qs, qawafelConnector as qt, workdayConnector as qu, resendConnector as r, bolnaConnector as ra, paddleConnector as rc, reddit as rd, chaindeskConnector as rf, flipandoConnector as ri, googleTasksConnector as rl, placidConnector as rn, zendeskSellConnector as ro, lucidyaConnector as rr, cloudbedsConnector as rs, upgradechatConnector as rt, recurlyConnector as ru, getresponseConnector as s, blandAiConnector as sa, oneDrive as sc, pagerdutyConnector as sd, cambAiConnector as sf, fathomAnalyticsConnector as si, googleMyBusinessConnector as sl, pdfmonkeyConnector as sn, gitlabConnector as so, loftyConnector as sr, zapierConnector as ss, totalcmsConnector as st, confluenceConnector as su, adapters_exports as t, browseAiConnector as ta, pipedreamConnector as tc, sanityConnector as td, chatsistantConnector as tf, foreplayCoConnector as ti, granolaConnector as tl, pocketbaseConnector as tn, postmarkConnector as to, manychatConnector as tr, zohoDeskConnector as ts, validatedmailsConnector as tt, cashfreePaymentsConnector as tu, nooksConnector as u, azureOpenaiConnector as ua, netsuiteConnector as uc, netlifyConnector as ud, beehiivConnector as uf, emailitConnector as ui, googleDrive as ul, pinchPaymentsConnector as un, stripeWebhookReceiverConnector as uo, lokaliseConnector as ur, wordpressConnector as us, timeOpsConnector as ut, cloudflareConnector as uu, brightdataConnector as v, clayConnector as va, miroConnector as vc, discordConnector as vd, actualbudgetConnector as vf, dumplingAiConnector as vi, snapchatAdsConnector as vl, openRouterConnector as vn, hunterConnector as vo, lettaConnector as vr, twitter as vs, supadataConnector as vt, billComConnector as vu, leadfeederConnector as w, appfollowConnector as wa, microsoftOnenoteConnector as wc, canvaConnector as wd, declarativeRestConnector as wf, devinConnector as wi, googleAdsConnector as wl, mindStudioConnector as wn, mysqlConnector as wo, knackConnector as wr, tlDvConnector as ws, simplirouteConnector as wt, basecampConnector as wu, autoboundConnector as x, similarwebConnector as xa, mastodonConnector as xc, cloudconvertConnector as xd, oneloginConnector as xf, dittofeedConnector as xi, tiktokAdsConnector as xl, odooConnector as xn, supabaseConnector as xo, leapAiConnector as xr, twentyConnector as xs, smartsuiteConnector as xt, boxConnector as xu, leadmagicConnector as y, cognismConnector as ya, mollieConnector as yc, demandbaseConnector as yd, scimConnector as yf, doctlyConnector as yi, redditAdsConnector as yl, omnihrConnector as yn, fullenrichConnector as yo, leexiConnector as yr, twitterConnector as ys, socialkitConnector as yt, brexConnector as yu, workableConnector as z, agentxConnector as za, createKafkaConnector as zc, elevenlabsConnector as zd, cloutlyConnector as zi, flowluConnector as zl, gristConnector as zn, chatwootConnector as zo, heymarketSmsConnector as zr, salesforceConnector as zs, retellAiConnector as zt, amazonCloudWatchConnector as zu };
|
|
189267
193120
|
|
|
189268
|
-
//# sourceMappingURL=adapters-
|
|
193121
|
+
//# sourceMappingURL=adapters-Dp5h7mF-.js.map
|