Zendesk App Error & Delayed/Failed Webhook Post - javascript

I am building a Zendesk app that will post a variety of information to a webhook. Currently, I am running into two issues. The client.invoke() function says it is not a function in the console when the send email button is pressed. Additionally, sometimes the after the button is pressed, the app will successfully post to the webhook, other times it won't post at all. I cannot narrow down what is causing the discrepancies on when it posts. I'm unsure if this is related to the app I've built or an issue interacting with Zendesk.
Here is the app:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
<link href="main.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://assets.zendesk.com/apps/sdk/2.0/zaf_sdk.js"></script>
<script src="https://cdn.jsdelivr.net/handlebarsjs/4.0.8/handlebars.min.js"></script>
</head>
<body>
<script>
var client = ZAFClient.init();
client.invoke('resize', { width: '100%', height: '450px' });
client.get('ticket.brand.subdomain').then(
function(data) {
var subdomain = data['ticket.brand.subdomain'];
console.log('Zendesk Subdomain is ' + subdomain);
document.getElementById('subdomainform').value = subdomain;
}
);
client.get('ticket.organization.id').then(
function(data) {
var org_id = data['ticket.organization.id'];
console.log('Org id is ' + org_id);
document.getElementById('orgidform').value = org_id;
}
);
</script>
<form name="submissionForm">
<div class="formBox">
<label for="title">First Name</label>
<input type="text" id="firstName" placeholder="First Name"/>
</div>
<div class="formBox">
<label for="title">Last Name</label>
<input type="text" id="lastName" placeholder="Last Name"/>
</div>
<div class="formBox">
<label for="title">Email</label>
<input type="text" id="email" placeholder="Email"/>
</div>
<div class="formBox">
<select id="rescom">
<option value="residential">Residential</option>
<option value="commercial">Commercial</option>
</select>
</div>
<div class="formBox">
<button id="btn">Click to Send Email</button>
</div>
<div><p id="explain">The fields below are ready-only and required for submission. If you don't see them, please refresh the app.</p></div>
<div class="formBox">
<input type="text" id="subdomainform" readonly="readonly"/>
</div>
<div class="formBox">
<input type="text" id="orgidform" readonly="readonly"/>
</div>
</form>
<script>
let content = [];
const addDay1 = (ev)=>{
let information = {
id: Date.now(),
firstName: document.getElementById('firstName').value,
lastName: document.getElementById('lastName').value,
email: document.getElementById('email').value,
subdomain: document.getElementById('subdomainform').value,
orgid: document.getElementById('orgidform').value,
rescom: document.getElementById('rescom').value
}
content.push(content);
document.forms[0].reset();
const Url ='{PLACEHOLDER}';
$.ajax({
url: "{WEBHOOK URL}",
type: "POST",
dataType: 'json',
data: {information},
complete: function(){alert("Failure")}
});
}
document.addEventListener('DOMContentLoaded', ()=>{
document.getElementById('btn').addEventListener('click', addDay1);
});
</script>
</body>
</html>
What am I missing? Appreciate any and all help that can be provided.

This was solved my a community manager from Zendesk. See post below:
Make sure ZAFClient is fully registered before attempting to do
subsequent ZAFClient methods. Something like:
client.on('app.registered', e => {
client.get('ticket.brand.subdomain').then(
function(data) {
var subdomain = data['ticket.brand.subdomain'];
console.log('Zendesk Subdomain is ' + subdomain);
document.getElementById('subdomainform').value = subdomain;
}
);
client.get('ticket.organization').then(
function(data) {
var org_id = data['ticket.organization.id'];
console.log('Org id is ' + org_id);
document.getElementById('orgidform').value = org_id;
}
);
}) The "not a function in the console" error is caused from the app's HTML page being resubmitted again when you click the button. In
Zendesk Apps framework, the connection from the app (using
ZAFClient.init()) to the main agent window is done through parameters
that are passed to the app when the framework first loads it. You can
see this in your browser's Network tab if you look for something like
"iframe.html?origin=https%3A%2F%2Fyour_subdomain.zendesk.com&app_guid=ff7133010-abff-4f1c-a7bf-ff7133fff7133"
-- the origin and app_guid params are needed to make the connection. When you resubmit the page, those parameters no longer are passed on
the new page reload and the new call to ZAFClient.init() doesn't
successfully initialize. Thus leading the error when the now invalid
'client' object is attempting to be used to call 'invoke'. You have to
treat these app pages like single-page apps.
Phew! All that said -- you can still use HTML functionality,
just don't have it resubmit the entire page when the button is
pressed. You can do this by adding type="button" to the button tag.
Click to Send Email
See also: HTML button to NOT submit form
Hope this gets you on your way!

Related

Sender email address not included in EmailJS

When I submit the form, I receive the user's message. However, I don't know who it's from. I don't receive their email address, nor their name. I tried looking at their documentation but wasn't able to get past this. Any help will be appreciated. Thank you!
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/emailjs-com#2/dist/email.min.js"></script>
<script type="text/javascript">
(function () {
// https://dashboard.emailjs.com/admin/integration
emailjs.init("MY_USER_ID");
})();
</script>
<script type="text/javascript">
window.onload = function () {document.getElementById("contact-form").addEventListener("submit", function (event) {
event.preventDefault();
// generate a five digit number for the contact_number variable
this.contact_number.value = Math.random() * 100000 | 0;
// these IDs from the previous steps
emailjs.sendForm("MY_SERVICE_ID", "MY_TEMPLATE_ID", this).then(
function () {
console.log("SUCCESS!");
},
function (error) {
console.log("FAILED...", error);
}
);
});};
</script>
</head>
<body>
<form id="contact-form">
<input type="hidden" name="contact_number" />
<label>Name</label>
<input type="text" name="user_name" />
<label>Email</label>
<input type="email" name="user_email" />
<label>Message</label>
<textarea name="message"></textarea>
<input type="submit" value="Send" />
</form>
</body>
{{message}} is the only thing you can receive from the form for now because your template has two dynamic variables {{from_name}}, {{message}} but you are sending contact_number, user_name, user_email and message which is written in name attributes for each inputs in the form.
You have to match names of template variables and names of form inputs. If you want to maintain your form, you have to modify your template like
from You got a new email from {{from_name}}: {{message}}
to You got a new email from {{user_name}}({{user_email}}): {{message}}
You can also use built-in variables without getting input but I'll leave them because you need to read the documentation for good.

Javascript doesnt recognize anything from html (spring boot)

This is my first time with spring boot. So, I have a simple index.html page, i go to it just through localhost:8080. I have some console.log() in my js under the html and they dont log a single thing. The api does work though, i tried it in postman and there is no problem. But it seems that the js doesnt recognize anything of the html. This is what the console.log() prints in the console:
As you can see they are empty. See my structure and my code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Page</title>
</head>
<body>
<form id="loginform">
<div class="form-group">
<label for="Username">Username</label>
<input name="username" class="form-control" type="text" placeholder="Enter username" required>
</div>
<div class="form-group">
<label for="Password">Password</label>
<input name="password" class="form-control" type="password" placeholder="Password" required>
</div>
<button id="login">Login</button>
</form>
<script>
function login() {
var formData = new FormData(document.querySelector("#loginform"));
var encData = new URLSearchParams(formData.entries());
console.log(formData);
console.log(encData);
console.log(document.querySelector("#loginform"));
fetch("/authenticate", {method: 'POST', body: encData})
.then(function (response) {
if (response.ok) {
window.location.href = "/lingogame.html";
return response.json();
} else {
alert("Invalid Username or password");
}
})
.then(myJson => window.sessionStorage.setItem("myJWT", myJson.JWT))
.catch(error => console.log(error));
}
var loginButton = document.querySelector("#login")
if (loginButton) {
loginButton.addEventListener("click", login);
}
</script>
</body>
</html>
The problem may result from CSRF support of Spring Security. Check CSRF support is enabled or disabled, by default it is enabled by Spring Security. If enabled you must be send csrf_token with "X-CSRF-TOKEN" header with csrfToken value, otherwise it is not required.

Put method with Ajax (the script isn't triggered)

I am implementing Put method with Ajax:
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#submitPut').click( function () {
console.log("click");
var sendName = $('#name').val();
var sendDescription = $('#description').val();
$.ajax({
url: '/musicalstyle', //Your api url
type: 'PUT', //type is any HTTP method
data: {
name: sendName,
description: sendDescription,
}, //Data as js object
success: function () {
}
})
;
});
});
</script>
</head>
<body>
<form>
<label for="name">Nombre</label>
<input type="text" id="name" />
<label for="description">DescripciĆ³n</label>
<input type="text" name="description" id="description"/>
<input id="submitPut" type="button" value="SubmitPut">
</form>
</body>
</html>
This form is working fine but when introduce it on real environment the script isn't called (my view in production environment is using Thymeleaf and Boostrap). It's like <button class="btn btn-primary" id="submitPut" type="button">Actualizar</button> isn't triggering the submitPut function.
Here form of production environment:
<form>
<div class="form-group row">
<label for="name" class="col-sm-2 col-form-label">Nombre</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="name">
</div>
</div>
<div class="form-group row">
<label for="description" class="col-sm-2 col-form-label">DescripciĆ³n</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="description">
</div>
</div>
<br>
<button class="btn btn-primary" id="submitPut" type="button">Actualizar</button>
</form>
How can I force to button call ajax function?
Thanks,
Your id of input is submit while you called onclick function on query, submitPut.
So,
<input id="submitPut" type="button" value="SubmitDelete"/>
#Biplove I have eddited my comment. Id of input is equal than name of onclick function.
After import JQuery with
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>window.jQuery || document.write('<script src="../js/jquery.slim.min.js"> <\/script>')</script><script src="../js/bootstrap.bundle.js"></script></body>
Ajax is executed.
My method Put in Controller should redirect to another view and seems to be redirecting. The Spring logs show:
2020-05-21 16:04:15.367 DEBUG 552 --- [nio-8182-exec-9] o.s.web.servlet.DispatcherServlet : PUT "/musicalstyle", parameters={masked}
2020-05-21 16:04:15.368 DEBUG 552 --- [nio-8182-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.musicnet.springboot.controller.SystemAdministratorController#updateStyle(Style, Model)
2020-05-21 16:04:15.558 DEBUG 552 --- [nio-8182-exec-9] o.s.w.s.v.ContentNegotiatingViewResolver : Selected '*/*' given [*/*]
2020-05-21 16:04:15.632 DEBUG 552 --- [nio-8182-exec-9] o.s.web.servlet.DispatcherServlet : Completed 200 OK
Here the style is updated so put method is working fine but the view isn't showed on browser. I suspect that Spring doesn't have any problem in order to redirect view, the problem is that ajax script isn't redirecting to the returned view.
How can I modify the ajax script to process the view returned by Spring?
Edit
In fact, I get the redirect putting in ajax script:
success: function () {
window.location.reload();
}

Use JavaScript function return statement to open a new page

I'm trying to build a webpage that uses Adyen Encryption for Credit Cards. I have a form in which I ask for Credit Card data, and when the user presses submit it calls the JavaScript function. Now I want to redirect that page into another one that shows the value returned with the JavaScript function. I don't know if there is a simple way to do it.
The index.html code is the following:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://my.tidal.com/assets/javascripts/chosen.jquery.min.js"></script>
<script src="https://my.tidal.com/assets/javascripts/payment/adyen.js"></script>
<script src="https://my.tidal.com/assets/javascripts/payment/brazil-validate.js"></script>
<script>
function test(name, card, expMonth, expYear, cvc) {
var adyenPubKey = "10001|DCDD8889161843FF0CC8D0D904168E5B4ED5B529C685413F4F8087584F507C5158551B521B9226F7C24CAE3F9FF4B5721F39D23F1E706D3F27A4680C5A2F2B4714C1530BC1EE410B503F9487AF0F047004F4F5DA2614AF3955C25C36BA3881907063742C7687D8516176AD67570A5F0DFA682AC2B7DAD055CE00A68283B77C731E35F004A1D3FE72CE3AE52C3FA8A0E8A63C8D903E00B37DA6760C8C104332FEDD762D4BA8BDB9781C5DDF7E94E0D81529A7C01A2094E8240FB3C24C1E687AD2304A4346EBD82B5DF983806F57B2E0865143C8FEE568A6915A71044A707693C51112B80E2EC665194FD1F8FE362EF1479CCF938DDACFE9BEA56B530E81D567B3";
var options = {};
var cseInstance = adyen.encrypt.createEncryption(adyenPubKey, options);
var generationTime = new Date().toISOString();
var cardData = {
number : card,
cvc : cvc,
holderName : name,
expiryMonth : expMonth,
expiryYear : (expYear.length === 2) ? '20' + expYear : expYear,
generationtime : generationTime
};
return cseInstance.encrypt(cardData);
}
</script>
</head>
<body>
<form onsubmit="return test(document.getElementById('holderName').value,document.getElementById('number').value,document.getElementById('expiryMonth').value,document.getElementById('expiryYear').value,document.getElementById('cvc').value)" method="post">
<input type="text" name="holderName" id="holderName" required>
<br><br>
<input type="text" id="number" pattern="[0-9]{16}" required>
<br><br>
<input type="text" id="expiryMonth" pattern="[0-9]{2}" required>
<input type="text" id="expiryYear" pattern="[0-9]{4}" required>
<br><br>
<input type="text" id="cvc" pattern="[0-9]{3}" required>
<br><br>
<input type="submit" value="Enviar">
</form>
</body>
</html>
I'm not sure about your particular use case - but if you want to redirect to a new page (or request a new page from the server) and have any information carry forward to the new page - you have to send the data to the server. The server can then send back only the particular information you want to show. (Just make sure to use HTTPS considering the nature of the data).
If this is a single-page application then you could simply hide the form and load the next 'screen' on the current page. This way you could re-use the in-memory result from your form. Just store it in an accessibly-scoped variable.
Another option may be to use local storage, but considering this is sensitive credit card information I would advise against this - encrypted or not.

How do I manually test JavaScript?

I'm trying to learn javascript by making a simple price checking website using the Best Buy products API.
How do I "run" the javascript? My form takes in a product ID number (the SKU) and sends it to validateSKU() on submit. The function processData(data) searches for the product using the SKU.
Nothing is happening when I test the site, and any help would be great; thanks!
<!DOCTYPE html>
<html>
<head>
<title>Learn JavaScript</title>
</head>
<body>
<form id="bestBuyForm" name="bestBuyForm" onsubmit="validateSKU()">
<input id="SKU" name="SKU" required="" type="text">
<label for="SKU">SKU</label>
<input id="email" name="email" type="email">
<label for="email">Email</label>
<input class="button" id="submit" name="submit" type="submit">
</form>
<script>
function validateSKU() {
var SKU = document.forms["bestBuyForm"]["SKU"].value;
var bby = require('bestbuy')('process.env.BBY_API_KEY');
var search = bby.products('sku=' + SKU);
search.then(processData);
}
function processData(data) {
if (!data.total) {
console.log('No products found');
} else {
var product = data.products[0];
console.log('Name:', product.name);
console.log('Price:', product.salePrice);
}
}
</script>
</body>
</html>
Use web console to see what does happen and read about the console API.
Try to bind validateSKU with HTML element addEventListener method. Also you should prevent default form behaviour which cause page reloading on submit. Call event.preventDefault().
Working example code:
<html>
<form id="someForm">
...
<button type="submit">Submit</submit>
</form>
<script>
function validateSKU(event) {
console.log('IT works');
event.preventDefault();
// ...here your code
}
var form = document.getElementById('someForm');
form.addEventListener('submit', validateSKU, false);
</script>
</html>

Categories

Resources