mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
feat(media-use): tag HeyGen calls with X-HeyGen-Client-Source (#2365)
Send `X-HeyGen-Client-Source: media-use` on every media-use HeyGen API request (both auth types, via heygenAuthHeaders + the heygenJSON transport), so backend billing meta can isolate media-use consumption from other free TTS and avatar-video usage. Unconditional of auth type — a paying user's media-use call is still media-use — unlike the OAuth-only cli-source header that gates the free allowance.
This commit is contained in:
@@ -10,6 +10,11 @@ import { dirname, join, resolve } from "node:path";
|
||||
|
||||
export const HEYGEN_BASE = "https://api.heygen.com/v3";
|
||||
export const HEYGEN_CLI_SOURCE_HEADERS = { "X-HeyGen-Source": "cli" };
|
||||
// Tool-attribution sent on EVERY media-use HeyGen call regardless of auth type, so
|
||||
// the backend can isolate media-use consumption from other free TTS / avatar video.
|
||||
// Unconditional — a paying user's media-use call is still media-use — unlike the
|
||||
// OAuth-only cli-source header above, which also gates the free allowance.
|
||||
export const HEYGEN_CLIENT_SOURCE_HEADERS = { "X-HeyGen-Client-Source": "media-use" };
|
||||
|
||||
// Walk up ≤5 dirs from startDir; load the first .env (shell env always wins).
|
||||
export function loadEnvFromDir(startDir) {
|
||||
@@ -88,7 +93,9 @@ export function heygenAuthHeaders() {
|
||||
// grant the free allowance for OAuth requests and ignores it for API-key
|
||||
// (X-Api-Key) traffic, where it's dead metadata.
|
||||
const isOauth = "Authorization" in cred.headers;
|
||||
return isOauth ? { ...cred.headers, ...HEYGEN_CLI_SOURCE_HEADERS } : { ...cred.headers };
|
||||
return isOauth
|
||||
? { ...cred.headers, ...HEYGEN_CLI_SOURCE_HEADERS, ...HEYGEN_CLIENT_SOURCE_HEADERS }
|
||||
: { ...cred.headers, ...HEYGEN_CLIENT_SOURCE_HEADERS };
|
||||
}
|
||||
if (cred?.expired)
|
||||
throw new Error(
|
||||
@@ -101,7 +108,7 @@ export function heygenAuthHeaders() {
|
||||
|
||||
// Authed JSON request against the v3 API; throws on a non-OK status.
|
||||
export async function heygenJSON(path, { method = "GET", headers = {}, body } = {}) {
|
||||
const opts = { method, headers: { ...headers } };
|
||||
const opts = { method, headers: { ...HEYGEN_CLIENT_SOURCE_HEADERS, ...headers } };
|
||||
if (body !== undefined) {
|
||||
opts.headers["Content-Type"] = "application/json";
|
||||
opts.body = JSON.stringify(body);
|
||||
|
||||
@@ -24,18 +24,20 @@ function withCleanHeygenEnv(fn) {
|
||||
}
|
||||
}
|
||||
|
||||
test("heygenAuthHeaders does not tag API-key requests as CLI traffic", () => {
|
||||
test("heygenAuthHeaders does not tag API-key requests as CLI traffic, but still carries the media-use tool tag", () => {
|
||||
withCleanHeygenEnv(() => {
|
||||
process.env.HEYGEN_API_KEY = "hg_test";
|
||||
// API-key requests use normal billing; the backend ignores the cli-source
|
||||
// header for them, so it's not sent.
|
||||
// header for them, so it's not sent. The tool-attribution header IS sent on
|
||||
// every media-use call (any auth type) so the backend can isolate media-use.
|
||||
assert.deepEqual(heygenAuthHeaders(), {
|
||||
"X-Api-Key": "hg_test",
|
||||
"X-HeyGen-Client-Source": "media-use",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("heygenAuthHeaders tags OAuth requests as CLI traffic", () => {
|
||||
test("heygenAuthHeaders tags OAuth requests as CLI traffic and with the media-use tool tag", () => {
|
||||
withCleanHeygenEnv(() => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "heygen-cred-"));
|
||||
try {
|
||||
@@ -52,6 +54,7 @@ test("heygenAuthHeaders tags OAuth requests as CLI traffic", () => {
|
||||
assert.deepEqual(heygenAuthHeaders(), {
|
||||
Authorization: "Bearer at_test",
|
||||
"X-HeyGen-Source": "cli",
|
||||
"X-HeyGen-Client-Source": "media-use",
|
||||
});
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
|
||||
Reference in New Issue
Block a user