elementor form google sheet

엘리멘토 엘리멘터 엘레멘토 엘레멘터 폼 구글 시트 연동 방법

// Change to true to enable email notifications
let emailNotification = false;
let emailAddress = "Change_to_your_Email";



// DO NOT EDIT THESE NEXT PARAMS
let isNewSheet = false;
let postedData = [];
const EXCLUDE_PROPERTY = 'e_gs_exclude';
const ORDER_PROPERTY = 'e_gs_order';
const SHEET_NAME_PROPERTY = 'e_gs_SheetName';

/**
 * this is a function that fires when the webapp receives a GET request
 * Not used but required.
 */
function doGet( e ) {
  return HtmlService.createHtmlOutput( "Yepp this is the webhook URL, request received" );
}

// Webhook Receiver - triggered with form webhook to published App URL.
function doPost( e ) {
  let params = JSON.stringify( e.parameter );
  params = JSON.parse( params );
  postedData = params;
  insertToSheet( params );

  // HTTP Response
  return HtmlService.createHtmlOutput( "post request received" );
}

/**
 * flattenObject
 * Flattens a nested object for easier use with a spreadsheet
 * @param ob
 * @returns {{}}
 */
const flattenObject = ( ob ) => {
  let toReturn = {};
  for ( let i in ob ) {
    if ( ! ob.hasOwnProperty( i ) ) {
      continue;
    }

    if ( ( typeof ob[ i ] ) !== 'object' ) {
      toReturn[ i ] = ob[ i ];
      continue;
    }

    let flatObject = flattenObject( ob[ i ] );
    for ( let x in flatObject ) {
      if ( ! flatObject.hasOwnProperty( x ) ) {
        continue;
      }
      toReturn[ i + '.' + x ] = flatObject[ x ];
    }
  }
  return toReturn;
}

/**
 * getHeaders
 * normalize headers
 * @param formSheet
 * @param keys
 * @returns {*[]}
 */
const getHeaders = ( formSheet, keys ) => {
  let headers = [];

  // retrieve existing headers
  if ( ! isNewSheet ) {
    headers = formSheet.getRange( 1, 1, 1, formSheet.getLastColumn() ).getValues()[0];
  }
  const newHeaders = keys.filter( h => ! headers.includes( h ) );
  headers = [ ...headers, ...newHeaders ];
  // maybe set order
  headers = getColumnsOrder( headers );
  // maybe exclude headers
  headers = excludeColumns( headers );
  // filter out control columns
  headers = headers.filter( header => ! [ EXCLUDE_PROPERTY, ORDER_PROPERTY, SHEET_NAME_PROPERTY ].includes( header ) );
  return headers;
};

/**
 * getValues
 * normalize values
 * @param headers
 * @param flat
 * @returns {*[]}
 */
const getValues = ( headers, flat ) => {
  const values = [];
  // push values based on headers
  headers.forEach( ( h ) => values.push( flat[ h ] ) );
  return values;
}

/**
 * insertRowData
 * inserts values to a given sheet at a given row
 * @param sheet
 * @param row
 * @param values
 * @param bold
 */
const insertRowData = ( sheet, row, values, bold = false ) => {
  const currentRow = sheet.getRange( row, 1, 1, values.length );
  currentRow.setValues( [ values ] )
    .setFontWeight( bold ? "bold" : "normal" )
    .setHorizontalAlignment( "center" );
}

/**
 * setHeaders
 * Insert headers
 * @param sheet
 * @param values
 */
const setHeaders = ( sheet, values ) => insertRowData( sheet, 1, values, true );

/**
 * setValues
 * Insert Data into Sheet
 * @param sheet
 * @param values
 */
const setValues = ( sheet, values ) => {
  const lastRow = Math.max( sheet.getLastRow(), 1 );
  sheet.insertRowAfter( lastRow );
  insertRowData( sheet, lastRow + 1, values );
}

/**
 * getFormSheet
 * Find or create sheet for form
 * @param sheetName
 * @returns Sheet
 */
const getFormSheet = ( sheetName ) => {
  const activeSheet = SpreadsheetApp.getActiveSpreadsheet();

  // create sheet if needed
  if ( activeSheet.getSheetByName( sheetName ) == null ) {
    const formSheet = activeSheet.insertSheet();
    formSheet.setName( sheetName );
    isNewSheet = true;
  }
  return activeSheet.getSheetByName( sheetName );
}

/**
 * insertToSheet
 * magic function where it all happens
 * @param data
 */
const insertToSheet = ( data ) => {
  const flat = flattenObject( data ),
    keys = Object.keys( flat ),
    formSheet = getFormSheet( getSheetName( data ) ),
    headers = getHeaders( formSheet, keys ),
    values = getValues( headers, flat );

  setHeaders( formSheet, headers );
  setValues( formSheet, values );

  if ( emailNotification ) {
    sendNotification( data, getSheetURL() );
  }
}

/**
 * getSheetName
 * get sheet name based on form field named "e_gs_SheetName" if exists or used form name
 * @param data
 * @returns string
 */
const getSheetName = ( data ) => data[SHEET_NAME_PROPERTY] || data["form_name"];

/**
 * getSheetURL
 * get sheet url as string
 * @returns string
 */
const getSheetURL = () => SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getUrl();

/**
 * stringToArray
 * split and trim comma seperated string to array
 * @param str
 * @returns {*}
 */
const stringToArray = ( str ) => str.split( "," ).map( el => el.trim() );

/**
 * getColumnsOrder
 * used to set the columns order, set this by adding a form field (hidden) named "e_gs_order"
 * and set its value to the names of the columns you want to seperated by comma in the order you want,
 * any other colum not in that field will be added after
 * @param data
 * @param headers
 * @returns {*}
 */
const getColumnsOrder = ( headers ) => {
  if ( ! postedData[ORDER_PROPERTY] ) {
    return headers;
  }
  let sortingArr = stringToArray( postedData[ORDER_PROPERTY] );
  // filter out non existing headers
  sortingArr = sortingArr.filter( h => headers.includes( h ) );
  // filterout sorted headers
  headers = headers.filter( h => ! sortingArr.includes( h ) );

  return [ ...sortingArr, ...headers ];
}
/**
 * excludeColumns
 * used to exclude columns, set this by adding a form field (hidden) named "e_gs_exclude"
 * and set its value to the names of the columns you want to exclude seperated by comma
 * @param data
 * @param headers
 * @returns {*}
 */
const excludeColumns = ( headers ) => {
  if ( ! postedData[EXCLUDE_PROPERTY] ) {
    return headers;
  }
  const columnsToExclude = stringToArray( postedData[EXCLUDE_PROPERTY] );
  return headers.filter( header => ! columnsToExclude.includes( header ) );
}

/**
 * sendNotification
 * send email notification if enabled
 * @param data
 * @param url
 */
const sendNotification = ( data, url ) => {
  MailApp.sendEmail(
    emailAddress,
    "A new Elementor Pro Forms submission has been inserted to your sheet", // mail subject
    `A new submission has been received via ${data['form_name']} form and inserted into your Google sheet at: ${url}`, //mail body
    {
      name: 'Automatic Emailer Script'
    }
  );
};

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤