Google App Script: Send email with attachments from google form responses

I am adjusting an existing script that we have for a Google Form that sends a custom email to the desired address, now we want to add a PDF upload in the form and we want to add it to the script in order to be attached in the email. I know it shouldnt be difficult but so many years without programming and I can’t fix it. I will attach my code right now without the tests I am doing to add the PDF attached from the form so you can see the structure and maybe help me with the import:

function GetContactsAndMakeThemMultiChoise(){
  // Copy your form ID from the browser address bar when you open the form in edit mode
 var form = FormApp.openById('XXXXXXXXXXmyformXXXXXXX'); 
var formItems = form.getItems(FormApp.ItemType.LIST);
     var arr=[]
  //i<contacts.length; i++
  var contacts = ContactsApp.getContacts();
   for (var i=0; i<contacts.length; i++) {
//Access my contacts and get all contact name that not blank (name.length>0)
    var name = contacts[i].getEmailAddresses();
     if(name.length>0 ){
       arr.push(name); }
    
   }
   
   // Add the contact name to the first dropdown list found in my form
     
     formItems[3].asListItem().setChoiceValues(arr.sort()); 
  }

  // Installation --> copy this code in the inbound code from the form (open form --> three dots --> Scripteditor
// run function createTrigger() once

function createTrigger() {
  ScriptApp.newTrigger("sendMail").forForm(FormApp.getActiveForm()).onFormSubmit().create();
}

function getInfo(e) {
  var formResponse;
  if (!e) { formResponse = FormApp.getActiveForm().getResponses()[FormApp.getActiveForm().getResponses().length - 1]; } else { formResponse = e.response; }

  var answers = {};
  formResponse.getItemResponses().forEach(function (r) {
    if (r.getResponse() != undefined && r.getResponse() != "") {
      answers[r.getItem().getTitle()] = r.getResponse();
    }

  });

  var equipo = answers["División"];

  //please enter here your email adresses for the form
  if (equipo == "S1") { sendtheMail("[email protected]", answers) }
  else if (equipo == "R1") { sendtheMail("[email protected]", answers) }
  else {
    { sendtheMail("[email protected]", answers) }
  }


  function sendtheMail(contactName, answers) {

    var tipo = answers["Tipo de"];
    var nombre = answers["Tu nombre"];
    var beneficiario = answers["Nombre"];
    var cantidad = answers["Cantidad"];
    var comentarios = answers["Coments"];
    var propertyid = answers["ID"];
    var paddress = answers["Dirección"];
    
        

    //You can change the mail text under htmlBody
    MailApp.sendEmail({
      name: "Mailing",
      to: "[email protected]",
      subject: "Nueva solicitud " + nombre + " del equipo " + equipo,
      htmlBody: "<p>text " +nombre+ " del equipo " + equipo +
        "<p>El tipo de transferencia es: "+ tipo +
        "<p>El ID: "+ propertyid +
        "<p>La dirección de la propiedad es: "+ paddress +
        "<p>El nombre del beneficiario es: " + beneficiario +
        "<p>Cantidad a transferir: " + cantidad + " €" +
        "<p>Coments: " + comentarios ,
      attachments: ,
      noReply: true
    });
  }
}

I modified a little bit the names but everything works as should, the only thing is just to add the attachment to the email but cant find the way, thank you for the help in advance!

I tried already:
var attach = formResponse.getItemResponses();
var file = DriveApp.getFileById(attach[10].getItem());

attachments: [file.getAs(MimeType.PDF)]

But probably I am not setting it correctly on what we need.

My animation is very laggy and i cant find the way how to correct it. Any method or tips?

I want a page-turning book but the animation is very choppy and can even freeze in places. I’m trying to improve the JS in every possible way so that the whole page doesn’t freeze.

I think the error is in updatePageContent() because it updates the pages and when I scroll it is brutally jagged and doesn’t even load properly.

document.addEventListener('DOMContentLoaded', function() {
  const book = document.getElementById('book');
  let currentLocation = 1;
  const numOfPapers = 1000;
  let maxLocation = numOfPapers + 1;
  const nextBtn = document.createElement('button');
  nextBtn.id = 'next-btn';
  nextBtn.textContent = 'Következő';
  const prevBtn = document.createElement('button');
  prevBtn.id = 'prev-btn';
  prevBtn.textContent = 'Előző';


  nextBtn.style.position = 'absolute';
  nextBtn.style.right = '20px';
  nextBtn.style.bottom = '20px';
  prevBtn.style.position = 'absolute';
  prevBtn.style.left = '20px';
  prevBtn.style.bottom = '20px';

  document.body.appendChild(prevBtn);
  document.body.appendChild(nextBtn);

  nextBtn.addEventListener('click', goNextPage);
  prevBtn.addEventListener('click', goPrevPage);

  for (let i = 0; i < numOfPapers; i++) {
    const paper = document.createElement('div');
    paper.className = 'paper';
    paper.id = `p${i + 1}`;

    const front = document.createElement('div');
    front.className = 'front';
    const frontContent = document.createElement('div');
    frontContent.className = 'front-content';
    frontContent.innerHTML = `<h1>Front ${i + 1}</h1>`;
    front.appendChild(frontContent);

    const back = document.createElement('div');
    back.className = 'back';
    const backContent = document.createElement('div');
    backContent.className = 'back-content';
    backContent.innerHTML = `<h1>Back ${i + 1}</h1>`;
    back.appendChild(backContent);

    paper.appendChild(front);
    paper.appendChild(back);

    book.appendChild(paper);

  }

  function updatePageContent() {
    if (currentLocation > 1) {
      const prevPage = document.getElementById(`p${currentLocation - 1}`);
      const prevFrontContent = prevPage.querySelector('.front-content');
      const prevBackContent = prevPage.querySelector('.back-content');
      prevFrontContent.innerHTML = `<h1>Front ${currentLocation * 2 - 2}</h1>`;
      prevBackContent.innerHTML = `<h1>Back ${currentLocation * 2 - 1}</h1>`;
    }

    if (currentLocation <= numOfPapers) {
      const currentPage = document.getElementById(`p${currentLocation}`);
      const currentFrontContent = currentPage.querySelector('.front-content');
      const currentBackContent = currentPage.querySelector('.back-content');
      currentFrontContent.innerHTML = `<h1>Front ${currentLocation * 2}</h1>`;
      currentBackContent.innerHTML = `<h1>Back ${currentLocation * 2 + 1}</h1>`;
    }

    if (currentLocation < numOfPapers) {
      const nextPage = document.getElementById(`p${currentLocation + 1}`);
      if (nextPage) {
        const nextFrontContent = nextPage.querySelector('.front-content');
        const nextBackContent = nextPage.querySelector('.back-content');
        nextFrontContent.innerHTML = `<h1>Front ${currentLocation * 2 + 1}</h1>`;
        nextBackContent.innerHTML = `<h1>Back ${currentLocation * 2 + 2}</h1>`;
      }
    }
  }



  function openBook() {
    book.style.transform = "translateX(50%)";
  }

  function closeBook(isAtEnd) {
    if (isAtEnd) {
      book.style.transform = "translateX(100%)";
    } else {
      book.style.transform = "translateX(0%)";
    }
  }

  function goNextPage() {
    if (currentLocation < maxLocation) {
      currentLocation++;
      const currentPage = document.getElementById(`p${currentLocation}`);
      currentPage.classList.add("flipped");
      currentPage.style.zIndex = currentLocation;

      if (currentLocation === 1) {
        openBook();
      } else if (currentLocation === numOfPapers) {
        closeBook(false);
      }

      updatePageContent();
    }
  }

  function goPrevPage() {
    if (currentLocation > 1) {
      const currentPage = document.getElementById(`p${currentLocation}`);
      currentPage.classList.remove("flipped");
      currentPage.style.zIndex = numOfPapers - currentLocation + 1;

      currentLocation--;

      if (currentLocation === 1) {
        closeBook(true);
      } else if (currentLocation < numOfPapers) {
        openBook();
      }

      updatePageContent();
    }
  }


  document.getElementById('next-btn').addEventListener('click', goNextPage);
  document.getElementById('prev-btn').addEventListener('click', goPrevPage);
});
<div id="book" class="book">
  <div id="p1" class="paper">
    <div class="front">
      <div id="f1" class="front-content">
        <h1>Front 1</h1>
      </div>
    </div>
    <div class="back">
      <div id="b1" class="back-content">
        <h1>Back 1</h1>
      </div>
    </div>
  </div>
</div>

Vue3: app.component does not on page and inspect element

I am trying to implement vue 3 code on html and js format.

 <div id="app">
 ...
</div>

and this my script vue 3

const app = Vue.createApp({
   ...
})

app.component("test-a", {
    template: '<span style="background: green">test a</span>',

});

app.mount('#app');

At the moment I want the component test-a can show up inside <div id="app">. However, it does not show up at all.
And the component does not show up at all on the console vue inspect (Please see the image below).

Can anyone tell me how to solve this?

please see the image below

Adding a Custom Field to the Sign-in Page in Azure B2C

I’m wondering if there’s a way to include a custom field on the Sign-in page in Azure B2C using custom policy. My goal is to add a checkbox for users to consent to cookies. Currently, I’ve tried a simple solution with custom HTML and JavaScript, but it can be bypassed by password manager tools like Bitwarden. I think the B2C server needs to be involved to validate the checkbox before allowing the login submission to proceed.

Loading Angular component when a GoJs link is clicked

I am working on an angular 17 app.
As a part of the shared lib, I am creating generic classes for GoJs.

One such class is link.ts which defines the linkTemplate, on link hover, I want to load an angular component.

I am not using GoJs for angular, neither want to convert the generic class into a component.
How can I load an angular component in gojs ?

For ex. have a look at this snippet –

It will load an adornment on mouse hover, click of which will generate an alert.

I want to load an angular 17 standalone component on the click.

const $ = go.GraphObject.make;

    let linkHoverAdornment =
        $(go.Adornment, "Spot",
          {
            // hide the Adornment when the mouse leaves it
            mouseLeave: (e, obj) => {
              let ad = obj.part;
              (ad as any).adornedPart.removeAdornment("mouseHover");
            },
            padding: 10
          },
          $(go.Placeholder,
            {
              isActionable: true,
              click: (e: any, obj: any) => {
                var node = obj.part.adornedPart;
                node.diagram.select(node);
              }
            }),
          $("Button",
            { alignment: go.Spot.Right, alignmentFocus: go.Spot.Left},
            { 
              click: (e, obj) => {
                alert("load menu component")
              } 
            },
            $(go.TextBlock, " + icon "))
        );



    let linkTemplateObj = $(
      OffsetLink,
      {
        relinkableFrom: true,
        relinkableTo: true,
        selectable: false,
        corner: defaultDiagramStyles.nodeCornerSize,
        routing: go.Link.AvoidsNodes,
        layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutAdded & ~go.Part.LayoutRemoved,
        mouseHover: (e, obj) => {
          linkHoverAdornment.adornedObject = obj.part;
          (obj.part as any).addAdornment("mouseHover", linkHoverAdornment);
        }
      },
      $(go.Shape, {
        toArrow: 'Standard',
        mouseEnter: (e: any, obj: any) => { obj.strokeWidth = 4; obj.stroke = "blue"; },
        mouseLeave: (e: any, obj: any) => { 
          obj.strokeWidth = 2; 
          obj.stroke = "black";
          console.log('mouse leave 2');
        },
      }),
    );

Error in init.ts when using jsTreeR’s grid parameter

I’ve already raised the issue here and here. By now a workaround exists however, I still don’t understand the root cause.

When running the following app using the latest CRAN version of library(shiny) and library(jsTreeR) (2.5.0) after resizing the browser window this error can be seen in the browser console:

image

Example app:

library(jsTreeR)
library(shiny)

nodes <- list(
  list(
    text = "Fruits",
    type = "fruit",
    children = list(
      list(
        text = "Apple",
        type = "fruit",
        data = list(
          quantity = 20
        )
      ),
      list(
        text = "Banana",
        type = "fruit",
        data = list(
          quantity = 31
        )
      ),
      list(
        text = "Grapes",
        type = "fruit",
        data = list(
          quantity = 34
        )
      )
    ),
    state = list(
      opened = TRUE
    )
  )
)

grid <- list(
  columns = list(
    list(
      width = 200,
      header = "Product"
    ),
    list(
      width = 150,
      value = "quantity",
      header = "Quantity"
    )
  )
)

ui <-   fluidPage(
  titlePanel("jsTree grid"),
  jstreeOutput("jstree")
)

server <-   function(input, output, session){
  output$jstree <- renderJstree(jstree(nodes, search = TRUE, grid = grid))
}

shinyApp(ui, server)

This is only the case when jstree is provided with the grid parameter.

@StéphaneLaurent identified that the class shiny-bound-output is assigned to the jstree-grid-wrapper div which causes the issue and that removing it prevents the error.

I’d like to understand why this class is added in the first place and if there is a proper way to implement the grid parameter without running into this issue.

there is data in dropdown but not showing

i want to when i choose country automatic get city from db to dropdown. i chose country and get to state from state ( i wrote on console ) console.log

data got to dropdown but not showing in dropdown.

when i selected empty area and when i post operation. operation and state added correctly.

post operation and not showing state names in dropdown

after post operation, get operation

person-add.component.html

<label>Country</label>
              <div class="form-group">
                <div class="input-space">
                  <select  formControlName="country" (ngModelChange)="onSelect($event)" id="">
                    <option value="" disabled selected> Choose Country</option>
                    <option *ngFor="let country of countries" [ngValue]="country.id" >
                        {{country.name}}
                    </option>
                  </select>
                </div>
              </div>

              <label>State</label>
              <div class="form-group">
                <div class="input-space">
                  <select  formControlName="state" id="">
                    <option  value="" disabled selected>Choose State</option>
                    <option *ngFor="let state of states"  [ngValue]="state.id" >
                        {{state.name}}
                    </option>
                  </select>
                </div>
              </div>

person-add.component.ts

ngOnInit(): void {
    this.countryService.getCountries().subscribe(
      response => {
        this.countries = response.data
      }
    )
    this.createPerson();
  }

  createPerson(){
    this.personAddForm = this.formBuilder.group(
      {
        name:["", Validators.required],
        surname:["", Validators.required],
        age:["", Validators.required],
        country:["", Validators.required],
        state:["", Validators.required]
      }
    )
  }

  add(){
    if(this.personAddForm.valid){
      let createPerson  = {name: this.personAddForm.value.name, surname:this.personAddForm.value.surname, age:this.personAddForm.value.age  ,countryId:this.personAddForm.value.country, stateId:this.personAddForm.value.state}
      this.peopleService.addPerson(createPerson).subscribe(
        response => {
          console.log(response.message)
          this.personAddForm.reset()
          this.router.navigate([""])
        }
      )
    }else{

    }
  }

  onSelect(countryId : any){
    this.stateService.getStatesAccordingToCountryId(countryId).subscribe(
      response => {
        this.states = response.data;
        console.log(response.data)
      }
    )
  }
}

i want to expect show data on dropdown menu

Emit audio cue upon connection with Airplay (Shairport-Sync)?

In my house I have installed 2 speakers in the wall of every room. My goal was to connect them through airplay and simply play music off my phone.

To do this I have familiarised myself with a Raspberry Pi 4, running on Raspberry Pi OS Lite. I have also installed a Hifiberry AMP2 to connect the speakers.

I am currently running shairport-sync and it works flawlessly, easy to connect from my iPhone and sound is right.

Now, whenever I connect to one of my speakers, I would like it to emit a sound, but it doesn’t.

I thought of somehow make in a script which listens for connections in shairplay-sync and then emits a mp3 file. Then I would make a service file, etc.

But I don’t have any experience with log files and very little experience with JavaScript. Could anyone help me with this?

How to use Numpy functionality in JavaScript/React Native? [closed]

The numpy library in Python provides the basic interface, which I use to work with the body pose data (body parts, motion sequences) and all different kinds of mathematical operations on 2D / 3D data. At the moment I’m developing a mobile app in React Native, where I plan to rewrite the functionalities created in Python (using numpy) to the JavaScript.

Since the numjs (https://www.npmjs.com/package/numjs) library seems to be outdated and doesn’t work well with RN, I’m looking for a new way to use the same functionality provided by numpy to manipulate with motion sequences / body pose data in React Native.

resize down a component without its content being affected

I need help, I am using NextJS and I have a CV preview section(parent component) that has a CV Component(child component) and I want to achieve similar affect as in video on shrinking browser, making the cv component smaller just like object-fit applies to image instead of shrinking the width of cv component, b/c I have given a fixed width and height to cv component, b/c I dont want to have formatting issue just like if I would have given using max-width etc.

What I want is to reduce the cv component from all sides at once, just like object-fit applies to image

What I want to achieve: https://imgur.com/a/3K7HsUS

I have tried every possible solution but can’t achieve desired result

2 Errors: wp.blockEditor.RichText value prop as children type is deprecated and wp.blocks.children.toHTML is deprecated

Here is the errors

error1 : wp.blockEditor.RichText value prop as children type is deprecated since version 6.1 and will be removed in version 6.3. Please use value prop as string instead

error2: wp.blocks.children.toHTML is deprecated since version 6.1 and will be removed in version 6.3. Please use wp.richText.toHTMLString instead

Both give the following link: https://developer.wordpress.org/block-editor/getting-started/fundamentals/block-json/

However, looking at the link I can’t see anything referancing either problem.

Here is my RichText reference in my code:

    <RichText
                                tagName="h3"
                                value={ m.label }
                                class="stamp-title"
                                onChange={ ( content ) => updateAttributes(string1, string2, string3, string4, index) }
                                
                            />
                            <RichText
                                tagName="p"
                                value={ m.content }
                                class="stamp-excerpt"
                                onChange={ ( content ) => updateAttributes(string1, string2, string3, string4, index) }
                            />

Here is the attribute related to the code.

        "myTest": {
            "type": "array",
            "source": "query",
            "selector": "div",
            "default": [],
            "query": {
                "image": {
                    "type": "string",
                    "source": "attribute",
                    "selector": ".stamp-image",
                    "attribute": "src"
                },
                "title": {
                    "type": "string",
                    "selector": "h3",
                    "source": "html"
                },
                "excerpt": {
                    "type": "string",
                    "selector": "p",
                    "source": "html"
                },
                "link": {
                    "type": "string",
                    "source": "attribute",
                    "selector": ".button-parent a",
                    "attribute": "href"
                }
            }
        },

Hopefully someone has the answer. Thanks in advance

want to save file with filename given by user using multer

    const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const multer = require("multer");
const path = require("path");

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const app = express();

app.use(cors());
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies for form data
mongoose.connect("mongodb://127.0.0.1:27017/Gallary");

const schema = new mongoose.Schema({
  email: {
    required: true,
    type: String,
  },
  password: {
    required: true,
    type: String,
  },
});
const Login = mongoose.model("Login", schema);

app.get("/", (req, res) => {
  res.send("Gallery it is");
});

app.post("/SignUp", async (req, res) => {
  try {
    let result = await Login.find(req.body);
    if (result.length == 0) {
      let data = new Login(req.body);
      await data.save();
      res.send({ result: true });
    } else {
      res.send({ result: false });
    }
  } catch (e) {
    res.send(e);
  }
});

app.post("/Login", async (req, res) => {
  try {
    let result = await Login.find(req.body);
    console.log("came");
    if (result.length != 0) {
      res.send({ result: true });
    } else {
      res.send({ result: false });
    }
  } catch (e) {
    res.send({ result: false });
  }
});

// Define multer storage configuration
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "uploads/");
  },
  filename: (req, file, cb) => {
    console.log("place2"+req.body.filename );
    const filename = req.body.filename ? req.body.filename : `default_filename_${Date.now()}${path.extname(file.originalname)}`;
    cb(null, filename);
  },
});

const upload = multer({ storage: storage });

// Define route for image upload
app.post("/upload", upload.single("image"), (req, res) => {
  console.log("Uploaded file:", req.file.filename);
  res.json({ filename: req.file.filename });
});

app.listen(process.env.PORT || 3001, () => {
  console.log("Server is running on port 3001");
});

In above code I am trying to save file using multer but it is always saving file with default name.
in upload route it is printing correct filename but in place2 tag
i am getting undefined when i printing using console.

Why i am getting {} empty object in place2 console.log ,however i am getting correct object or req.body in upload route as sent by the frontend.

react antd.notification renders only after i refresh the page

I don’t why notification shows only after refreshing the page. Maybe somebody faced it

const MyComponent = () => {

  const handleSave = async () => {
    // ... other code

    try {
      await axios.put(...);
      // success handling
    } catch (error) {
      if (error.code === "ERR_BAD_REQUEST") {
        //
      } else {
        // handle generic error
        notification.error({
            message: t("Error while saving"),
            description: JSON.stringify(error.response.data),
            placement: "topRight",
            duration: 2,
        })
      }
    }
  };

  return (
    // ... Other component content
  );
};

Expect notification.error shows without refreshing

Custom Filter for Kendo UI multiselect asp.net mvc

I have a multiselect created with the below code

@(Html.Kendo().MultiSelectFor(model => model.data)
        .Name("SampleData")
        .AutoClose(false)
        .MaxSelectedItems(10)
        .DataSource(source =>
            {
                source.Read(read =>
                {
                    read.Action("GetData", "SampleData");
                });
            })
        )

In Controller I’m returning a list with around 1000 items
The datasource is something like below having
List<string> listitem=new List<string>(){"value item 1 here", "this item is 2", "some other value here"......}

Is there any way such that when i enter something in the kendo multiselect it filter the values based on the start of the words in the sentences of that string list?
for eg:
if i enter “ite” it should show all the sentences of that string list which has words starting with “ite”.

Help is much appreciated. Thanks!

I have seen some filters like “startswith” which only checks the start of the sentences and “contains” which checks even the substring of the words. But what I’m trying to get is some filtering which check the start of all the words in the sentence and then filter it based on the match.