UNPKG

@roytran91/bb-gg-ads-core

Version:
1,036 lines (931 loc) 39.5 kB
'use strict' // const { GoogleAdsClient, ListAccessibleCustomersRequest } = require('google-ads-node') const { GoogleAdsApi, enums, fromMicros, toMicros, getEnumString } = require('google-ads-api') const { AdwordsUser, AdwordAPI } = require('bb-adwords') const moment = require('moment') const GOOGLE_ERROR = 'GoogleError' const { google } = require('googleapis') // const ADWORD_VERSION = 'v201809' const PAGE_SIZE = 9999 module.exports = class Google { /** * @param object { client_id, client_secret, refresh_token, customer_account_id, developer_token, login_customer_id } */ constructor ({ client_id, client_secret, refresh_token, customer_account_id, developer_token, login_customer_id }) { this.googleAdsOpts = arguments[0] if (!client_id || !client_secret || !refresh_token || !developer_token) { throw new Error('Must specify {client_id, client_secret, refresh_token, developer_token}') } this.api = new GoogleAdsApi({ client_id, client_secret, developer_token }) this.authClient = this._buildOAuth2Client(client_id, client_secret) this._setRefreshToken(refresh_token) // this.client = new GoogleAdsClient({ // client_id, // client_secret, // developer_token, // refresh_token, // parseResults: true // }) this.adwordAPI = new AdwordsUser({ developerToken: developer_token, client_id, client_secret, refresh_token }) // create customer instance if customer_account_id provided if (customer_account_id) { this.customer = this.api.Customer({ customer_account_id, refresh_token, // login_customer_id }) const adwordApi = new AdwordAPI({ client_id, client_secret, developer_token, refresh_token, customer_account_id }) // add customer adword instance to user adword api this.adwordUser = adwordApi.Customer({ customer_account_id, refresh_token }) } } /** * get list ENUMS * @returns {{BiddingSource: BiddingSource; ConversionActionCountingType: ConversionActionCountingType; FeedItemValidationError: FeedItemValidationError; SimulationModificationMethod: SimulationModificationMethod; PolicyTopicEvidenceDestinationNotWorkingDevice: PolicyTopicEvidenceDestinationNotWorkingDevice; LocationGroupRadiusUnits: LocationGroupRadiusUnits; RangeError: RangeError; FeedLinkStatus: FeedLinkStatus; DsaPageFeedCriterionField: DsaPageFeedCriterionField; CustomerPayPerConversionEligibilityFailureReason: CustomerPayPerConversionEligibilityFailureReason; AgeRangeType: AgeRangeType; AdType: AdType; UserListDateRuleItemOperator: UserListDateRuleItemOperator; QuotaError: QuotaError; TargetImpressionShareLocation: TargetImpressionShareLocation; SizeLimitError: SizeLimitError; FieldMaskError: FieldMaskError; GoogleAdsFieldCategory: GoogleAdsFieldCategory; PageOnePromotedStrategyGoal: PageOnePromotedStrategyGoal; CustomerError: CustomerError; CampaignCriterionError: CampaignCriterionError; ManagerLinkStatus: ManagerLinkStatus; UserListStringRuleItemOperator: UserListStringRuleItemOperator; PromotionExtensionDiscountModifier: PromotionExtensionDiscountModifier; KeywordPlanNegativeKeywordError: KeywordPlanNegativeKeywordError; CampaignCriterionStatus: CampaignCriterionStatus; MutateJobError: MutateJobError; HotelRateType: HotelRateType; AdGroupCriterionStatus: AdGroupCriterionStatus; FrequencyCapTimeUnit: FrequencyCapTimeUnit; FeedItemQualityApprovalStatus: FeedItemQualityApprovalStatus; MediaType: MediaType; LabelError: LabelError; ChangeStatusOperation: ChangeStatusOperation; DatabaseError: DatabaseError; VanityPharmaDisplayUrlMode: VanityPharmaDisplayUrlMode; UserListCrmDataSourceType: UserListCrmDataSourceType; ContextError: ContextError; JobPlaceholderField: JobPlaceholderField; CampaignStatus: CampaignStatus; AdGroupAdError: AdGroupAdError; MultiplierError: MultiplierError; MimeType: MimeType; BudgetStatus: BudgetStatus; CampaignSharedSetError: CampaignSharedSetError; CriterionType: CriterionType; ResourceCountLimitExceededError: ResourceCountLimitExceededError; PolicyTopicEvidenceDestinationMismatchUrlType: PolicyTopicEvidenceDestinationMismatchUrlType; PlaceholderType: PlaceholderType; SharedSetError: SharedSetError; SharedCriterionError: SharedCriterionError; DateRangeError: DateRangeError; ExternalConversionSource: ExternalConversionSource; FeedItemError: FeedItemError; Device: Device; AdvertisingChannelSubType: AdvertisingChannelSubType; CampaignExperimentError: CampaignExperimentError; NotEmptyError: NotEmptyError; MerchantCenterLinkStatus: MerchantCenterLinkStatus; CampaignExperimentStatus: CampaignExperimentStatus; GeoTargetConstantStatus: GeoTargetConstantStatus; ConversionActionType: ConversionActionType; AppPaymentModelType: AppPaymentModelType; DataDrivenModelStatus: DataDrivenModelStatus; InternalError: InternalError; OperatorError: OperatorError; PriceExtensionType: PriceExtensionType; BidModifierSource: BidModifierSource; WebpageConditionOperator: WebpageConditionOperator; FeedItemTargetDevice: FeedItemTargetDevice; CustomerManagerLinkError: CustomerManagerLinkError; MatchingFunctionOperator: MatchingFunctionOperator; UserListSizeRange: UserListSizeRange; BudgetDeliveryMethod: BudgetDeliveryMethod; ProductBiddingCategoryStatus: ProductBiddingCategoryStatus; PromotionExtensionOccasion: PromotionExtensionOccasion; FunctionParsingError: FunctionParsingError; CountryCodeError: CountryCodeError; UserListClosingReason: UserListClosingReason; ServedAssetFieldType: ServedAssetFieldType; QueryError: QueryError; AdGroupType: AdGroupType; FunctionError: FunctionError; FeedAttributeType: FeedAttributeType; CustomInterestError: CustomInterestError; KeywordPlanForecastInterval: KeywordPlanForecastInterval; ProductCondition: ProductCondition; ChangeStatusError: ChangeStatusError; FeedMappingError: FeedMappingError; CustomPlaceholderField: CustomPlaceholderField; VanityPharmaText: VanityPharmaText; MinuteOfHour: MinuteOfHour; LocalPlaceholderField: LocalPlaceholderField; ExtensionType: ExtensionType; ClickType: ClickType; IdError: IdError; TargetCpaOptInRecommendationGoal: TargetCpaOptInRecommendationGoal; WebpageConditionOperand: WebpageConditionOperand; AccountBudgetStatus: AccountBudgetStatus; CustomInterestStatus: CustomInterestStatus; NewResourceCreationError: NewResourceCreationError; PaymentMode: PaymentMode; DisplayUploadProductType: DisplayUploadProductType; ConversionLagBucket: ConversionLagBucket; AffiliateLocationFeedRelationshipType: AffiliateLocationFeedRelationshipType; StringFormatError: StringFormatError; SimulationType: SimulationType; BiddingStrategyError: BiddingStrategyError; InteractionEventType: InteractionEventType; AppCampaignBiddingStrategyGoalType: AppCampaignBiddingStrategyGoalType; NotWhitelistedError: NotWhitelistedError; AdCustomizerError: AdCustomizerError; FieldError: FieldError; CustomerClientLinkError: CustomerClientLinkError; KeywordMatchType: KeywordMatchType; ConversionActionStatus: ConversionActionStatus; GoogleAdsFieldDataType: GoogleAdsFieldDataType; ConversionAdjustmentUploadError: ConversionAdjustmentUploadError; YoutubeVideoRegistrationError: YoutubeVideoRegistrationError; FrequencyCapEventType: FrequencyCapEventType; LegacyAppInstallAdAppStore: LegacyAppInstallAdAppStore; ConversionOrAdjustmentLagBucket: ConversionOrAdjustmentLagBucket; SystemManagedResourceSource: SystemManagedResourceSource; BiddingStrategyType: BiddingStrategyType; LanguageCodeError: LanguageCodeError; Slot: Slot; LocationExtensionTargetingCriterionField: LocationExtensionTargetingCriterionField; DistinctError: DistinctError; AdSharingError: AdSharingError; ConversionAdjustmentType: ConversionAdjustmentType; AdStrength: AdStrength; KeywordPlanNetwork: KeywordPlanNetwork; AttributionModel: AttributionModel; PriceExtensionPriceUnit: PriceExtensionPriceUnit; MediaFileError: MediaFileError; ExtensionFeedItemError: ExtensionFeedItemError; TravelPlaceholderField: TravelPlaceholderField; NullError: NullError; MutateJobStatus: MutateJobStatus; LocationPlaceholderField: LocationPlaceholderField; BillingSetupStatus: BillingSetupStatus; FrequencyCapLevel: FrequencyCapLevel; OperatingSystemVersionOperatorType: OperatingSystemVersionOperatorType; ImageError: ImageError; CustomerMatchUploadKeyType: CustomerMatchUploadKeyType; KeywordPlanKeywordError: KeywordPlanKeywordError; StructuredSnippetPlaceholderField: StructuredSnippetPlaceholderField; CampaignDraftError: CampaignDraftError; AdServingOptimizationStatus: AdServingOptimizationStatus; MediaUploadError: MediaUploadError; DayOfWeek: DayOfWeek; AppStore: AppStore; AdCustomizerPlaceholderField: AdCustomizerPlaceholderField; ProductBiddingCategoryLevel: ProductBiddingCategoryLevel; FlightPlaceholderField: FlightPlaceholderField; MutateError: MutateError; CampaignExperimentType: CampaignExperimentType; ContentLabelType: ContentLabelType; CampaignSharedSetStatus: CampaignSharedSetStatus; HotelPlaceholderField: HotelPlaceholderField; AppUrlOperatingSystemType: AppUrlOperatingSystemType; GeoTargetConstantSuggestionError: GeoTargetConstantSuggestionError; ConversionUploadError: ConversionUploadError; AdGroupStatus: AdGroupStatus; DisplayAdFormatSetting: DisplayAdFormatSetting; LabelStatus: LabelStatus; CriterionError: CriterionError; ParentalStatusType: ParentalStatusType; PolicyViolationError: PolicyViolationError; CustomerFeedError: CustomerFeedError; AdGroupAdRotationMode: AdGroupAdRotationMode; ExtensionSettingError: ExtensionSettingError; RegionCodeError: RegionCodeError; CampaignBudgetError: CampaignBudgetError; UserListRuleType: UserListRuleType; InteractionType: InteractionType; DateError: DateError; TrackingCodePageFormat: TrackingCodePageFormat; SearchEngineResultsPageType: SearchEngineResultsPageType; MediaBundleError: MediaBundleError; AdGroupBidModifierError: AdGroupBidModifierError; BrandSafetySuitability: BrandSafetySuitability; TrackingCodeType: TrackingCodeType; PolicyTopicEntryType: PolicyTopicEntryType; PositiveGeoTargetType: PositiveGeoTargetType; SearchTermTargetingStatus: SearchTermTargetingStatus; GenderType: GenderType; RealEstatePlaceholderField: RealEstatePlaceholderField; BiddingError: BiddingError; PricePlaceholderField: PricePlaceholderField; CampaignDraftStatus: CampaignDraftStatus; ConversionActionError: ConversionActionError; KeywordPlanCampaignError: KeywordPlanCampaignError; FeedItemTargetType: FeedItemTargetType; UserListType: UserListType; SpendingLimitType: SpendingLimitType; SharedSetType: SharedSetType; FeedItemValidationStatus: FeedItemValidationStatus; ListOperationError: ListOperationError; ListingCustomAttributeIndex: ListingCustomAttributeIndex; CalloutPlaceholderField: CalloutPlaceholderField; SettingError: SettingError; FeedError: FeedError; PartialFailureError: PartialFailureError; ChangeStatusResourceType: ChangeStatusResourceType; CallPlaceholderField: CallPlaceholderField; ExtensionSettingDevice: ExtensionSettingDevice; OperationAccessDeniedError: OperationAccessDeniedError; UserListMembershipStatus: UserListMembershipStatus; FeedMappingCriterionType: FeedMappingCriterionType; PolicyApprovalStatus: PolicyApprovalStatus; ProductChannel: ProductChannel; ErrorEnum: ErrorEnum; AssetError: AssetError; GeoTargetingType: GeoTargetingType; PlacementType: PlacementType; HotelDateSelectionType: HotelDateSelectionType; CustomInterestType: CustomInterestType; RecommendationError: RecommendationError; AuthorizationError: AuthorizationError; UserListCombinedRuleOperator: UserListCombinedRuleOperator; AdError: AdError; SharedSetStatus: SharedSetStatus; UserListNumberRuleItemOperator: UserListNumberRuleItemOperator; FeedMappingStatus: FeedMappingStatus; AdxError: AdxError; CallConversionReportingState: CallConversionReportingState; RecommendationType: RecommendationType; AdGroupFeedError: AdGroupFeedError; AdGroupAdStatus: AdGroupAdStatus; CampaignServingStatus: CampaignServingStatus; CollectionSizeError: CollectionSizeError; MessagePlaceholderField: MessagePlaceholderField; AppPlaceholderField: AppPlaceholderField; UserListLogicalRuleOperator: UserListLogicalRuleOperator; PolicyValidationParameterError: PolicyValidationParameterError; AffiliateLocationPlaceholderField: AffiliateLocationPlaceholderField; ListingGroupType: ListingGroupType; MonthOfYear: MonthOfYear; PolicyReviewStatus: PolicyReviewStatus; CustomInterestMemberType: CustomInterestMemberType; ConversionAttributionEventType: ConversionAttributionEventType; AdParameterError: AdParameterError; AccountBudgetProposalStatus: AccountBudgetProposalStatus; RequestError: RequestError; KeywordPlanAdGroupError: KeywordPlanAdGroupError; CriterionSystemServingStatus: CriterionSystemServingStatus; TimeType: TimeType; AppCampaignAppStore: AppCampaignAppStore; GeoTargetingRestriction: GeoTargetingRestriction; KeywordPlanCompetitionLevel: KeywordPlanCompetitionLevel; HeaderError: HeaderError; FeedItemStatus: FeedItemStatus; AdGroupCriterionApprovalStatus: AdGroupCriterionApprovalStatus; KeywordPlanIdeaError: KeywordPlanIdeaError; AssetType: AssetType; CampaignError: CampaignError; ProximityRadiusUnits: ProximityRadiusUnits; TargetingDimension: TargetingDimension; UserListError: UserListError; ManagerLinkError: ManagerLinkError; CampaignFeedError: CampaignFeedError; UserListPrepopulationStatus: UserListPrepopulationStatus; EducationPlaceholderField: EducationPlaceholderField; SitelinkPlaceholderField: SitelinkPlaceholderField; AdGroupError: AdGroupError; AdvertisingChannelType: AdvertisingChannelType; FeedAttributeReferenceError: FeedAttributeReferenceError; ResourceAccessDeniedError: ResourceAccessDeniedError; KeywordPlanError: KeywordPlanError; PriceExtensionPriceQualifier: PriceExtensionPriceQualifier; CampaignExperimentTrafficSplitType: CampaignExperimentTrafficSplitType; BudgetType: BudgetType; SearchTermMatchType: SearchTermMatchType; ConversionActionCategory: ConversionActionCategory; ProductChannelExclusivity: ProductChannelExclusivity; AccessReason: AccessReason; PreferredContentType: PreferredContentType; NegativeGeoTargetType: NegativeGeoTargetType; CriterionCategoryChannelAvailabilityMode: CriterionCategoryChannelAvailabilityMode; AdGroupCriterionError: AdGroupCriterionError; FeedStatus: FeedStatus; BillingSetupError: BillingSetupError; MatchingFunctionContextType: MatchingFunctionContextType; BiddingStrategyStatus: BiddingStrategyStatus; AccountBudgetProposalType: AccountBudgetProposalType; ProductTypeLevel: ProductTypeLevel; UserListAccessStatus: UserListAccessStatus; IncomeRangeType: IncomeRangeType; PromotionPlaceholderField: PromotionPlaceholderField; UrlFieldError: UrlFieldError; AdNetworkType: AdNetworkType; UserInterestTaxonomyType: UserInterestTaxonomyType; AuthenticationError: AuthenticationError; BudgetPeriod: BudgetPeriod; MobileDeviceType: MobileDeviceType; CriterionCategoryLocaleAvailabilityMode: CriterionCategoryLocaleAvailabilityMode; FeedItemTargetError: FeedItemTargetError; QualityScoreBucket: QualityScoreBucket; PolicyFindingError: PolicyFindingError; StringLengthError: StringLengthError; FeedOrigin: FeedOrigin; AccountBudgetProposalError: AccountBudgetProposalError; FeedItemQualityDisapprovalReason: FeedItemQualityDisapprovalReason}} * @constructor */ static get ENUMS () { return enums } static fromMicros () { return fromMicros.apply(null, arguments) } static toMicros () { return toMicros.apply(null, arguments) } static getEnumString () { return getEnumString.apply(null, arguments) } /** * * @param customerAccountId * @param managerAccountId * @returns {{}|CustomerInstance} * @constructor */ Customer (customerAccountId, managerAccountId) { if (!customerAccountId) { return {} } if (typeof customerAccountId !== 'string') { customerAccountId = customerAccountId.toString() } if (typeof managerAccountId !== 'string' && managerAccountId) { managerAccountId = managerAccountId.toString() } return this.api.Customer({ customer_account_id: customerAccountId, refresh_token: this.googleAdsOpts.refresh_token, login_customer_id: managerAccountId }) } adwordCustomer (customerAccountId) { if (!customerAccountId) { return {} } if (typeof customerAccountId !== 'string') { customerAccountId = customerAccountId.toString() } return new AdwordsUser({ developerToken: this.googleAdsOpts.developer_token, clientCustomerId: customerAccountId, client_id: this.googleAdsOpts.client_id, client_secret: this.googleAdsOpts.client_secret, refresh_token: this.googleAdsOpts.refresh_token }) } // /** // * Get list manager ads account // * @returns {Array<ids>} // */ // async getManagerAccountIds () { // try { // // Load a Customer Service // const service = this.client.getService('CustomerService') // // Create a new service request // const request = new ListAccessibleCustomersRequest() // // Call the ListAccessibleCustomers method of the CustomerService (Note: Methods are camel case in this library) // const response = await service.listAccessibleCustomers(request) // if (!response) { // return [] // } // // return Object.values(response.resourceNames) // } catch (e) { // e.name = GOOGLE_ERROR // throw e // } // } /** * Get list ads account * @returns {Array<ids>} */ async getAccounts (accountId) { try { let managerUser = this.adwordAPI.getService('CustomerService') if (accountId) { managerUser = this.adwordCustomer(accountId).getService('CustomerService') } const selector = { fields: ['Name', 'CustomerId', 'CurrencyCode', 'DateTimeZone', 'CanManageClients'], // ordering: [{ field: 'Name', sortOrder: 'ASCENDING' }], paging: { startIndex: 0, numberResults: PAGE_SIZE } } const customers = await managerUser.getCustomers({ serviceSelector: selector }) if (!customers) { return [] } return customers } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get list managed ads account * @returns {Array<ids>} */ async getManagedAccounts (managerId) { try { const managerUser = this.adwordCustomer(managerId).getService('ManagedCustomerService') const selector = { fields: ['Name', 'CustomerId', 'CurrencyCode', 'DateTimeZone', 'CanManageClients'], // ordering: [{ field: 'Name', sortOrder: 'ASCENDING' }], paging: { startIndex: 0, numberResults: PAGE_SIZE } } const customers = await managerUser.get({ serviceSelector: selector }) if (!customers) { return [] } return customers.entries } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * create a new adAccount under manager ad-account * @param managerId * @param customer {currencyCode, name, dateTimeZone} * @returns {Promise<*>} */ async createCustomerClient (customer) { try { let managerId = this.googleAdsOpts.login_customer_id if (!managerId) { managerId = this.googleAdsOpts.customer_account_id } const managerUser = this.adwordCustomer(managerId).getService('ManagedCustomerService') return await managerUser.mutate({ operations: [ { operator: 'ADD', operand: customer } ] }) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * get list ads account from google account * @param options * @param includeManagerAccount if false the list will not have manager account information * @returns {Promise<Array>} */ // async getAdAccounts (options = {}, includeManagerAccount = false) { // try { // const managerAccounts = await this.getManagerAccountIds() // let accountList = [] // // // return accountList // await Promise.all(managerAccounts.map(async accountId => { // // if resource name format convert to id format // if (typeof accountId === 'string' && accountId.startsWith('customers/')) { accountId = accountId.replace('customers/', '') } // // if (!includeManagerAccount) { // options = Object.assign(options, { // constraints: [ // { // key: 'customer_client.level', // op: '>', // val: '0' // }, // { // key: 'customer_client.hidden', // op: '=', // val: false // }] // }) // } // // const isManagerAccount = await this.isManagerAccount(accountId) // if (isManagerAccount) { // let adsAccounts = await this.Customer(accountId).customerClients.list(options) // // get detail info of client customer // adsAccounts = await Promise.all(adsAccounts.map(async ({ customer_client }) => new Promise((resolve) => { // this.getAdAccount( // customer_client.client_customer, // accountId).then(resolve).catch(resolve.bind(resolve, null)) // }))) // accountList = accountList.concat(adsAccounts.filter(acc => acc !== null)) // } else { // const account = await this.getAdAccount(accountId) // accountList.push(account) // } // })) // // return accountList // } catch (e) { // e.name = GOOGLE_ERROR // throw e // } // } /** * get list ads account from google account * @param options * @param includeManagerAccount if false the list will not have manager account information * @returns {Promise<Array>} */ async getAdAccountsV2 (options = {}, includeManagerAccount = false) { try { const managerAccounts = await this.getAccounts() let accountList = [] // return accountList await Promise.all(managerAccounts.map(async account => { // if resource name format convert to id format // console.log(`acc`, account) const accountId = account.customerId if (account.canManageClients) { const adsAccounts = await this.getManagedAccounts(accountId) // get detail info of client customer accountList = accountList.concat(adsAccounts.map(account => { return { descriptive_name: account.name, currency_code: account.currencyCode, id: account.customerId, manager: account.canManageClients, time_zone: account.dateTimeZone, managerId: accountId } })) } else { const { customerId, name, canManageClients, currencyCode, dateTimeZone } = account accountList.push({ descriptive_name: name, currency_code: currencyCode, id: customerId, manager: canManageClients, time_zone: dateTimeZone }) } })) // dont return account is manager return accountList.filter(acc => includeManagerAccount || !acc.manager) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * get list ads account Id from google account * @param options * @param includeManagerAccount if false the list will not have manager account information * @returns {Promise<Array>} */ // async getAdAccountIds (options = {}, includeManagerAccount = false) { // try { // const managerAccounts = await this.getManagerAccountIds() // let accountIdList = [] // // // return accountList // await Promise.all(managerAccounts.map(async accountId => { // // if resource name format convert to id format // if (typeof accountId === 'string' && accountId.startsWith('customers/')) { accountId = accountId.replace('customers/', '') } // // if (!includeManagerAccount) { // options = Object.assign(options, { // constraints: [ // { // key: 'customer_client.level', // op: '>', // val: '0' // }, // { // key: 'customer_client.hidden', // op: '=', // val: false // }] // }) // } // // const isManagerAccount = await this.isManagerAccount(accountId) // if (isManagerAccount) { // const adsAccounts = await this.Customer(accountId).customerClients.list(options) // accountIdList = accountIdList.concat(adsAccounts.map(({ customer_client }) => { // return { managerId: accountId, adAccountId: customer_client.client_customer, ...customer_client } // })) // } else { // accountIdList.push({ // adAccountId: accountId // }) // } // })) // return accountIdList // } catch (e) { // e.name = GOOGLE_ERROR // throw e // } // } /** * get ads account information * @param accountId * @param managerId * @returns {Promise<any>} */ async getAdAccount (accountId, managerId) { try { if (!accountId) { return null } accountId = accountId.replace('customers/', '') // If have managerId should add it to each client account const [{ customer }] = await this.Customer(accountId, managerId) .query(`SELECT customer.descriptive_name, customer.currency_code, customer.id, customer.manager, customer.time_zone, customer.resource_name FROM customer`) return Object.assign(customer, { managerId }, { id: customer.id.toString() }) } catch (e) { return null } } /** * update a other refresh token dont need create new instance for new customer, just update new token for the customer * @param token the refresh token want to update */ updateRefreshToken (token) { if (typeof token !== 'string') { throw Error('Token is invalid') } this.googleAdsOpts.refresh_token = token // const { client_id, client_secret, developer_token, refresh_token } = this.googleAdsOpts // this.client = new GoogleAdsClient({ // client_id, // client_secret, // developer_token, // refresh_token, // parseResults: true // }) if (this.customer) { const { customer_account_id, login_customer_id } = this.googleAdsOpts this.customer = this.Customer(customer_account_id, login_customer_id) } } /** * * @param campaignObj * @param options * @returns {Promise<Mutation>} */ async createCampaign (campaignObj, options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.campaigns.create(campaignObj, options) } catch (e) { e.name = GOOGLE_ERROR throw e } } async isManagerAccount (accountId) { const account = await this.getAdAccount(accountId) return account && account.manager } /** * * @param campaignObj * @param options * @returns {Promise<Mutation>|*} */ async updateCampaign (campaignObj, options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.campaigns.update(campaignObj, options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get a campaign * @param resource_name the resource_name of the campaign * @returns {Campaign} */ async getCampaign (resource_name) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.campaigns.get(resource_name) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get list campaigns * @param options * @returns {Campaigns} */ async getCampaigns (options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.campaigns.list(options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get list campaigns use adword API * @param options * @returns {Campaigns} */ async getCampaignsV2 (options) { try { if (!this.adwordUser) { throw new Error('Don\'t have adwordUser instance') } return await this.adwordUser.campaign.list(options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get list campaigns Criteria * @param options * @returns Promise[]<adGroupCriteria> | Promise.reject */ async getCampaignCriteria (options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.campaignCriteria.list(options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * create campaigns Criteria * @param data * @param options * @returns Promise[]<adGroupCriteria> | Promise.reject */ async createCampaignCriteria (data, options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.campaignCriteria.create(data, options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * create adSet Criteria * @param data * @param options * @returns Promise[]<adGroupCriteria> | Promise.reject */ async createAdSetCriteria (data, options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.adGroupCriteria.create(data, options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Update ad-group criteria * @param data * @param options * @returns {Promise<Mutation>} */ async updateAdSetCriteria (data, options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.adGroupCriteria.update(data, options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * create bidding strategies * @param entity * @param options * @returns Promise[]<adGroupCriteria> | Promise.reject */ async createBiddingStrategy (entity, options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.biddingStrategies.create(entity, options) } catch (e) { e.name = GOOGLE_ERROR throw e } } async mutateResources (resources) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.mutateResources(resources) } catch (e) { e.name = GOOGLE_ERROR console.error(e) throw e } } /** * Get list campaigns Criteria * @param options * @returns Promise[]<adGroupCriteria> | Promise.reject */ async getAdSetCriteria (options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.adGroupCriteria.list(options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get list adSet * @param options * @returns {Promise<Array<{ad_group: AdGroup}>>} */ async getAdSets (options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.adGroups.list(options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get list campaigns use adWord API * @param options * @returns {Promise<*>} */ async getAdSetsV2 (options) { try { if (!this.adwordUser) { throw new Error('Don\'t have adwordUser instance') } return await this.adwordUser.adGroup.list(options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get list ad * @param options * @returns {Promise<Array<{ad_group_ad: AdGroupAd}>>} */ async getAds (options) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.adGroupAds.list(options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get history change of list campaignId in a ad account * @param campaignIds * @param fromTime * @param toTime * @returns {Promise<*|Promise<*>>} */ async getHistory (campaignIds, fromTime, toTime) { try { if (!this.adwordUser) { throw new Error('Don\'t have customer instance') } if (!campaignIds || !Array.isArray(campaignIds)) { throw new Error('campaignIds need provide') } if (!fromTime) { fromTime = moment().subtract(1, 'd') } if (!toTime) { toTime = new Date() } return await this.adwordUser.customerSync.get({ selector: { dateTimeRange: { min: moment(fromTime).utc().format('YMMDD HHmmss [GMT]'), max: moment(toTime).utc().format('YMMDD HHmmss [GMT]') }, campaignIds: campaignIds } }) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get list ad * @param options * @returns {Promise<*>} */ async getAdsV2 (options) { try { if (!this.adwordUser) { throw new Error('Don\'t have customer instance') } return await this.adwordUser.adGroupAd.list(options) } catch (e) { e.name = GOOGLE_ERROR throw e } } async updateCustomerV2 (data = {}) { try { if (!this.adwordUser) { throw new Error('Don\'t have customer instance') } if (!data.customerId) { throw new Error('customerId field need to provider') } return await this.adwordUser.managedCustomer.mutate({ operations: [ { operator: 'SET', operand: data } ] }) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Delete a campaign * @param campaignId * @returns {Promise<Mutation>} */ async deleteCampaign (campaignId) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.campaigns.delete(campaignId) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Update a adSet or adSet list * @param adSets Object or Array * @param options Object of the form { validate_only, partial_failure }: * @returns {Promise} */ async updateAdSet (adSets, options = {}) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.adGroups.update(adSets, options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Update a Campaign or campaign List * @param campaigns Object or Array * @param options Object of the form { validate_only, partial_failure }: * @returns {Promise} */ // async updateCampaign (campaigns, options = {}) { // try { // if (!this.customer) { // throw new Error('Don\'t have customer instance') // } // // return await this.customer.campaigns.update(campaigns, options) // } catch (e) { // e.name = GOOGLE_ERROR // throw e // } // } /** * Update a Ad or Ad list * @param ads Object or Array * @param options Object of the form { validate_only, partial_failure }: * @returns {Promise} */ async updateAd (ads, options = {}) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.adGroupAds.update(ads, options) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * API Query * @param query * @returns {Promise<Array<any>>} */ async apiQuery (query) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.query(query) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * API report * @param params * @returns {ReportResponse} */ async apiReport (params) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.report(params) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * AdWord report * @param params * @returns {Promise<unknown>} */ async adwordReport (params) { try { if (!this.adwordUser) { throw new Error('Don\'t have customer instance') } return await this.adwordUser.report.getReport(params, false) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Location * @param params * @returns {Promise<*>} */ async location (params) { try { if (!this.adwordUser) { throw new Error('Don\'t have customer instance') } return await this.adwordUser.locationCriterion.list(params) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * Get bidding strategy * @param params * @returns {ReportResponse} */ async getBibdingStrategies (params) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.biddingStrategies.list(params) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * * @param params * @returns {ReportResponse} */ async getKeywordPlan (params) { try { if (!this.customer) { throw new Error('Don\'t have customer instance') } return await this.customer.keywordPlanKeywords.list(params) } catch (e) { e.name = GOOGLE_ERROR throw e } } /** * get google account information * @returns {Promise<Account>} */ getMe () { return new Promise((resolve, reject) => { try { const oauth2 = google.oauth2({ auth: this.authClient, version: 'v2' }) const params = { fields: 'email,family_name,given_name,gender,id,locale,name,picture,verified_email' } oauth2.userinfo.v2.me.get(params, (err, res) => { if (err) { err.name = GOOGLE_ERROR return reject(err) } else { return resolve(res.data) } } ) } catch (e) { e.name = GOOGLE_ERROR return reject(e) } }) } _buildOAuth2Client (clientId, clientSecret) { const OAuth2 = google.auth.OAuth2 return new OAuth2({ clientId, clientSecret }) } _setRefreshToken (refreshToken) { const credentials = { refresh_token: refreshToken } this.authClient.setCredentials(credentials) } }