How to send a email with a PDF file attachment based on a condition using Google App Script

I solved the following problem.
Send PDF files to everyone using the Google Script service of Google Sheets.
I tried sending one file to everyone on the list. It went well.
However, I’ve run into a problem trying to make a similar Script, but for sending multiple files to different people on a Google Sheet list.Each person has different files.

For example:
John has three PDF files: John_ 999901.pdf, John_ 999902.pdf, and John_999903.pdf.
David has two PDF files: David_ 999901.pdf and David_99990.
Jun has two PDF files: Jun_999901.pdf and Jun_999902.pdf.
And finally, Michel has only one PDF file: Michel_999901.pdf.
All PDF files are saved on GOOGLE DRIVE.
This is where I save the PDF file
This is my spreadsheet
Is there a way to send an email based on the file name that corresponds to the person of the same name in the list?
Below is the code that I tried to send the file

function onOpen() 
{
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('メール送信')
     
      .addItem('送信', 'sendFormToAll')
      .addToUi();
}
function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function sendFormToAll()
{
   var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
  
   var last_row = sheet.getDataRange().getLastRow();
  
   for(var row=2; row <= last_row; row++)
   {
     sendEmailWithAttachment(row);
     sheet.getRange(row,8).setValue("send");
   }
}

function sendPDFForm()
{
  var row = SpreadsheetApp.getActiveSheet().getActiveCell().getRow();
  sendEmailWithAttachment(row);
}

function sendEmailWithAttachment(row)
{
  var filename= '?????.pdf';// I don't know what to do at this point
  
  var file = DriveApp.getFilesByName(filename);
  
  if (!file.hasNext()) 
  {
    console.error("Could not open file "+filename);
    return;
  }
  
  var client = getClientInfo(row);
  
  var template = HtmlService
      .createTemplateFromFile('index');
  template.client = client;
  var message = template.evaluate().getContent();
  
  
  MailApp.sendEmail({
    to: client.email,
    subject: "Send File",
    htmlBody: message ,
    attachments: [file.next().getAs(MimeType.PDF)]
  });

}

function getClientInfo(row)
{
   var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
   
   var values = sheet.getRange(row,1,row,8).getValues();
   var rec = values[0];
  
  var client = 
      {
        name:rec[0],
        email: rec[1]
      };
  client.name = client.name;
  return client;
}
<!DOCTYPE html>
<html>
   <head>
      <base target="_top">
      <!-- CSS only -->
      <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
      <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
      
   </head>

  
   <body>
     <div  >
     
     
      <p>Hi, <?= client.name ?>Sir </p>
      <p>I send you file . Please check it</p>
   
     
      <p>*********************************************************</p>
     
     </div>
   </body>
</html>

How Would I replace a string if its input in a certain order?

I tried a few different ways with no luck. As you can tell the stuff I added broke it if (out.input == “236”) & “236” : “Quarter Circle”,

    var xboxConverter = {
      "1" : "Up",
      "2" : "Down",
      "3" : "Down Foward",
      "4" : "Backward",
      "5" : "Standing",
      "6" : "Forward",
      "7" : "Up Backward",
      "8" : "Up",
      "9" : "Up Foward",
      "236S": "Quarter Circle A",
      ",": "  ",
      "H" : "B",
      "M": "Y",
      "L": "X",
      "S": "A",
      "2" : "Down",
      "236" : "Quarter Circle",
    };

document.querySelector("textarea").addEventListener("keyup", (e) => {
  const input = e.target.value.toUpperCase();
  const inputValidated = input.replace(/[^a-zA-Z0-9 ,]/g, "");
  const arrOfIns = inputValidated.split("");
  const arrOfOuts = arrOfIns.map((e) =>
    xboxConverter[e] ? xboxConverter[e] : ""    
  );
  const out = arrOfOuts.join(" , ");
  document.getElementById("output").innerText = out;
  if (out.input == "236")
  return "QC";
});

How can I learn Javascript

I am new to web design. I have a decent understanding of HTML and CSS already and I love to start Javascript. It seems a bit technical than others learned so far. So I need advice on the best way to approach Javascript, especially for web App. List of topics and basic concepts to be covered, suggested time frame, and projects to attempt.

How do I calculate the inverseBindMatrices in glTF by hand from Translation, Rotation, and Scale?

I am having trouble calculating the inverseBindMatrices from .gltf files. My model displays correctly in gltf-viewer, but not in my engine.

Here is the node I have an issue with:

{
  name: 'Base Bone',
  rotation: [ 1, 0, 0, 0 ],
  translation: [ -2.81376314163208, 4.689605236053467, 0 ],
  inverseBindMatrix: Matrix {
    array: [
      1,
      -0,
      0,
      -0,
      0,
      -1,
      -0,
      0,
      0,
      -0,
      -1,
      -0,
      2.81376314163208,
      4.689605236053467,
      0,
      1
    ]
  }
}

Another node if it helps answer the question:

{
  children: [ 0 ],
  name: 'Lid Bone',
  rotation: [
    1.5454311608209537e-8,
    1.5454311608209537e-8,
    -0.7071068286895752,
    0.7071068286895752
  ],
  scale: [ 1, 0.9999999403953552, 1 ],
  translation: [ -2.81376314163208, 4.689605236053467, 1.4210854715202004e-14 ],
  inverseBindMatrix: Matrix {
    array: [
                          0, 1.0000001192092896,
                          0,                 -0,
                         -1,                  0,
      -4.371138828673793e-8,                  0,
      -4.371138828673793e-8,                 -0,
                          1,                 -0,
          4.689605236053467,  2.813763380050659,
       2.049891492106326e-7,                  1
    ]
  },
  globalTransformOfJointNode: Matrix {
    array: [
            -1,       0,  0,
             0,      -0, -0,
            -1,       0,  0,
            -1,      -0,  0,
      -2.81376, 4.68961,  0,
             1
    ]
  }
}

I parsed the binary data to retrieve this inverseBindMatrix. I used the Blender 2.83 exporter, and as you can see, there is no rotation (w,x,y,z) = (1,0,0,0). However, there is a translation left then up. The inverseBindMatrix appears to flip the y and z-axes. I have really struggled for weeks on this problem. On to my question:

How can I take this rotation, translation, and scale and calculate this inverseBindMatrix? Why are two of the axes flipped?

Thank you for any help.

Graphql Apollo Client query by ID

I’m new to GraphQL and I’m trying to build a work around project for training purposes.

For this project I’m using an external GraphQL API to get some movies.
I’m making my requests through Apollo-Client the newest version and display them within a small react native app and the useQuery hook from the Apollo-Client library. No particular backend for this app.

I’m currently trying to display 2 different screens :

  • The main one with a list of all the movies. Got them with this query :
const GET_MOVIES = gql `
{
allMovies {
movies {
title 
id } 
  } 
} 
`

Everything is ok so far. But I’m stuck with the next part. I’m trying to use this id i got from a movie (map through movies) as a variable for my next request which i want to use to display my next screen. The movie screen.

I got the id but i don’t know how to use it as a variable and pass it to my query to then get all the movie informations i need from this particular movie.

I found something like this :

const GET_THIS_MOVIE = gql `
{
movie (id : $movieID) {
title
.... 
.... 
  } 
} 
`

But i don’t know how to use the id i got as this movieID variable. Knowing this id will change depending on the movie selected.

A precise answer with some code would be really appreciated as im new to GraphQL

Thanks for your help !

Convert HTML string to JSX string?

Is there is a tool or quick way to convert arbitrary HTML strings to valid JSX strings? And by string, I mean an actual string.

const htmlString = "<button class="foo" onclick="..." >Hello World</button>"
const jsxString = htmlStringToJsxString(htmlString)
console.log(jsxString)

And my desired output:

"<button className="foo" onClick="..." >Hello World</button>"

I’m not trying to parse HTML then render JSX, nor am I injecting HTML into the DOM. I specifically need to convert an HTML string to the conventions of JSX (camel-casing attributes, replacing “class” with “className”, etc).

How to setFormulas() to a range using Google Apps Script?

What do I need to change so that this script sets the formulas (from row 2) to the range defined?
The code below doesn’t give me any error, but it doesn’t set the formulas at all.

  var lc = sheet.getLastColumn();
  var range = sheet.getRange(2, 1, 1, lc);
  var formulas = range.getFormulas();
  
  range.copyFormatToRange(sheet, 1, lc, 3, 3+response); //This pastes the format to the range, whose number of rows is defined depending on the # that the user inputs.

  var pasteTo = sheet.getRange(3, 1, response, lc);//Defines the range for setting formulas
  for (var a = 3; a < response; a++){
    pasteTo = sheet.getRange("A" + a,sheet.getLastColumn());
    pasteTo.setFormulas(formulas);
  }
  }
}

Error (‘httpResponse is not defined’)Not sure where I’ve gone wrong but getting this error

Been trying to get this code to work for a while now can’t see where I’m going wrong when I try to ‘open with live server’ on visual studio code and inspect the page I can see I’m getting the error:

GET  https://txvxu97okj3q.usemoralis.com:2053/server/functions/getNFT?_ApplicationId=hvSK2mZVUIMqGoMT8CJA06NJG8KPEAjrt2ZlLokl&nftId=1 400

and then also,

{code: 141, error: 'httpResponse is not defined'}
code: 141
error: "httpResponse is not defined"

not sure where the error is would greatly appreciate any help 🙂

Moralis.start({ serverUrl: "https://txvxu97okj3q.usemoralis.com:2053/server", appId: "hvSK2mZVUIMqGoMT8CJA06NJG8KPEAjrt2ZlLokl" });
    
function fetchNFTMetadata(NFTs){
  for (let i = 0; i < NFTs.length; i++) {
    let nft = NFTs[i];
    let id = nft.token_id;
        
//Call Moralis Cloud function -> Static JSON file 
        
  fetch("https://txvxu97okj3q.usemoralis.com:2053/server/functions/getNFT?_ApplicationId=hvSK2mZVUIMqGoMT8CJA06NJG8KPEAjrt2ZlLokl&nftId=" + id)
  .then(res => res.json())
  .then(res => console.log(res))
  }
}

async function initializeApp(){
    let currentUser = Moralis.User.current();
    if(!currentUser){
        current = await Moralis.Web3.authenticate();
    }

    const options = { address: "0x3be1812365e150157a326a8d0860a72fadee2db0", chain: "rinkeby" };
    let NFTs = await Moralis.Web3API.token.getAllTokenIds(options);
    console.log(NFTs);
    fetchNFTMetadata(NFTs.result);
}

initializeApp();

{code: 141, error: ‘httpResponse is not defined’}

Using two querySelector in js

I’m trying to use js in a way that when you hover the mouse over text links, the background image changes with each link.
I’ve been able to initiate the Event Listener to the link texts but am unable to direct the output to the background image div (style elemet)

Here is my html code

<div id="livestream">  
      </div>
      <div id="wedding">  
      </div>
      <div id="documentary">  
      </div>

      <div class="container text-box">
          <a href="#">Livestreaming</a> 
          <a href="#">Weddings</a>
          <a href="#">Documentaries</a>
      </div>

My css, which im stuck too;

.landing #documentary{
    background-image: url("/img/pic-01.jpg");
    background-size: cover;
    height: 100vh;
    z-index: -1;
}

.landing #livestream, #wedding, #documentary{
    display: none;
}

.text-box a:nth-child(1):hover{
    color: #e08416;
    transition: 0.4s ease;}
}

And here is my js code

document.querySelector('.text-box a:nth-child(1)').addEventListener('mouseenter', entering);
document.querySelector('.text-box a:nth-child(1)').addEventListener('mouseleave', leaving);

function entering(ev){
    ev.currentTarget.style.display = "block";
    console.log('mouseenter  a');
}

function leaving(ev){
    ev.currentTarget.style.display = "none";
    console.log('mouseleave a');
}

I got stuck here

How can I call Discord.js functions from a lib.js file into index.js?

I am trying to have a separate class full of my functions so index.js doesn’t get cluttered up. The problem I encountered is that my new lib.js file cannot work with discord.js. I am planning on adding multiple, more complex functions, so replacing lib.start() with msg.channel.send('Game Started') won’t fix my issue. Is there a way I can get discord.js commands to work in lib.js so I can call them into index.js?

index.js

const Discord = require('discord.js')
const client = new Discord.Client();

const lib = require("./classes/lib");

const { token } = require('./Data/config.json');

client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
})

client.on('message', async msg => {
  if(msg.content.startsWith("m!")) {
    const command = msg.content.substring(2)

    switch(command) {
      
      //Calling 'start()'
      case "start game" : lib.start(); break;
    
      default: msg.channel.send('Unknown Command');
    
    }
  } 
})

client.login(token)

lib.js

function start() {
    msg.channel.send('Game Started');   //Trying to get this to work
}

module.exports = {start};

I am trying to retrieve data from a single key in firebase

var ratingRef = firebase.database().ref(“hollywood/”); ratingRef.orderByValue().on(“value”, function(data) { data.forEach(function(data) { var name = (“The ” + data.val().name + ” rating is ” + data.val().director +data.val().
year);
var pic= data.val().src;
alert(pic)
var fame= $(“#tame”).attr(“src”,pic +””)
$(“#test”).append(name +”
“);
}); });

Why is my confirm password field not firing validation at all (react-hook-form)

Here is a codesandbox to see my problem replicated: https://codesandbox.io/s/inspiring-haslett-1c8sw?file=/pages/index.js

I want to ensure the confirmPassword field matches the password field, however it will always say “Passwords match”, it never changes.

I have followed the docs however I cannot seem to get the functionality im after. I have set the mode to onChange

Here is my form:

import { SubmitHandler, useForm, useFormState } from "react-hook-form";

function IndexPage() {
  //Hook form
  const {
    register,
    watch,
    formState: { errors, isValid, dirtyFields }
  } = useForm({
    mode: "onChange",
    defaultValues: {
      email: "",
      password: "",
      confirmPassword: "",
      username: "",
      firstName: "",
      surname: "",
      isShop: false
    }
  });
  const { password } = watch();

  const [passwordFocused, setPasswordFocused] = useState(false);

  const onSubmit = async (data) => {
    //submit here
  };

  return (
    <>
      {/* NEW SIGNUP FORM */}
      <main className="min-h-screen flex">
        <div className="w-full flex flex-col py-12 md:w-1/2 flex-grow min-h-full">
          <div className="mt-6 h-full w-full flex flex-col md:w-96 mx-auto">
            <form
              onSubmit={onSubmit}
              autoComplete="off"
              className="space-y-6 relative flex flex-col w-full flex-1"
            >
              <span className="flex-1"></span>
              {/* STEP 1*/}
              <div>
                <div className="space-y-1">
                  <label
                    htmlFor="password"
                    className="block text-sm font-medium text-gray-700"
                  >
                    Password
                  </label>
                  <div className="mt-1">
                    <input
                      {...register("password", {
                        required: true,
                        minLength: 8,
                        maxLength: 50,
                        pattern: /^(?=.*[A-Za-z])(?=.*d)[A-Za-zd@$!%*#?&^_-]{8,}$/
                      })}
                      id="password"
                      name="password"
                      type="password"
                      autoComplete="current-password"
                      required
                      className="input w-full"
                      onFocus={() => {
                        setPasswordFocused(true);
                      }}
                      onBlur={() => {
                        setPasswordFocused(false);
                      }}
                    />
                    <span
                      className={`${
                        passwordFocused && errors.password
                          ? "max-h-46 opacity-100"
                          : "max-h-0 opacity-0"
                      } duration-500 ease-in-out transition-all flex flex-col overflow-hidden`}
                    >
                      <p className="text-gray-600 mt-2">
                        Passwords must contain:
                      </p>
                      <ul className="space-y-2">
                        <li
                          className={`mt-2 ${
                            password.length >= 8
                              ? "text-green-600"
                              : "text-gray-600"
                          }`}
                        >
                          At least 8 characters
                        </li>
                        <li
                          className={`mt-2 ${
                            /[A-Z]/.test(password)
                              ? "text-green-600"
                              : "text-gray-600"
                          }`}
                        >
                          Upper and lower case characters
                        </li>
                        <li
                          className={`mt-2 ${
                            /d/.test(password)
                              ? "text-green-600"
                              : "text-gray-600"
                          }`}
                        >
                          At least one digit
                        </li>
                      </ul>
                    </span>
                  </div>
                </div>
                <div
                  className={`space-y-1 ${
                    !errors.password && dirtyFields.password
                      ? "visible"
                      : "invisible"
                  } `}
                >
                  <label
                    htmlFor="password"
                    className="block text-sm font-medium text-gray-700"
                  >
                    Confirm password
                  </label>
                  <div className="mt-1">
                    <input
                      {...register("confirmPassword", {
                        validate: (value) =>
                          value === password || "Passwords do not match"
                      })}
                      id="confirm-password"
                      name="confirm-password"
                      type="password"
                      autoComplete="confirm-password"
                      required
                      className={`input w-full`}
                    />
                  </div>
                  {errors.confirmPassword
                    ? "Passwords do not match"
                    : "Passwords match"}
                </div>
              </div>
            </form>
          </div>
        </div>
      </main>
    </>
  );
}

export default IndexPage;

JavaScript to use a different proxy link if the first one returns a 404 error

I have some JS that works as follows:
If the Word Count button is pressed, go to the Word Count function, if the status of the requested page is 200, then let the url be proxyURL, which is defined correctly in index.html and this as it stands works.

I have then added an else if statement to say if a 404 is returned, then go to the function “WordCountProxyBackup” function, which works the same way as the original, but instead of using “proxyURL”, it uses proxybackupURL, which is defined in index.html

I have intentionally broken by original proxyURL to try and test this, and a 404 is returned, but the button is not finding it’s way to the backup function to then find it’s way to the backup link, can someone help with this? The code is below.

   function Wordcount()
{
    $(".operation").attr('disabled', true);
    this.disabled = true;
    let xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var j = JSON.parse(this.response);
            document.getElementById('output').value = j.answer;
        }else if (this.readyState == 4 && this.status == 404) {
            document.getElementById('output').value = "Error Bad Pathway - Rerouting";
            WordcountProxyBackup();
        }
    };

    let url = proxyURL + "/?text=" + encodeURI(document.getElementById('content').value) + "&route=" + "wordcount";
    xhttp.open("GET",url);
    xhttp.send();
    $(".operation").attr('disabled', false);
}

function WordcountProxyBackup()
{
    $(".operation").attr('disabled', true);
    this.disabled = true;
    let xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var j = JSON.parse(this.response);
            document.getElementById('output').value = j.answer;
        }else if (this.readyState == 4 && this.status == 500) {
            document.getElementById('output').value = "Error Bad Pathway - Rerouting";
            WordcountProxyBackup2();
        }
    };

    let url = proxybackupURL + "/?text=" + encodeURI(document.getElementById('content').value) + "&route=" + "wordcount";
    xhttp.open("GET",url);
    xhttp.send();
    $(".operation").attr('disabled', false);
}