Posts tagged with azure-functions

I have been using a Twilio phone number connected to a WhatsApp Business Account.

As far as I understand, for each conversation started, WhatsApp gives me a 24-hour window where I can send and receive any number of messages without additional charges (WhatsApp Conversation - Free Tier). However, it seems that I am somehow incurring in additional charges for each message sent and received (Messaging Channels Inbound Message and Messaging Channels Outbound Message where each costs $0.005).

I configured the WhatsApp sender to work with a webhook redirecting to an Azure Function App running Python Flask. Despite I can answer an incoming message via a Python Flask, I chose answering via the Twilio REST API (from twilio.rest import Client), since the webhook method gives me only 15 seconds to send an answer or it cuts the connection throwing error 11200, and some of my processes take longer than that.

Are this extra costs because I am using the Twilio REST API or is this a normal behavior of Twilio WhatsApp?

I am writing an Azure Function in C# using .NET core.

I have tried to authenticate as an APPLICATION per this page.

I've tried authenticating with a service account per this page.

In both cases I'm getting an access denied error message.

The root question I have is,

Which authentication method should I use for the Google Ads API from within an Azure Function?

Update:

In my latest attempt to use a service account I have this code

GoogleAdsConfig config = new GoogleAdsConfig()             {            OAuth2Mode = Google.Ads.GoogleAds.Config.OAuth2Flow.SERVICE_ACCOUNT,            OAuth2SecretsJsonPath = pathtojsonfile,            OAuth2PrnEmail = "something@somethingelse.iam.gserviceaccount.com",            OAuth2Scope = "https://www.googleapis.com/auth/adwords",            DeveloperToken = "********"         };                  var responseMessage = "";         var client = new GoogleAdsClient(config);                  // Get the GoogleAdsService.         GoogleAdsServiceClient googleAdsService = client.GetService(Services.V6.GoogleAdsService);         // Create the query.         string query =             @"SELECT              campaign.id,              campaign.name,              ad_group.id,              ad_group.name,              ad_group_criterion.criterion_id,              ad_group_criterion.keyword.text,              ad_group_criterion.keyword.match_type,              metrics.impressions,              metrics.clicks,              metrics.cost_micros          FROM keyword_view          WHERE segments.date DURING LAST_7_DAYS              AND campaign.advertising_channel_type = 'SEARCH'              AND ad_group.status = 'ENABLED'              AND ad_group_criterion.status IN ('ENABLED','PAUSED')          ORDER BY metrics.impressions DESC          LIMIT 50";         try         {             // Issue a search request.             await googleAdsService.SearchStreamAsync(customerId.ToString(), query,                 delegate (SearchGoogleAdsStreamResponse resp)                 {                     // Display the results.                     foreach (GoogleAdsRow criterionRow in resp.Results)                     {                         responseMessage +=                             "Keyword with text " +                             $"'{criterionRow.AdGroupCriterion.Keyword.Text}', match type " +                             $"'{criterionRow.AdGroupCriterion.Keyword.MatchType}' and ID " +                             $"{criterionRow.AdGroupCriterion.CriterionId} in ad group " +                             $"'{criterionRow.AdGroup.Name}' with ID " +                             $"{criterionRow.AdGroup.Id} in campaign " +                             $"'{criterionRow.Campaign.Name}' with ID " +                             $"{criterionRow.Campaign.Id} had " +                             $"{criterionRow.Metrics.Impressions.ToString()} impressions, " +                             $"{criterionRow.Metrics.Clicks} clicks, and " +                             $"{criterionRow.Metrics.CostMicros} cost (in micros) during the " +                             "last 7 days.";                     }                 }             );         }         catch (GoogleAdsException e)         {             responseMessage += "Failure:\n";             responseMessage += $"Message: {e.Message}\n";             responseMessage += $"Failure: {e.Failure}\n";             responseMessage += $"Request ID: {e.RequestId}\n";             throw;         }         return responseMessage; 

When I call this I get the following error:

{     "StatusCode": 16,     "Details": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",     "RequestId": "0Yk2OYrUATjwftZ5I0qi2g",     "Failure": {       "errors": [         {           "errorCode": {             "authenticationError": "NOT_ADS_USER"           },           "message": "User in the cookie is not a valid Ads user."         }       ]     }   }   

I have the service account set up with the Google Ads API Enabled. Why does it think I'm "NOT AN ADS USER" ???