using Google.Ads.Gax.Config; using Google.Ads.GoogleAds.Config; using Google.Ads.GoogleAds.Lib; using GoogleApi.Configuration; using Microsoft.Extensions.Options; namespace GoogleApi.Services; // ✅ Alias the Google library config type to avoid collision with your GoogleApi.Configuration.GoogleAdsConfig using LibGoogleAdsConfig = Google.Ads.GoogleAds.Config.GoogleAdsConfig; public sealed class GoogleAdsClientFactory { private readonly GoogleApi.Configuration.GoogleAdsConfig _cfg; private readonly ILogger _logger; public GoogleAdsClientFactory( IOptions config, ILogger logger) { _cfg = config.Value; _logger = logger; } public bool IsRealApiEnabled => _cfg.EnableRealApi && !string.IsNullOrWhiteSpace(_cfg.DeveloperToken) && !string.IsNullOrWhiteSpace(_cfg.OAuth.ClientId) && !string.IsNullOrWhiteSpace(_cfg.OAuth.ClientSecret) && !string.IsNullOrWhiteSpace(_cfg.OAuth.RefreshToken); public GoogleAdsClient CreateClient(GoogleAdsContext context) { var loginCustomerId = NormalizeCustomerId( context.LoginCustomerId ?? _cfg.DefaultLoginCustomerId ?? string.Empty); var libConfig = new LibGoogleAdsConfig { DeveloperToken = _cfg.DeveloperToken, // ✅ Headless/server-to-server refresh-token flow OAuth2Mode = OAuth2Flow.APPLICATION, OAuth2ClientId = _cfg.OAuth.ClientId, OAuth2ClientSecret = _cfg.OAuth.ClientSecret, OAuth2RefreshToken = context.RefreshToken ?? _cfg.OAuth.RefreshToken, // MCC/manager header LoginCustomerId = string.IsNullOrWhiteSpace(loginCustomerId) ? null : loginCustomerId, // ms Timeout = Math.Max(1, _cfg.TimeoutSeconds) * 1000 }; _logger.LogDebug( "[GoogleAds] CreateClient | RealApi={RealApi} LoginCustomerIdSet={LoginSet}", IsRealApiEnabled, !string.IsNullOrWhiteSpace(libConfig.LoginCustomerId)); return new GoogleAdsClient(libConfig); } public static string NormalizeCustomerId(string customerId) => (customerId ?? string.Empty).Replace("-", string.Empty).Trim(); public static string FormatCustomerId(string customerId) { var normalized = NormalizeCustomerId(customerId); if (normalized.Length != 10) return normalized; return $"{normalized[..3]}-{normalized[3..6]}-{normalized[6..]}"; } }