0

Objective:

build a prechat form in google apps scripts so this can be used in a google site as a webapp so that it would take a user's name, lastname, phone and email and pass those parameters to the freshchat javascript snippet, so when the chat is initiated, the user's info can be seen in the freshchat tool.

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <title>Chat form</title>
  </head>
  <body>
    <h1>Chatea Con Nosotros</h1>
    <form>
      <input type="text" id="fname" placeholder="Nombre">
      <input type="text" id="lname" placeholder="Apellido">
      <input type="text" id="email" placeholder="Email">
      <input type="text" id="phone" placeholder="Teléfono">
      <input type="button" value="Iniciar Chat" id="btnStartChat"/> 
    </form>
    <?!= include("index_js"); ?> 
  </body>
</html>

index_js

<script>
  //global variables
  var ffname = '';
  var flname= '';
  var femail = '';
  var fphone = '';

  //freshchat code starts ------------------------
  function initFreshChat() {
    window.fcWidget.init({
      token: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
      host: "https://wchat.freshchat.com",
      open: true,
      externalId: "john.doe1987",     // user’s id unique to your system
      firstName: ffname,              // user’s first name
      lastName: flname,                // user’s last name
      email: femail,    // user’s email address
      phone: fphone,            // phone number without country code
      phoneCountryCode: "+1"          // phone’s country code
    });
  }
  function initialize(i,t){
    var e;i.getElementById(t)?initFreshChat():((e=i.createElement("script")).id=t,e. async=!0,e.src="https://wchat.freshchat.com/js/widget.js",e.onload=initFreshChat,i.head.appendChild(e))
  }function initiateCall(){
    initialize(document,"Freshdesk Messaging-js-sdk")
  }
//freshchat code ends ---------------------  

  document.getElementById("btnStartChat").addEventListener("click", getFormValues);
  
  function getFormValues(){
    try{
      ffname = document.getElementById("fname").value;
      flname = document.getElementById("lname").value;
      femail = document.getElementById("email").value;
      fphone = document.getElementById("phone").value;
      window.addEventListener("load", initiateCall());
    }
    catch(e){
      console.log('error here: ' + e.message);
    }
  }

</script>

code.gs

function doGet(){
  var page = HtmlService.createTemplateFromFile('index');
  return page.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL).setHeight(400).setWidth(100);
  //return page.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
}

//funtion to append other files to htmlservice file
function include(filename){
  //return the content of an html file
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

Problem:

the problem is that I'm not sure how to get the freshchat function to be initiated only once I have populated the global variables with input data from the form. if I manually enter data within the window.fcWidget.init({...}) area it works nicely but I'm not sure how to do it programatically upon a button click.

sources consulted:

Thank you.

Francisco Cortes
  • 1,121
  • 10
  • 19
  • 1
    I think that you should include the server side code in order to have a [mcve]. – Rubén Jan 26 '22 at 17:35
  • 1
    Besides the missing server side code there are other parts missing like the use of preventDefault for the form (see https://stackoverflow.com/q/53825069/1595451 ) and debugging details (i.e. console messages, executions pages logs, ...) – Rubén Jan 26 '22 at 17:49
  • Have you tried just removing `initiateCall` function? – TheMaster Jan 26 '22 at 23:17
  • added the code.gs as requested there are no javascript errors thrown up in the console the initiatecall function is code from freshchat how would I call that function? – Francisco Cortes Jan 27 '22 at 12:25

2 Answers2

1

I'm assuming most of this code is verbatim from freshchat? I don't have access to a freshchat account but the connection is triggered on this line:

window.addEventListener?window.addEventListener("load",initiateCall,!1):window.attachEvent("load",initiateCall,!1);

So what is happening here is basically an if statement (a ternary if https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) so if a listener can be added to the window, then add the event listener, and if not, attach the event to the window (this is probably a way to accommodate different types and version of browsers, and may not be needed for more modern browsers). More info in this: What is the difference between addEventListener and attachEvent?

So if you want to wait until the user has entered details, you will need to move this to where you are checking for the existence of those details:

function getFormValues(){
    try{
      ffname = document.getElementById("fname").value;
      flname = document.getElementById("lname").value;
      femail = document.getElementById("email").value;
      fphone = document.getElementById("phone").value;
      window.addEventListener("load", initiateCall());
    }
    catch(e){
      console.log('error here: ' + e.message);
    }
  }

You don't really need the try/catch for getting the form info, but you should check that it is valid input (i.e. that an email address is formatted correctly, and that a name is given and not left blank).

You might also want to disable the button after the user has pressed it once, and re-enable it if there is an error, to prevent excessive calls to the API (which you might have to pay for). Another way to prevent this is to provide the user with an animation to show that something is happening while they wait for the chat to initiate, but these are out of the scope of this question.

Katharine Osborne
  • 6,571
  • 6
  • 32
  • 61
  • 1
    It's very likely that `!= include("index_js"); ?>` loads the second code snippet. This pattern is very common in Google Apps Script web apps. – Rubén Jan 26 '22 at 17:33
  • Looks like you are right. It took awhile but I found some documentation: https://developers.google.com/apps-script/guides/html/best-practices#page.html I missed the google-apps-script tag while looking at this post, and was unaware such a thing existed until today. I'll edit my answer. – Katharine Osborne Jan 26 '22 at 18:10
  • Thanks for you reply. I think that your answer is helpful but I'm afraid that the OP code have other issues (I already added couple of comments to the question). – Rubén Jan 26 '22 at 20:49
  • Hi @KatharineOsborne thank you. I made the changes you proposed (as seen in the last edit of my post) and now the chat bubble only loads after clicking on the button, but the variables I want to pass in are still not in the freshchat applet – Francisco Cortes Jan 27 '22 at 12:37
  • @KatharineOsborne I added comments to show what code was provided by freschchat – Francisco Cortes Jan 27 '22 at 15:08
  • 1
    @KatharineOsborne thank you so much also for the other suggestions, I will have some of those implemented if I'm able to get this question and issue sorted out. cheers :) – Francisco Cortes Jan 27 '22 at 19:06
1

I just followed the instructions of the first link and customized the labels. It it works within a Google Sites embed <> box.

One thing that you might be missing is that this kind of widgets have several security layers, so it might be possible that using custom HTML forms is not supported (the referred resources doesn't include instructions to use them).

Code.gs

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('index');
}

index.html

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
</head>
<script src="https://snippets.freshchat.com/js/fc-pre-chat-form-v2.min.js"></script>
<script>
  var preChatTemplate = {
    //Form header color and Submit button color.
    mainbgColor: '#0aa4db',
    //Form Header Text and Submit button text color.
    maintxColor: '#fff',
    //Chat Form Title
    heading: 'GadgetGod',
    //Chat form Welcome Message
    textBanner: 'We can\'t wait to talk to you. But first, please take a couple of moments to tell us a bit about yourself.',
    //Submit Button Label.
    SubmitLabel: 'Start Chat',
    //Fields List - Maximum is 5
    //All the values are mandatory and the script will not work if not available.
    fields : {
      field1 : {
        //Type can be either text or title
        type: "title",
        //Label for Field Title, can be in any language
        label: "Nombre",
        //Field ID for Title
        fieldId: "title",
        //Required "yes" or "no"
        required: "yes",
        //Error text to be displayed
        error: "Please Enter a valid Title"
      },
      field2 : {
        //Type for Name - Do not Change
        type: "name",
        //Label for Field Name, can be in any language
        label: "Apellido",
        //Default - Field ID for Name - Do Not Change
        fieldId: "name",
        //Required "yes" or "no"
        required: "yes",
        //Error text to be displayed
        error: "Please Enter a valid name"
      },
      field3 : {
        //Type for Email - Do Not Change
        type: "email",
        //Label for Field Email, can be in any language
        label: "Email",
        //Default - Field ID for Email - Do Not Change
        fieldId: "email",
        //Required "yes" or "no"
        required: "yes",
        //Error text to be displayed
        error: "Please Enter a valid Email"
      },
      field4 : {
        //Type for Phone - Do Not Change
        type: "phone",
        //Label for Field Phone, can be in any language
        label: "Teléfono",
        //Default - Field ID for Phone - Do Not Change
        fieldId: "phone",
        //Required "yes" or "no"
        required: "yes",
        //Error text to be displayed
        error: "Please Enter a valid Phone Number"
      },
      field5 : {
        //Type for Dropdown
        type: "dropdown",
        //Label for Field Dropdown, can be in any language
        label: "Plan",
        //Field ID for Plan Dropdown
        fieldId: "plan",
        //Required "yes" or "no"
        required: "yes",
        //Error text to be displayed
        error: "Please select an option",
        //Options for the Dropdown field
        options: ['Sprout','Blossom','Garden','Estate','Forest']
      }
    }
  };
  window.fcSettings = {
    token: "WEB_CHAT_TOKEN",
    host: "https://wchat.freshchat.com",
    config: {
      cssNames: {
        //The below element is mandatory. Please add any custom class or leave the default.
        widget: 'custom_fc_frame',
        //The below element is mandatory. Please add any custom class or leave the default.
        expanded: 'custom_fc_expanded'
      }
    },
    onInit: function() {
      console.log('widget init');
      fcPreChatform.fcWidgetInit(preChatTemplate);
    }
  };
</script>
<script src="https://wchat.freshchat.com/js/widget.js" async></script>
<body>
  
</body>

</html>
Rubén
  • 34,714
  • 9
  • 70
  • 166
  • 1
    Hey Rubén I had tried that option but for some reason it was not working as expected, I guess you need all the fields, regardless. nevertheless, I tried again today as you suggested and i got it working with the embededed html snippet option within google sites, no need to do it as a webapp. that's great.. I was really hoping to use a custom prechat but this solution ended up working at the end. Thank you so much! – Francisco Cortes Jan 28 '22 at 12:37
  • According to the code comments it's possible to have from 1 to 5 fields but all the values (type, label, fieldId, etc.) are required. – Rubén Jan 28 '22 at 17:21