Posts under category google-ads-api

How can a CRM data be sent to Google Ads via API as a custom audience just like Facebook Custom Audience? Is there any sample APIs that I can refer to build one.

What i see so far is below on google Ads, https://developers.google.com/google-ads/api/docs/remarketing/audience-types/customer-match

But what we looking for is something like this, https://developers.facebook.com/docs/marketing-api/audiences/guides/custom-audiences/

Google says this should be added to html on the "conversion page".

<!-- Event snippet for Website lead conversion page --> <script>gtag('event', 'conversion', {'send_to': 'AW-sdad/-dsafdsa'});</script> 

I have a ReactJS app, so I have no single html "conversion page".

Can I run it from javascript somehow?

createAccount = () => {     Axios.post(`/api/signup`, { user })       .then(async (resp) => {         await Axios.post("/api/login", { email: this.state.email, password: this.state.password });         this.props.history.push("/app");         // Run google ad convert here?       })       .catch((err) => {         console.log(err);       });   }; 

I added a single Native ad to my application, but on different devices, ads, especially videos, come with a delay, on the emulator the video is not shown at all. I know that you can somehow preload ads, but I don’t know how to do it, please explain to me.

Here is my code:

class Fragment(private var index: Int, private var adsId: String) : Fragment() {     var currentNativeAd: UnifiedNativeAd? = null     lateinit var adLoader: AdLoader     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {         val view = inflater.inflate(R.layout.fragment, container, false)         return view     }     override fun onActivityCreated(savedInstanceState: Bundle?) {         super.onActivityCreated(savedInstanceState)         val unifiedNativeAdView = layoutInflater.inflate(R.layout.native_ad_layout, null) as UnifiedNativeAdView         val nativeAdLayout = view!!.findViewById<FrameLayout>(R.id.id_native_ad)         val adLoader = AdLoader.Builder(activity, adsId).forUnifiedNativeAd { unifiedNativeAd -> (unifiedNativeAd)             mapUnifiedNativeAdToLayout(unifiedNativeAd, unifiedNativeAdView)             nativeAdLayout.removeAllViews()         }.withAdListener(object : AdListener() {             // Code to be executed when an ad request fails.             override fun onAdLoaded() {                 super.onAdLoaded()                 if (!adLoader.isLoading) {                   nativeAdLayout.addView(unifiedNativeAdView)                 }             }             override fun onAdFailedToLoad(errorCode: Int) {                Toast.makeText(applicationContext, "Ad failed to load! error code: $errorCode", Toast.LENGTH_SHORT).show()             }             override fun onAdClosed() {                 nativeAdLayout.removeAllViews()             }         }).build()         adLoader.loadAd(AdRequest.Builder().build())         }     fun mapUnifiedNativeAdToLayout(adFromGoogle: UnifiedNativeAd, myAdView: UnifiedNativeAdView) {         currentNativeAd?.destroy()         currentNativeAd = adFromGoogle         val mediaView: MediaView = myAdView.findViewById(R.id.ad_media)         myAdView.mediaView = mediaView         myAdView.bodyView = myAdView.findViewById(R.id.ad_body)         if (adFromGoogle.body == null) {             myAdView.bodyView.visibility = View.GONE         } else {             (myAdView.bodyView as TextView).text = adFromGoogle.body         }         myAdView.setNativeAd(adFromGoogle)         val vc = adFromGoogle.videoController         if (vc.hasVideoContent()) {             vc.videoLifecycleCallbacks = object : VideoController.VideoLifecycleCallbacks() {                 override fun onVideoEnd() {                     super.onVideoEnd()                 }             }         }      }     override fun onDestroy() {         currentNativeAd?.destroy()         super.onDestroy()     } } 

native_ad_layout.xml

<?xml version="1.0" encoding="utf-8"?> <com.google.android.gms.ads.formats.UnifiedNativeAdView xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:layout_gravity="bottom">     <LinearLayout         android:layout_width="match_parent"         android:layout_height="match_parent"         android:layout_gravity="center"         android:orientation="vertical">         <RelativeLayout             android:layout_width="match_parent"             android:layout_height="match_parent">             <LinearLayout                 android:layout_width="match_parent"                 android:layout_height="wrap_content"                 android:weightSum="2"                 android:orientation="vertical">                 <com.google.android.gms.ads.formats.MediaView                     android:id="@+id/ad_media"                     android:layout_width="match_parent"                     android:layout_height="0dp"                     android:padding="@dimen/_8sdp"                     android:layout_gravity="center"                     android:layout_weight="2"                     android:background="#fff" />                 <TextView                     android:id="@+id/ad_body"                     android:layout_width="match_parent"                     android:layout_height="wrap_content"                     android:fontFamily="@font/sf_pro_display_regular"                     android:gravity="center"                     android:text="body of ad"                     android:textSize="14sp" />             </LinearLayout>         </RelativeLayout>          </LinearLayout> </com.google.android.gms.ads.formats.UnifiedNativeAdView> 

In a fragment.xml, just a FrameView for the ad.

How do I use Google protocol buffers in a multiprocess script?

My use case is:

  • pulling data from the new Google Ads API
  • appending the objects with metadata
  • modelling using the objects
  • pushing the results to a database

AdWords Campaign Wrapper Object

I have an existing process for the old AdWords API, where I pull the data and store it in custom classes, e.g.

class Campaign(Represantable):     def __init__(self, id, managed_customer_id, base_campaign_id, name, status, serving_status):         self.id = id         self.managed_customer_id = managed_customer_id         self.base_campaign_id = base_campaign_id         self.name = name         self.status = status         self.serving_status = serving_status @classmethod     def from_zeep(cls, campaign, managed_customer_id):         return cls(             campaign.id,             managed_customer_id,             campaign.baseCampaignId,             campaign.name,             campaign.status,             campaign.servingStatus         ) 

Multiprocessing script

If I want to pull campaigns from a dozen accounts, I can run the scripts that populate the Campaign objects in parallel using pathos (again code simplified for this example):

import multiprocessing as mp from pathos.pools import ProcessPool class WithParallelism(object):     def __init__(self, parallelism_level):         self.parallelism_level = parallelism_level     def _parallel_apply(self, fn, collection, **kwargs):         pool = ProcessPool(             nodes=self.parallelism_level         )                  # this is to prevent Python from printing large traces when user interrupts execution (e.g. Ctrl+C)         def keyboard_interrupt_wrapper_fn(*args_wrapped):             try:                 return fn(*args_wrapped, **kwargs)             except KeyboardInterrupt:                 pass             except Exception as err:                 return err         errors = pool.map(keyboard_interrupt_wrapper_fn, collection)         return error 

Google Ads Campaign Wrapper Object

With the new API, I planned to store the protobuf object within my class, and use pointers to access the objects attributes. My class is a lot more complex than the example, using descriptors and subclass init for the attributes, but for simplicity it's effectively something like this:

class Campaign(Proto):     def __init__(self, **kwargs):         if "proto" in kwargs:             self._proto = kwargs['proto']         if "parent" in kwargs:             self._parent = kwargs['parent']         self._init_metadata(**kwargs) @property     def id(self):         return self._proto.id.value @property     def name(self):         return self._proto.name.value    ... 

This has the added advantage of being able to traverse the parent Google Ads object, to extract data from that protobuf object.

However, when I run my script of to populate these new objects in parallel, I get a pickle error. I understand that multiprocess uses pickle to serialize the objects, and one of the key advantages of protobuf objects is that they can be easily serialized.

How should I go about pulling the new Google Ads data in parallel:

  • Should I be serializing and deserializing the data in the Campaign object using SerializeToString
  • Should I just be extracting and storing the scalar data (id, name) like how I did with AdWords
  • Is there an entirely different approach?