RSVP - Google Sheets integration

Hello all,

I need some help with Velo coding.

As much as I enjoy the challenge of figuring these things out for myself this is just too hard.

My site has a number of events each month. All I want to do is populate a Google Sheet whenever someone RSVPs to any event with the form data. I know I can do that with Automations but I don’t want to have to go in every time to reconfigure the Automation.

It looks like the onRSVPCreated () backend event will do the job combined with the Google Sheets Integration. I just can’t put all the pieces together.

The documentation and examples are sparse so I’m hoping someone can give me a hand.

Regards,

Andrew

Hello! Sorry this is overwhelming you but I bet you can get through it.

What I would suggest first is trying out this Velo package as is - get the demo form hooked up to a google sheet and test it out. That way you can see how the interaction works and then modify the code to connect to your form elements instead.

To add a Velo package to your site, click on the {} on the left hand navigation with dev mode on

Under Packages > Velo > Install Velo package

Search for google sheets integration

Once the package is installed, follow along in the README file in the package and see how far you can get. Post any code specific questions to the forum if you get stuck.

Thanks Amanda,

I managed to get the form example working. My events rsvp shouldn’t bee too much harder.
I’m using the same googlesheet-wrapper and also importing the wixEvents-onRsvpCreated module from the events.js backend file. So far so good.

Now I just need a bit of code on the page to push the RSVP Form data to the spreadsheet.

This is what I have so far

import { appendValuesWrapper } from ‘backend/googlesheet-wrapper’
import { wixEvents_onRsvpCreated } from ‘backend/events’
$w . onReady ( function () {

aync function saveValuesToSheet () {
wixEvents_onRsvpCreated ( Event )
const values = [ firstName , lastName , email ];
appendValuesWrapper ( values );

}
}

I’m not sure if I have to specify the event or it will just work for all events. Do I have to declare the variables again (firstname, lastname, email) as they are declared in the wixEvents_onRsvpCreated .js file

I can’t be the only one who has ever done this, yet I can’t find an example anywhere.

Any clues would be greatly appreciated.

Hello again! Okay, so first thing I’m noticing is you have a misspelling in your code:

aync should be async

The second thing is that you never await anything inside the async function. You may have fixed those 2 issues already. Let me know.

If you don’t know what I mean by having await in your async functions we do have some resources:
Promises Post
Asynchronous Programming Intro video

A follow up to my last comment. You will notice in the documentation that you need to await the appendvalueswrapper function call. I would try structuring your code similarly to the documentation .

And I’ve also taken your note about needing a more in depth tutorial outside of the integration docs. I think that’s a good idea as well, but it will take some time to create/release that.

import { appendValuesWrapper } from 'backend/googlesheet-wrapper.jsw';

$w.onReady(function () {
    registerHandlers();
});

function registerHandlers() {
    $w('#appendButton').onClick(() => saveValuesToSheet());
}

async function saveValuesToSheet() {
    const name = $w('#nameInput').value;
    const email = $w('#emailInput').value;
    const values = [name, email];
    try {
        const res = await appendValuesWrapper(values);
        $w('#nameInput').value = '';
        $w('#emailInput').value = '';
        showMessage(res);
    } catch (err) {
        showMessage(err.toString());
    }
}

function showMessage(msg) {
    $w('#showMsg').text = msg;
    $w('#showMsg').expand()
    setTimeout(() => {
        $w('#showMsg').collapse();
    }, 5000);
}

Hi again,

Thanks for your help so far, we are getting there.

The piece of the puzzle that is missing is how the data from the Events RSVP is pulled into the function,

https://www.wix.com/velo/reference/wix-events-backend/events/onrsvpcreated apparently " fires when a guest registers to a Wix event" but how do we get that payload into our function?

Note that we aren’t using forms here, we are using the Wix Events App.

If and when we get this working I’m happy to help document. The Google Sheets Integration documentation is good, but it’s very specific.

Normally I give people a chocolate frog (https://www.pinterest.com.au/pin/59602395044248530/ when they help me out, but yours might have to be virtual. :wink:

If you want a nocode solution, you can also possibly create a webhook to a tool like zapier/integromat for an ticket order confirmed event (onOrderConfirmed - Velo API Reference - Wix.com)

Once you get the details from the payload, you can use the next steps in zapier/integromat to integrate it to your sheets / any other solution.

So quick update for you.
I’m testing to see how the wixEvents_onRsvpCreated fires and where the code needs to go.

In the events.js file I added a static constant (Bob) and found that when I RSVPed to an event the constant popped up in my spreadsheet

export function wixEvents_onRsvpCreated(event) {
let eventId = event.eventId;
let rsvpId = event.rsvpId;
let status = event.status;

let firstName = event.firstName; 
let lastName = event.lastName; 
let email = event.email; 

const name =(‘Bob’);
const values = [name];
const res = appendValuesWrapper(values);
console.log(res);
}

I’m one step closer.

OK, so now it looks like this

import { appendValuesWrapper } from ‘backend/googlesheet-wrapper.jsw’ ;

export function wixEvents_onRsvpCreated ( event ) {
const eventId = event . eventId ;
const rsvpId = event . rsvpId ;
const status = event . status ;
const firstName = event . firstName ;
const lastName = event . lastName ;
const email = event . email ;
const rsvp = event . rsvpForm ;
const comment = event . comment ;

const  values  = [ firstName ,  lastName ,  email ]; 

const res = appendValuesWrapper ( values );
}
That works as expected and I get the values from the Event RSVP form populating my Google Sheet.

However there is a fields called rsvpForm as “documented” here onRsvpCreated - Velo API Reference - Wix.com

Those are the values that I really want.

Hello. If you console.log the entire RSVP event, is there data in your rsvpForm field?

Hi Amanda,

Good idea. Here is what happened in the logs

jsonPayload": {

“message”:“[{“inputValues”:[{“inputName”:“email”,“value”:“paul@email.com.au”,“values”:[]},{“inputName”:“lastName”,“value”:“Hogan”,“values”:[]},{“inputName”:“firstName”,“value”:“Paul”,“values”:[]},{“inputName”:“comment”,“value”:“That’s not a knife”,“values”:[]}]}]”

However if I try to append rsvp to the spreadsheet I get nothing.

const rsvp = event . rsvpForm ;
console . log ( rsvp );

     **const**  values  = [ rsvp ]; 
 **try**  { 
 **const**  res  =  appendValuesWrapper ( values ); 

I think we’re close.

Okay, so you have data which is great, but if you look at the documentation you will notice that it expects an array and that is an object.

I think at this point your issues are data structure so. you may need to massage how the rsvp event comes back to format it in a way that appendvalueswrapper() expects.

You may have to simplify that data even more then just changing it to an array. That I’m not sure about as I haven’t played with this package much but given that the docs show a very simple array being passed, I’m not sure how complex an array it can handle.

Thanks again Amanda,

I got to that point too. I’m clearly not a coder so this bit might be a bit of a hurdle.
I don’t think it’s far away . Even if it doesn’t get to the spreadsheet looking pretty, it’s easier to massage it there than out of Wix.

The function that updates the spreadsheet will not work unless the data is structured correctly so you will have to do it in JavaScript. You have a few options here…

You will have to take some time to learn how to work with multidimensional JSON in JavaScript. This is not Wix/Velo specific so you can use any source you like.

The data you have returning has what you really want to send a few levels down so you will need to start with one variable extraction at a time something like this…

const email = jsonPayload.message[0].inputValues[0].value
(please note this is untested pseudocode, i don’t know if it will work exactly but I’m trying to demonstrate conceptually how to drill down to the data you need)

You can also just try sending jsonPayload.message[0] but that is still an array of objects so I’m not sure the function will accept that as the docs show it wants a simple array

Or if you were not hoping to learn this much Javascript that’s totally okay and you can visit the marketplace to hire a developer if you like.

Here is what works - roughly

export function wixEvents_onRsvpCreated ( event ) {
const eventId = event . eventId ;

**const**  rsvp  =  event . rsvpForm . inputValues ; 

**const**  formfirstName  =  rsvp [ 2 ]. value ; 
**const**  formemail  =  rsvp [ 0 ]. value ; 
**const**  formlastName  =  rsvp [ 1 ]. value ; 
**const**  formComment  =  rsvp [ 3 ]. value ; 
console . log ( formfirstName ,  formlastName ,  formemail ,  formComment ); 


 **const**  values  =[ formfirstName ,  formlastName ,  formemail ,  formComment ]; 

 **const**  res  =  appendValuesWrapper ( values ); 

Interestingly, events that have more fields have different indexing.

The next trick is to loop though the array and add each result to the value constant. Hopefully that way it will grab everything.

Awesome! Looks great so far and yes a loop should do the trick. Keep me posted if you have any other issues getting to a full working solution

Here is is with a loop. That works and grabs all the data from any event, regardless of whether they have 3 fields or 6.

The order that the values are returned are different for different events, which seems a bit weird. The guts of it is working though.

import { appendValuesWrapper } from ‘backend/googlesheet-wrapper.jsw’ ;
import { wixEvents } from “wix-events-backend” ;

export function wixEvents_onRsvpCreated ( event ) {
const eventId = event . eventId ;

**const**  rsvp  =  event . rsvpForm . inputValues ; 

const values =;

for ( let i = 0 ; i < rsvp . length ; i ++){
values . push ( rsvp [ i ]. value );
}
console . log ( values );

**const**  res  =  appendValuesWrapper ( values ); 

}

Perfect! I see you tried to fool me by saying you weren’t a coder. This all looks like code to me :slight_smile:

As far as the order, does it mess up your insert or can you leave it as is (even if it is kind of weird)

Hi Amanda,

The order is a bit weird. Some fields are optional and that tends to break things. As the fields are then all moved down 1. Although that gives me an idea. I could insert an extra array index if required so the values import in the right order.
I’ve added some code that re-orders the array before the append. It will be interesting to see what happens when there are multiple events with slightly different forms.
The onRSVP() action doesn’t return the event name, only the event ID (which isn’t very helpful) so I’m trying to pull that in and add it as well.

It’s working well enough, but there is still some tinkering to do.

Here is what I’ve settled on

Although the loop (above) worked. It was difficult to work with the output. Depending on whether the guest RSVPs from the webpage or the mobile app there is some different behaviour.

If the guest doesn’t leave a comment then the phone number index moves, same for additional guests. The only way to guarantee that I’m getting right result is to use findIndex to return the objects index number. I can then assign the variable with the right value using rsvp[indexName].value. Some things never move, such as firstName and lastName, so I didn’t need to use findIndex.

You’ll also notice the default values for guestOne and guestTwo || " ". This is to overcome the differences between the behaviour of the Web vs App and the information that they return.

Because the comment is optional I’ve used a push (values.push(comment) to tac that on to the end of [values], if the comment is present.

This should work for any event, provided that the custom fields don’t get out of hand, then you might need to tweak it a bit.

There is probably a nicer, neater way butt hopefully someone finds this useful or at least helpful.

import { appendValuesWrapper } from ‘backend/googlesheet-wrapper.jsw’;

export function wixEvents_onRsvpCreated(event) {
const eventId = event.eventId;

const rsvp = event.rsvpForm.inputValues; 
console.log(rsvp); 
const bb = rsvp[0].value; 
const formemail = rsvp[1].value; 
const formlastName = rsvp[2].value; 
const formfirstName = rsvp[3].value; 
let addGuests = "0" 
let guestNameOne =" " 
let guestNameTwo = " " 

let addGuestIdx=rsvp.findIndex(function(ag){ 
  return ag.InputName === "additionalGuests"; 
}) 
 if(addGuestIdx>0){ 
    addGuests = rsvp[addGuestIdx].value; 
  
  } 
  let guestNamesIdx = rsvp.findIndex(function(gn){ 
    return gn.inputName ==="guestNames" 
    
  }) 
  
  if (guestNamesIdx>0){ 
    guestNameOne=rsvp[guestNamesIdx].values[0] || " "; 
    console.log(guestNameOne); 
    guestNameTwo=rsvp[guestNamesIdx].values[1] || "";  
    
  } 

let commentIdx = rsvp.findIndex(function(cm){ 
  return cm.inputName === "comment"; 
 
}) 
let phoneIdx = rsvp.findIndex(function(ph){ 
  return ph.inputName === "phone"; 
}) 

const phone = rsvp[phoneIdx].value; 

const values =[formfirstName, formlastName, formemail, phone, addGuests, bb, guestNameOne, guestNameTwo]

if(commentIdx>0){
let comment = rsvp[commentIdx].value;
values.push(comment) }

const res = appendValuesWrapper(values); 
}