Custom Jscript Event ALWAY returns “undefined” in GA4/GTM/Debug – any ideas

I have tried multiple different scripts ranging from simply “hello world” prints to more complex ones in GA4/GTM Custom Javascript Events.

I had a jscript developer look at it as is stumped so was wondering if theres any hints or tips or ideas?

Current example is to try and build a script that grabs the pageloadtime for example

function() {
if (window.performance && window.performance.getEntriesByType) {
    var entries = window.performance.getEntriesByType("navigation");
    if (entries.length > 0) {
        var navTiming = entries[0];
        var pageLoadTime = navTiming.loadEventEnd - navTiming.startTime;
    return Math.round(((pageLoadTime / 1000) + Number.EPSILON) * 100) / 100;
    }
}
}

however when I test in preview… the response is always the sane “undefined”.

As the devs also stumped is there something in ga4 config or something in GA that perhaps I need to do?

ps… the tag is linked to the trigger and i’ve even opened up the trigger to fire on all pages all the time…no joy.

really appreciate any advice…

ps.. ive also used about 5 different scripts so i’m sure its not the script but something either blocked or not switched on but console works fine with “window.performance.timing.loadEventEnd – window.performance.timing.navigationStart”

multiple different scripts ranging from “hello world” prints to the pageload one included above…

Ive looked at console and tested (it works)…..
looked at GTM preview (“undefined” response”)….
Network collect looks fine….
no obvious 404 or failures in network console notices
no obvious blocking of jscript but it feels like this is the issue as no script works.

jsrsasign KJUR.asn1.cms.SignedData not always working

i’m using jsrsasign for 2 year on a Heroku server to sign contents. It work fine.
i migrate my node.js server on AWS (using docker).

Now my sign service work sometime, and sometime not .

Here is my code :

var rs = require('jsrsasign');
 var param = {
    version: 1,
    hashalgs: ['sha256'],
    econtent: {
      type: 'data',
      content: {
      },
    },
    sinfos: [{
      version: 1,
      id: {type: 'isssn', cert: ''},
      hashalg: 'sha256',
      sattrs: {array: [
        {
          attr: 'contentType',
          type: 'data',
        },
      ]},
      sigalg: 'SHA256withRSA',
      signkey: '',
    }
    ],
    certs: [cert],
  };

  param.sinfos[0].id = {type: 'isssn', cert: cert};
  param.sinfos[0].signkey = pk;
  param.certs =  [cert];
  param.econtent.content = {hex: rs.utf8tohex(strDataToSign)};
  var mdHex = createDigest(rs.utf8tohex(strDataToSign));
  var sattrs0 = param.sinfos[0].sattrs.array;
  sattrs0.push({attr: 'signingTime'});
  sattrs0.push({attr: 'signingCertificateV2', array: [cert]});
  sattrs0.push({attr: 'messageDigest', hex: mdHex });

  var hCmsSignedData;
  var sd = new rs.KJUR.asn1.cms.SignedData(param);
  hCmsSignedData = sd.getContentInfoEncodedHex();
  var verifResult = rs.KJUR.asn1.cms.CMSUtil.verifySignedData({ cms: hCmsSignedData });

verifResult.isValid is true 3/5 times using the sames pk/cert generating systems.
in the signerInfos i found :

"verifyDetail":{"validMessageDigest":true,"validSignatureValue":false, ... "isValid":false}

Running the signing code on my computer ( mac m2) or with heroku work every time.
Version JsRsaSign is the same on all platform.

have you any idea of what can make the verify or signedData not working when running under AWS ?

Yann.

Does Intersector Observer works with Z-indexes?

I am trying to create a frontend logic here, and the requirement is as follows -:

  1. There are 4 UI elements on the screen.
  2. On certian device resolutions, some of these UI elements overflow outside of the screen or get hidden behind the main header component.
  3. I want to prompt the user to change the zoom level of the browser till all of the 4 UI elements are completely visible in their respective position or not.

Initially, I thought of using the Intersection Observer to check the Intersection Ratio of the 4 UI elements. But, I am confused if the intersections observer works when elements are hidden visually, but present on the screen DOM wise?

regex validation for multiple input formats from a single input

I have a situation where I should check for 2 different cases from one input. There is a validation function which validates for domain names and ipv4 and ipv6 address. Since I am accepting the subdomain names, the ipv4 address when fails to be a valid address is considered as a subdomain and the function is returning true which should not be doing that. so I need help to rewrite the code according to the input. If the input is of ipv4 or ipv6 format it should check the validation condition related to them otherwise it should check the conditions for the domain name.

validateDomain = (input) => {
const domainRegex =
/^(?=.{0,63}$)([A-Za-z0-9]+s*([-_]s*[A-Za-z0-9]+)(.s[A-Za-z0-9]{2,6})*)?$/;
const ipRegex =
/^b((?:(?:d|[1-9]d|1dd|2[0-4]d|25[0-5]).){3}(?:d|[1-9]d|1dd|2[0-4]d|25[0-5])|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4})b$/;
// /^b(?:d{1,3}.d{1,3}.d{1,3}.d{1,3}|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4})b$/;
if (ipRegex.test(input)) {
return true;
} else if (domainRegex.test(input)) return true;
return false;
};

I tried to check for the IP address and then check for the domain but as soon as it is failing for the ip regex validation it is considered as the subdomain and returning true;

example:
123.123.255.256 must be a invalid ip address because the last part is greater than 255
as soon as this condition is failed it is being considered as domain which can consist the numbers and can also be a sub domain and returning true which should not be happening and return false

What approaches should I use to build a framework agnostic component? [closed]

I need to build a complex form that should be included in a next app (with ssr), a nuxt app (with ssr) and an angular app.

What are the different approaches that I can use to avoid code duplication?

I have already some research and I have already in found some solutions

  • Web component : framework agnostic, but doesn’t seem to play nicely with SSR.
  • Microfrontend : framework agnostic, but I have no idea of the feasibility.

Python HTTP Server Javascript function return value can’t be displayed in .html

I have a server using Python that displays a HTML website at localhost:8080. The use of my javascript file is to connect to a SPS and to retrieve some data.

When I try the buttons on my website, the log shows the correct information in the browser console. However, I am unable to display the same value I display in the log on the HTML website itself.

server.py:

import http.server
import socketserver

# Set the port number you want to use
port = 8080

# Create a custom request handler to serve files
handler = http.server.SimpleHTTPRequestHandler

# Create a TCP server
with socketserver.TCPServer(("", port), handler) as httpd:
    print(f"Serving on port {port}")

    # Start the server
    httpd.serve_forever()

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Your API Website</title>
</head>
<body> 
    <h1>Your API Website</h1>

    <script src="app.js" defer></script>

    <!-- Buttons for API methods -->
    <button id="loginBtn">Login</button>
    <button id="getPermissionsBtn">Get Permissions</button>
    <button id="pingBtn">Ping</button>
    <button id="readBtn">Read</button>

    <!-- Button to display all API implementations -->
    <button id="displayAllBtn">Display All</button>

    <!-- Result display area -->
    <div id="resultDisplay"></div>

</body>
</html>

app.js:

document.addEventListener('DOMContentLoaded', function () {
  function API() {
      this.token = null;
      this.requests = [];
  }

  API.prototype.login = function () {
      const payload = {
          id: 0,
          jsonrpc: '2.0',
          method: 'Api.Login',
          params: {
              user: '5AHIT',
              password: '5ahiT',
          },
      };

      const headers = {
          'Content-Type': 'application/json',
          'Content-Length': JSON.stringify(payload).length,
          Host: '192.168.10.1',
      };

      return new Promise((resolve, reject) => {
          const xhr = new XMLHttpRequest();
          xhr.open('POST', 'https://192.168.10.61/api/jsonrpc', true);
          Object.entries(headers).forEach(([key, value]) => xhr.setRequestHeader(key, value));

          xhr.onload = function () {
              const response = JSON.parse(xhr.responseText);
              console.log(response);

              if (response.result && response.result.token) {
                  this.token = response.result.token;
                  this.requests.push(response);
                  console.log('Token:', this.token);
                  displayResponse(response);
                  resolve();
              } else {
                  reject(new Error('Login failed.'));
              }
          }.bind(this);

          xhr.onerror = function () {
              reject(new Error('Network error during login.'));
          };

          xhr.send(JSON.stringify(payload));
      });
  };

  API.prototype.getPermissions = function () {
      const payload = {
          id: 1,
          jsonrpc: '2.0',
          method: 'Api.GetPermissions',
      };

      const headers = {
          'Content-Type': 'application/json',
          'X-Auth-Token': this.token,
      };

      return new Promise((resolve, reject) => {
          const xhr = new XMLHttpRequest();
          xhr.open('POST', 'https://192.168.10.61/api/jsonrpc', true);
          Object.entries(headers).forEach(([key, value]) => xhr.setRequestHeader(key, value));

          xhr.onload = function () {
              const response = JSON.parse(xhr.responseText);
              console.log(response);

              if (response.result) {
                  for (const permission of response.result) {
                      console.log(permission);
                  }
                  this.requests.push(response);
                  resolve();
              } else {
                  reject(new Error('GetPermissions failed.'));
              }
          }.bind(this);

          xhr.onerror = function () {
              reject(new Error('Network error during GetPermissions.'));
          };

          xhr.send(JSON.stringify(payload));
      });
  };

  API.prototype.ping = function () {
      const payload = {
          id: 1,
          jsonrpc: '2.0',
          method: 'Api.Ping',
      };

      const headers = {
          'Content-Type': 'application/json',
          'X-Auth-Token': this.token,
      };

      return new Promise((resolve, reject) => {
          const xhr = new XMLHttpRequest();
          xhr.open('POST', 'https://192.168.10.61/api/jsonrpc', true);
          Object.entries(headers).forEach(([key, value]) => xhr.setRequestHeader(key, value));

          xhr.onload = function () {
              const response = JSON.parse(xhr.responseText);
              console.log(response);
              this.requests.push(response);
              resolve();
          }.bind(this);

          xhr.onerror = function () {
              reject(new Error('Network error during Ping.'));
          };

          xhr.send(JSON.stringify(payload));
      });
  };

  API.prototype.read = function () {
      const payload = {
          id: 1,
          jsonrpc: '2.0',
          method: 'PlcProgram.Read',
          params: {
              var: '"dVisu".sinus',
          },
      };

      const headers = {
          'Content-Type': 'application/json',
          'X-Auth-Token': this.token,
      };

      return new Promise((resolve, reject) => {
          const xhr = new XMLHttpRequest();
          xhr.open('POST', 'https://192.168.10.61/api/jsonrpc', true);
          Object.entries(headers).forEach(([key, value]) => xhr.setRequestHeader(key, value));

          xhr.onload = function () {
              const response = JSON.parse(xhr.responseText);
              console.log(response);
              this.requests.push(response);
              resolve();
          }.bind(this);

          xhr.onerror = function () {
              reject(new Error('Network error during Read.'));
          };

          xhr.send(JSON.stringify(payload));
      });
  };

  API.prototype.displayRequests = function () {
      console.log(this.requests);
  };

  function displayResponse(response) {
      const resultDisplay = document.getElementById('resultDisplay');
      resultDisplay.innerHTML = `<pre>${JSON.stringify(response, null, 2)}</pre>`;
  }

  const api = new API();

  function handleLogin() {
      api.login().then(api.displayRequests).catch(error => console.error(error.message));
  }

  function handleGetPermissions() {
      api.getPermissions().then(api.displayRequests).catch(error => console.error(error.message));
  }

  function handlePing() {
      api.ping().then(api.displayRequests).catch(error => console.error(error.message));
  }

  function handleRead() {
      api.read().then(api.displayRequests).catch(error => console.error(error.message));
  }

  function handleDisplayAll() {
      console.log('All API Implementations:');
      console.log('------------------------');
      console.log('1. Login');
      console.log('2. Get Permissions');
      console.log('3. Ping');
      console.log('4. Read');
  }

  document.getElementById('loginBtn').addEventListener('click', handleLogin);
  document.getElementById('getPermissionsBtn').addEventListener('click', handleGetPermissions);
  document.getElementById('pingBtn').addEventListener('click', handlePing);
  document.getElementById('readBtn').addEventListener('click', handleRead);
  document.getElementById('displayAllBtn').addEventListener('click', handleDisplayAll);

  window.onload = function () {
      api.login().then(api.displayRequests).catch(error => console.error(error.message));
  };
});

Anyone knows why I get this behaviour?

Using other payment processors along with Stripe

We’re using Stripe as our main payment processor / initiator with a few different payment methods enabled. We use stripe Elements to render the UI and it’s hosted on our website (not Stripe’s). We are now interested in adding more payment options that are not supported by Stripe.

My question is:

  1. If I want to keep the look and feel of the payment UI the same, what
    are my options? For e.g. I would like to add the new payment method
    button alongside Stripe provided ones – is this straightforward? Like
    this:

    Apple pay | Google Pay | Card | New Option

    The PaymentElement from Stripe.js React library renders the enabled
    payment methods that are applicable for the user geography, device
    and other constraints. I’ll have to keep that behaviour intact.

  2. Stripe mentions some external payment methods that they are not integrated with but their frontend library supports for a seamless UI. However their React wrapper doesn’t seem to support options related to external payment methods. https://stripe.com/docs/payments/external-payment-methods Any idea how to go about this?

Thanks for any help.

i need a text field where a user can enter only numbers & only words like px, rem & em (for CSS styles).(EX: 10px, 10em, 10rem case insensitive)

I need a text(input) field in a form where a user can enter only numbers (3 digits max length) & specific words like px, em & rem.
It should not accecpt when user enter only characters like p, r, e, m, x.
It should accepts px/em/rem as a whole word or else it not.

I’ve tried with one regex but its accepting px along with p, x, 10dfdpx (string which has px)

here is my regex: /([0-9px]|[0-9rem]|[0-9em])$/;

Requesting someone to plz help in achieving this. Googled a lot but couldn’t find anything related.

How to get all users in one organization unit using Google Directory API using vue3

In the Google Directory API, I cannot find a method to get all users in a specific organization unit of Google Apps. Is it possible? And how? Based on the Google Directory API document, programmers can get all the organization units, or all the users for the whole domain, but there is no description on how to get users of one organization unit. This feature is crucial important to construct the organizations/users hierarchical tree. Please help, thanks.

I have tried to look into the documentation but wasn`t able to solve the problem.

Problem with using google earth engine api with react

I am creating a react app with google earth engine api and leaflet with a django backend. The backend will be used for computer vision purposes, Google earth engine is to be used to add layers to the map with the dataset available through it but i’m not able to authenticate the api on the client side as i can send the earth engine through the server cause it requires initializing the google earth engine neverthless . How to tackle this problem?

I tried authenticating through client id:

var ee = require('@google/earthengine');
ee.data.authenticateViaOauth("client-id");
ee.initialize();

i get this error :
Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential.

And when i try to use the service account auth:

var ee = require('@google/earthengine');
ee.data.authenticateViaPrivateKey('.key.json');
ee.initialize();

i get this error :
Use of private key authentication in the browser is insecure. Consider using OAuth, instead.
at webpack_modules…/../../../node_modules/@google/earthengine/build/browser.js.ee.data.authenticateViaPrivateKe
s

Request error message is not available in production when using Nuxt 3

I’m trying to access the error message returned by the Nuxt 3 API endpoint in the client. I’m able to access the error message in local development, but once I run in production the message is not accessible, only the status code is available. Why is it not possible to access the error message?

Furthermore, I can see that the message is included in the response, but it is not available in error object.

// /server/api/example-api.ts
export default defineEventHandler(async (event) => {
    throw createError({
        statusCode: 400,
        message: "Test message",
        statusMessage: "Test message",
    });
};

Response:

{
  "url":"/api/example-api",
  "statusCode":400,
  "statusMessage":"Test message",
  "message":"Test message",
  "stack":""
}
// Client request
async (body: any) => {
    try {
        const response = await $fetch("/example-api", {
            method: "POST",
            body: body,
        });
    } catch (err) {
        console.log(err.message, err.statusMessage, err.statusCode);
    }
};

Print from console.log:

[POST] "/api/example-api": 400  <empty string> 400

If relevant, the site is deploy in Netlify.

A chrome extension error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘action’)

This is a chrome Extension project that aims to produce summary and major points of a selected text on the web. I’m new to chrome extension development and trying to run this code. Any suggestion and help will be greatly valued.

**Manifest.json file **

//manifest.json
{
  "manifest_version": 3,
  "name": "Text Summarizer and Major Points generator",
  "version": "1.0",
  "description": "A Chrome extension that uses OpenAI API to summarize or produce major poinnts on the selected text.",
  "permissions": [
    "contextMenus",
    "storage",
    "activeTab",
    "scripting",
    "tabs"
  ],
  "action": {
    "default_popup": "popup.html"
  },
  "icons": {
    "16": "images/icon16.png",
    "48": "images/icon48.png",
    "128": "images/icon128.png"
  },
  "host_permissions": [
    "https://*.openai.com/"
  ],
  "background": {
    "service_worker": "background.js"
  },
 
  "options_page": "options.html"
 
}```
**background.js file**
``chrome.runtime.onInstalled.addListener(function () {
  chrome.contextMenus.create({
    id: 'summarize',
    title: 'Summarize it',
    contexts: ['selection'],
  });

  chrome.contextMenus.create({
    id: 'majorpoints',
    title: 'Major Point it',
    contexts: ['selection'],
  });
});

chrome.contextMenus.onClicked.addListener(async function (info, tab) {
  if (info.menuItemId === 'summarize' || info.menuItemId === 'majorpoints') {
    // Inject the content script
    chrome.scripting.executeScript( { 
      target:{tabId: tab.id},
      function: fetchDataAndInteract,
      args: [info], 
    });
    }
  });
  

      async function fetchDataAndInteract (info) {

      chrome.storage.sync.get('openaiApiKey', async function (apiKeyData) {
        const apiKey = apiKeyData.openaiApiKey;

        if (!apiKey) {
          alert('Please set your OpenAI API key in the extension settings.');
          return;
        }
   
        const action = info.menuItemId;
        const selectedText = info.selectionText;
        const prompt = action === 'summarize' ? `Summarize: ${selectedText}` : `Write the major point of this post: ${selectedText}`;

        const response = await fetch('https://api.openai.com/v1/completions', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${apiKey}`,
          },
          body: JSON.stringify({
            prompt: prompt,
            max_tokens: 100,
            n: 1,
            stop: null,
            temperature: 0.3,
          }),
        });

        const resultData = await response.json();

        if (resultData.choices && resultData.choices.length > 0) {
          const resultText = resultData.choices[0].text.trim();
          const resultTitle = action === 'summarize' ? 'Summary:' : 'Major Points:';

          chrome.scripting.executeScript({
            target: { tabId: tab.id },
            function: showResult,
            args: [resultTitle, resultText],
          });

        } else {
          console.error('No choices returned from API call.');
        }
      });
    }

    async function showResult(resultTitle, resultText) {
      const popup = document.createElement('div');
      popup.style.position = 'fixed';
      popup.style.top = '20%';
      popup.style.left = '50%';
      popup.style.transform = 'translate(-50%, -50%)';
      popup.style.zIndex = '9999';
      popup.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
      popup.style.padding = '20px';
      popup.style.borderRadius = '10px';
      popup.style.maxWidth = '80%';
      popup.style.textAlign = 'center';
      popup.style.fontFamily = 'Arial, sans-serif';
    
      const title = document.createElement('h3');
      title.innerText = resultTitle;
      title.style.marginBottom = '10px';
      popup.appendChild(title);
    
      const result = document.createElement('p');
      result.innerText = resultText;
      popup.appendChild(result);
    
      document.body.appendChild(popup);
    
      setTimeout(function () {
        document.body.removeChild(popup);
      }, 10000);
    }

Content.js

//content.js
chrome.runtime.onMessage.addListener( function (request, sender, sendResponse) {
  if (request.action === 'showResult') {
    console.log('Message received in content.js:', request);
    const { resultTitle, resultText } = request;
    const popup = document.createElement('div');
  popup.style.position = 'fixed';
  popup.style.top = '20%';
  popup.style.left = '50%';
  popup.style.transform = 'translate(-50%, -50%)';
  popup.style.zIndex = '9999';
  popup.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
  popup.style.padding = '20px';
  popup.style.borderRadius = '10px';
  popup.style.maxWidth = '80%';
  popup.style.textAlign = 'center';
  popup.style.fontFamily = 'Arial, sans-serif';

  const title = document.createElement('h3');
  title.innerText = resultTitle;
  title.style.marginBottom = '10px';
  popup.appendChild(title);

  const result = document.createElement('p');
  result.innerText = resultText;
  popup.appendChild(result);

  document.body.appendChild(popup);

  setTimeout(function () {
    document.body.removeChild(popup);
  }, 10000);

    sendResponse({ success: true });
  } 
  // sendResponse({ success: true });
});

popup.js

// popup.js
document.addEventListener('DOMContentLoaded', async function () {
  chrome.runtime.sendMessage({ action: 'processText' }, async function (globalData) {
    const title = document.getElementById('title');
    const result = document.getElementById('result');

    if (globalData && globalData.action === 'summarize' || globalData.action === 'majorpoints') {
      const apiKey = globalData.apiKey;
      const selectedText = globalData.selectedText;
      const prompt = globalData.action === 'summarize' ? `Summarize: ${selectedText}` : `Major Points of: ${selectedText}`;

      title.textContent = globalData.action === 'summarize' ? 'Summary:' : 'Major Points:';
      result.textContent = 'Loading...';

      try {
        const response = await fetch('https://api.openai.com/v1/completions', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${apiKey}`,
          },
          body: JSON.stringify({
            prompt: prompt,
            max_tokens: 50,
            n: 1,
            stop: null,
            temperature: 0.7,
          }),
        });

        const data = await response.json();
        const resultText = data.choices[0].text.trim();
        result.textContent = resultText;
      } catch (error) {
        console.error('Error fetching the summary/Major Point:', error);
        result.textContent = 'An error occurred. Please try again later.';
      }
    }
  });
});

Popup.html

<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        width: 300px;
        height: 200px;
        font-family: Arial, sans-serif;
      }
    </style>
  </head>
  <body>
    <h3 id="title"></h3>
    <div id="result"></div>
    <script src="popup.js"></script>
  </body>
</html>

I am new to chrome extension development and trying to run this code. Any suggestion and help will be greatly valued.

The problem is with handling promises. However i’m clueless as of how to correctly handle async/await.