Send conversion event to Google Ads from NodeJs backend (AWS) - google-tag-manager

I have a website hosted in AWS with a NodeJS backend.
I have Google Ads conversion events being sent from the frontend using gtag.js, but I noticed missing events and a lot of duplication (even if I use transaction IDs with my events)
I has similar issues with Facebook Pixel and was able to resolve the problem by sending simple vanilla http calls from the backend.
Is it possible to do the same with Google Ads? I have not been able to find any documentation for server side APIs for Javascript.
This documentation here seems promising, but no Javascript SDK exists. That's is why I would like to know what vanilla http calls to make.
I have seen documentation about GTM server side, but it seems I need to host a GTM container (server?) which I would prefer not to have to. Unless I misunderstood what hosting a GTM container means in the context of a AWS cloud solution.

In addition to the native, gRPC-based Ads API there's also a REST alternative which can be used if there's no native client library, such as for NodeJS.
The endpoint relevant for your use case is customers.uploadClickConversions, which allows you to register a conversion given a specific click ID.
Keep in mind that you'll need to apply for API access in order to be able to use the Ads API (aside from accessing test accounts).

Related

Load Tweets live to be displayed on front-end

I'm setting up a server using firebase and want to load Tweets dynamically/live from Twitter by filtering them by hashtags.
Basically what I want to do is integrate a live feed of sorts from twitter to load tweets about Bitcoin and other Cryptocurrencies on my webpage. I'm using Vue CLI for the front end.
I've done extensive research on twitter, signed up for a developer account and had many go's and tries, but without any luck. I am really stuck as there does not seem to be any way to fetch tweets and then display the, live on my front end.
Ì actually do not have any code to show, as I do not even understand how it would be possible.
I've set-up the backend successfully on firebase and do not have any issues with CRUD operations and Authentications etc. What I need is to dynamically load(live) tweets from twitter and then filter them using a hashtag.
I haven't been successful at even understanding if this is possible, so I haven't received any error messages. It seems to me that you can only let users sign in and then they can post tweets through an integrated API.
You have to open a twitter stream in your backend and send the results to the frontend using sockets, if you want it to be updated in real time.
You can check this out to get you started:
Running a Node.JS background process for Twitter streaming API in Firebase
Adding to what Haris has said, another alternative would be to use SSE (Server-Sent Events) since you are only concerned of unilateral communication rather than bilateral communication. A tutorial for this action, however, will depend on the backend framework you are using.
Feel free to consult the following link that suites your framework on how to use SSEs:
Server-Sent Events with Node
Real-Time Web Apps with Server-Sent Events (Express JS)
Server-Sent Events with Fastify (fastify-sse)
Server-Sent Events with Hapi (SuSiE)

How to restrict my endpoint api discovery

I have an endpoint api at project-id.appspot.com. It is possible for anyone to see all methods (but not to run them) via google api explorer. How to disbable it? I don't want to tell publically what my api is.
The discovery document is used by the JS API client library, and as such was not designed to be disabled. There's currently no support for that.

How to (can you) configure Azure API Management for Auth0 single page application

Scenario: Auth0 Single Page application client. .NET Web API and Angular SPA both configured to use this client. Works great.
I'd like to add Azure API Management as a layer in front of the API. Have set up the API in the Management Portal, updated SPA to call API, tested calls from SPA, works great.
Now, I'd like to configure API Management Portal with the right security settings such that people can invoke API calls from the Developer Portal. I've used this [https://auth0.com/docs/integrations/azure-api-management/configure-azure] as a guide.
Where I'm at:
From the Developer portal, I can choose Authorization Code as an Auth type, go through a successful sign-in process with Auth0 and get back a Bearer token. However, calls made to the API always return 401. I think this is because I'm confused about how to set it up right. As I understand it:
either I follow the instructions and setup a new API client in Auth0, but if that's the case then surely it's not going to work, because tokens generated from one client aren't going to work against my SPA client? (or is there something I need to change to make it work)
or, how should I configure Azure API Management to work with a SPA application. (this would be my preferred method, having two clients in Auth0 seems 'messy'). But, don't I need an 'audience' value in my authorization endpoint URL? How do I get that?
If anyone has done this, would very much appreciate some guidance here.
Well, I didn't think I'd be back to answer my own question quite so soon. The reason is mostly rooted in my general ignorance of this stuff, combined with trying to take examples and fuse them together for my needs. Posting this to help out anyone else who finds themselves here.
Rather than take the Single Application Client in Auth0 and make it work with Azure API Management, I decided to go the other way, and make the non-interactive Client work with my SPA. This eventually 'felt' more right: the API is what I'm securing, and I should get the API Management portal working, then change my SPA to work with it.
Once I remembered/realised that I needed to update my audience in the API to match the audience set in the Client in Auth0, then the Management Portal started working. Getting the SPA to work with the API then became a challenge: I was trying to find out how to change the auth0 angular code to pass an audience to match the one the API was sending, but it kept sending the ClientID instead. (by the way, finding all that out was made easier by using https://jwt.io/ to decrypt the Bearer tokens and work out what was happening - look at the 'aud' value for the audience.
In the end, I changed my API, in the new JwtBearerAuthenticationOptions object, the TokenValidationParameters object (of type TokenValidationParameters) has a property ValidAudiences (yes, there is also a ValidAudience property, confusing) which can take multiple audiences. So, I added my ClientID to that.
The only other thing I then changed (which might be specific to me, not sure) is that I had to change the JsonWebToken Signature Algorithm value in Auth0 for my non-interactive client (advanced settings, oAuth tab) from HS256 to RS256.
With all that done, now requests from both the API Management Portal, and my SPA work.
Curious to know if this is the "right" way of doing it, or if I've done anything considered dangerous here.
Since you're able to make the validation of the jwts with the .Net API work, Only few changes are actually necessary to get this working with Azure API Management.
In API management,
Create a validate-jwt inbound policy on an Operation (or all operations)
set the audiences and issuers the same as what you've used with your .NET web api. (you can check the values in Auth0 portal if you don't know this yet)
The important field that is missing at this point is the Open ID URLs since auth0 uses RS256 by default. The url can be found in you Auth0 portal at: Applications -> your single page application -> settings -> Scroll down, Show Advanced Settings -> End points. Then copy the OpenID Configuration
Here's the reference for API management's requirement for JWT tokens
optional reading

Make api explorer private

Is it possible to either turn off the api explorer completely or limit the access to it?
I noticed some logs in my app that come from failed requests executed from a browser. My api is only consumed by an Android app so the only place where they can come from is the api explorer. Also the api access is limited to 1 web and 1 android client id.
Unfortunately no. The API explorer works by using the Discovery Service associated with your API, which is not actually part of your backend, so you can't specify auth or visibility for those URIs.
The list method from the Discovery service is used to generate the list on the APIs Explorer app using your app as base:
discovery.apis.list:
your-app-id.appspot.com/_ah/api/discovery/v1/apis
When someone clicks one of the APIs from the list, the full discovery document is retrieved for that apiName and apiVersion using the getRest method from the Discovery service:
discovery.apis.getRest:
your-app-id.appspot.com/_ah/api/discovery/v1/apis/{apiName}/{apiVersion}/rest
If you are looking for ways to prevent the executing of the API, check out Cloud Endpoints: Control who can execute API through API Explorer
endpoints makes auth easy and you can get the current user. You should use auth to ensure people don't mess with your private apis - otherwise people could trace what kind of post or get requests you're sending anyway - auth is always a good idea rather than trying to keep your apis secret.
If you're building a secret product and you don't want your competitor to find out, you could perhaps use some obfuscation method on the backend and on your client which makes the apis unreadable.
Also a user messing with your apis shouldn't break your database - or if it does - it should only break it for the user that was being foolish. Having logic in your client for how apis are used so that the backend doesn't break is a bad idea - the backend apis should take care of themselves and not worry about how or why they are used and who by for what purpose.

Google Translate API proxy

Im investigating the translate API and the example script contains a warning advising me to use a proxy to hide my api key.
// WARNING: be aware that YOUR-API-KEY inside html is viewable by all your users.
// Restrict your key to designated domains or use a proxy to hide your key
// to avoid misuse by other parties.
I am just wondering how do I run the script via a proxy?
UPDATE: Thanks for this.. I have since removed the project as it was made redundant. But great advice
I believe in this instance the reference to proxy means a server side encapsulation (or something similar) to hide the API key. You'd therefore make a call to your server, which would proxy the call to Google instead of making the call in client-side Javascript and exposing your API key.

Resources