Posts tagged with python

I am trying to setup a webhook in AWS Lambda (using API Gateway) for Meta's WhatsApp Business API. They have the following guidelines:

Whenever your endpoint receives a verification request, it must:

Verify that the hub.verify_token value matches the string you set in the Verify Token field when you configure Webhooks in your App Dashboard (you haven't set up this token string yet). Respond with the hub.challenge value."

I have setup all the query strings it needs in the API gateway. Here is what my lambda handler looks like:

def lambda_handler(event, context):     response = {         "status": 400,         "body" : "failed"     }          print(str(event))          print("Received context" + str(context))          if(len(event) != 0 and (event['hub.verify_token'] == "some value")):         response['status'] = 200         response['body'] = event['hub.challenge']         return event['hub.challenge']               #print(response)         #returnResponse = re.findall('[0-9]+', event['hub.challenge'])         #return returnResponse[0]              else:         return(response) 

the event looks like:

{     "hub.mode" : "some value",     "hub.verify_token": "some value",     "hub.challenge": "1158201444" } 

The response in AWS console looks like "1158201444" but on meta's end, the response looks like "\"1158201444\"" and the webhook confirmation fails in Meta's dashboard.

How can remove the extra characters and decode the string? I have already tried regex and still getting the extra characters (\"\").

I'm trying to use selenium to download reports from Google Ads, the script is working fine until I try to click the Campaign-wide target button in the image, It's not showing in the DOM and selenium can't see it until I click/inspect it that it's accessible.

I tried to switch frames and search for it but to no avail, I have only two frames when I try

iframes = b.driver.find_elements(By.XPATH, "//iframe")

Code:

from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService from webdriver_manager.chrome import ChromeDriverManager from time import sleep from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC import csv class Bot:     def __init__(self, user_data_dir=None, profile_dir=None, csv_filename=None):         self.__service = ChromeService(ChromeDriverManager().install())         self.user_data_dir = user_data_dir          self.profile_dir = profile_dir         self.__options = webdriver.ChromeOptions()         self.__options.add_argument(f"user-data-dir={self.user_data_dir}")         self.__options.add_argument(f"--profile-directory={self.profile_dir}")         self.csv_filename = csv_filename or "data.csv"         self.driver = webdriver.Chrome(service=self.__service, options=self.__options)       def login(self):         self.driver.get("https://ads.google.com")         sleep(1)         try:             # get the sign in button and click it             sign_in_btn = self.driver.find_element(By.XPATH, '//*[@id="header-topbar"]/div/div[3]/div/div[3]/a')             sign_in_btn.click()             sleep(2)                      except Exception as e:             print(e)             # if the sign in button is not found, try clicking the drawer menu button and then the sign in button             drawer_btn = self.driver.find_element(By.XPATH, '//*[@id="header-drawer"]/div/div/div/div[1]/div/button')             drawer_btn.click()             sleep(2)                          sign_in_btn = self.driver.find_element(By.XPATH, '//*[@id="header-topbar"]/div/div[3]/div/div[3]/a')             sign_in_btn.click()             sleep(2)         finally:             accnt_btn = self.driver.find_element(By.XPATH, '/html/body/div[1]/root/div[2]/nav-view-loader/multiaccount-view/div/div[2]/div/div[1]/material-list/material-list-item[4]/div/div[1]')             accnt_btn.click()             sleep(5)          def do(self):         self.login()         # get the campaigns button dropdown button and click it         campaigns_drpdwn_btn = self.driver.find_element(By.XPATH, '/html/body/div[2]/root/div/div[1]/div/div/div[3]/div/div/awsm-skinny-nav/nav/div[1]/div[3]/awsm-skinny-nav-item[1]/a/material-ripple')         campaigns_drpdwn_btn.click()         sleep(2)         # TODO get all the campaigs lists and click on each one of them         # get a certain campaign and click it         campaign_btn = self.driver.find_element(By.XPATH, '//*[@id="cmExtensionPoint-id"]/base-root/div/div[2]/div[1]/view-loader/campaign-view/tableview/div[6]/ess-table/ess-particle-table/div[1]/div/div[2]/div[3]/ess-cell[2]/campaign-name/campaign-name-generic/a')         campaign_btn.click()         sleep(2)         # campaign more details button         campaign_more_details_btn = self.driver.find_element(By.XPATH, '/html/body/div[2]/root/div/div[1]/div/div/div[3]/div/content-header/deferred-infosnack/infosnack/div/div[1]/review-panel-trigger/button/div[2]')         campaign_more_details_btn.click()         sleep(5)         # get the bid strategy button, using the 'Maximize conversions' text as a span and click it         campaign_bid_strategy_btn = self.driver.find_element(By.XPATH, "//span[contains(text(), 'Maximize conversions')]")         campaign_bid_strategy_btn.click()         sleep(4)         # get the campaign simulator button and click it         campaign_sim_btn = self.driver.find_element(By.XPATH, "//span[contains(text(), 'Campaign simulator')]")         campaign_sim_btn.click()         sleep(2)         # get the campaign simulator target dropdown and click it [%, campaign wide target]         campaign_sim_target_dropdn = self.driver.find_element(By.XPATH, "//span[contains(text(), 'Target scaling')]")         campaign_sim_target_dropdn.click()         sleep(2)         campaign_wide_target_btn = self.driver.find_element(By.XPATH, "//span[contains(text(), 'Campaign-wide target')]")         campaign_wide_target_btn.click()         sleep(2) 

I'm trying to get selenium to see the button, any help would be appreciated.

I have everything set up on my google adwords account and I'm able to retrieve data via the API. However, I just can't seem to find how I'm supposed to add IP addresses to the blacklist

I know that I should be using IPBlock, I just don't know how

I found an old code that goes like this:

from google.ads.googleads.client import GoogleAdsClient client = (GoogleAdsClient.load_from_storage(path="google-ads.yaml")) campaign_criterion_operation = client.get_type('CampaignCriterionOperation', version='v2') campaign_criterion = campaign_criterion_operation.create campaign_criterion.negative.value = True campaign_criterion.campaign.value = campaign_service.campaign_path(customer, campaign) campaign_criterion.ip_block.ip_address.value = "80.67.167.81" campaign_criterion_response = campaign_criterion_service.mutate_campaign_criteria(customer, [campaign_criterion_operation]) for reponse in campaign_criterion_response.results:     print('Added campaign criterion "%s".' % reponse.resource_name) 

However, it has multiple issues if you try to run it.

Any help would be greatly appreciated!

I am building something to sort and add values from an API response. I ended up going with an interesting structure, and I just want to make sure there's nothing inherently wrong with it.

from collections import defaultdict # Helps create a unique nested default dict object # for code readability def dict_counter():     return defaultdict(lambda: 0) # Creates the nested defaultdict object ad_data = defaultdict(dict_counter) # Sorts each instance into its channel, and # adds the dict values incrimentally for ad in example:        # Collects channel and metrics     channel = ad['ad_group']['type_']     metrics = dict(         impressions= int(ad['metrics']['impressions']),         clicks     = int(ad['metrics']['clicks']),         cost       = int(ad['metrics']['cost_micros'])     )          # Adds the variables     ad_data[channel]['impressions'] += metrics['impressions']     ad_data[channel]['clicks'] += metrics['clicks']     ad_data[channel]['cost'] += metrics['cost'] 

The output is as desired. Again, I just want to make sure I'm not reinventing the wheel or doing something really inefficient here.

defaultdict(<function __main__.dict_counter()>,             {'DISPLAY_STANDARD': defaultdict(<function __main__.dict_counter.<locals>.<lambda>()>,                          {'impressions': 14, 'clicks': 4, 'cost': 9}),              'SEARCH_STANDARD': defaultdict(<function __main__.dict_counter.<locals>.<lambda>()>,                          {'impressions': 6, 'clicks': 2, 'cost': 4})}) 

Here's what my input data would look like:

example = [     {         'campaign':          {             'resource_name': 'customers/12345/campaigns/12345',             'status': 'ENABLED',             'name': 'test_campaign_2'         },         'ad_group': {             'resource_name': 'customers/12345/adGroups/12345',             'type_': 'DISPLAY_STANDARD'},         'metrics': {             'clicks': '1', 'cost_micros': '3', 'impressions': '5'         },         'ad_group_ad': {             'resource_name': 'customers/12345/adGroupAds/12345~12345',             'ad': {                 'resource_name': 'customers/12345/ads/12345'             }         }     },     {         'campaign':          {             'resource_name': 'customers/12345/campaigns/12345',             'status': 'ENABLED',             'name': 'test_campaign_2'         },         'ad_group': {             'resource_name': 'customers/12345/adGroups/12345',             'type_': 'SEARCH_STANDARD'},         'metrics': {             'clicks': '2', 'cost_micros': '4', 'impressions': '6'         },         'ad_group_ad': {             'resource_name': 'customers/12345/adGroupAds/12345~12345',             'ad': {                 'resource_name': 'customers/12345/ads/12345'             }         }     },     {         'campaign':          {             'resource_name': 'customers/12345/campaigns/12345',             'status': 'ENABLED',             'name': 'test_campaign_2'         },         'ad_group': {             'resource_name': 'customers/12345/adGroups/12345',             'type_': 'DISPLAY_STANDARD'},         'metrics': {             'clicks': '3', 'cost_micros': '6', 'impressions': '9'         },         'ad_group_ad': {             'resource_name': 'customers/12345/adGroupAds/12345~12345',             'ad': {                 'resource_name': 'customers/12345/ads/12345'             }         }     } ] 

Thanks!