@roytran91/bb-gg-ads-core
Version:
bb-gg-ads-core
1,036 lines (931 loc) • 39.5 kB
JavaScript
'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)
}
}