How to automatically change agent status on Amazon Connect? - amazon-connect

I need step by step directions on how to load the CCP into a webpage and use the streams API. I would need the javascript to turn the agent from "missed" to "available" after 25 seconds.
Currently we have to manually update staus which doesn't make sense for our use case.
I saw on the Amazon Connect forum someone made mention of a way to automatically change the status of from Missed to Available.
If you're embedding the CCP and using the Streams API, you can check
the agent status on refresh, and if it's in Missed Call, set it to
Available. I have this set to happen after 10 seconds.

For an embedded CCP you can do this using Stream API. You can subscribe to the agent refresh status, and do it there.
connect.agent(function (agent) {
logInfoMsg("Subscribing to events for agent " + agent.getName());
logInfoMsg("Agent is currently in status of " + agent.getStatus().name);
agent.onRefresh(handleAgentRefresh);
}
function handleAgentRefresh(agent) {
var status = agent.getStatus().name;
logInfoEvent("[agent.onRefresh] Agent data refreshed. Agent status is " + status);
//if status == Missed Call,
// set it to Available after 25 seconds."
//For example -but maybe this is not the best approach
if (status == "Missed") { //PLEASE review if "Missed" and "Availble" are proper codes
setTimeout(function () {
agent.setState("Available", {
success: function () {
logInfoEvent(" Agent is now Available");
},
failure: function (err) {
logInfoEvent("Couldn't change Agent status to Available. Maybe already in another call?");
}
});
;
}, 25000);
}
}
If you also need to know how to embed the CCP in a website, you can just do something like this
<!DOCTYPE html>
<meta charset="UTF-8">
<html>
<head>
<script type="text/javascript" src="amazon-connect-1.4.js"></script>
</head>
<!-- Add the call to init() as an onload so it will only run once the page is loaded -->
<body onload="init()">
<div id=containerDiv style="width: 400px;height: 800px;"></div>
<script type="text/javascript">
var instanceURL = "https://my-instance-domain.awsapps.com/connect/ccp-v2/";
// initialise the streams api
function init() {
// initialize the ccp
connect.core.initCCP(containerDiv, {
ccpUrl: instanceURL, // REQUIRED
loginPopup: true, // optional, defaults to `true`
region: "eu-central-1", // REQUIRED for `CHAT`, optional otherwise
softphone: { // optional
allowFramedSoftphone: true, // optional
disableRingtone: false, // optional
ringtoneUrl: "./ringtone.mp3" // optional
}
});
}
</script>
</body>
</html>
You can see the documentation for StreamsAPI here https://github.com/amazon-connect/amazon-connect-streams/blob/master/Documentation.md

Related

SignalR usage and potential issues of getting connectionID in the masterpage

Recently, we have introduced SignalR into our project and hoping use its features. Currently SignalR is used only for showing progress bar on a couple of webpages on the client side for long running processes on the server. Could anyone help me with implementation of the SignalR and its ramifications?
.Net Framework Standard MVC application at at a time more than 3000 users connected to the webapp in Microsoft Azure hosted site.
SignalR is loaded and a connectionID is ($.connection.hub.start().done(function ().....) acquired in the _Layout.chtml. This is because, if the user may open different features in the webapp on different tabs and the these tabs may happen to have progress bars in it. So a unique connection ID on each Tab opened will help the SignalR to process the response.
I suspect a potential problem here for the page load performance and other unknown issues can be triggered because the layout page is opening a new connectionID each time the pages are loaded or refreshed.
Any other standard solution welcome if this is problematic.
Thanks for your help.
_Layout.chtml
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/ProgressBarHelper.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.signalR-2.4.2.min.js" type="text/javascript"></script>
<script src="/signalr/hubs"></script>
<script type="text/javascript">
var connectionId = null;
$(function () {
// Reference the auto-generated proxy for the hub.
var progress = $.connection.progressHub;
//console.log(progress);
// Create a function that the hub can call back to display messages.
progress.client.AddProgress = function (message, percentage, reportmsg, showProgressReport, autoClose) {
if (CommonProgressBar.IsVisible() == false)
popupProgressBar.Show();
CommonProgressBar.SetPosition(percentage);
$('#popupProgressMessageText').text(message); //+ 'for ' + connectionId);
if (percentage == "100") {
if (autoClose == true) {
popupProgressReportText.SetText("Report");
popupProgressBar.Hide();
}
else {
popupProgressCloseButton.SetEnabled(true);
}
}
else {
if (autoClose == true) {
popupProgressCloseButton.SetEnabled(false);
}
}
var rptmsg = popupProgressReportText.GetText(); // $('#popupProgressReportText').GetText();
if (reportmsg != null && reportmsg != "") {
if (rptmsg != null && rptmsg != "") {
popupProgressReportText.SetText(rptmsg + "\r\n" + reportmsg);
}
else {
popupProgressReportText.SetText(rptmsg);
}
}
};
$.connection.hub.start().done(function () {
connectionId = $.connection.hub.id;
console.log(connectionId);
});
});
</script>

Alert when code is running background in google sheet

Working with Google App script and Javascript, I managed to retrieve xls Gmail attachments, convert it to google sheets, send an warning email to some recipients, insert an event with the Google Drive folder link when a new attachment is added to it, and at the end I managed with a standalone script to import some of the data coming from such xls file converted to a main Google Sheet where one operator is working h24 ( updating some data to be forwarded later on and during the service itself).
The standalone script run every 30 minutes to check incoming mail ( the schedule for the next day or days), and when it find it, it execute the code.
The lock service is not available on standalone scripts up to now, so I cannot lock the document, so I wish to display a message to the user that the script is about to run and not edit anything, since other scripts bounded to the Spreadsheet are using the Lock service, and so the result could be quite disappointing. I searched info regarding this "alert", but I cannot find a clue about it.
Could you address me somewhere?
I could add a menu function instead of a standalone script, and the operator could select "Import data" and that's it, but I wish to automate the operation in background.
You could use the HTML Service. I don't know much about it myself but I think the following may do what you need:
At the top of you .gs file:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var htmlApp = HtmlService.createTemplateFromFile("html");
var status = "Loading....."
htmlApp.data = status;
ss.show(htmlApp.evaluate()
.setWidth(300)
.setHeight(200));
At the end (just before the last brace):
var status = "Finished!"
htmlApp.data = status;
ss.show(htmlApp.evaluate()
.setWidth(300)
.setHeight(200));
In a new HTML script file named 'html':
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>Updating..</h2>
<p id="status">(innerHTML).</p>
<div id="imageico"></div>
<script>
var imageContainer = document.getElementById("imageico");
if (<?= data ?> != "Finished!"){
document.getElementById("status").innerHTML = "Running script, please wait..";
} else {
document.getElementById("status").innerHTML = "Finished! You can now close the window.";
closeBtn();
}
function closeBtn(){
var button = document.createElement("INPUT");
button.setAttribute("type", "button");
button.setAttribute("value", "Close");
button.setAttribute("onclick", "closeWindow();");
imageContainer.appendChild(button);
}
function closeWindow(){
google.script.host.close();
}
</script>
</body>
</html>
EDITED Based on comments
In your .gs file:
function test() {
htmlApp("","");
/*
*
* Put your code in here....
*
*/
Utilities.sleep(3000); // change this value to show the "Running script, please wait.." HTML window for longer time.
htmlApp("Finished!","");
Utilities.sleep(3000); // change this value to show the "Finished! This window will close automatically. HTML window for longer time.
htmlApp("","close"); // Automatically closes the HTML window.
}
function htmlApp (status,close) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var htmlApp = HtmlService.createTemplateFromFile("html");
htmlApp.data = status;
htmlApp.close = close;
ss.show(htmlApp.evaluate()
.setWidth(300)
.setHeight(200));
}
In the HTML script file named 'html':
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>Updating..</h2>
<p id="status">(innerHTML).</p>
<div id="imageico"></div>
<script>
var imageContainer = document.getElementById("imageico");
if (<?= data ?> != "Finished!"){
document.getElementById("status").innerHTML = "Running script, please wait..";
} else {
document.getElementById("status").innerHTML = "Finished! This window will close automatically.";
}
if (<?= close ?> == "close"){
google.script.host.close();
}
</script>
</body>
</html>
Have a look at this Sample Spreadsheet.
I don't see any methods or sample scripts regarding your concern. But this documentation about alert might help. It will open a dialog box in the user's editor with the given message and an "OK" button. However, this method suspends the server-side script while the dialog is open and the script will resume after the user dismisses the dialog.
You may also execute alert dialogs before running your script.
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show alert', 'showAlert')
.addToUi();
}
function showAlert() {
var ui = SpreadsheetApp.getUi(); // Same variations.
var result = ui.alert(
'Please confirm',
'Are you sure you want to continue?',
ui.ButtonSet.YES_NO);
// Process the user's response.
if (result == ui.Button.YES) {
// User clicked "Yes".
ui.alert('Confirmation received.');
} else {
// User clicked "No" or X in the title bar.
ui.alert('Permission denied.');
}
}

How to read/intercept JavaScript on the page before it is executed?

I would like to intercept location.reload(); via a Firefox API or by reading the JS on the page (remote & embedded) before it is loaded/executed or by any other means possible.
Example:
<head>
<script>
window.setTimeout(function() { location.reload(); }, 10000);
</script>
</head>
I have tried beforescriptexecute event listener (via GreaseMonkey & // #run-at document-start) but it is fired AFTER above is executed.
Update:
beforescriptexecute works nicely on REMOTE scripts since the event beforescriptexecute is fired before making the request (but then on the script src and not script content). It is different if the script is within normal script tag (and not remote), as per the example given. The beforescriptexecute fires and the script content can be rewritten but by then the window.setTimeout() has already fired and it is executing.
The beforescriptexecute should work. Its a non-greasemonkey event:
https://developer.mozilla.org/en-US/docs/Web/Events/beforescriptexecute
You can do stuff like this:
document.addEventListener("beforescriptexecute", function(e) {
src = e.target.src;
content = e.target.text;
if (src.search("i18n.js") > -1) {
// Stop original script
e.preventDefault();
e.stopPropagation();
window.jQuery(e.target).remove();
var script = document.createElement('script');
script.textContent = 'script you want';
(document.head || document.documentElement).appendChild(script);
script.onload = function() {
this.parentNode.removeChild(this);
}
}

How to control meteorjs authentication based on geolocation?

I want to force users to enable their geolocation, otherwise disallow login to meteor site.
I am using accounts-ui, and {{loginButtons}} in a handlebars template called "login".
login.html
<template name="login">
{{loginButtons}}
</template>
login.js
Template.login.rendered = function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success, error);
} else {
Meteor.logout();
}
}
I get the prompt for geolocation (using chrome), but when I click deny, it still lets me log in. Would it be better to check for geolocation on meteor startup prior to even using the site? Ideally, I'm looking for a way to check for geolocation when Meteor.isLoggingIn().
Your best bet is to avoid showing the login buttons at all unless there is a geocode.
login.html
<template name="login">
{{#if showLogin}}
{{loginButtons}}
{{/if}}
</template>
login.js
Template.login.helpers({
showLogin: function () {
successCallback = function (loc) { Session.set('curLocation', loc);}
errorCallback = function (err) {
Session.set('curLocation', null);
if (Meteor.userId()) {
Meteor.logout();
}
}
// This just checks to see if the browser supports geolocation.
if (navigator.geolocation){
// Actually checks for geocode.
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
}
// Tricky bit: Reactive variable changes (and reruns) when callback changes.
// Since the variable is only set on success, this function will
// only ever be true on a success.
return Session.get('curLocation');
}
});

What would unhook my View and Controller from each other in Chrome and IE but not in Firefox?

I have previously successfully tested this MVC functionality in my app in Chrome but have recenlty also tested in IE (10) and Firefox.
When I mash the submit button on a page which sends model values to its controller for running a query and generating a report, it now works only in Firefox (each of the three browser indeed have their own peculiar characteristics -- where they shine or "dull" in relation to their cohorts (gleaming in purple and gold) -- but Chrome and Firefox seem to have lost the connection between the submit button's click handler and the corresponding Controller's method.
The app seems to simply hang after mashing the submit button in Chrome and IE; the breakpoints I have -- the first of which is at the very beginning of the corresponding [HttpPost] ActionResult in the Controller class -- are not reached. In fact, the app seems to freeze after mashing the button -- right-clicking the submit button after that does not give me an "inspect that element" in the context menu.
[HttpPost]
public ActionResult ReceiptCriteria(SalesReceiptCriteriaModel model)
{
if (ModelState.IsValid) // <-- there is a breakpoint here; only Firefox reaches it
{
. . .
In Firefox, it runs, and the breakpoints are hit.
What could possibly cause Chrome and IE to fail in this way, wheras Firefox soldiers on?
UPDATE
In response to Moby's request, here is the jQuery for the View in question:
The HTML in the View is pretty generic; the jQuery is:
$("#submit_button").click(function() {
// http://stackoverflow.com/questions/18192288/how-can-i-compare-date-time-values-using-the-jqueryui-datepicker-and-html5-time
var begD = $.datepicker.parseDate('mm/dd/yy', $('#BeginDate').val());
var endD = $.datepicker.parseDate('mm/dd/yy', $('#EndDate').val());
if (begD > endD) {
alert('Begin date must be before End date');
$('#BeginDate').focus();
return false;
}
else if (begD.toString() == endD.toString()) {
var dteString = begD.getFullYear() + "/" + (begD.getMonth() + 1) + "/" + begD.getDate();
var begT = new Date(dteString + " " + $('#BeginTime').val());
var endT = new Date(dteString + " " + $('#EndTime').val());
if (begT > endT) {
alert('Begin date must be before End date');
$('#BeginTime').focus();
return false;
}
}
$("#NumberOfResults").css("visibility", "visible");
$("#NumberOfResults").html("Please wait...");
EnableButton("submit_button", false);
// If all are selected, don't enumerate them; just set it at "All" (change of case, from 'all' to 'All', shows that the logic did execute)
var deptsList = $('#depts').checkedBoxes();
if (deptsList.length < deptsArray.length) {
$('#deptHeader span').html(deptsList.join(", "));
}
else if (deptsList.length == deptsArray.length) {
$('#deptHeader span').html("All");
}
// " "
var sitesList = $('#sites').checkedBoxes();
$('#sitesHeader span').html(sitesList.join(", "));
if (sitesList.length < sitesArray.length) {
$('#sitesHeader span').html(sitesList.join(", "));
}
else if (sitesList.length == sitesArray.length) {
$('#sitesHeader span').html("All");
}
$('#hiddenDepts').val(deptsList);
$('#hiddenSites').val(sitesList);
var UPCs = $('#UPC').val();
if (UPCs == "All") {
$('#UPC').val("1"); // take everything (1 and greater)
}
var resultsText = jQuery.trim($("#spanNumberOfResults").text());
if (resultsText != "") {
$("#NumberOfResults").css("visibility", "visible");
if (resultsText == "0") {
$("#NumberOfResults").css("color", "red");
} else {
var href = '/#ConfigurationManager.AppSettings["ThisApp"]/TLDCriteria/LoadReport';
var report_parms = {
GUID: "#Model.GUID",
SerialNumber: "#Model.SerialNumber",
ReportName: "#Model.ReportName"
};
window.open(href, "report_window", "resizable=1, width=850, left=" + (screen.width / 2 - 425));
}
}
}); // end of submit button click
function EnableButton(id, enable) {
if (enable) {
$("#" + id).removeAttr("disabled")
.removeClass("bottomButtonDisabled")
.removeClass("bottomButtonEnabled")
.addClass("bottomButtonEnabled");
} else {
$("#" + id).attr("disabled", "true")
.removeClass("bottomButtonDisabled")
.removeClass("bottomButtonEnabled")
.addClass("bottomButtonDisabled");
}
}
UPDATE 2
Something else which may or may not shed some light on this problem is my .js and .css references:
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js" type="text/javascript" defer > </script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript" defer> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript" defer> </script>
<script src="#Url.Content("~/Scripts/jquery-migrate-1.2.0.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/anytime.compressed.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/dynamicCheckboxes.js")" type="text/javascript" > </script>
. . .
<link href="http://code.jquery.com/ui/1.9.2/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/dynamicCheckboxes.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/anytime.compressed.css")" rel="stylesheet" type="text/css" />
<!--[if lt IE 9]>
<script src="/Scripts/html5shiv.js"> </script>
<![endif]-->
UPDATE 3
The Network tab in the Chrome Developer Tools looks like the middle of Wyoming (a whole lot of nothing), with a msg about the bottom informing me "No requests captured. Reload the page to see detailed information on the network activity."
When I dutifully mashed F5, it showed all the .js and .css files accessed, and finally (at the top), the page I'm gawking at. Mashing the "View Report" causes no more activity in the tab, though. I do see the console.log() msg I placed at the end of the submit button click handler, though, to wit: "made it to the end of submit button click"
There is one err msg in the console, too, but this:
Failed to load resource: the server responded with a status of 400 (Bad Request) http://localhost/%3C%=%20System.Configuration.ConfigurationManager.AppSettings[%22ThisApp%22]%20%%3E/Content/Images/SSCSsprite.png
Would simply fail to load the resource, not wreak other mayhem, right?
UPDATE 4
Based on Simon Halsey's hint, I found that, on stepping though the jQuery in Chrome, it fails this test:
if (resultsText != "") {
...obviously it's not in Firefox, and I assume that it also fails in IE (I'll czech to be sure in both cases, and update this).
Later: It's "" in Firefox, too...and the first time through, it also failed-wouldn't continue on. Second time through, it got through, though...???
There is two options:
There is no request due to javascript error
Your request signature doesnt math controller method
A.
Browsers have different behaivior with some javascript functions. Thats one of the reasons why jQuery is so popular.
The most efficient way to find it is to debug javascript line by line in each browser.
Likely it is the reason.
B.
Also your javascript is quite exotic for me. I guess you are catching sumbit button click and modifying inputs values on a fly.
I would recommend to use $.post or $.ajax and preventDefault instead.
It would make your javascript more clear and simple.
C.
To analyze what requests are sent from your browser I would recommend to use fiddler.
http://fiddler2.com/

Resources