Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions cmd/heygen/auth.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package main

import "github.com/spf13/cobra"
import (
"github.com/spf13/cobra"

clierrors "github.com/heygen-com/heygen-cli/internal/errors"
)

// authGuidance is the single source of truth for how to set up CLI auth.
// Referenced by auth_login.go, auth_status.go, and the auth group help below.
const authGuidance = `Three ways to provide your API key:
var authGuidance = `Three ways to provide your API key:
1. Environment variable (current shell only):
export HEYGEN_API_KEY=<your-key>
2. Pipe to auth login (saves to ~/.heygen/credentials):
Expand All @@ -14,7 +18,7 @@ const authGuidance = `Three ways to provide your API key:

When both env var and stored credential are set, the env var takes priority.

Get a key: https://app.heygen.com/settings/api`
Get a key: ` + clierrors.APIKeySettingsURL

func newAuthCmd(ctx *cmdContext) *cobra.Command {
cmd := newCommandGroup("auth", "Manage authentication")
Expand Down
4 changes: 2 additions & 2 deletions cmd/heygen/auth_status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestAuthStatus_AuthError_AddsHint(t *testing.T) {
if !strings.Contains(res.Stderr, "HEYGEN_API_KEY environment variable") {
t.Fatalf("stderr should mention env var source:\n%s", res.Stderr)
}
if !strings.Contains(res.Stderr, "app.heygen.com/settings/api") {
if !strings.Contains(res.Stderr, "app.heygen.com/settings?nav=API") {
t.Fatalf("stderr should contain key generation URL:\n%s", res.Stderr)
}
}
Expand Down Expand Up @@ -124,7 +124,7 @@ func TestAuthStatus_NoKey(t *testing.T) {
if !strings.Contains(res.Stderr, "Three ways to provide your API key") {
t.Fatalf("stderr = %s, want auth guidance", res.Stderr)
}
if !strings.Contains(res.Stderr, "app.heygen.com/settings/api") {
if !strings.Contains(res.Stderr, "app.heygen.com/settings?nav=API") {
t.Fatalf("stderr = %s, want key URL in hint", res.Stderr)
}
}
4 changes: 2 additions & 2 deletions cmd/heygen/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ func enrichAuthHint(cliErr *clierrors.CLIError, source auth.CredentialSource) {
credPath := filepath.Join(paths.ConfigDir(), "credentials")
switch source {
case auth.SourceEnv:
cliErr.Hint = "The HEYGEN_API_KEY environment variable contains an invalid or expired key.\nGenerate a new key: https://app.heygen.com/settings/api"
cliErr.Hint = "The HEYGEN_API_KEY environment variable contains an invalid or expired key.\nGenerate a new key: " + clierrors.APIKeySettingsURL
case auth.SourceFile:
cliErr.Hint = fmt.Sprintf("The stored API key (%s) is invalid or expired.\nReplace it: heygen auth login\nGenerate a new key: https://app.heygen.com/settings/api", credPath)
cliErr.Hint = fmt.Sprintf("The stored API key (%s) is invalid or expired.\nReplace it: heygen auth login\nGenerate a new key: %s", credPath, clierrors.APIKeySettingsURL)
}
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/heygen/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestEnrichAuthHint_EnvSource_401(t *testing.T) {
if !strings.Contains(res.Stderr, "HEYGEN_API_KEY environment variable") {
t.Fatalf("stderr should mention env var source:\n%s", res.Stderr)
}
if !strings.Contains(res.Stderr, "app.heygen.com/settings/api") {
if !strings.Contains(res.Stderr, "app.heygen.com/settings?nav=API") {
t.Fatalf("stderr should contain key generation URL:\n%s", res.Stderr)
}
}
Expand Down
4 changes: 3 additions & 1 deletion internal/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const (
ExitTimeout = 4
)

const APIKeySettingsURL = "https://app.heygen.com/settings?nav=API"

// CLIError is the canonical error type for all CLI operations.
type CLIError struct {
Code string // machine-readable: "auth_error", "not_found", "network_error"
Expand Down Expand Up @@ -131,7 +133,7 @@ func hintForAPICode(code string) string {
case "voice_not_found":
return "This voice does not exist. Retrying the same ID is unlikely to help. List voices: heygen voice list"
case "insufficient_credit":
return "Check your credit balance: heygen user me get. Purchase API credits: https://app.heygen.com/settings?nav=API"
return "Check your credit balance: heygen user me get. Purchase API credits: " + APIKeySettingsURL
case "invalid_parameter":
return "Use --request-schema on the command to see expected fields"
case "rate_limited":
Expand Down
Loading