Skip to content

Instantly share code, notes, and snippets.

@ObjectIsAdvantag
Created July 6, 2016 13:46
Show Gist options
  • Save ObjectIsAdvantag/075f1ef3dd1a838f4928649662d4f769 to your computer and use it in GitHub Desktop.
Save ObjectIsAdvantag/075f1ef3dd1a838f4928649662d4f769 to your computer and use it in GitHub Desktop.
DEVNET3002 - Step 3 - ChatOps
// QUICK START GUIDE
//
// 1. Clone this gists and make it secrete
// 2. Create an incoming integratin in a Spark Room from the Spark Web client : http://web.ciscospark.com
// 3. Replace INCOMING_INTEGRATION_SUFFIX by the integration id, example: Y2lzY29zcGFyazovL3VzL1dFQkhPT0svZjE4ZTI0MDctYzg3MS00ZTdmLTgzYzEtM2EyOGI1N2ZZZZZ
// 4. Create your Tropo application pointing to your gist URL, append /raw/tropodevops-sample.js to the gist URL
//
// Cisco Spark Logging Library for Tropo
//
// Factory for the Spark Logging Library, with 2 parameters
// - the name of the application will prefix all your logs,
// - the Spark Incoming integration (to which logs will be posted)
// To create an Incoming Integration
// - click integrations in the right pane of a Spark Room (Example : I create a dedicated "Tropo Logs" room)
// - select incoming integration
// - give your integration a name, it will be displayed in the members lists (Example : I personally named it "from tropo scripting")
// - copy your integration ID, you'll use it to initialize the SparkLibrary
function SparkLog(appName, incomingIntegrationID) {
if (!appName) {
appName = "";
//log("SPARK_LOG : bad configuration, no application name, exiting...");
//throw createError("SparkLibrary configuration error: no application name specified");
}
this.tropoApp = appName;
if (!incomingIntegrationID) {
log("SPARK_LOG: bad configuration, no Spark incoming integration URI, exiting...");
throw createError("SparkLibrary configuration error: no Spark incoming integration URI specified");
}
this.sparkIntegration = incomingIntegrationID;
log("SPARK_LOG: all set for application:" + this.tropoApp + ", posting to integrationURI: " + this.sparkIntegration);
}
// This function sends the log entry to the registered Spark Room
// Invoke this function from the Tropo token-url with the "sparkIntegration" parameter set to the incoming Webhook ID you'll have prepared
// Returns true if the log entry was acknowledge by Spark (ie, got a 2xx HTTP status code)
SparkLog.prototype.log = function(newLogEntry) {
// Robustify
if (!newLogEntry) {
newLogEntry = "";
}
var result;
try {
// Open Connection
var url = "https://api.ciscospark.com/v1/webhooks/incoming/" + this.sparkIntegration;
var connection = new java.net.URL(url).openConnection();
// Set timeout to 10s
connection.setReadTimeout(10000);
connection.setConnectTimeout(10000);
// Method == POST
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
// TODO : check if this cannot be removed
connection.setRequestProperty("Content-Length", newLogEntry.length);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send Post Data
var bodyWriter = new java.io.DataOutputStream(connection.getOutputStream());
log("SPARK_LOG: posting: " + newLogEntry + " to: " + url);
var contents = '{ "text": "' + this.tropoApp + ': ' + newLogEntry + '" }'
bodyWriter.writeBytes(contents);
bodyWriter.flush();
bodyWriter.close();
var result = connection.getResponseCode();
log("SPARK_LOG: read response code: " + result);
if (result < 200 || result > 299) {
log("SPARK_LOG: could not log to Spark, message format not supported");
return false;
}
}
catch (e) {
log("SPARK_LOG: could not log to Spark, socket Exception or Server Timeout");
return false;
}
log("SPARK_LOG: log successfully sent to Spark, status code: " + result);
return true; // success
}
//
// Script logic starts here
//
// Let's create several instances for various log levels
var ChatOps = new SparkLog("", "INCOMING_INTEGRATION_SUFFIX"); // Change with an Incoming Integration URI suffix
function info(logEntry) {
log("CHATOPS: " + logEntry);
ChatOps.log(logEntry);
}
if (!currentCall) { // No tropo session => the token-url has been hit
// Log a dummy message to show everything goes well: tropo script compiles, chatops is all set
var offset = -7; // Vegas is CET-7
var now = new Date(Date.now() + (3600000 * offset));
info("it is now " + now.getHours() + ":" + now.getMinutes() + " in Vegas");
}
else {
answer();
wait(1000); // On-boarding pause : do not speak too quickly the IVR
// Pick a voice depending on your language & preference (male/female)
// https://www.tropo.com/docs/scripting/international-features/speaking-multiple-languages
var currentVoice = "Ava"; // Allison, Ava, Samantha, Susan, Veronica, Vanessa (Default), Tom, Victor
info("speaking the welcome invite to: +" + currentCall.callerID);
say("Hello, Welcome to the DevNet Quiz !", { voice: currentVoice });
wait(500);
say("To take a Quiz, please text your email to this number. You'll be automatically added to the Quiz Spark room.", { voice: currentVoice });
wait(1000);
// SSML: https://www.tropo.com/docs/scripting/advanced-speech-control/manipulating-say-ssml
event = ask("<speak> Dial 1 to receive more details by SMS <break time='500ms'/> Dial 2 to take a challenge from your phone </speak>", {
voice: currentVoice,
choices: "1,2",
timeout: 5,
attempts: 3,
mode: "dtmf", // dial tone only as we are in an open conference room
onTimeout: function(event) {
say("Sorry, I didn't hear your choice.", { voice: currentVoice });
},
onBadChoice: function(event) {
say("Sorry, I didn't understand what you said.", { voice: currentVoice });
}
});
if (event.name == 'choice') {
var selected = parseInt(String(event.value));
switch (selected) {
case 1:
say("Got it, we are texting you more details.", { voice: currentVoice });
// Send a SMS from a new Tropo session
info("sending details via SMS to: +" + currentCall.callerID);
var forkedCall = call(currentCall.callerID, {
network: "SMS"
});
forkedCall.value.say("Welcome to the DevNet Quiz. Text your email to join the 'Quiz' Spark room. Attend DEVNET3002 in the DevNet Zone to learn Spark & Tropo APIs.");
forkedCall.value.hangup();
break;
case 2:
default:
info("running the Quiz challenge via Tropo: +" + currentCall.callerID);
// [TODO] Implement takeChallenge()
say("Sorry, this feature is not implemented yet !", { voice: currentVoice });
break;
}
}
// Finish the conversation gently
wait(500);
say("Thanks and see you in the DevNet Zone. Bye Bye.", { voice: currentVoice });
wait(1000);
hangup();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment