Re: adgroupcriterionoperation - update listinggrouptype unit to subdivision

2024-02-22 Thread Jebron Lames
I figured it out and can now convert a UNIT to SUBDIVISION with additional 
UNIT nodes. Firstly, thank you for getting back each time. 

For those whom I hope this helps...

*first error:*  I was pointing the "others" node parent resource to that of 
the root node criterion_id and not the new subdivision.

*second error: * I was subdividing the partition by product_item_id, I 
incorrectly configured my code to mimic the case_value property of the 
selected node and not what it was going to be subdivided by.

The example is the order of how I am doing it (order of operations).  I 
want to note though that *I only create a subdivision if a user decides to 
subdivide a node (i.e. brand or product type) that is currently a UNIT*.  
case_value for all nodes are dynamically determined based on the 
selectedNode and to be added UNIT nodes. If it's already a subdivision, 
then this process is skipped.

const updateSelectedNodeType = new resources.AdGroupCriterion({
resource_name: tempSubdivisionResource,
ad_group: adGroupResource,
listing_group: {
  parent_ad_group_criterion: parentNode,
  type: enums.ListingGroupType.SUBDIVISION,
  case_value: caseValue,
},
negative: false,
status: enums.AdGroupCriterionStatus.ENABLED,
  });

  const everythingElseNode = new resources.AdGroupCriterion({
resource_name: everythingElseResource,
ad_group: adGroupResource,
cpc_bid_micros: toMicros(0.4),
listing_group: {
  parent_ad_group_criterion: tempSubdivisionResource,
  type: enums.ListingGroupType.UNIT,
  case_value: everythingElseCaseValue,
},
negative: false,
status: enums.AdGroupCriterionStatus.ENABLED,
  });

  const updatePartitionToSubdivision: MutateOperation =
{
  entity: "ad_group_criterion",
  operation: "create",
  resource: {
...updateSelectedNodeType,
  },
};

  createSubdivisionOperation.push(updatePartitionToSubdivision);

  const createEverythingElseNodeOperation: MutateOperation =
{
  entity: "ad_group_criterion",
  operation: "create",
  resource: {
...everythingElseNode,
  },
};
  createSubdivisionOperation.push(createEverythingElseNodeOperation);
//partition object with set cpc, but can be changed for user.
const newPartition = new resources.AdGroupCriterion({
  ad_group: `customers/${customer}/adGroups/${adGroupId}`,
  resource_name: criterionResourceOperation,
  cpc_bid_micros: toMicros(0.4),
  negative: false,
  status: enums.AdGroupCriterionStatus.ENABLED,
  listing_group: {
parent_ad_group_criterion: parentAdGroupCriterion,
type: enums.ListingGroupType.UNIT,
case_value: caseValue,
  },
});
//finalize for operation
const addPartitionNodes: MutateOperation 
=
  {
entity: "ad_group_criterion",
operation: "create",
resource: newPartition,
  };

//push for batch operation
addPartitionOperation.push(addPartitionNodes);


mutation: [
  {
entity: 'ad_group_criterion',
operation: 'create',
resource: {
  resource_name: 'customers/2595901092/adGroupCriteria/157149367644~-1',
  ad_group: 'customers/2595901092/adGroups/157149367644',
  listing_group: [Object],
  negative: false,
  status: 2
}
  },
  {
entity: 'ad_group_criterion',
operation: 'create',
resource: {
  resource_name: 'customers/2595901092/adGroupCriteria/157149367644~-2',
  ad_group: 'customers/2595901092/adGroups/157149367644',
  cpc_bid_micros: 40,
  listing_group: [Object],
  negative: false,
  status: 2
}
  },
  {
operation: 'create',
resource: v {
  ad_group: 'customers/2595901092/adGroups/157149367644',
  resource_name: 'customers/2595901092/adGroupCriteria/157149367644~-3',
  cpc_bid_micros: 40,
  negative: false,
  status: 2,
  listing_group: [Object]
}
  }
] [
//case values:
  { product_brand: { value: 'bromic' } },
  { product_item_id: {} },
  {
product_item_id: { value: 'shopify_us_5695534235803_36317916823707' }
  }
]
Operation Success! Subdivision created.

Purely comes down to a misunderstanding on my part. Thanks for working with 
me on this.

Regards,
Michael H.



On Thursday, February 22, 2024 at 2:01:29 PM UTC+7 Google Ads API Forum 
Advisor wrote:

> Hi,
>
> Thank you for getting back to us.
>
> I understand that you are seeking assistance for 
> LISTING_GROUP_ALREADY_EXISTS 
> 
>  error 
> and LISTING_GROUP_SUBDIVISION_REQUIRES_OTHERS_CASE 
> 

Re: adgroupcriterionoperation - update listinggrouptype unit to subdivision

2024-02-21 Thread 'Google Ads API Forum Advisor' via Google Ads API and AdWords API Forum
Hi,

Thank you for getting back to us.

I understand that you are seeking assistance for LISTING_GROUP_ALREADY_EXISTS 
error and LISTING_GROUP_SUBDIVISION_REQUIRES_OTHERS_CASE error. Kindly 
double-check the ID of the listing group you are trying to add. Make sure it 
doesn't already exist in the ad group you are adding it to. You can check for 
this by looking for repeated creation operations for the same ID or name.

As per the API documentation, a subdivision introduces a new level in the tree, 
while units are leaves of the tree. Each subdivision must always be completely 
partitioned, so it must contain a node representing 'Other'. To avoid error, 
add 'Other' node to the subdivision. You may refer to this guide for more 
information.

Regarding the above conflict between 'Others' nodes, the Google Ads API 
requires a single "Others" node per ad group. Having two nodes with the same 
name "Others" in the same ad group creates the conflict you're encountering. 
Since you want to create "Others" node for each brand, the earlier created 
'Others' node might be redundant. You can remove it from the brands partition. 
If you want to keep separate "Others" nodes, ensure they have distinct 
case_value fields. This helps differentiate them in the API calls. Hope this 
helps.
This message is in relation to case "ref:!00D1U01174p.!5004Q02rzEgV:ref"

Thanks,

Google Ads API Team

-- 
-- 
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
Also find us on our blog:
https://googleadsdeveloper.blogspot.com/
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~

You received this message because you are subscribed to the Google
Groups "AdWords API and Google Ads API Forum" group.
To post to this group, send email to adwords-api@googlegroups.com
To unsubscribe from this group, send email to
adwords-api+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/adwords-api?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Google Ads API and AdWords API Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to adwords-api+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/adwords-api/il2Xr0S98WTR00xgAeAs3ETZeBoCtGeLQO9g%40sfdc.net.


Re: adgroupcriterionoperation - update listinggrouptype unit to subdivision

2024-02-21 Thread Jebron Lames
Thanks for getting back to me again. I just want to say I appreciate your 
responses and deeply apologize as this is quite a complex and sensitive 
process given the constraints.

in your response:

   - You don't necessarily need to find and delete an "Others" node that 
   doesn't exist in your current tree. While the "Others" node captures 
   everything not explicitly covered by your subdivisions, it's automatically 
   created if it doesn't exist when you add a new subdivision.

Here are 3 separate examples (server-side logs) of trying to work with the 
API to convert a unit to a subdivision.
In each test I am:  In the 1st case, I pass just 2 objects (resource -1 & 
resource -2) as I was curious to see if I didn't add an "others" case, if 
it would be added. Each subsequent test I pass 3 objects to handle the 
"others" case.
*Note: To create this campaign with the Google Ads Api I had to have a root 
Node -> everything else root node -> brand node > everything else in brand 
node -> product_item_id node.*
 {
//*SUBDIVISION*
entity: 'ad_group_criterion',
operation: 'create',
resource: {
  resource_name: 'customers/2595901092/adGroupCriteria/157149367644~-1',
  ad_group: 'customers/2595901092/adGroups/157149367644',
  listing_group: [Object],
  negative: false,
  status: 2
}
  },
  {
// *UNIT*
entity: 'ad_group_criterion',
operation: 'create',
resource: {
  resource_name: 'customers/2595901092/adGroupCriteria/157149367644~-2',
  ad_group: 'customers/2595901092/adGroups/157149367644',
  cpc_bid_micros: 40,
  listing_group: [Object],
  negative: false,
  status: 2
}
  },
  {
// *UNIT*
entity: 'ad_group_criterion',
operation: 'create',
resource: v {
  ad_group: 'customers/2595901092/adGroups/157149367644',
  resource_name: 'customers/2595901092/adGroupCriteria/157149367644~-3',
  cpc_bid_micros: 40,
  negative: false,
  status: 2,
  listing_group: [Object]
}
  }

*case_value (in order):*
[
//brand
  { product_brand: { value: 'american fyre designs' } },

//everything else in brand - 1st test does not contain this.
  { product_brand: {} },

  {
// product under brand
product_item_id: { value: 'shopify_us_5960181579931_37204494057627' }
  }
]
*Test 1 - Do not add 'Others Node' because it is "automatically created" 
according to the previous explanation (2 operations)*
Ed {
  errors: [
Sd {
  error_code: { criterion_error: 108 },
  message: 'Subdivided listing groups must have an "others" case.',
  trigger: { int64_value: Long { low: -1, high: -1, unsigned: false } },
  location: [
Pd { field_name: 'mutate_operations', index: 0 },
Pd { field_name: 'ad_group_criterion_operation' },
Pd { field_name: 'create' },
Pd { field_name: 'listing_group' },
Pd { field_name: 'type' }
  ],
},
Sd {
  error_code: { criterion_error: 106 },
  message: 'Ad group is invalid due to the listing groups it contains.',
  trigger: { int64_value: Long { low: -1, high: -1, unsigned: false } },
  location: [
Pd { field_name: 'mutate_operations', index: 1 },
Pd { field_name: 'ad_group_criterion_operation' },
Pd { field_name: 'create' },
Pd { field_name: 'listing_group' }
  ]
}
  ],
request_id: '9V0lNLIqNwZz2PtuK5Dmtw'

*Test 2 - Add everything else node again with case_value: {} (empty 
object) *
Ed {
  errors: [
Sd {
  error_code: criterion_error: 108,
  message: 'Subdivided listing groups must have an "others" case.',
  trigger: { int64_value: Long { low: -1, high: -1, unsigned: false } },
  location: [
Pd { field_name: 'mutate_operations', index: 0 },
Pd { field_name: 'ad_group_criterion_operation' },
Pd { field_name: 'create' },
Pd { field_name: 'listing_group' },
Pd { field_name: 'type' }
  ],
},
Sd {
  error_code: { field_error: 2 },
  message: 'The required field was not present.',
  location: [
Pd { field_name: 'mutate_operations', index: 1 },
Pd { field_name: 'ad_group_criterion_operation' },
Pd { field_name: 'create' },
Pd { field_name: 'listing_group' },
Pd { field_name: 'case_value' }
  ]
},
Sd {
  error_code: criterion_error: 106,
  message: 'Ad group is invalid due to the listing groups it contains.',
  trigger: { int64_value: Long { low: -1, high: -1, unsigned: false } },
  location: [
Pd { field_name: 'mutate_operations', index: 2 },
Pd { field_name: 'ad_group_criterion_operation' },
Pd { field_name: 'create' },
Pd { field_name: 'listing_group' }
  ]
}
  ],
  request_id: 'iQhvrUQYbKU3Zpc6o2V84g'
}

*Test 3 - Set case_value property to empty object (i.e. product_brand: {} 
)  *
Ed {
  errors: [
Sd {
  error_code: criterion_error: 108,
  message: 'Subdivided listing groups must have an "others" case.',
  trigger: { int64_value: Long { low: -1, high: -1, unsigned: false } },
  

Re: adgroupcriterionoperation - update listinggrouptype unit to subdivision

2024-02-20 Thread Jebron Lames
So, after I successfully remove the node and begin to recreate it as a 
subdivision with children, I am getting an error at index 1 where it says 
the 'listing_group already exists'. This is my "other's node" operation.

//new subdivided node
const updateSelectedNodeType = new resources.AdGroupCriterion({
resource_name: tempSubdivisionResource,
ad_group: adGroupResource,
listing_group: {
  parent_ad_group_criterion: parentNode,
  type: enums.ListingGroupType.SUBDIVISION,
  case_value: caseValue,
},
negative: false,
status: enums.AdGroupCriterionStatus.ENABLED,
  });
//everything else node
  const everythingElseNode = new resources.AdGroupCriterion({
resource_name: everythingElseResource,
ad_group: adGroupResource,
cpc_bid_micros: toMicros(0.4),
listing_group: {
  parent_ad_group_criterion: parentNode,
  type: enums.ListingGroupType.UNIT,
  case_value: everythingElseCaseValue,
},
negative: false,
status: enums.AdGroupCriterionStatus.ENABLED,
  });
 //partition object with set cpc.
const newPartition = new resources.AdGroupCriterion({
  ad_group: `customers/${customer}/adGroups/${adGroupId}`,
  resource_name: criterionResourceOperation,
  cpc_bid_micros: toMicros(0.4),
  negative: false,
  status: enums.AdGroupCriterionStatus.ENABLED,
  listing_group: {
parent_ad_group_criterion: parentAdGroupCriterion,
type: enums.ListingGroupType.UNIT,
case_value: caseValue,
  },
});


0//tempid -1 
 const updatePartitionToSubdivision: MutateOperation =
{
  entity: "ad_group_criterion",
  operation: "create",
  resource: {
...updateSelectedNodeType,
  },
};

1//tempid -2 - ERROR - LISTING_GROUP ALREADY EXISTS
  const createEverythingElseNodeOperation: MutateOperation =
{
  entity: "ad_group_criterion",
  operation: "create",
  resource: {
...everythingElseNode,
  },
};
  
2//tempid -3
 const addPartitionNodes: MutateOperation =
  {
entity: "ad_group_criterion",
operation: "create",
resource: newPartition,
  };


How do I find a node that doesn't currently exist in my active tree, remove 
it and make sure I am not removing the wrong node? 

I tried to query:
query = `
SELECT 
ad_group_criterion.criterion_id,
ad_group_criterion.listing_group.case_value.${caseValue},
ad_group_criterion.listing_group.parent_ad_group_criterion,
ad_group_criterion.listing_group.path,
ad_group_criterion.listing_group.type
FROM product_group_view
WHERE ad_group_criterion.listing_group.type = 'UNIT'
AND ad_group_criterion.listing_group.case_value.${caseValue} IS NULL
AND ad_group_criterion.listing_group.parent_ad_group_criterion = '${
selectedNode?.listing_group?.parent_ad_group_criterion}'
`;

with this line:  AND 
ad_group_criterion.listing_group.parent_ad_group_criterion = '${selectedNode
?.listing_group?.parent_ad_group_criterion}'

I get the one partition from my active tree that is already the "others 
node" for an already subdivided partition (done during creation).

when I remove the line targeting parent criterion, I am left with about 900 
partitions. So I am really interested in learning how this works. In terms 
of the data relationship and structure, how does one identify the "others" 
node of a specific partition when 1. the other's node does not currently 
exist in the current product_group_view where ad_group.id = ${adgroupId}?

my tree is like this for said ag_group > product_group_view:
I already have a brand node subdivided by product item id.
I now want to do the same the other unit node(**).
S = Subdivision
U = UNIT
** = convert UNIT to SUBDIVISION operation

   all products(S)
|
   **brand(U) 
-brand (S)
|  
 |
|  
item_id(U)
|  
  |
  ev else (all)
   ev else (brand1) (U)

Can you please confirm that i have to find the "other's node" and delete it 
despite it not existing in my current tree? 
2. I saw in your response that I should querying the ad_group_criterion 
resource? not the product_group_view? Is there a specific advantage using 
the ad_group_criterion in this case?

Kind Regards,
Michael H.

On Tuesday, February 20, 2024 at 3:26:43 AM UTC+7 Google Ads API Forum 
Advisor wrote:

> Hi,
>
> Thank you for reaching out to the Google Ads API support team.
>
> By reviewing