9 | Click to chat
10 |
11 |
12 |
--------------------------------------------------------------------------------
/callback/android-sample/res/drawable/gradbackground.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/callback/android-sample/res/menu/activity_call_form.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/callback/android-sample/res/menu/activity_callback_task.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/task/node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-sample",
3 | "version": "0.1.0",
4 | "description": "Proxy server for task sample",
5 | "main": "TaskProxy.js",
6 | "dependencies": {
7 | "http-proxy" : "~0.10.3",
8 | "node-static" : "~0.7.2",
9 | "optimist" : "~0.6.0"
10 | },
11 | "readmeFilename": "../README.md"
12 | }
13 |
--------------------------------------------------------------------------------
/callback/html-sample/node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "callback-sample",
3 | "version": "0.1.0",
4 | "description": "Proxy server for callback sample",
5 | "main": "CallbackProxy.js",
6 | "dependencies": {
7 | "http-proxy" : "~0.10.3",
8 | "node-static" : "~0.7.2",
9 | "optimist" : "~0.6.0"
10 | },
11 | "readmeFilename": "readme.txt"
12 | }
13 |
--------------------------------------------------------------------------------
/customer-chat-proactive/config/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "socialminer" : {
3 | "host" : "10.78.95.38"
4 | },
5 |
6 | "chat" : {
7 | "feedid" : "100020",
8 | "author" : "Web Guest",
9 | "title" : "New visitor on web page",
10 | "ccx_csq_id" : 1,
11 | "pollingInterval" : 5000
12 | },
13 |
14 | "popup" : {
15 | "elementid" : "popup_chat_div",
16 | "initdelay" : 20000,
17 | "myself" : "Me"
18 | }
19 | }
--------------------------------------------------------------------------------
/customer-chat/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "customer_chat_sample",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "dependencies": {
9 | "express": "~4.9.0",
10 | "body-parser": "~1.8.1",
11 | "cookie-parser": "~1.3.3",
12 | "morgan": "~1.3.0",
13 | "debug": "3.1.0",
14 | "ejs": "~>2.5.5",
15 | "request": "~2.46.0",
16 | "express-xml-bodyparser": "~0.0.4",
17 | "minimist": "~1.1.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/callback/android-sample/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/src/resources/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "GREETING" : "Hello %s! Thanks for contacting us. I am %s. How may I help you today?",
3 | "PLEASE_WAIT_FOR_AGENT" : "Ah, alright. Let me go find you someone who can help you out. Please wait.",
4 | "CHAT_FAILURE_TRY_LATER" : "Yikes! Something bad just happened. We are unable to help you right now. Please try again after some time.",
5 | "CHAT_ENDED" : "Your chat session has ended. Thanks a lot for reaching out! We appreciate your feedback on this interaction (below).",
6 | "SURVEY_HIGH" : "Very Good :-)",
7 | "SURVEY_MEDIUM" : "I dunno, it was alright :-|",
8 | "SURVEY_LOW" : "Bad Experience :-("
9 | }
--------------------------------------------------------------------------------
/callback/android-sample/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/callback/android-sample/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | CallMe
4 | Settings
5 | Example SocialMiner Callback
6 | CallFormActivity
7 | SettingsActivity
8 |
9 | Request Form
10 | Name
11 | Phone
12 | Enter your name
13 | Enter your phone number
14 | Enter SocialMiner Callback Feed Id
15 | Call Me Back
16 |
17 | Callback Preferences
18 | Server
19 |
20 | CallbackTask
21 |
22 |
--------------------------------------------------------------------------------
/bubble-chat-scheduling/scripts/schedule_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "timezone": "Asia/Baku",
3 | "holidays": [
4 | "2018-09-13"
5 | ],
6 | "specialDays": [
7 | {
8 | "date": "2018-09-13",
9 | "workTime": {
10 | "startTime": 0,
11 | "endTime": 720
12 | }
13 | }
14 | ],
15 | "routineDays": [
16 | {
17 | "day": "1",
18 | "workTime": {
19 | "startTime": 300,
20 | "endTime": 1140
21 | }
22 | },
23 | {
24 | "day": "2",
25 | "workTime": {
26 | "startTime": 665,
27 | "endTime": 1200
28 | }
29 | },
30 | {
31 | "day": "3",
32 | "workTime": {
33 | "startTime": 1130,
34 | "endTime": 1140
35 | }
36 | },
37 | {
38 | "day": "4",
39 | "workTime": {
40 | "startTime": 360,
41 | "endTime": 1200
42 | }
43 | },
44 | {
45 | "day": "5",
46 | "workTime": {
47 | "startTime": 1000,
48 | "endTime": 1080
49 | }
50 | }
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "node": true,
4 | "es6": true
5 | },
6 | "extends": "airbnb-base",
7 | "rules": {
8 | "no-implicit-coercion": "error",
9 | "no-process-env": "off",
10 | "no-path-concat": "error",
11 | "import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
12 | "no-use-before-define": ["warn", { "functions": false }],
13 | "no-underscore-dangle": "off",
14 | "lines-around-comment": "off",
15 | "indent": [2, 4],
16 | "space-before-function-paren": ["error", "always"],
17 | "quotes": ["error", "double"],
18 | "array-element-newline": ["off"],
19 | "capitalized-comments": ["off"],
20 | "comma-dangle": ["error", "always-multiline"],
21 | "curly": ["error", "multi-line", "consistent"],
22 | "max-len": ["warn", { "code": 160}],
23 | "no-inline-comments": ["off"],
24 | "no-multiple-empty-lines": ["error", { "max": 1 }],
25 | "no-ternary": ["off"],
26 | "arrow-body-style": ["off"],
27 | }
28 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Cisco Systems, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Cisco Systems, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/customer-chat-proactive/scripts/constants.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cisco SocialMiner Pop-up Chat Example
3 | *
4 | * Copyright (c) 2016 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * The code included in this example is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Chat RESTful
9 | * APIs and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the Chat RESTful API interface and
13 | * the quality of the Chat RESTful API interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilities refer to the documentation that accompanies the latest
18 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | // Defines global constants
23 |
24 | var constants = {
25 | scheme : 'http://',
26 | feedRefURL : '/ccp-webapp/ccp/feed/',
27 | chatURI : '/ccp/chat',
28 | chatEventsPathParam : '?all=false&eventid=',
29 | locationHeader : 'Location',
30 | xmlMIMEType : 'application/xml',
31 | ccx_chat_csq_tag : 'Chat_Csq'
32 | };
33 |
--------------------------------------------------------------------------------
/customer-chat-proactive/styles/main.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Cisco SocialMiner Pop-up Chat Example
3 | *
4 | * Copyright (c) 2016 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * The code included in this example is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Chat RESTful
9 | * APIs and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the Chat RESTful API interface and
13 | * the quality of the Chat RESTful API interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilities refer to the documentation that accompanies the latest
18 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | body {
23 | background-color: #24726a;
24 | color: white;
25 | font-family: monospace;
26 | height: 100%;
27 | }
28 |
29 | div.content {
30 | border: 0.6em double white;
31 | text-align: center;
32 | }
33 |
34 | div.content h1 {
35 | font-size: 6em;
36 | margin-top: 0.2em;
37 | margin-bottom: 0.2em;
38 | }
39 |
40 | div.content h3 {
41 | font-size: 2em;
42 | }
43 |
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/callback/services/MessageType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample.callback.services;
23 |
24 | /**
25 | * The Enum MessageType.
26 | */
27 | public enum MessageType {
28 |
29 | /** The new contact. */
30 | NEW_CONTACT,
31 |
32 | /** The contact status. */
33 | CONTACT_STATUS;
34 | }
35 |
--------------------------------------------------------------------------------
/customer-chat-proactive/styles/3rdparty/jquery-ui-chatbox/jquery.ui.chatbox.css:
--------------------------------------------------------------------------------
1 | /* style sheets */
2 | .ui-chatbox {
3 | position: fixed;
4 | bottom:0;
5 | padding: 2px;
6 | background: #CCCCCC;
7 | }
8 |
9 | .ui-chatbox-titlebar {
10 | padding: 3px;
11 | height: 20px;
12 | cursor: pointer;
13 | }
14 |
15 | .ui-chatbox-content {
16 | padding: 0px;
17 | margin: 0px;
18 | border: 0px;
19 | }
20 |
21 | .ui-chatbox-log {
22 | padding: 3px;
23 | height: 250px;
24 | overflow-y: auto;
25 | overflow-x: hidden;
26 | background: #FFFFFF;
27 | }
28 |
29 | .ui-chatbox-input {
30 | padding: 3px;
31 | border-top: 1px solid grey;
32 | overflow: hidden;
33 | }
34 |
35 | .ui-chatbox-input-box {
36 | margin: 5px;
37 | border: 2px solid lightgrey;/* #6699FF */
38 | padding: 2px;
39 | height: 50px;
40 | }
41 |
42 | .ui-chatbox-icon {
43 | float: right;
44 | }
45 |
46 | .ui-chatbox-input-focus {
47 | border-color: #6699FF;
48 | }
49 |
50 | .ui-chatbox-msg {
51 | margin-top: 10px;
52 | float: left;
53 | clear: both;
54 | /* Source: http://snipplr.com/view/10979/css-cross-browser-word-wrap */
55 | white-space: pre-wrap; /* CSS3 */
56 | white-space: -moz-pre-wrap; /* Firefox */
57 | white-space: -pre-wrap; /* Opera <7 */
58 | white-space: -o-pre-wrap; /* Opera 7 */
59 | word-wrap: break-word; /* IE */
60 | }
61 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/src/routes/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs
3 | *
4 | * Copyright (c) 2017 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * This sample should act as a guide for a programmer to understand how to
8 | * integrate and manage the customer-side of a chat session with
9 | * custom messaging services on the web. It is also intended to provide guidance
10 | * to the developer on best practices and usage of the SocialMiner Chat RESTful
11 | * APIs and is not intended for production use “as is”.
12 | *
13 | * Cisco's responsibility and liability on this code is limited ONLY to the
14 | * correctness and accuracy on the usage of the Chat RESTful API interface and
15 | * the quality of the Chat RESTful API interface itself. Any omissions from this
16 | * example are not to be considered capabilities that are supported or not
17 | * supported by the product.
18 | *
19 | * For specific capabilities refer to the documentation that accompanies the latest
20 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
21 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
22 | */
23 |
24 | const express = require("express");
25 |
26 | const router = express.Router();
27 |
28 | router.get("/", (req, res) => {
29 | res.contentType("html").send("
There's nothing for you here
");
30 | });
31 |
32 | module.exports = router;
33 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/src/util/logger.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs
3 | *
4 | * Copyright (c) 2017 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * This sample should act as a guide for a programmer to understand how to
8 | * integrate and manage the customer-side of a chat session with
9 | * custom messaging services on the web. It is also intended to provide guidance
10 | * to the developer on best practices and usage of the SocialMiner Chat RESTful
11 | * APIs and is not intended for production use “as is”.
12 | *
13 | * Cisco's responsibility and liability on this code is limited ONLY to the
14 | * correctness and accuracy on the usage of the Chat RESTful API interface and
15 | * the quality of the Chat RESTful API interface itself. Any omissions from this
16 | * example are not to be considered capabilities that are supported or not
17 | * supported by the product.
18 | *
19 | * For specific capabilities refer to the documentation that accompanies the latest
20 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
21 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
22 | */
23 |
24 | const winston = require("winston");
25 |
26 | module.exports = new (winston.Logger)({
27 | transports: [
28 | new (winston.transports.Console)({
29 | level: process.env.DEBUG ? "debug" : "info",
30 | handleExceptions: true,
31 | colorize: true,
32 | prettyPrint: true,
33 | }),
34 | ],
35 | });
36 |
--------------------------------------------------------------------------------
/customer-chat-proactive/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Cisco SocialMiner - Pop-up Chat Example
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Your Web Page
26 |
Based on custom heuristics, a pop-up chat session can be initiated
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/callback/services/HandleMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample.callback.services;
23 |
24 |
25 | /**
26 | * The Interface HandleMessage.
27 | * This message interface enables service handler to serve both activities
28 | */
29 | public interface HandleMessage {
30 |
31 | /**
32 | * Handle message.
33 | *
34 | * @param type
35 | * the type
36 | * @param message
37 | * the message
38 | */
39 | public void handleMessage(MessageType type,String message);
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/callback/android-sample/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
28 |
29 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/SettingsActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample;
23 |
24 | import com.cisco.sample.R;
25 | import android.os.Bundle;
26 | import android.preference.PreferenceActivity;
27 |
28 | /**
29 | * The Class SettingsActivity.
30 | */
31 | public class SettingsActivity extends PreferenceActivity {
32 |
33 | /* (non-Javadoc)
34 | * @see android.preference.PreferenceActivity#onCreate(android.os.Bundle)
35 | */
36 | @SuppressWarnings("deprecation")
37 | @Override
38 | public void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | addPreferencesFromResource(R.layout.activity_settings);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chat-facebook-messenger",
3 | "description": "Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs",
4 | "version": "0.0.1",
5 | "main": "src/app.js",
6 | "scripts": {
7 | "start": "node src/app.js",
8 | "lint": "node_modules/eslint/bin/eslint.js src",
9 | "test": "node_modules/nyc/bin/nyc.js node_modules/mocha/bin/mocha test/**/*Spec.js",
10 | "coverage": "node_modules/nyc/bin/nyc.js --reporter html npm test"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/chat-facebook-messenger"
15 | },
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/chat-facebook-messenger/issues"
19 | },
20 | "homepage": "https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/chat-facebook-messenger#readme",
21 | "readme": "https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/chat-facebook-messenger#readme",
22 | "engines": {
23 | "node": "6.11.3",
24 | "npm": "5.4.2"
25 | },
26 | "dependencies": {
27 | "body-parser": "^1.18.2",
28 | "botly": "^1.4.2",
29 | "express": "^4.15.5",
30 | "express-ping": "^1.4.0",
31 | "lodash": "^4.17.4",
32 | "morgan": "^1.9.0",
33 | "request-promise-native": "^1.0.5",
34 | "winston": "^2.3.1",
35 | "xml2js": "^0.4.19"
36 | },
37 | "devDependencies": {
38 | "chai": "^4.1.2",
39 | "eslint": "^4.9.0",
40 | "eslint-config-airbnb-base": "^12.1.0",
41 | "eslint-plugin-import": "^2.8.0",
42 | "mocha": "^4.0.1",
43 | "nyc": "^11.2.1",
44 | "sinon": "^4.0.2",
45 | "sinon-chai": "^2.14.0"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/callback/android-sample/res/layout/activity_callback_task.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
20 |
21 |
32 |
33 |
41 |
42 |
49 |
50 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/src/session/session.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs
3 | *
4 | * Copyright (c) 2017 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * This sample should act as a guide for a programmer to understand how to
8 | * integrate and manage the customer-side of a chat session with
9 | * custom messaging services on the web. It is also intended to provide guidance
10 | * to the developer on best practices and usage of the SocialMiner Chat RESTful
11 | * APIs and is not intended for production use “as is”.
12 | *
13 | * Cisco's responsibility and liability on this code is limited ONLY to the
14 | * correctness and accuracy on the usage of the Chat RESTful API interface and
15 | * the quality of the Chat RESTful API interface itself. Any omissions from this
16 | * example are not to be considered capabilities that are supported or not
17 | * supported by the product.
18 | *
19 | * For specific capabilities refer to the documentation that accompanies the latest
20 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
21 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
22 | */
23 |
24 | const request = require("request-promise-native");
25 | const STATES = require("../resources/states");
26 |
27 | module.exports = user => ({
28 | // details of facebook user who has initiated chat
29 | // we can also keep additional fields like profile pic URL,
30 | // email ID, etc. based on use cases
31 | user: {
32 | id: user.id,
33 | name: `${user.first_name} ${user.last_name}`,
34 | },
35 |
36 | // a buffer that holds messages sent by the facebook user
37 | // until an agent can join this chat
38 | customerMessagesBuffer: [],
39 |
40 | state: STATES.STARTED,
41 |
42 | socialminer: {
43 | scRefURL: null,
44 | latestEventID: 0,
45 | eventPoller: null,
46 | cookieJar: request.jar(), // IMPORTANT! Maintains chat client HTTP session
47 | },
48 | });
49 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/src/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs
3 | *
4 | * Copyright (c) 2017 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * This sample should act as a guide for a programmer to understand how to
8 | * integrate and manage the customer-side of a chat session with
9 | * custom messaging services on the web. It is also intended to provide guidance
10 | * to the developer on best practices and usage of the SocialMiner Chat RESTful
11 | * APIs and is not intended for production use “as is”.
12 | *
13 | * Cisco's responsibility and liability on this code is limited ONLY to the
14 | * correctness and accuracy on the usage of the Chat RESTful API interface and
15 | * the quality of the Chat RESTful API interface itself. Any omissions from this
16 | * example are not to be considered capabilities that are supported or not
17 | * supported by the product.
18 | *
19 | * For specific capabilities refer to the documentation that accompanies the latest
20 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
21 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
22 | */
23 |
24 | const express = require("express");
25 | const health = require("express-ping");
26 | const bodyParser = require("body-parser");
27 | const httpLogger = require("morgan");
28 | const logger = require("./util/logger");
29 | const utils = require("./util/utils");
30 | const indexRoute = require("./routes/index");
31 | const fbWebhookRoute = require("./routes/fb_webhook");
32 |
33 | logger.info("**** STARTUP ****");
34 | logger.debug("Environment = ", process.env);
35 |
36 | // Check if the environment is proper
37 | utils.validateEnvironment();
38 |
39 | // Setup the web service
40 | const app = express();
41 | app.use(bodyParser.json());
42 | app.use(httpLogger("short"));
43 | app.use(health.ping());
44 |
45 | // setup routes
46 | app.use("/", indexRoute);
47 | app.use("/webhook", fbWebhookRoute);
48 |
49 | // Start the web service
50 | app.listen(process.env.PORT, () => {
51 | logger.info("Service listening on port %d ...", process.env.PORT);
52 | });
53 |
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/callback/services/ServiceMessageHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample.callback.services;
23 |
24 |
25 | import android.os.Bundle;
26 | import android.os.Handler;
27 | import android.os.Message;
28 |
29 | /**
30 | * The Class ServiceMessageHandler.
31 | * This class is used to pass messages between activity and services
32 | */
33 | public class ServiceMessageHandler extends Handler{
34 |
35 | /** The msg handler. */
36 | HandleMessage msgHandler;
37 |
38 | /**
39 | * Instantiates a new service message handler.
40 | *
41 | * @param msgHandler
42 | * the msg handler
43 | */
44 | public ServiceMessageHandler(HandleMessage msgHandler) {
45 | this.msgHandler=msgHandler;
46 | }
47 |
48 | /* (non-Javadoc)
49 | * @see android.os.Handler#handleMessage(android.os.Message)
50 | */
51 | @Override
52 | public void handleMessage(Message msg) {
53 | Bundle bundle = msg.getData();
54 | String type = bundle.getString("msgType");
55 | String msgContent = bundle.getString("msgContent");
56 | msgHandler.handleMessage(MessageType.valueOf(type), msgContent);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/test/util/utilsSpec.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | const chai = require("chai");
3 | const sinon = require("sinon");
4 | const sinonChai = require("sinon-chai");
5 | const utils = require("../../src/util/utils");
6 | const logger = require("../../src/util/logger");
7 |
8 | const { expect } = chai;
9 | chai.use(sinonChai);
10 | // suppress all logs on STDOUT
11 | logger.transports.console.silent = true;
12 |
13 | const _setEnvironmentDefaults = () => {
14 | process.env.PORT = "7777";
15 | process.env.FB_PAGE_ACCESS_TOKEN = "abcd123";
16 | process.env.FB_VERIFICATION_TOKEN = "abcd";
17 | process.env.VIRTUAL_ASSISTANT_NAME = "Melania";
18 | process.env.SOCIALMINER_HOST = "socialminer.example.com";
19 | process.env.SOCIALMINER_CHAT_FEED_ID = "100000";
20 | process.env.CCX_QUEUE_ID = "1";
21 | };
22 |
23 | describe("Tests for util/utils", () => {
24 | it("checks all mandatory env vars are defined", () => {
25 | _setEnvironmentDefaults();
26 | expect(utils.validateEnvironment).to.not.throw(ReferenceError);
27 | });
28 |
29 | it("throws ReferenceError when any env var is undefined", () => {
30 | _setEnvironmentDefaults();
31 | // deliberately remove this variable
32 | delete process.env.FB_PAGE_ACCESS_TOKEN;
33 | expect(utils.validateEnvironment).to.throw(ReferenceError);
34 | });
35 |
36 | it("throws ReferenceError when any env var is empty", () => {
37 | _setEnvironmentDefaults();
38 | // deliberately make this empty
39 | process.env.FB_PAGE_ACCESS_TOKEN = " ";
40 | expect(utils.validateEnvironment).to.throw(ReferenceError);
41 | });
42 |
43 | it("logs provided error with its stack trace", () => {
44 | const spy = sinon.spy(logger, "error");
45 | const myError = new TypeError("This is a TypeError");
46 | utils.logErrorWithStackTrace(myError, "Logging a TypeError");
47 | expect(spy).to.have.been.calledWith("Something went wrong.", myError);
48 | });
49 |
50 | it("decodes encoded strings", () => {
51 | expect(utils.decodeString("")).to.equal("<hello world>");
52 | expect(utils.decodeString("hello%20world")).to.equal("hello world");
53 | expect(utils.decodeString("hello+world")).to.equal("hello world");
54 | });
55 | });
56 |
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample;
23 |
24 | import com.cisco.sample.R;
25 | import com.cisco.sample.callback.CallbackFormActivity;
26 |
27 | import android.app.TabActivity;
28 | import android.content.Intent;
29 | import android.os.Bundle;
30 | import android.widget.TabHost;
31 | import android.widget.TabHost.TabSpec;
32 |
33 | /**
34 | * The Class MainActivity.
35 | * This launches two activities in two tabs
36 | */
37 | @SuppressWarnings("deprecation")
38 | public class MainActivity extends TabActivity{
39 |
40 | /* (non-Javadoc)
41 | * @see android.app.ActivityGroup#onCreate(android.os.Bundle)
42 | */
43 | @Override
44 | public void onCreate(Bundle savedInstanceState) {
45 | super.onCreate(savedInstanceState);
46 | setContentView(R.layout.activity_main);
47 |
48 | TabHost tabHost = getTabHost();
49 | // Callform tab
50 | Intent intentForm = new Intent().setClass(this, CallbackFormActivity.class);
51 |
52 | TabSpec tabSpecForm = tabHost
53 | .newTabSpec("Form")
54 | .setIndicator("Form")
55 | .setContent(intentForm);
56 |
57 | // Settings tab
58 | Intent intentSettings = new Intent().setClass(this, SettingsActivity.class);
59 | TabSpec tabSpecSettings = tabHost
60 | .newTabSpec("Settings")
61 | .setIndicator("Settings")
62 | .setContent(intentSettings);
63 |
64 | tabHost.addTab(tabSpecForm);
65 | tabHost.addTab(tabSpecSettings);
66 |
67 | tabHost.setCurrentTab(0);
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/customer-chat-proactive/scripts/chatbox.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cisco SocialMiner Pop-up Chat Example
3 | *
4 | * Copyright (c) 2016 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * The code included in this example is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Chat RESTful
9 | * APIs and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the Chat RESTful API interface and
13 | * the quality of the Chat RESTful API interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilities refer to the documentation that accompanies the latest
18 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | // Based on an open-source jQuery-UI based chatbox plugin
23 | // See https://github.com/dexterpu/jquery.ui.chatbox
24 |
25 | var chatbox_ui = {
26 | /**
27 | * Options for the popup chat widget
28 | */
29 | options : {
30 | id: 'popup_chat_div',
31 | title: 'How may I help you?',
32 | hidden: false,
33 | width: 250,
34 | offset: 20,
35 | messageSent: function (id, user, msg) {
36 | chatbox_ui.showMessage(config.popup.myself, msg);
37 | // push the chat message to SocialMiner to be shown to agent
38 | restUtil.putChatMessage(msg);
39 | },
40 | boxClosed: function (id) {
41 | // stop polling for chat events
42 | clearInterval(session.pollerID);
43 | // delete chat session with SocialMiner
44 | restUtil.deleteChat().done(new function () {
45 | console.log('Chat session terminated successfully.');
46 | });
47 | }
48 | },
49 |
50 | /**
51 | * Launch the chat widget using options specified above
52 | */
53 | launch : function () {
54 | console.log('Displaying chat widget...');
55 | $('#' + config.popup.elementid).chatbox(chatbox_ui.options);
56 | },
57 |
58 | /**
59 | * Display a message
60 | *
61 | * @param from - The sender of the message
62 | * @param message - The content of the message
63 | */
64 | showMessage : function (from, message) {
65 | $('#' + config.popup.elementid).chatbox('option', 'boxManager').addMsg(from, message);
66 | }
67 | };
68 |
69 |
70 |
--------------------------------------------------------------------------------
/callback/android-sample/res/layout/activity_call_form.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
19 |
30 |
31 |
42 |
51 |
52 |
53 |
62 |
63 |
70 |
71 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/src/util/utils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs
3 | *
4 | * Copyright (c) 2017 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * This sample should act as a guide for a programmer to understand how to
8 | * integrate and manage the customer-side of a chat session with
9 | * custom messaging services on the web. It is also intended to provide guidance
10 | * to the developer on best practices and usage of the SocialMiner Chat RESTful
11 | * APIs and is not intended for production use “as is”.
12 | *
13 | * Cisco's responsibility and liability on this code is limited ONLY to the
14 | * correctness and accuracy on the usage of the Chat RESTful API interface and
15 | * the quality of the Chat RESTful API interface itself. Any omissions from this
16 | * example are not to be considered capabilities that are supported or not
17 | * supported by the product.
18 | *
19 | * For specific capabilities refer to the documentation that accompanies the latest
20 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
21 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
22 | */
23 |
24 | const _ = require("lodash");
25 | const logger = require("../util/logger");
26 |
27 | const MANDATORY_ENV_VARS = [
28 | "PORT",
29 | "FB_PAGE_ACCESS_TOKEN",
30 | "FB_VERIFICATION_TOKEN",
31 | "VIRTUAL_ASSISTANT_NAME",
32 | "SOCIALMINER_HOST",
33 | "SOCIALMINER_CHAT_FEED_ID",
34 | "CCX_QUEUE_ID",
35 | ];
36 |
37 | module.exports = {
38 | /**
39 | * Validates the deployed environment to ensure
40 | * all required variables are defined. If not, it
41 | * aborts the entire application.
42 | */
43 | validateEnvironment: () => {
44 | _.each(MANDATORY_ENV_VARS, (variable) => {
45 | if (_.isUndefined(process.env[variable]) ||
46 | _.isEmpty(_.trim(process.env[variable]))) {
47 | throw new ReferenceError(`SEVERE ERROR: MISSING/INVALID environment variable value: ${variable}`);
48 | }
49 | });
50 | },
51 |
52 | /**
53 | * Logs an error with its stack trace
54 | *
55 | * @param {*} err
56 | * @param {String} msg
57 | */
58 | logErrorWithStackTrace: (err, msg) => {
59 | logger.error("Something went wrong.", err, new Error(msg).stack);
60 | },
61 |
62 | /**
63 | * Properly decode a URLEncoded string
64 | *
65 | * @param {String} str
66 | */
67 | decodeString: (str) => {
68 | let decodedStr = decodeURIComponent(str.replace(/\+/g, " "));
69 | decodedStr = decodedStr.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """)
70 | .replace(/'/g, "'")
71 | .replace(/\//g, "/");
72 |
73 | return decodedStr;
74 | },
75 | };
76 |
--------------------------------------------------------------------------------
/script-filters/translate.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2016
4 | * All rights reserved.
5 | * Cisco SocialMiner 11.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Script Filter
9 | * interface and is not intended for production use "as is".
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the script filter interface
13 | * and the quality of the script filter interface itself. Any omissions
14 | * from this example are not to be considered capabilities that are
15 | * supported or not supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | /*
23 | * How to call an external API and update SocialContact.
24 | *
25 | * To demonstrate, here is an example script filter that uses google apis.
26 | * This script will use google translate api to translate socialcontact
27 | * title and description
28 | * For more information, visit -> https://developers.google.com/translate/v2/getting_started
29 | *
30 | * THE TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
31 | */
32 |
33 | //If need be, set the proxy to access the internet using the provided restClient
34 | //restClient.setProxy("PROXY_HOST", 80, null);
35 |
36 | def title = socialContact.title;
37 | def description = socialContact.description;
38 | def API_KEY = "YOUR_GOOGLE_API_KEY";
39 | def TARGET_LANGUAGE = "YOUR_TARGET_LANGUAGE";
40 | def titleResponse = "";
41 |
42 | boolean updated = false;
43 |
44 | if (title != null && title != ""){
45 | log "trying to translate title ${title}"
46 | titleResponse = restClient.get( uri : "https://www.googleapis.com/", path : "language/translate/v2", query : [key:API_KEY,target:TARGET_LANGUAGE,q:title] );
47 | def translatedTitle = titleResponse.data.data.translations.translatedText[0];
48 | socialContact.title = "${translatedTitle} <---> ${title}";
49 | log "updating social contact with title ${translatedTitle} "
50 | }
51 |
52 | def descResponse = "";
53 |
54 | if (description != null && description != ""){
55 | log "trying to translate title ${description}"
56 | descResponse = restClient.get( uri : "https://www.googleapis.com/", path : "language/translate/v2", query : [key:API_KEY,target:TARGET_LANGUAGE,q:description]);
57 | def translatedDescription = descResponse.data.data.translations.translatedText[0];
58 | log "updating social contact with description ${translatedDescription} "
59 | socialContact.description = "${translatedDescription} <---> ${description}"
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/src/session/session_manager.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs
3 | *
4 | * Copyright (c) 2017 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * This sample should act as a guide for a programmer to understand how to
8 | * integrate and manage the customer-side of a chat session with
9 | * custom messaging services on the web. It is also intended to provide guidance
10 | * to the developer on best practices and usage of the SocialMiner Chat RESTful
11 | * APIs and is not intended for production use “as is”.
12 | *
13 | * Cisco's responsibility and liability on this code is limited ONLY to the
14 | * correctness and accuracy on the usage of the Chat RESTful API interface and
15 | * the quality of the Chat RESTful API interface itself. Any omissions from this
16 | * example are not to be considered capabilities that are supported or not
17 | * supported by the product.
18 | *
19 | * For specific capabilities refer to the documentation that accompanies the latest
20 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
21 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
22 | */
23 |
24 | const Session = require("./session");
25 | const STATES = require("../resources/states");
26 | const logger = require("../util/logger");
27 |
28 | /**
29 | * `Map `
30 | *
31 | * holds all sessions that are ongoing
32 | */
33 | const sessionMap = new Map();
34 |
35 | /**
36 | * Exposes an interface for the rest of the
37 | * application to create, update and destroy sessions
38 | */
39 | const SessionManager = {
40 | isSessionOngoing: id => sessionMap.has(id) &&
41 | sessionMap.get(id).state !== STATES.STARTED &&
42 | sessionMap.get(id).state !== STATES.ENDED,
43 |
44 | createSession: (user) => {
45 | logger.info("Creating new session for user", user);
46 | sessionMap.set(user.id, Session(user));
47 | },
48 |
49 | getSession: (id) => {
50 | return sessionMap.get(id);
51 | },
52 |
53 | setState: (id, state) => {
54 | sessionMap.get(id).state = state;
55 | },
56 |
57 | setSCRefURL: (id, url) => {
58 | sessionMap.get(id).socialminer.scRefURL = url;
59 | },
60 |
61 | setLatestEventId: (id, eventId) => {
62 | sessionMap.get(id).socialminer.latestEventID = eventId;
63 | },
64 |
65 | setEventPoller: (id, poller) => {
66 | sessionMap.get(id).socialminer.eventPoller = poller;
67 | },
68 |
69 | addToCustomerMessageBuffer: (id, text) => {
70 | sessionMap.get(id).customerMessagesBuffer.push(text);
71 | },
72 |
73 | destroySession: (id) => {
74 | // clear interval if it exists
75 | if (sessionMap.get(id) && sessionMap.get(id).socialminer.eventPoller) {
76 | clearInterval(sessionMap.get(id).socialminer.eventPoller);
77 | }
78 | // then, remove the session from sessionMap
79 | sessionMap.delete(id);
80 | },
81 | };
82 |
83 | module.exports = SessionManager;
84 |
--------------------------------------------------------------------------------
/script-filters/README.md:
--------------------------------------------------------------------------------
1 | # Cisco SocialMiner - Groovy Script Filter Samples
2 | _Sample Groovy Script Filters for SocialMiner_
3 |
4 | ## Overview
5 | - **[translate.groovy](translate.groovy)**: An example script filter that uses Google APIs. This script will use [Google Translate API](https://cloud.google.com/translate/v2/getting_started) to translate the socialcontact title and description.
6 |
7 | ## Pre-requisites
8 | - An installed SocialMiner server
9 | - Create a Feed
10 | - Create a Campaign and add the created feed (above) in this campaign
11 |
12 | - Find out if you need to set a proxy for internet access and what it is.
13 |
14 | - For **[translate.groovy](translate.groovy)**, Get your Google API KEY [here](https://cloud.google.com/translate).
15 |
16 | ## Configuring the samples
17 | ### Translate
18 | - Edit [translate.groovy](translate.groovy) and update the following:
19 | - replace the text `"PROXY_HOST"` with a HTTP proxy Host/IP Address, if/as required.
20 | - replace the text `"YOUR_GOOGLE_API_KEY"` with your Google API Key.
21 | - replace the text `"YOUR_TARGET_LANGUAGE"` with your designed target language code. See [language codes](https://cloud.google.com/translate/v2/using_rest#language-params).
22 |
23 | ## Using the Script Filters
24 | - Create a new script filter and upload the chosen groovy script file.
25 | 
26 |
27 | - Edit the campaign (created earlier) and add the Filter created above to this campaign.
28 | 
29 |
30 | - Based on your choice of script filter applied to the campaign, the filter will act on all social contacts in the campaign and you will see the changes to the social contact accordingly.
31 |
32 | ## Disclaimer
33 | The Groovy Script Filter samples are intended to provide guidance to the developer on best practices and usage of the SocialMiner Script Filter interface.
34 |
35 | This is only a sample and is NOT intended to be a production quality application and will not be supported as such. It is NOT guaranteed to be bug free. It is merely provided as a guide for 3rd-party developers on best practices and usage of the SocialMiner Script Filter interface and is not intended for production use "as is".
36 |
37 | Cisco's responsibility and liability on this code is limited ONLY to the correctness and accuracy on the usage of the script filter interface and the quality of the script filter interface itself. Any omissions from this example are not to be considered capabilities that are supported or not supported by the product.
38 |
39 | For specific capabilities refer to the documentation that accompanies the latest Cisco SocialMiner release and/or request help from [DevNet](http://developer.cisco.com) or the Cisco Technical Assistance Center (TAC).
40 |
41 | ## Support Notice
42 | DevNet provides sample support on a “best effort” basis. Like any custom deployment, it is the responsibility of the partner and/or customer to ensure that the customization works correctly. Cisco reserves the right to make changes to APIs and any other published interfaces as part of the normal Cisco SocialMiner release cycle.
43 |
44 | https://developer.cisco.com/site/socialminer/overview/
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SocialMiner Sample Code
2 | This repository contains examples and sample code to be used with [Cisco SocialMiner](https://developer.cisco.com/site/socialminer/overview/).
3 |
4 | | Sample | Description |
5 | |--------|-------------|
6 | |[Customer Chat Client Sample](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/customer-chat) | Sample javascript (Node.js) based chat client application to illustrate the use of SocialMiner Chat APIs |
7 | |[Customer Proactive Chat Client Sample](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/customer-chat-proactive) | Sample web application illustrating a proactive customer-side pop-up live chat with Cisco Unified CCX web chat via Cisco SocialMiner |
8 | |[Facebook Messenger Integration Sample](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/chat-facebook-messenger) | Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs |
9 | |[Bubble Chat Scheduling Sample](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/bubble-chat-scheduling) | Sample web application (HTML + javascript) which encapsulates Bubble Chat invocation to implement a basic scheduling based on working hours and holidays. |
10 | |[Bulk Transcript Downloader](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/bulk-transcript-downloader) | Sample application to bulk export chat transcripts from a SocialMiner server |
11 | |[Task API Sample](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/task) | Sample web-based (javascript) application to illustrate SocialMiner Task APIs |
12 | |[Callback HTML Sample](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/callback/html-sample) | Sample web-based (javascript) application to illustrate SocialMiner Agent Request (Callback) APIs |
13 | |[Callback Android Sample](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/callback/android-sample) | Sample Android application to illustrate use of SocialMiner Agent Request (Callback) APIs |
14 | |[Groovy Script Filter Samples](https://github.com/CiscoDevNet/socialminer-sample-code/tree/master/script-filters) | Sample Groovy Script Filters for SocialMiner |
15 |
16 | ## Disclaimer
17 | Code in this repository is only a sample and is **NOT guaranteed to be bug free and production quality.** This is NOT intended to be used in production environments. It is merely provided as a guide for 3rd-party developers on best practices and usage of the SocialMiner RESTful APIs and other published interfaces and is not intended for production use "as is".
18 |
19 | Cisco's responsibility and liability on this code is limited ONLY to the correctness and accuracy on the usage of the RESTful API interface and the quality of the RESTful API interface itself. Any omissions from this example are not to be considered capabilities that are supported or not supported by the product.
20 |
21 | For specific capabilities refer to the documentation that accompanies the latest Cisco SocialMiner release and/or request help from [Cisco DevNet](http://developer.cisco.com) or the Cisco Technical Assistance Center (TAC).
22 |
23 | ## Support Notice
24 | DevNet provides sample support on a “best effort” basis. Like any custom deployment, it is the responsibility of the partner and/or customer to ensure that the customization works correctly. Cisco reserves the right to make changes to APIs and any other published interfaces as part of the normal Cisco SocialMiner release cycle.
25 |
26 | https://developer.cisco.com/site/socialminer/overview/
27 |
--------------------------------------------------------------------------------
/customer-chat/public/javascripts/utils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Chat
9 | * APIs and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | /**
23 | * A set of Javascript utilities to be used with customer chat.
24 | */
25 |
26 | var socialminer = socialminer || {};
27 |
28 | socialminer.utils = socialminer.utils || {};
29 |
30 | /**
31 | * Log the given message to the console if the console is defined
32 | */
33 | socialminer.utils.log = function(message)
34 | {
35 | if ( console && console.log )
36 | {
37 | console.log(message);
38 | }
39 | }
40 |
41 | /**
42 | * Decode a string carried in a MessageEvent body field.
43 | *
44 | * @param str the string to be decoded
45 | * @returns the decoded string
46 | */
47 | socialminer.utils.decodeString = function(str)
48 | {
49 | str = decodeURIComponent(str.replace(/\+/g, " "));
50 | str = str.replace(/&/g,'&').replace(//g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');
51 |
52 | return str;
53 | }
54 |
55 | /**
56 | * This method ensures that the output String has only
57 | * valid XML unicode characters as specified by the
58 | * XML 1.0 standard. For reference, please see
59 | * the
60 | * standard. This method will return an empty
61 | * String if the input is null or empty.
62 | *
63 | * @param in The String whose non-valid characters we want to remove.
64 | * @return The in String, stripped of non-valid characters.
65 | */
66 | socialminer.utils.stripNonValidXMLCharacters = function(text)
67 | {
68 | var out = []; // Used to hold the output.
69 | if (!text || text === '')
70 | return '';
71 |
72 | for ( var i = 0; i < text.length; i++) {
73 | var current = text.charCodeAt(i);
74 | if ((current == 0x9) ||
75 | (current == 0xA) ||
76 | (current == 0xD) ||
77 | ((current >= 0x20) && (current <= 0xD7FF)) ||
78 | ((current >= 0xE000) && (current <= 0xFFFD)) ||
79 | ((current >= 0x10000) && (current <= 0x10FFFF)))
80 | out.push(text.charAt(i));
81 | }
82 | return out.join("");
83 | }
84 |
85 | /**
86 | * Returns true if the given string is blank; false otherwise
87 | */
88 | socialminer.utils.isBlank = function(s)
89 | {
90 | return !s || (s.replace(/\s/g, '').length === 0);
91 | }
92 |
93 | /**
94 | * trim leading and trailing spaces from the given string.
95 | */
96 | socialminer.utils.trim = function(s)
97 | {
98 | if ( !s )
99 | {
100 | return "";
101 | }
102 |
103 | return s.replace(/^\s+|\s+$/g, '');
104 | }
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/callback/CallbackStatusActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample.callback;
23 |
24 | import android.app.Activity;
25 | import android.content.Intent;
26 | import android.os.Bundle;
27 | import android.os.Messenger;
28 | import android.view.View;
29 | import android.view.View.OnClickListener;
30 | import android.widget.Button;
31 | import android.widget.TextView;
32 |
33 | import com.cisco.sample.R;
34 | import com.cisco.sample.callback.services.ContactStatusService;
35 | import com.cisco.sample.callback.services.HandleMessage;
36 | import com.cisco.sample.callback.services.MessageType;
37 | import com.cisco.sample.callback.services.ServiceMessageHandler;
38 |
39 | /**
40 | * The Class CallbackStatusActivity.
41 | * Activity to show callback request status
42 | */
43 | public class CallbackStatusActivity extends Activity implements HandleMessage{
44 |
45 | /** The handler. */
46 | private ServiceMessageHandler handler;
47 |
48 | /**
49 | * Instantiates a new callback status activity.
50 | */
51 | public CallbackStatusActivity(){
52 | handler = new ServiceMessageHandler(this);
53 | }
54 |
55 |
56 | /* (non-Javadoc)
57 | * @see android.app.Activity#onCreate(android.os.Bundle)
58 | */
59 | @Override
60 | public void onCreate(Bundle savedInstanceState) {
61 | super.onCreate(savedInstanceState);
62 |
63 | setContentView(R.layout.activity_callback_task);
64 | Button cmdDone = (Button)findViewById(R.id.buttonDone);
65 | // Get contact URL from bundle
66 | Bundle bundle = getIntent().getExtras();
67 | String contactUrl =bundle.getString("contactUrl");
68 |
69 | // Start background service to poll for contact status
70 | Intent intent = new Intent(CallbackStatusActivity.this,ContactStatusService.class);
71 | intent.putExtra("contactUrl", contactUrl);
72 | // Put the handler where service will send message
73 | Messenger messenger = new Messenger(handler);
74 | intent.putExtra("MESSENGER", messenger);
75 | startService(intent);
76 |
77 |
78 | cmdDone.setOnClickListener(new OnClickListener() {
79 | @Override
80 | public void onClick(View v) {
81 | // stop polling service and finish the activity
82 | stopService(new Intent(CallbackStatusActivity.this,ContactStatusService.class));
83 | finish();
84 | }
85 | });
86 | }
87 |
88 | /* (non-Javadoc)
89 | * @see com.cisco.sample.HandleMessage#handleMessage(com.cisco.sample.MessageType, java.lang.String)
90 | */
91 | @Override
92 | public void handleMessage(MessageType type, String message) {
93 | if(type != MessageType.CONTACT_STATUS)
94 | return;//do not process any other message
95 | // Show status on UI
96 | TextView lblStatus = (TextView) findViewById(R.id.lblStatus);
97 | if(lblStatus!=null)
98 | lblStatus.setText(message);
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/customer-chat-proactive/README.md:
--------------------------------------------------------------------------------
1 | # Cisco SocialMiner - Proactive / Live Chat Client Sample
2 | _Sample web application illustrating a proactive customer-side pop-up live chat with Cisco Unified CCX web chat via Cisco SocialMiner_
3 |
4 | ## Overview
5 | This sample does the following:
6 | - Provides a basic example web page with a built-in logic to inject a web chat request into Cisco SocialMiner based on a simple time delay.
7 |
8 | - Implements a **pop-up live chat chat bubble** which serves as a customer chat client to send and receive chat messages from CCX chat agents.
9 |
10 | - Thereby illustrates usage of SocialMiner chat feed APIs, and abilities to customize and extend Unified CCX web chat capabilities.
11 |
12 | ## Pre-requisites
13 | - Your favorite static web server ([Apache](https://httpd.apache.org), [nginx](https://nginx.org/), [IIS](https://www.iis.net/))
14 |
15 | - Cisco SocialMiner 11.5 SU (and future releases)
16 |
17 | - Cisco Unified CCX 11.5 (and future releases) with all web chat configurations (Please refer [Unified CCX Administration Guide](https://www.cisco.com/c/en/us/support/customer-collaboration/unified-contact-center-express/products-installation-and-configuration-guides-list.html))
18 |
19 | ## Setup / Configuration
20 | The [config.json](config/config.json) allows you to customize important details required to run this sample.
21 | Modify it with details such as:
22 | - Cisco SocialMiner IP / Fully Qualified Hostname
23 | - Chat feed ID, CCX Chat Contact Service Queue ID
24 | - misc. configurations
25 |
26 | ## Running
27 | - Modify [config.json](config/config.json) (see above section)
28 |
29 | - Host the entire code in this project (`index.html`, `config/`, `scripts/` and `styles/` directories) to be served from your favorite static web server.
30 |
31 | - Login chat agents into the Finesse desktop, and move them to **READY** state for Chat and Email.
32 |
33 | - Access [index.html](index.html) via web server, and a chat will be injected into the CCX system (via SocialMiner) and routed to the right available chat agent, who can then accept, join and start the chat conversation.
34 | This will pop-up the chat bubble on the customer web page.
35 |
36 | ## Disclaimer
37 | The Proactive customer-side pop-up live chat sample is intended to serve as an example of using SocialMiner REST APIs (specifically, the chat APIs) using a simple static web application which can be hosted and served from any web server.
38 |
39 | This sample should act as a guide for a programmer to understand how to initiate and manage the customer-side of a chat session. Please refer [SocialMiner Developer's Guide](https://developer.cisco.com/site/socialminer/documentation/) for further details about the chat APIs. Please see the _"Web Chat"_ section of [Unified CCX Configuration Guides](https://developer.cisco.com/site/contact-center-express/docs/) for instructions on deploying Unified CCX Web Chat Feature using SocialMiner Chat APIs.
40 |
41 | This is only a sample and is NOT intended to be a production quality application and will not be supported as such. It is NOT guaranteed to be bug free. It is merely provided as a guide for 3rd-party developers on best practices and usage of the SocialMiner RESTful APIs and is not intended for production use "as is".
42 |
43 | Cisco's responsibility and liability on this code is limited ONLY to the correctness and accuracy on the usage of the RESTful API interface and the quality of the RESTful API interface itself. Any omissions from this example are not to be considered capabilities that are supported or not supported by the product.
44 |
45 | For specific capabilities refer to the documentation that accompanies the latest Cisco SocialMiner release and/or request help from [DevNet](http://developer.cisco.com) or the Cisco Technical Assistance Center (TAC).
46 |
47 | ## Support Notice
48 | DevNet provides sample support on a “best effort” basis. Like any custom deployment, it is the responsibility of the partner and/or customer to ensure that the customization works correctly. Cisco reserves the right to make changes to APIs and any other published interfaces as part of the normal Cisco SocialMiner release cycle.
49 |
50 | https://developer.cisco.com/site/socialminer/overview/
--------------------------------------------------------------------------------
/task/node/TaskProxy.js:
--------------------------------------------------------------------------------
1 | /**
2 | Cisco SocialMiner - Simple HTTP Proxy to enable testing of the SocialMiner task HTML
3 | form.
4 |
5 | Version 10.0(1)
6 | Cisco Systems, Inc.
7 | http://www.cisco.com/
8 |
9 | Portions created or assigned to Cisco Systems, Inc. are
10 | Copyright (c) 2013 Cisco Systems, Inc. or its affiliated entities. All Rights Reserved.
11 |
12 | This javascript library is made available to Cisco partners and customers as
13 | a convenience to help minimize the cost of Cisco SocialMiner customizations.
14 | This library can be used in Cisco SocialMiner deployments. Cisco does not
15 | permit the use of this library in customer deployments that do not include
16 | Cisco SocialMiner. Support for the javascript library is provided on a
17 | "best effort" basis via CDN. Like any custom deployment, it is the
18 | responsibility of the partner and/or customer to ensure that the
19 | customization works correctly and this includes ensuring that the Cisco
20 | SocialMiner JavaScript is properly integrated into 3rd party applications.
21 | Cisco reserves the right to make changes to the javascript code and
22 | corresponding API as part of the normal Cisco SocialMiner release cycle. The
23 | implication of this is that new versions of the javascript might be
24 | incompatible with applications built on older SocialMiner integrations. That
25 | said, it is Cisco's intention to ensure javascript compatibility across
26 | versions as much as possible and Cisco will make every effort to clearly
27 | document any differences in the javascript across versions in the event
28 | that a backwards compatibility impacting change is made.
29 | **/
30 |
31 | var SOCIAL_MINER_PORT = 80;
32 |
33 | var STATIC_CONTENT_LISTEN_PORT = 8082;
34 | var API_PROXY_LISTEN_PORT = 8080;
35 |
36 | var http = require('http'), httpProxy = require('http-proxy'), static = require('node-static'),
37 | argv = require('optimist')
38 | .usage('usage: $0 --host socialMiner')
39 | .demand(['host'])
40 | .argv;
41 |
42 | var socialMinerHost = argv.host;
43 |
44 | console.log('Proxying API requests for ' + socialMinerHost);
45 |
46 | var fileServer = new static.Server('../html');
47 |
48 | // Create a simple server to serve up the task.html page.
49 | //
50 | var staticContentServer = http.createServer(function (request, response)
51 | {
52 | request.addListener('end', function ()
53 | {
54 | fileServer.serve(request, response);
55 | }).resume();
56 |
57 | }).listen(STATIC_CONTENT_LISTEN_PORT);
58 |
59 | staticContentServer.on('error', function (e) {
60 | if (e.code == 'EADDRINUSE') {
61 | console.log('ERROR: The port: '+ STATIC_CONTENT_LISTEN_PORT +' is currently occupied. Please change STATIC_CONTENT_LISTEN_PORT to free port');
62 | process.exit();
63 |
64 | }
65 | });
66 |
67 | staticContentServer.on('listening', function () {
68 | console.log('Static content server listening on ' + STATIC_CONTENT_LISTEN_PORT);
69 | });
70 |
71 | // Create a proxy to proxy requests for the task.html page as well as API
72 | // requests to SocialMiner.
73 | //
74 | var proxy = new httpProxy.RoutingProxy();
75 |
76 | var proxyServer = http.createServer(function(request, response)
77 | {
78 | console.log('Request url: ' + request.url);
79 | targetHost = '127.0.0.1';
80 | targetPort = STATIC_CONTENT_LISTEN_PORT;
81 | if ( request.url && (request.url.indexOf('/ccp/') === 0) )
82 | {
83 | // Any requests that start with /ccp/ are deemed API requests and are directed to SocialMiner.
84 | //
85 | targetHost = socialMinerHost;
86 | targetPort = SOCIAL_MINER_PORT;
87 | }
88 |
89 | console.log('Target host: ' + targetHost);
90 | console.log('Target port: ' + targetPort);
91 | proxy.proxyRequest(request, response,
92 | {
93 | host: targetHost,
94 | port: targetPort
95 | });
96 | }).listen(API_PROXY_LISTEN_PORT);
97 |
98 | proxyServer.on('error', function (e) {
99 | if (e.code == 'EADDRINUSE') {
100 | console.log('ERROR: The port: '+ API_PROXY_LISTEN_PORT +' is currently occupied. Please change API_PROXY_LISTEN_PORT to free port');
101 | process.exit();
102 |
103 | }
104 | });
105 |
106 | proxyServer.on('listening', function () {
107 | console.log('SocialMiner API proxy listening on ' + API_PROXY_LISTEN_PORT);
108 | });
--------------------------------------------------------------------------------
/callback/html-sample/node/CallbackProxy.js:
--------------------------------------------------------------------------------
1 | /**
2 | Cisco SocialMiner - Simple HTTP Proxy to enable testing of the SocialMiner callback HTML
3 | form.
4 |
5 | Version 10.0(1)
6 | Cisco Systems, Inc.
7 | http://www.cisco.com/
8 |
9 | Portions created or assigned to Cisco Systems, Inc. are
10 | Copyright (c) 2013 Cisco Systems, Inc. or its affiliated entities. All Rights Reserved.
11 |
12 | This javascript library is made available to Cisco partners and customers as
13 | a convenience to help minimize the cost of Cisco SocialMiner customizations.
14 | This library can be used in Cisco SocialMiner deployments. Cisco does not
15 | permit the use of this library in customer deployments that do not include
16 | Cisco SocialMiner. Support for the javascript library is provided on a
17 | "best effort" basis via CDN. Like any custom deployment, it is the
18 | responsibility of the partner and/or customer to ensure that the
19 | customization works correctly and this includes ensuring that the Cisco
20 | SocialMiner JavaScript is properly integrated into 3rd party applications.
21 | Cisco reserves the right to make changes to the javascript code and
22 | corresponding API as part of the normal Cisco SocialMiner release cycle. The
23 | implication of this is that new versions of the javascript might be
24 | incompatible with applications built on older SocialMiner integrations. That
25 | said, it is Cisco's intention to ensure javascript compatibility across
26 | versions as much as possible and Cisco will make every effort to clearly
27 | document any differences in the javascript across versions in the event
28 | that a backwards compatibility impacting change is made.
29 | **/
30 |
31 | var SOCIAL_MINER_PORT = 80;
32 |
33 | var STATIC_CONTENT_LISTEN_PORT = 8082;
34 | var API_PROXY_LISTEN_PORT = 8080;
35 |
36 | var http = require('http'), httpProxy = require('http-proxy'), static = require('node-static'),
37 | argv = require('optimist')
38 | .usage('usage: $0 --host socialMiner')
39 | .demand(['host'])
40 | .argv;
41 |
42 | var socialMinerHost = argv.host;
43 |
44 | console.log('Proxying API requests for ' + socialMinerHost);
45 |
46 | var fileServer = new static.Server('../html');
47 |
48 | // Create a simple server to serve up the callback.html page.
49 | //
50 | var staticContentServer = http.createServer(function (request, response)
51 | {
52 | request.addListener('end', function ()
53 | {
54 | fileServer.serve(request, response);
55 | }).resume();
56 |
57 | }).listen(STATIC_CONTENT_LISTEN_PORT);
58 |
59 | staticContentServer.on('error', function (e) {
60 | if (e.code == 'EADDRINUSE') {
61 | console.log('ERROR: The port: '+ STATIC_CONTENT_LISTEN_PORT +' is currently occupied. Please change STATIC_CONTENT_LISTEN_PORT to free port');
62 | process.exit();
63 |
64 | }
65 | });
66 |
67 | staticContentServer.on('listening', function () {
68 | console.log('Static content server listening on ' + STATIC_CONTENT_LISTEN_PORT);
69 | });
70 |
71 | // Create a proxy to proxy requests for the callback.html page as well as API
72 | // requests to SocialMiner.
73 | //
74 | var proxy = new httpProxy.RoutingProxy();
75 |
76 | var proxyServer = http.createServer(function(request, response)
77 | {
78 | console.log('Request url: ' + request.url);
79 | targetHost = '127.0.0.1';
80 | targetPort = STATIC_CONTENT_LISTEN_PORT;
81 | if ( request.url && (request.url.indexOf('/ccp/') === 0) )
82 | {
83 | // Any requests that start with /ccp/ are deemed API requests and are directed to SocialMiner.
84 | //
85 | targetHost = socialMinerHost;
86 | targetPort = SOCIAL_MINER_PORT;
87 | }
88 |
89 | console.log('Target host: ' + targetHost);
90 | console.log('Target port: ' + targetPort);
91 | proxy.proxyRequest(request, response,
92 | {
93 | host: targetHost,
94 | port: targetPort
95 | });
96 | }).listen(API_PROXY_LISTEN_PORT);
97 |
98 | proxyServer.on('error', function (e) {
99 | if (e.code == 'EADDRINUSE') {
100 | console.log('ERROR: The port: '+ API_PROXY_LISTEN_PORT +' is currently occupied. Please change API_PROXY_LISTEN_PORT to free port');
101 | process.exit();
102 |
103 | }
104 | });
105 |
106 | proxyServer.on('listening', function () {
107 | console.log('SocialMiner API proxy listening on ' + API_PROXY_LISTEN_PORT);
108 | });
--------------------------------------------------------------------------------
/customer-chat/app.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var path = require('path');
3 | var logger = require('morgan');
4 | var cookieParser = require('cookie-parser');
5 | var bodyParser = require('body-parser');
6 | var request = require('request');
7 | var routes = require('./routes/index');
8 | var parseArgs = require('minimist');
9 |
10 | var argv = parseArgs(process.argv, { string: "socialminer" });
11 | if ( !argv.socialminer )
12 | {
13 | process.stderr.write("usage: node app.js --socialminer \n");
14 | process.exit(-1);
15 | }
16 |
17 | var socialMiner = "http://" + argv.socialminer;
18 |
19 | var app = express();
20 |
21 | // view engine setup
22 | app.set('views', path.join(__dirname, 'views'));
23 | app.set('view engine', 'ejs');
24 |
25 | app.use(logger('dev'));
26 | app.use(bodyParser.urlencoded({ extended: false }));
27 | app.use(cookieParser());
28 | app.use(express.static(path.join(__dirname, 'public')));
29 |
30 | app.use('/', routes);
31 |
32 | app.get("/ccp/chat", function(req, response)
33 | {
34 | var get = request.get(
35 | {
36 | url: socialMiner + "/ccp/chat?eventid=" + req.query.eventid,
37 | headers: req.headers,
38 | cookies: req.cookies
39 | });
40 |
41 | req.pipe(get).pipe(response);
42 | });
43 |
44 | app.put("/ccp/chat", function(req, response)
45 | {
46 | var put = request.put(
47 | {
48 | url: socialMiner + "/ccp/chat/",
49 | headers: req.headers,
50 | cookies: req.cookies,
51 | body: req.rawBody
52 | });
53 |
54 | req.pipe(put).pipe(response);
55 | });
56 |
57 | app.put("/ccp/chat/leaveChat", function(req, response)
58 | {
59 | var put = request.put(
60 | {
61 | url: socialMiner + "/ccp/chat/leaveChat",
62 | headers: req.headers,
63 | cookies: req.cookies
64 | });
65 |
66 | req.pipe(put).pipe(response);
67 | });
68 |
69 | app.put("/ccp/chat/event", function(req, response)
70 | {
71 | var put = request.put(
72 | {
73 | url: socialMiner + "/ccp/chat/event",
74 | headers: req.headers,
75 | cookies: req.cookies
76 | });
77 |
78 | req.pipe(put).pipe(response);
79 | });
80 |
81 | app.post("/ccp/chat", function(req, response)
82 | {
83 | var post = request.post(
84 | {
85 | url: socialMiner + "/ccp/chat/",
86 | headers: req.headers,
87 | cookies: req.cookies,
88 | body: req.rawBody
89 | });
90 |
91 | req.pipe(post).pipe(response);
92 | });
93 |
94 | app.get("/ccp/chat/transcript.pdf", function(req, response)
95 | {
96 | var url = "/ccp/chat/transcript.pdf" + (req.query.locale ? "?locale=" + req.query.locale : ""),
97 | get = request.get(
98 | {
99 | url: socialMiner + url,
100 | headers: req.headers,
101 | cookies: req.cookies
102 | });
103 |
104 | req.pipe(get).pipe(response);
105 | });
106 |
107 | app.use(function(req, res, next)
108 | {
109 | req.rawBody = '';
110 | req.setEncoding('utf8');
111 |
112 | req.on('data', function(chunk)
113 | {
114 | req.rawBody += chunk;
115 | });
116 |
117 | req.on('end', function()
118 | {
119 | next();
120 | });
121 | });
122 |
123 | // catch 404 and forward to error handler
124 | app.use(function(req, res, next)
125 | {
126 | var err = new Error('Not Found');
127 | err.status = 404;
128 | next(err);
129 | });
130 |
131 | // error handlers
132 |
133 | // development error handler
134 | // will print stacktrace
135 | if (app.get('env') === 'development')
136 | {
137 | app.use(function(err, req, res, next)
138 | {
139 | res.status(err.status || 500);
140 | res.render('error',
141 | {
142 | message: err.message,
143 | error: err
144 | });
145 | });
146 | }
147 |
148 | // production error handler
149 | // no stacktraces leaked to user
150 | app.use(function(err, req, res, next)
151 | {
152 | res.status(err.status || 500);
153 | res.render('error',
154 | {
155 | message: err.message,
156 | error: {}
157 | });
158 | });
159 |
160 | var server = app.listen(8080, function()
161 | {
162 | console.log("listening on port " + server.address().port);
163 | });
--------------------------------------------------------------------------------
/bubble-chat-scheduling/scripts/schedule.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample chat schedule configuration and deployment for UCCX Bubble Chat using javascript.
3 | *
4 | * Copyright (c) 2018 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * This sample should act as a guide for a programmer to understand how to
8 | * add scheduling capabilities for bubble chat in the customer side of the chat session.
9 | *
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16 | * SOFTWARE.
17 | *
18 | * For specific capabilities refer to the documentation that accompanies the latest
19 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
20 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
21 | **/
22 |
23 |
24 | // declare necessary libraries
25 | var libraries = [
26 | 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.0/moment.min.js', // Needed to egt current datettime from client
27 | 'https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js', //Needed to parse time in accordance with given timezone.
28 | 'https://cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.4/jstz.js', //Needed to determine client's timezone.
29 | 'https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js' //Needed for simple,better reading/parsing of scheduling configuration which is in json.
30 | ]
31 |
32 | // source and initialize neccesary libraries
33 | function initialize() {
34 | for (var index = 0; index < libraries.length; index++) {
35 | var script = document.createElement('script');
36 | script.src = libraries[index];
37 | document.getElementsByTagName('head')[0].appendChild(script);
38 | }
39 | }
40 |
41 | // invoke initialization
42 | initialize();
43 |
44 | var config;
45 |
46 | // read schedule configuration from external source in JSON format.
47 | function readConfig(path) {
48 | $.getJSON(path, function(data) {
49 | config = data;
50 | });
51 | }
52 |
53 | // get current datetime
54 | function getCurrentTime() {
55 | var currentDateInServerTimeZone = moment().tz(config.timezone);
56 | return currentDateInServerTimeZone;
57 | }
58 |
59 | // check whether current date is an holiday
60 | function isOnHoliday(currDate) {
61 | if (config.holidays == null) {
62 | return false;
63 | }
64 | for (var i = 0; i < config.holidays.length; i++) {
65 | if (config.holidays[i] == currDate) {
66 | return true;
67 | }
68 | }
69 | return false;
70 | }
71 |
72 | // check whether current date is a special day
73 | function isOnSpecialDay(currDate) {
74 | if (config.specialDays == null) {
75 | return false;
76 | }
77 |
78 | for (var i = 0; i < config.specialDays.length; i++) {
79 | if (config.specialDays[i].date == currDate) {
80 | break;
81 | }
82 | }
83 | return config.specialDays[i];
84 | }
85 |
86 | // check whether current time is in operating hours.
87 | function isInWorkingHour(workTime, currWorkTimeMins) {
88 | return currWorkTimeMins <= workTime.endTime && currWorkTimeMins >= workTime.startTime;
89 | }
90 |
91 |
92 | // determine whether current datetime is in operating hour.
93 | function isOperatingHour() {
94 | var isOperatingHour = false;
95 | var current = getCurrentTime();
96 | if (!isOnHoliday(current)) {
97 | var specialDate = isOnSpecialDay(current);
98 | var currWorkTimeMins = (current.hours() * 60) + current.minutes();
99 | if (specialDate) {
100 | isOperatingHour = isInWorkingHour(specialDate.workTime, currWorkTimeMins);
101 | } else {
102 | if (config.routineDays == null) {
103 | return false;
104 | }
105 |
106 | for (var i = 0; i < config.routineDays.length; i++) {
107 | if (config.routineDays[i].day == current.day()) {
108 | isOperatingHour = isInWorkingHour(config.routineDays[i].workTime, currWorkTimeMins);
109 | break;
110 | }
111 | }
112 | if (config.routineDays.length == 0) {
113 | isOperatingHour = true;
114 | }
115 | }
116 | }
117 | return isOperatingHour
118 | }
--------------------------------------------------------------------------------
/customer-chat-proactive/scripts/main.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cisco SocialMiner Pop-up Chat Example
3 | *
4 | * Copyright (c) 2016 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * The code included in this example is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Chat RESTful
9 | * APIs and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the Chat RESTful API interface and
13 | * the quality of the Chat RESTful API interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilities refer to the documentation that accompanies the latest
18 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | // globals
23 | var config;
24 | var session = {};
25 |
26 | /**
27 | * Executes on page load
28 | */
29 | $(document).ready(function () {
30 | loadConfig();
31 |
32 | // auto-initiate a chat to SocialMiner after a fixed duration
33 | setTimeout(initiateChatToSocialMiner, config.popup.initdelay);
34 | }
35 | );
36 |
37 | /**
38 | * Loads configs from config/config.json
39 | */
40 | function loadConfig () {
41 | console.log('Loading config...');
42 | $.get({
43 | url : 'config/config.json',
44 | async : false,
45 | success : function(configJson) {
46 | console.log('Loaded config: ' + JSON.stringify(configJson));
47 | config = configJson;
48 | },
49 | error : function(err) {
50 | console.error('Failed to load config. Error = ' + err);
51 | }
52 | });
53 | }
54 |
55 | /**
56 | * Initiates (POST) a chat request to SocialMiner
57 | */
58 | function initiateChatToSocialMiner () {
59 | console.log("Initiating chat request to SocialMiner " + config.socialminer.host);
60 | restUtil.postChatRequest().done(function (data, textStatus, jqXHR) {
61 | // update session
62 | session.scRefURL = jqXHR.getResponseHeader(constants.locationHeader);
63 | session.latestEventID = 0;
64 | session.launched = false;
65 | console.log("Injection of chat successful. SC RefURL = " + session.scRefURL);
66 |
67 | // start polling for chat events from SocialMiner
68 | session.pollerID = setInterval(pollForChatEvents, config.chat.pollingInterval);
69 | })
70 | .fail(function (jqXHR, textStatus) {
71 | console.error('Failed to initiate chat request! Response status = ' + jqXHR.status);
72 | });
73 | }
74 |
75 | /**
76 | * Does one poll for chat events from SocialMiner, parses the set of events
77 | * received and updates the chat accordingly
78 | */
79 | function pollForChatEvents () {
80 | console.log('Starting to poll for chat events every ' + config.chat.pollingInterval + ' milliseconds...');
81 | restUtil.getChatEvents(session.latestEventID).done(function (data, textStatus, jqXHR) {
82 | // parse the XML response
83 | var chatEvents = $.xml2json(data);
84 | console.log('Received chat events: ' + JSON.stringify(chatEvents));
85 |
86 | // process message events
87 | if (chatEvents && chatEvents.MessageEvent) {
88 | if (!session.launched) {
89 | chatbox_ui.launch();
90 | session.launched = true;
91 | }
92 | processIncomingMessages(chatEvents.MessageEvent);
93 | }
94 | });
95 | }
96 |
97 | /**
98 | * Processes incoming MessageEvents
99 | *
100 | * @param messages
101 | */
102 | function processIncomingMessages(messages) {
103 | if ($.isArray(messages)) {
104 | for (var i = 0; i < messages.length; i++) {
105 | chatbox_ui.showMessage(decodeString(messages[i].from), decodeString(messages[i].body));
106 | session.latestEventID = parseInt(messages[i].id);
107 | }
108 | } else {
109 | chatbox_ui.showMessage(decodeString(messages.from), decodeString(messages.body));
110 | session.latestEventID = parseInt(messages.id);
111 | }
112 | }
113 |
114 | /**
115 | * Decode a string carried in a MessageEvent body field.
116 | *
117 | * @param str the string to be decoded
118 | * @returns the decoded string
119 | */
120 | function decodeString (str)
121 | {
122 | str = decodeURIComponent(str.replace(/\+/g, " "));
123 | str = str.replace(/&/g,'&').replace(//g,'>').replace(/\"/g,'"').replace(/\'/g,''').replace(/\//g,'/');
124 |
125 | return str;
126 | }
127 |
--------------------------------------------------------------------------------
/bulk-transcript-downloader/README.md:
--------------------------------------------------------------------------------
1 | # Cisco SocialMiner - Bulk Chat Transcript Downloader
2 | _Sample application to export chat transcripts from a SocialMiner server_
3 |
4 | ## Overview
5 | This sample does the following:
6 | 0. Invokes a `/search` REST API request on a Cisco SocialMiner server for all handled chat contacts
7 | 1. By default the script fetches 100 Conversations, but this can be increased up to 200.
8 | 2. If there are more than 100 conversations, the script will send API requests to fetch 100 at a time, till all conversations are downloaded.
9 | 3. Processes the response from the server, and extracts chat transcript data
10 | 4. Exports transcript for each chat session into a separate text file (with additional metadata)
11 | 5. Archives all the exported transcripts into a ZIP file
12 |
13 | ## Pre-requisites
14 | 1. Cisco SocialMiner server (any supported release)
15 |
16 | 2. Any client machine (Windows, macOS, *nix-based systems) with the following:
17 |
18 | a) [Python 3.0.0+](https://www.python.org/downloads/) installed and configured in `PATH`
19 |
20 | b) Direct connectivity to the SocialMiner server
21 |
22 | 3. The python module `requests` must be pre-installed. Python modules can be installed
23 | using either `pip` or `easy_install`.
24 |
25 | ```
26 | pip install requests
27 | ```
28 | OR
29 | ```
30 | easy_install requests
31 | ```
32 |
33 | ## Running
34 | ### STEP 0
35 | On your client machine, ensure `python` is present in your system/user `PATH`.
36 |
37 | ```
38 | python --version
39 | ```
40 | _The version of python installed on your system should be printed on the terminal console._
41 |
42 | If you get an error (`command not found`), configure your system/user `PATH` so that `python` is added to it and try again to make sure you are able to make it work.
43 |
44 | If the version of python is less than 3.0, please upgrade it to the latest version (in 3.x release). ** This sample does NOT work with python versions below 3.0.0 **
45 |
46 | ### STEP 1
47 | Run the sample by providing all the necessary arguments to the python script.
48 |
49 | ```
50 | python bulk-transcript-downloader.py --host --user --password
51 | ```
52 | where
53 |
54 | `` is the IP address/hostname of the SocialMiner server
55 |
56 | `` is the login id of the application administrator account of the SocialMiner server
57 |
58 | `` is the login password of the application administrator account of the SocialMiner server
59 |
60 | This script will export chat transcripts as follows:
61 | - The transcript for each individual handled chat session will be exported into a separate text file
62 | - Apart from the chat messages, important metadata pertaining to the chat session are also written into each transcript file
63 | - The filename of an exported chat transcript file is of the form `ChatTranscript_-.txt`
64 | - All of these transcript files are compressed into a single ZIP archive that will be created in the current working directory from where the sample is being run.
65 |
66 | ## Modifying / Extending
67 | This sample has been created using standard python modules, and does not have dependencies on anything else.
68 |
69 | All SocialMiner RESTful APIs support XML data format. Modify the URL in the python script to invoke other REST APIs, and use the `xml.etree.ElementTree` module (or any other XML parsing module) in python to enhance and modify the functionality in this sample.
70 |
71 | ## Disclaimer
72 | The Bulk Chat Transcript Downloader sample is intended to serve as an example of using SocialMiner REST APIs (specifically, the `search` API) using a simple python script.
73 |
74 | This is only a sample and is NOT intended to be a production quality application and will not be supported as such. It is NOT guaranteed to be bug free. It is merely provided as a guide for 3rd-party developers on best practices and usage of the SocialMiner RESTful APIs and is not intended for production use "as is".
75 |
76 | Cisco's responsibility and liability on this code is limited ONLY to the correctness and accuracy on the usage of the RESTful API interface and the quality of the RESTful API interface itself. Any omissions from this example are not to be considered capabilities that are supported or not supported by the product.
77 |
78 | For specific capabilities refer to the documentation that accompanies the latest Cisco SocialMiner release and/or request help from [DevNet](http://developer.cisco.com) or the Cisco Technical Assistance Center (TAC).
79 |
80 | ## Support Notice
81 | DevNet provides sample support on a “best effort” basis. Like any custom deployment, it is the responsibility of the partner and/or customer to ensure that the customization works correctly. Cisco reserves the right to make changes to APIs and any other published interfaces as part of the normal Cisco SocialMiner release cycle.
82 |
83 | https://developer.cisco.com/site/socialminer/overview/
--------------------------------------------------------------------------------
/customer-chat-proactive/scripts/rest-util.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cisco SocialMiner Pop-up Chat Example
3 | *
4 | * Copyright (c) 2016 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * The code included in this example is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Chat RESTful
9 | * APIs and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the Chat RESTful API interface and
13 | * the quality of the Chat RESTful API interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilities refer to the documentation that accompanies the latest
18 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | var restUtil = {
23 | postChatRequest : function () {
24 | console.log('POSTing a chat request to SocialMiner ' + config.socialminer.host);
25 | return $.post({
26 | url : constants.scheme + config.socialminer.host + constants.chatURI,
27 | data : constructPostPayload(),
28 | contentType : constants.xmlMIMEType,
29 | crossDomain : true,
30 | xhrFields : { withCredentials : true } // Required to share session cookie while making cross-domain requests
31 | });
32 | },
33 |
34 | getChatEvents : function (eventID) {
35 | console.log('GETting chat events from SocialMiner ' + config.socialminer.host + ' since eventID ' + eventID);
36 | return $.get({
37 | url : constants.scheme + config.socialminer.host + constants.chatURI + constants.chatEventsPathParam + eventID,
38 | crossDomain : true,
39 | xhrFields : { withCredentials: true } // Required to share session cookie while making cross-domain requests
40 | });
41 | },
42 |
43 | putChatMessage : function (message) {
44 | console.log('PUTting chat message to SocialMiner ' + config.socialminer.host + '. Message = [' + message + ']');
45 | // silly jQuery does not have a $.put() ?!
46 | return $.ajax({
47 | type : 'PUT',
48 | url : constants.scheme + config.socialminer.host + constants.chatURI,
49 | data : constructMessagePayload(message),
50 | contentType : constants.xmlMIMEType,
51 | crossDomain : true,
52 | xhrFields : { withCredentials: true } // Required to share session cookie while making cross-domain requests
53 | });
54 | },
55 |
56 | deleteChat : function () {
57 | console.log('DELETEing chat session with SocialMiner ' + config.socialminer.host);
58 | // silly jQuery does not have a $.delete() ?!
59 | return $.ajax({
60 | type : 'DELETE',
61 | url : constants.scheme + config.socialminer.host + constants.chatURI,
62 | crossDomain : true,
63 | xhrFields : { withCredentials: true } // Required to share session cookie while making cross-domain requests
64 | });
65 | }
66 |
67 | };
68 |
69 | function constructPostPayload () {
70 | var feedRefURL = constants.scheme + config.socialminer.host + constants.feedRefURL + config.chat.feedid;
71 | var chatPostPayload = '' +
72 | '' + feedRefURL + '' +
73 | '' + config.chat.author + '' +
74 | '' + config.chat.title + '' +
75 | '' +
76 | '' +
77 | 'ccxqueuetag' +
78 | '' + constants.ccx_chat_csq_tag + config.chat.ccx_csq_id + '' +
79 | '' +
80 | '' +
81 | 'h_Name' +
82 | '' + config.chat.author + '' +
83 | '' +
84 | '' +
85 | '';
86 |
87 | console.log ('Chat request (POST) : ' + chatPostPayload);
88 | return chatPostPayload;
89 | }
90 |
91 | function constructMessagePayload (message) {
92 | var chatMessagePayload = '' +
93 | '' + message + '' +
94 | '';
95 |
96 | console.log ('Chat message (PUT) : ' + chatMessagePayload);
97 | return chatMessagePayload;
98 | }
99 |
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/callback/services/RequestCallbackService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample.callback.services;
23 |
24 | import java.io.IOException;
25 | import java.util.LinkedList;
26 | import java.util.List;
27 |
28 | import org.apache.http.HttpResponse;
29 | import org.apache.http.NameValuePair;
30 | import org.apache.http.client.ClientProtocolException;
31 | import org.apache.http.client.HttpClient;
32 | import org.apache.http.client.methods.HttpGet;
33 | import org.apache.http.client.utils.URLEncodedUtils;
34 | import org.apache.http.impl.client.DefaultHttpClient;
35 | import org.apache.http.message.BasicNameValuePair;
36 |
37 |
38 | import android.app.IntentService;
39 | import android.content.Intent;
40 | import android.os.Bundle;
41 | import android.os.IBinder;
42 | import android.os.Message;
43 | import android.os.Messenger;
44 | import android.os.RemoteException;
45 | import android.util.Log;
46 |
47 | /**
48 | * The Class RequestCallbackService.
49 | * This service is responsible for initialing callback request
50 | * and informing the generated contact URL to calling activity
51 | */
52 | public class RequestCallbackService extends IntentService{
53 |
54 | /** The callback url format. */
55 | private final String CALLBACK_URL_FORMAT = "http://%s/ccp/callback/feed/%s?%s";
56 |
57 | /**
58 | * Instantiates a new request callback service.
59 | */
60 | public RequestCallbackService() {
61 | super("RequestCallback");
62 | }
63 |
64 | /* (non-Javadoc)
65 | * @see android.app.IntentService#onBind(android.content.Intent)
66 | */
67 | @Override
68 | public IBinder onBind(Intent arg0) {
69 | return null;
70 | }
71 |
72 | /* (non-Javadoc)
73 | * @see android.app.IntentService#onCreate()
74 | */
75 | @Override
76 | public void onCreate() {
77 | super.onCreate();
78 | }
79 |
80 | /* (non-Javadoc)
81 | * @see android.app.IntentService#onDestroy()
82 | */
83 | @Override
84 | public void onDestroy() {
85 | super.onDestroy();
86 | }
87 |
88 | /* (non-Javadoc)
89 | * @see android.app.IntentService#onHandleIntent(android.content.Intent)
90 | */
91 | @Override
92 | protected void onHandleIntent(Intent intent) {
93 | Log.d("CallMe","Request Callback Service Starting");
94 | String hostname =intent.getExtras().getString("hostname");
95 |
96 | String name =intent.getExtras().getString("name");
97 | String phone =intent.getExtras().getString("phone");
98 | String feedId =intent.getExtras().getString("feedId");
99 |
100 | List params = new LinkedList();
101 | params.add(new BasicNameValuePair("title", "callback to " + phone));
102 | params.add(new BasicNameValuePair("name", name));
103 | params.add(new BasicNameValuePair("mediaAddress", phone));
104 |
105 | String paramString = URLEncodedUtils.format(params, "utf-8");
106 |
107 |
108 | String callbackUrl = String.format(CALLBACK_URL_FORMAT,hostname ,feedId,paramString);
109 | HttpClient httpclient = new DefaultHttpClient();
110 |
111 | HttpGet httpget = new HttpGet(callbackUrl);
112 | Log.d("CallMe","executing request" + httpget.getRequestLine());
113 | String contactUrl=null;
114 | try {
115 | HttpResponse response = httpclient.execute(httpget);
116 | if(response.getStatusLine().getStatusCode()==201)
117 | contactUrl= response.getFirstHeader("Location").getValue();
118 |
119 | } catch (ClientProtocolException e) {
120 | e.printStackTrace();
121 | } catch (IOException e) {
122 | e.printStackTrace();
123 | }
124 |
125 | Messenger messenger = (Messenger) intent.getExtras().get("MESSENGER");
126 | Message message = Message.obtain();
127 | Bundle bundle =new Bundle();
128 | bundle.putString("msgType", MessageType.NEW_CONTACT.toString());
129 | bundle.putString("msgContent", contactUrl);
130 | message.setData(bundle);
131 | try {
132 | messenger.send(message);
133 | } catch (RemoteException e) {
134 | e.printStackTrace();
135 | }
136 |
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/src/util/socialminer_rest_util.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs
3 | *
4 | * Copyright (c) 2017 by Cisco Systems, Inc.
5 | * All rights reserved.
6 | *
7 | * This sample should act as a guide for a programmer to understand how to
8 | * integrate and manage the customer-side of a chat session with
9 | * custom messaging services on the web. It is also intended to provide guidance
10 | * to the developer on best practices and usage of the SocialMiner Chat RESTful
11 | * APIs and is not intended for production use “as is”.
12 | *
13 | * Cisco's responsibility and liability on this code is limited ONLY to the
14 | * correctness and accuracy on the usage of the Chat RESTful API interface and
15 | * the quality of the Chat RESTful API interface itself. Any omissions from this
16 | * example are not to be considered capabilities that are supported or not
17 | * supported by the product.
18 | *
19 | * For specific capabilities refer to the documentation that accompanies the latest
20 | * Cisco SocialMiner release and/or request help from the Cisco Developer Network
21 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
22 | */
23 |
24 | const request = require("request-promise-native");
25 | const util = require("util");
26 | const logger = require("./logger");
27 | const sessionManager = require("../session/session_manager");
28 |
29 | // constants
30 | const CHAT_TITLE = "Chat from Facebook Messenger";
31 | const CCX_QUEUETAG_PREFIX = "Chat_Csq";
32 | const CHAT_FEED_REFURL = "http://%s/ccp-webapp/ccp/feed/%s";
33 | const CHAT_URL = "http://%s/ccp/chat";
34 | const CHAT_EVENTS_QUERY_PARAMS = "?all=false&eventid=";
35 | const MIME_XML = "application/xml";
36 |
37 | // private functions
38 |
39 | const _constructChatRequestPayload = (sessionId) => {
40 | const feedRefURL = util.format(
41 | CHAT_FEED_REFURL,
42 | process.env.SOCIALMINER_HOST, process.env.SOCIALMINER_CHAT_FEED_ID
43 | );
44 | const thisSession = sessionManager.getSession(sessionId);
45 |
46 | return `${"" +
47 | ""}${feedRefURL}` +
48 | `${thisSession.user.name}` +
49 | `${CHAT_TITLE}` +
50 | "" +
51 | "" +
52 | "ccxqueuetag" +
53 | `${CCX_QUEUETAG_PREFIX}${process.env.CCX_QUEUE_ID}` +
54 | "" +
55 | "" +
56 | "h_Name" +
57 | `${thisSession.user.name}` +
58 | "" +
59 | "" +
60 | "";
61 | };
62 |
63 | const _constructMessagePayload = text => `${"" +
64 | ""}${text}` +
65 | "";
66 |
67 | const SocialMinerRESTClient = {
68 | postChatRequest: (sessionId) => {
69 | logger.info(
70 | "Posting a chat request to SocialMiner [HOST=%s], [FEEDID=%s]",
71 | process.env.SOCIALMINER_HOST, process.env.SOCIALMINER_CHAT_FEED_ID
72 | );
73 |
74 | const options = {
75 | url: util.format(CHAT_URL, process.env.SOCIALMINER_HOST),
76 | method: "POST",
77 | headers: {
78 | "Content-Type": MIME_XML,
79 | },
80 | body: _constructChatRequestPayload(sessionId),
81 | resolveWithFullResponse: true,
82 | jar: sessionManager.getSession(sessionId).socialminer.cookieJar,
83 | };
84 |
85 | logger.debug("POST: new chat request", options);
86 | return request(options);
87 | },
88 |
89 | getLatestChatEvents: (sessionId) => {
90 | const thisSession = sessionManager.getSession(sessionId);
91 | const latestEventId = thisSession.socialminer.latestEventID;
92 |
93 | const options = {
94 | url: util.format(CHAT_URL, process.env.SOCIALMINER_HOST) + CHAT_EVENTS_QUERY_PARAMS + latestEventId,
95 | method: "GET",
96 | headers: {
97 | Accept: MIME_XML,
98 | },
99 | jar: thisSession.socialminer.cookieJar,
100 | };
101 |
102 | logger.debug("GET: chat events", options);
103 | return request(options);
104 | },
105 |
106 | putChatMessage: (sessionId, text) => {
107 | const options = {
108 | url: util.format(CHAT_URL, process.env.SOCIALMINER_HOST),
109 | method: "PUT",
110 | headers: {
111 | "Content-Type": MIME_XML,
112 | },
113 | body: _constructMessagePayload(text),
114 | jar: sessionManager.getSession(sessionId).socialminer.cookieJar,
115 | };
116 |
117 | logger.debug("PUT: chat message", options);
118 | return request(options);
119 | },
120 | };
121 |
122 | module.exports = SocialMinerRESTClient;
123 |
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/callback/services/ContactStatusService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample.callback.services;
23 | import java.io.IOException;
24 | import java.util.concurrent.atomic.AtomicBoolean;
25 |
26 | import org.apache.http.HttpEntity;
27 | import org.apache.http.HttpResponse;
28 | import org.apache.http.client.ClientProtocolException;
29 | import org.apache.http.client.HttpClient;
30 | import org.apache.http.client.methods.HttpGet;
31 | import org.apache.http.impl.client.DefaultHttpClient;
32 |
33 |
34 | import android.app.IntentService;
35 | import android.content.Intent;
36 | import android.os.Bundle;
37 | import android.os.IBinder;
38 | import android.os.Message;
39 | import android.os.Messenger;
40 | import android.os.RemoteException;
41 | import android.util.Log;
42 |
43 | /**
44 | * The Class ContactStatusService.
45 | * This service polls contact status and inform activity about the status
46 | */
47 | public class ContactStatusService extends IntentService{
48 |
49 | /** The poll status. */
50 | private AtomicBoolean pollStatus=new AtomicBoolean(true);
51 | /** Timeout between polls */
52 | private final long TIMEOUT=1000;//1 sec
53 | /**
54 | * Instantiates a new contact status service.
55 | */
56 | public ContactStatusService() {
57 | super("ContactStatusService");
58 |
59 | }
60 |
61 | /* (non-Javadoc)
62 | * @see android.app.IntentService#onBind(android.content.Intent)
63 | */
64 | @Override
65 | public IBinder onBind(Intent arg0) {
66 | return null;
67 | }
68 |
69 | /* (non-Javadoc)
70 | * @see android.app.IntentService#onCreate()
71 | */
72 | @Override
73 | public void onCreate() {
74 | super.onCreate();
75 | }
76 |
77 | /* (non-Javadoc)
78 | * @see android.app.IntentService#onDestroy()
79 | */
80 | @Override
81 | public void onDestroy() {
82 | super.onDestroy();
83 | this.pollStatus.getAndSet(false);
84 | }
85 |
86 | /* (non-Javadoc)
87 | * @see android.app.IntentService#onHandleIntent(android.content.Intent)
88 | */
89 | @Override
90 | protected void onHandleIntent(Intent intent) {
91 | String contactUrl =intent.getExtras().getString("contactUrl");
92 | Log.d("CallMe","Status Service starting poll for contactUrl :" + contactUrl);
93 | Messenger messenger = (Messenger) intent.getExtras().get("MESSENGER");
94 | this.pollStatus.getAndSet(true);
95 |
96 | while(this.pollStatus.get()){
97 | String status =getStatus(contactUrl);
98 |
99 | // inform activity about the status
100 | Message message = Message.obtain();
101 | Bundle bundle =new Bundle();
102 | bundle.putString("msgType", MessageType.CONTACT_STATUS.toString());
103 | bundle.putString("msgContent", status);
104 | message.setData(bundle);
105 | try {
106 | messenger.send(message);
107 | } catch (RemoteException e) {
108 | // TODO Auto-generated catch block
109 | e.printStackTrace();
110 | }
111 | // sleep for given timeout
112 | try {
113 | Thread.sleep(TIMEOUT);
114 | } catch (InterruptedException e) {
115 | e.printStackTrace();
116 | }
117 | }
118 | }
119 |
120 |
121 | /**
122 | * Gets the status.
123 | *
124 | * @param contactUrl
125 | * the contact url
126 | * @return the status
127 | */
128 | private String getStatus(String contactUrl){
129 | HttpClient httpclient = new DefaultHttpClient();
130 | HttpGet httpget = new HttpGet(contactUrl);
131 | Log.d("CallMe","executing request" + httpget.getRequestLine());
132 |
133 | try {
134 | HttpResponse response = httpclient.execute(httpget);
135 | HttpEntity entity = response.getEntity();
136 | // get the status from XML response
137 | if (entity != null) {
138 | Log.d("CallMe","Response content length: " + entity.getContentLength());
139 | byte[] b = new byte [(int) entity.getContentLength()];
140 | entity.getContent().read(b);
141 | String xml = new String(b);
142 | int start = xml.indexOf("") + "".length();
143 | int end = xml.indexOf("");
144 | return xml.substring(start, end);
145 | }
146 | } catch (ClientProtocolException e) {
147 | e.printStackTrace();
148 | } catch (IOException e) {
149 | e.printStackTrace();
150 | }
151 | return "unknown";
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/bubble-chat-scheduling/bubble.html:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
76 |
77 |
80 |
81 |
82 |
85 |
86 |
87 |
92 |
93 |
94 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/chat-facebook-messenger/README.md:
--------------------------------------------------------------------------------
1 | # Cisco SocialMiner - Chat Integration with Facebook Messenger
2 | _Sample integration of Facebook Messenger and CCX Web Chat using SocialMiner Chat APIs_
3 |
4 |
5 |
6 | ## Overview
7 | This sample illustrates how CCX Web Chat (powered by Cisco SocialMiner) can be integrated with Facebook Messenger (using a bot on [Facebook Messenger Platform](https://developers.facebook.com/docs/messenger-platform)) to provide an end-to-end chat experience between customers (who are facebook users) and CCX web chat agents (on the finesse desktop).
8 |
9 | The code is basically for a [Node.js](https://nodejs.org/) based cloud service (called **_Chat Gateway Service_**) hosted on the cloud, chat messages are transformed between SocialMiner (in the DMZ) and Facebook cloud.
10 |
11 | This sample conveys several important principles to the third-party developer, including:
12 | - usage of SocialMiner Chat APIs
13 | - chat session management multi-tenancy
14 | - Facebook Messenger Platform and its capabilities
15 |
16 | The same principles are also extendable beyond just Facebook Messenger - they can also be used to build custom integrations with any similar messaging solutions ([Apple Business Chat](https://developer.apple.com/business-chat/), [WhatsApp for Business](https://blog.whatsapp.com/10000633/Building-for-People-and-Now-Businesses) etc.).
17 |
18 | ## High-Level Design
19 | 
20 |
21 | ## Pre-requisites
22 | ### Infrastructure
23 | While this app is ready to be hosted on [Heroku](https://heroku.com) (see [Procfile](Procfile)), it can be hosted on any application/hosting environment or container framework.
24 |
25 | The only considerations for the infrastructure are public addressibility and connectivity of this cloud app with
26 | - facebook.com
27 | - your SocialMiner instance
28 |
29 | ### Deploying SocialMiner and Unified CCX
30 | This sample requires:
31 | - SocialMiner 11.6(1) and above
32 | - Unified CCX 11.6(1) and above
33 |
34 | Cisco SocialMiner should ideally be deployed on the DMZ such that it can be addressible and connected from anywhere in the public Internet, as well as have a direct connectivity into the enterprise network where Unified CCX servers and Agents are located.
35 |
36 | If your organization has not deployed SocialMiner in the DMZ, you will need to use a forwarding/reverse proxy (such as [ngrok](https://ngrok.com) or [nginx](https://www.nginx.com/resources/admin-guide/reverse-proxy/).
37 |
38 | ### Setting-up Facebook Messenger Bot
39 | See the [Getting Started](https://developers.facebook.com/docs/messenger-platform/guides/setup) guides by Facebook on how to create a facebook app (bot), acquire required tokens etc.
40 |
41 | ## Running
42 | The following environment variables are required to be defined (in `process.env`) to launch and run the app.
43 |
44 | |Variable|Description|
45 | |--------|-----------|
46 | |__PORT__ |A 16-bit UNIX port number where this app will bind to|
47 | |__FB_PAGE_ACCESS_TOKEN__|The page access token issued by Facebook when you configure messenger for a page|
48 | |__FB_VERIFICATION_TOKEN__|A token that is to be provided by your app when Facebook challenges the validity of your webhook URL|
49 | |__VIRTUAL_ASSISTANT_NAME__|The name of your virtual assistant (E.g. _Siri_, _Alexa_ etc.)|
50 | |__SOCIALMINER_HOST__|A valid fully qualified hostname of your SocialMiner server|
51 | |__SOCIALMINER_CHAT_FEED_ID__|The ID of the chat feed in SocialMiner. Can be obtained by calling the `/feed` API on SocialMiner|
52 | |__CCX_QUEUE_ID__|The ID of the CCX Chat Contact Service Queue. Can be obtained by calling the `/csq/` API on CCX|
53 |
54 | ## Disclaimer
55 | This sample illustrates how CCX Web Chat (powered by Cisco SocialMiner) can be integrated with Facebook Messenger (using a bot on [Facebook Messenger Platform](https://developers.facebook.com/docs/messenger-platform)) to provide an end-to-end chat experience between customers (who are facebook users) and CCX web chat agents (on the finesse desktop).
56 |
57 | This sample should act as a guide for a programmer to understand how to integrate and manage the customer-side of a chat session with custom messaging services on the web. Please refer [SocialMiner Developer's Guide](https://developer.cisco.com/site/socialminer/documentation/) for further details about the chat APIs. Please see the _"Web Chat"_ section of [Unified CCX Configuration Guides](https://developer.cisco.com/site/contact-center-express/docs/) for instructions on deploying Unified CCX Web Chat Feature using SocialMiner Chat APIs.
58 |
59 | For more information regarding Facebook Messenger platform, see [here](https://developers.facebook.com/docs/messenger-platform/guides/setup).
60 |
61 | This is only a sample and is NOT intended to be a production quality application and will not be supported as such. It is NOT guaranteed to be bug free. It is merely provided as a guide for 3rd-party developers on best practices and usage of the SocialMiner RESTful APIs and is not intended for production use "as is".
62 |
63 | Cisco's responsibility and liability on this code is limited ONLY to the correctness and accuracy on the usage of the RESTful API interface and the quality of the RESTful API interface itself. Any omissions from this example are not to be considered capabilities that are supported or not supported by the product.
64 |
65 | For specific capabilities refer to the documentation that accompanies the latest Cisco SocialMiner release and/or request help from [DevNet](http://developer.cisco.com) or the Cisco Technical Assistance Center (TAC).
66 |
67 | ## Support Notice
68 | DevNet provides sample support on a “best effort” basis. Like any custom deployment, it is the responsibility of the partner and/or customer to ensure that the customization works correctly. Cisco reserves the right to make changes to APIs and any other published interfaces as part of the normal Cisco SocialMiner release cycle.
69 |
70 | https://developer.cisco.com/site/socialminer/overview/
--------------------------------------------------------------------------------
/callback/android-sample/README.md:
--------------------------------------------------------------------------------
1 | # Cisco SocialMiner - Callback (Agent Request API) Sample Android App
2 | _Sample Android application to illustrate use of SocialMiner Agent Request (Callback) APIs_
3 |
4 | ## Overview
5 | The Android Callback sample is intended to serve as an example of using the SocialMiner Callback API inside of an Android application.
6 |
7 | ## Pre-requisites
8 | - SocialMiner and PCCE/UCCE installed and the Agent Request Feature configured (Follow the directions in the _"Agent Request"_ section of [CCE Optional Features Guide](https://developer.cisco.com/site/packaged-contact-center/documentation/)).
9 |
10 | - A registered, online customer phone that is reachable from a CCE agent.
11 |
12 | - The ID of the callback feed configured to process callback requests. The ID can be obtained using the following SocialMiner REST API:
13 | ```
14 | http:///ccp-webapp/ccp/feed
15 | ```
16 | This REST API will list XML for each feed configured on SocialMiner. Feeds with type `10` are callback feeds. The name given when the feed was configured is also listed. This is the easiest way to find the XML for`the callback feed. Here is some sample output from the feed API:
17 | ```xml
18 |
19 |
20 | 0
21 | Callback
22 | http:///ccp/callback/feed/101212
23 | http:///ccp-webapp/ccp/feed/101212
24 | 1
25 |
26 | callback
27 |
28 | 10
29 |
30 | ...
31 |
32 | ```
33 | The ID of the feed is the number at the end of the `refURL` field. In this
34 | example, the ID is `101212`.
35 |
36 | - Necessary development environment for building Android apps ([Eclipse IDE](https://www.eclipse.org/downloads/packages/) with android development plugins)
37 |
38 | ## Loading and Running the Sample
39 | - Launch Eclipse.
40 | - Select **_File -> Import_** to bring up the Import dialog.
41 | - Select **_Android_** and select _"Existing Android Code into Workspace"_.
42 | - Click **_Browse_** and select the `/callback-android-sample` directory. `` is the directory in which the sample was extracted.
43 | - The first row of the Project table should be populated. Click **_Finish_**.
44 | - Once the project imports, right click on the project and select **_Run As -> Android Application_**.
45 | - The first time you do this you will be prompted to select an **Android Virtual Device**. Setup an Android Virtual Device that emulates a smartphone.
46 | - Once the virtual device is up, right-click on the project and select **_Run As -> Android Application_**. The callback example should appear on the virtual device.
47 | - Inside the app, click **_Settings_** and then click the **_Server_** field to display the Server dialog. Enter the IP address or fully qualified hostname of your SocialMiner server.
48 | - Click **_Form_** to go back to the callback form. Enter the name and phone number.
49 | - Enter the ID of the callback feed that is configured to process callback contacts. This ID can be obtained using SocialMiner's Feed API. Please see the [Pre-requisites](#pre-requisites) section of this document for further details on retrieving the feed ID.
50 | - Click **_Call me back_**. If everything is configured properly, you will see the app UI display the status of your request. If all goes well, you should see the request transition from queued to handled.
51 |
52 | ## Understanding the Code
53 | The following classes use the Callback API to manage the callback request:
54 | - `com.cisco.sample.callback.services.RequestCallbackService`: This class is used to initiate the callback request. The callback request is initiated using HTTP `GET`.
55 |
56 | - `com.cisco.sample.callback.services.ContactStatusService`: This class polls for the status of the callback request.
57 |
58 | The following classes are responsible for the Callback application UI:
59 | - `com.cisco.sample.MainActivity`: This is the main entry point into the application. It initializes the callback form and the settings form.
60 |
61 | - `com.cisco.sample.callback.CallbackFormActivity`: This form is responsible for collecting the callback information and generating a message to `RequestCallbackService` to initiate the callback request.
62 |
63 | - `com.cisco.sample.callback.CallbackStatusActivity`: Displays the status of the callback request.
64 |
65 | ## Disclaimer
66 | This callback sample is made available to Cisco partners and customers. _It is merely provided as a guide for a programmer to see how to initiate and manage a callback request._ Please refer [SocialMiner Developer's Guide](https://developer.cisco.com/site/socialminer/documentation/) for further details about the callback API. Please see the _"Agent Request"_ section of [CCE Optional Features Guide](https://developer.cisco.com/site/packaged-contact-center/documentation/) for UCCE and PCCE for instructions on deploying CCE Agent Request Feature using SocialMiner Callback API.
67 |
68 | This is only a sample and is NOT intended to be a production quality application and will not be supported as such. It is NOT guaranteed to be bug free. It is merely provided as a guide for 3rd-party developers on best practices and usage of the SocialMiner RESTful APIs and is not intended for production use "as is".
69 |
70 | Cisco's responsibility and liability on this code is limited ONLY to the correctness and accuracy on the usage of the RESTful API interface and the quality of the RESTful API interface itself. Any omissions from this example are not to be considered capabilities that are supported or not supported by the product.
71 |
72 | For specific capabilities refer to the documentation that accompanies the latest Cisco SocialMiner release and/or request help from [DevNet](http://developer.cisco.com) or the Cisco Technical Assistance Center (TAC).
73 |
74 | ## Support Notice
75 | DevNet provides sample support on a “best effort” basis. Like any custom deployment, it is the responsibility of the partner and/or customer to ensure that the customization works correctly. Cisco reserves the right to make changes to APIs and any other published interfaces as part of the normal Cisco SocialMiner release cycle.
76 |
77 | https://developer.cisco.com/site/socialminer/overview/
--------------------------------------------------------------------------------
/callback/android-sample/src/com/cisco/sample/callback/CallbackFormActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Cisco Systems, Inc.
3 | * Copyright (c) 2014
4 | * All rights reserved.
5 | * Cisco SocialMiner 10.5(1)
6 | *-------------------------------------------------------------------------
7 | * The code included in this module is intended to provide guidance to the
8 | * developer on best practices and usage of the SocialMiner Callback
9 | * interface and is not intended for production use “as is”.
10 | *
11 | * Cisco's responsibility and liability on this code is limited ONLY to the
12 | * correctness and accuracy on the usage of the callback interface and the
13 | * quality of the callback interface itself. Any omissions from this
14 | * example are not to be considered capabilities that are supported or not
15 | * supported by the product.
16 | *
17 | * For specific capabilites refer to the documentation that accompanies this
18 | * release and/or request help from the Cisco Developer Network
19 | * (http://developer.cisco.com) or the Cisco Technical Assistance Center
20 | */
21 |
22 | package com.cisco.sample.callback;
23 |
24 | import com.cisco.sample.R;
25 | import com.cisco.sample.callback.services.HandleMessage;
26 | import com.cisco.sample.callback.services.MessageType;
27 | import com.cisco.sample.callback.services.RequestCallbackService;
28 | import com.cisco.sample.callback.services.ServiceMessageHandler;
29 |
30 | import android.app.Activity;
31 | import android.app.ProgressDialog;
32 | import android.content.Context;
33 | import android.content.Intent;
34 | import android.content.SharedPreferences;
35 | import android.os.Bundle;
36 | import android.os.Messenger;
37 | import android.preference.PreferenceManager;
38 | import android.telephony.TelephonyManager;
39 | import android.view.View;
40 | import android.view.View.OnClickListener;
41 | import android.widget.Button;
42 | import android.widget.EditText;
43 | import android.widget.Toast;
44 |
45 | /**
46 | * The Class CallFormActivity.
47 | * Activity to collect callback request data and then calling service to create callback request
48 | *
49 | */
50 | public class CallbackFormActivity extends Activity implements HandleMessage{
51 |
52 | /** The progressDialog. */
53 | private ProgressDialog progressDialog=null;
54 |
55 | /** The handler. */
56 | private ServiceMessageHandler handler;
57 |
58 | /**
59 | * Instantiates a new call form activity.
60 | */
61 | public CallbackFormActivity() {
62 | handler = new ServiceMessageHandler(this);
63 | }
64 |
65 | /* (non-Javadoc)
66 | * @see android.app.Activity#onCreate(android.os.Bundle)
67 | */
68 | @Override
69 | public void onCreate(Bundle savedInstanceState) {
70 | super.onCreate(savedInstanceState);
71 | loadInitialFormView();
72 |
73 | Button button = (Button) findViewById(R.id.formSubmitButton);
74 |
75 | // add handler to button to submit callback request
76 | button.setOnClickListener(new OnClickListener()
77 | {
78 | public void onClick(View v)
79 | {
80 |
81 | EditText phone = (EditText) findViewById(R.id.entryFormPhone);
82 | EditText name = (EditText) findViewById(R.id.entryFormName);
83 | EditText feedId = (EditText) findViewById(R.id.entryFormFeedId);
84 | postCallbackRequest(feedId.getText().toString(), name.getText().toString(), phone.getText().toString());
85 |
86 | }
87 | });
88 | }
89 |
90 |
91 | /**
92 | * Post callback request.
93 | *
94 | * @param feedId
95 | * the feed id
96 | * @param name
97 | * the name
98 | * @param phone
99 | * the phone
100 | */
101 | private void postCallbackRequest(String feedId, String name,String phone){
102 | SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
103 | String hostname = sharedPrefs.getString("Hostname",null);
104 | if(hostname==null) {
105 | Toast.makeText(getApplicationContext(), "Please configure the hostname in settings before submitting callback request", Toast.LENGTH_LONG).show();
106 | return;
107 | }
108 | progressDialog = ProgressDialog.show(CallbackFormActivity.this, "",
109 | "Submitting your request", true);
110 | // Collect data from UI and pass to service which initiates callback request
111 | Intent intent = new Intent(CallbackFormActivity.this,RequestCallbackService.class);
112 | intent.putExtra("hostname", hostname);
113 | intent.putExtra("feedId", feedId);
114 | intent.putExtra("name", name);
115 | intent.putExtra("phone", phone);
116 | // Add handler for messages from service
117 | Messenger messenger = new Messenger(handler);
118 | intent.putExtra("MESSENGER", messenger);
119 | startService(intent);
120 | }
121 |
122 |
123 |
124 |
125 | /**
126 | * Poll for callback contact status.
127 | *
128 | * @param contactUrl
129 | * the contact url
130 | */
131 | private void pollForCallbackContactStatus(String contactUrl){
132 | if(contactUrl==null) {
133 | Toast.makeText(getApplicationContext(), "Cannot request for callback at this time. Try again", Toast.LENGTH_LONG).show();
134 | return;
135 | }
136 | // Call activity which polls for contact status
137 | Intent intent = new Intent(getBaseContext(), CallbackStatusActivity.class);
138 | intent.putExtra("contactUrl", contactUrl);
139 | startActivity(intent);
140 |
141 | }
142 |
143 | /**
144 | * Load initial form view.
145 | */
146 | private void loadInitialFormView(){
147 | setContentView(R.layout.activity_call_form);
148 |
149 | // Set device's phone number in form's phone field
150 | EditText phoneText = (EditText) findViewById(R.id.entryFormPhone);
151 | TelephonyManager tMgr =(TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
152 | String mPhoneNumber = tMgr.getLine1Number();
153 | phoneText.setText(mPhoneNumber);
154 | }
155 |
156 | /* (non-Javadoc)
157 | * @see com.cisco.sample.HandleMessage#handleMessage(de.ankit.callme.MessageType, java.lang.String)
158 | */
159 | @Override
160 | public void handleMessage(MessageType type, String msg) {
161 | if(type != MessageType.NEW_CONTACT)
162 | return;
163 |
164 | // dismiss the progress dialog
165 | progressDialog.dismiss();
166 | pollForCallbackContactStatus(msg);
167 |
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/callback/html-sample/README.md:
--------------------------------------------------------------------------------
1 | # Cisco SocialMiner - Callback (Agent Request API) Sample
2 | _Sample web-based (javascript) application to illustrate SocialMiner Agent Request (Callback) APIs_
3 |
4 | ## Overview
5 | The HTML Callback sample is intended to serve as an example of using the SocialMiner Callback API from Javascript.
6 |
7 | This sample illustrates using both GET and POST methods to initiate callbacks, using GET to poll for callback status (including estimated wait time), and using DELETE to cancel callbacks.
8 |
9 | This sample also includes a node-based HTTP proxy. This proxy serves up the callback html page and proxies the callback API to work around Cross Origin Resource Sharing (CORS) issues that would otherwise prevent the user from experimenting with the callback HTML page. (**NOTE:** The proxy is needed only for SocialMiner versions 11.5 and older. Starting SocialMiner 11.6, CORS support is fully implemented for callback APIs)
10 |
11 | ## Pre-requisites
12 | - SocialMiner and PCCE/UCCE installed and the Agent Request Feature configured (Follow the directions in the _"Agent Request"_ section of [CCE Optional Features Guide](https://developer.cisco.com/site/packaged-contact-center/documentation/)).
13 |
14 | - A registered, online customer phone that is reachable from a CCE agent.
15 |
16 | - The ID of the callback feed configured to process callback requests. The ID can be obtained using the following SocialMiner REST API:
17 | ```
18 | http:///ccp-webapp/ccp/feed
19 | ```
20 | This REST API will list XML for each feed configured on SocialMiner. Feeds with type `10` are callback feeds. The name given when the feed was configured is also listed. This is the easiest way to find the XML for`the callback feed. Here is some sample output from the feed API:
21 | ```xml
22 |
23 |
24 | 0
25 | Callback
26 | http:///ccp/callback/feed/101212
27 | http:///ccp-webapp/ccp/feed/101212
28 | 1
29 |
30 | callback
31 |
32 | 10
33 |
34 | ...
35 |
36 | ```
37 | The ID of the feed is the number at the end of the `refURL` field. In this
38 | example, the ID is `101212`.
39 |
40 | - Install [Node.js](https://nodejs.org/)
41 |
42 | ### Configuring Node.js
43 | Run these steps to ensure node.js has the necessary dependencies to run the proxy.
44 | - Change directory to `/callback-html-sample/node`.
45 |
46 | `` is the directory in which the sample was extracted.
47 |
48 | - Run the following command to install dependencies:
49 | ```
50 | npm install
51 | ```
52 | - At this point, `node` has the dependencies it needs to serve up the callback html page as well as proxy the SocialMiner callback API request.
53 |
54 | ## Running
55 | - Open a terminal and change directory to `/callback-html-sample/node`
56 |
57 | - Run the following command:
58 | ```
59 | node CallbackProxy.js --host
60 | ```
61 |
62 | - Open the following URL in your browser: http://localhost:8080/callback.html
63 |
64 | Port **8080** is the default setting for `API_PROXY_LISTEN_PORT` in `CallbackProxy.js`.
65 |
66 | If you changed `API_PROXY_LISTEN_PORT`, use the new setting in the URL.
67 |
68 | - Enter a Title, Name, and Phone on the form presented in your browser.
69 |
70 | - Enter the ID of the callback feed that is configured to process callback contacts. This ID can be obtained using SocialMiner's Feed API. Please see the pre-requisites section of this document for further details on retrieving the feed ID.
71 |
72 | - Optionally, enter call variables.
73 |
74 | - Optionally enter an ECC variable. By default, this sample uses the `user.test.callback` ECC variable. The sample can be modified to use an ECC variable configured in your deployment.
75 |
76 | - Click _**"Call me back"**_
77 |
78 | - If everything is configured properly, you will see the UI display the message _**"Finding the right agent for your request."**_
79 |
80 | - If estimated wait time is configured, it will be displayed.
81 |
82 | - When an agent is found, the UI displays the message _**"Agent found for your request. Expect a phone call shortly."**_
83 |
84 | ## Modifying / Extending
85 | The sample uses `GET` to initiate callback requests. This can be changed by modifying the callback.html file in the `/html` directory. Search for the string `var useGet`. You will see that the variable `useGet` is set to `true`. Changing this setting to `false` will make the application use `POST` to initiate callback requests.
86 |
87 | The `callbackUsingHTTPGet()` funciton illustrates how to use `GET` to initiate a callback. The `callbackUsingHTTPPost()` illustrates how to use `POST` to initiate a callback.
88 |
89 | To change the callback ECC variable, search for `user_user.test.callback`. If you are using `GET` to initiate callbacks, change the `user_user.test.callback` string in the `if ( useGet )` block to match the ECC variable configured in your deployment. For example, a deployment with the variable `user.accountNumber` would change `user_user.test.callback` to `user_user.accountNumber`.
90 |
91 | If you are using `POST` to initiate callbacks, modify the else portion of the `if ( useGet )` block.
92 |
93 | ## Disclaimer
94 | This callback sample is made available to Cisco partners and customers _as a convenience to help minimize the cost of Cisco SocialMiner customizations._ Please refer [SocialMiner Developer's Guide](https://developer.cisco.com/site/socialminer/documentation/) for further details about the callback API. Please see the _"Agent Request"_ section of [CCE Optional Features Guide](https://developer.cisco.com/site/packaged-contact-center/documentation/) for UCCE and PCCE for instructions on deploying CCE Agent Request Feature using SocialMiner Callback API.
95 |
96 | This is only a sample and is NOT intended to be a production quality application and will not be supported as such. It is NOT guaranteed to be bug free. It is merely provided as a guide for 3rd-party developers on best practices and usage of the SocialMiner RESTful APIs and is not intended for production use "as is".
97 |
98 | Cisco's responsibility and liability on this code is limited ONLY to the correctness and accuracy on the usage of the RESTful API interface and the quality of the RESTful API interface itself. Any omissions from this example are not to be considered capabilities that are supported or not supported by the product.
99 |
100 | For specific capabilities refer to the documentation that accompanies the latest Cisco SocialMiner release and/or request help from [DevNet](http://developer.cisco.com) or the Cisco Technical Assistance Center (TAC).
101 |
102 | ## Support Notice
103 | DevNet provides sample support on a “best effort” basis. Like any custom deployment, it is the responsibility of the partner and/or customer to ensure that the customization works correctly. Cisco reserves the right to make changes to APIs and any other published interfaces as part of the normal Cisco SocialMiner release cycle.
104 |
105 | https://developer.cisco.com/site/socialminer/overview/
--------------------------------------------------------------------------------
/customer-chat-proactive/scripts/3rdparty/jquery-xml2json/jquery.xml2json.js:
--------------------------------------------------------------------------------
1 | /*
2 | ### jQuery XML to JSON Plugin v1.2 - 2013-02-18 ###
3 | * http://www.fyneworks.com/ - diego@fyneworks.com
4 | * Licensed under http://en.wikipedia.org/wiki/MIT_License
5 | ###
6 | Website: http://www.fyneworks.com/jquery/xml-to-json/
7 | *//*
8 | # INSPIRED BY: http://www.terracoder.com/
9 | AND: http://www.thomasfrank.se/xml_to_json.html
10 | AND: http://www.kawa.net/works/js/xml/objtree-e.html
11 | *//*
12 | This simple script converts XML (document of code) into a JSON object. It is the combination of 2
13 | 'xml to json' great parsers (see below) which allows for both 'simple' and 'extended' parsing modes.
14 | */
15 | // Avoid collisions
16 | ;if(window.jQuery) (function($){
17 |
18 | // Add function to jQuery namespace
19 | $.extend({
20 |
21 | // converts xml documents and xml text to json object
22 | xml2json: function(xml, extended) {
23 | if(!xml) return {}; // quick fail
24 |
25 | //### PARSER LIBRARY
26 | // Core function
27 | function parseXML(node, simple){
28 | if(!node) return null;
29 | var txt = '', obj = null, att = null;
30 | var nt = node.nodeType, nn = jsVar(node.localName || node.nodeName);
31 | var nv = node.text || node.nodeValue || '';
32 | /*DBG*/ //if(window.console) console.log(['x2j',nn,nt,nv.length+' bytes']);
33 | if(node.childNodes){
34 | if(node.childNodes.length>0){
35 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'CHILDREN',node.childNodes]);
36 | $.each(node.childNodes, function(n,cn){
37 | var cnt = cn.nodeType, cnn = jsVar(cn.localName || cn.nodeName);
38 | var cnv = cn.text || cn.nodeValue || '';
39 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>a',cnn,cnt,cnv]);
40 | if(cnt == 8){
41 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>b',cnn,'COMMENT (ignore)']);
42 | return; // ignore comment node
43 | }
44 | else if(cnt == 3 || cnt == 4 || !cnn){
45 | // ignore white-space in between tags
46 | if(cnv.match(/^\s+$/)){
47 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>c',cnn,'WHITE-SPACE (ignore)']);
48 | return;
49 | };
50 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>d',cnn,'TEXT']);
51 | txt += cnv.replace(/^\s+/,'').replace(/\s+$/,'');
52 | // make sure we ditch trailing spaces from markup
53 | }
54 | else{
55 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>e',cnn,'OBJECT']);
56 | obj = obj || {};
57 | if(obj[cnn]){
58 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>f',cnn,'ARRAY']);
59 |
60 | // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
61 | if(!obj[cnn].length) obj[cnn] = myArr(obj[cnn]);
62 | obj[cnn] = myArr(obj[cnn]);
63 |
64 | obj[cnn][ obj[cnn].length ] = parseXML(cn, true/* simple */);
65 | obj[cnn].length = obj[cnn].length;
66 | }
67 | else{
68 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>g',cnn,'dig deeper...']);
69 | obj[cnn] = parseXML(cn);
70 | };
71 | };
72 | });
73 | };//node.childNodes.length>0
74 | };//node.childNodes
75 | if(node.attributes){
76 | if(node.attributes.length>0){
77 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'ATTRIBUTES',node.attributes])
78 | att = {}; obj = obj || {};
79 | $.each(node.attributes, function(a,at){
80 | var atn = jsVar(at.name), atv = at.value;
81 | att[atn] = atv;
82 | if(obj[atn]){
83 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'ARRAY']);
84 |
85 | // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
86 | //if(!obj[atn].length) obj[atn] = myArr(obj[atn]);//[ obj[ atn ] ];
87 | obj[cnn] = myArr(obj[cnn]);
88 |
89 | obj[atn][ obj[atn].length ] = atv;
90 | obj[atn].length = obj[atn].length;
91 | }
92 | else{
93 | /*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'TEXT']);
94 | obj[atn] = atv;
95 | };
96 | });
97 | //obj['attributes'] = att;
98 | };//node.attributes.length>0
99 | };//node.attributes
100 | if(obj){
101 | obj = $.extend( (txt!='' ? new String(txt) : {}),/* {text:txt},*/ obj || {}/*, att || {}*/);
102 | txt = (obj.text) ? (typeof(obj.text)=='object' ? obj.text : [obj.text || '']).concat([txt]) : txt;
103 | if(txt) obj.text = txt;
104 | txt = '';
105 | };
106 | var out = obj || txt;
107 | //console.log([extended, simple, out]);
108 | if(extended){
109 | if(txt) out = {};//new String(out);
110 | txt = out.text || txt || '';
111 | if(txt) out.text = txt;
112 | if(!simple) out = myArr(out);
113 | };
114 | return out;
115 | };// parseXML
116 | // Core Function End
117 | // Utility functions
118 | var jsVar = function(s){ return String(s || '').replace(/-/g,"_"); };
119 |
120 | // NEW isNum function: 01/09/2010
121 | // Thanks to Emile Grau, GigaTecnologies S.L., www.gigatransfer.com, www.mygigamail.com
122 | function isNum(s){
123 | // based on utility function isNum from xml2json plugin (http://www.fyneworks.com/ - diego@fyneworks.com)
124 | // few bugs corrected from original function :
125 | // - syntax error : regexp.test(string) instead of string.test(reg)
126 | // - regexp modified to accept comma as decimal mark (latin syntax : 25,24 )
127 | // - regexp modified to reject if no number before decimal mark : ".7" is not accepted
128 | // - string is "trimmed", allowing to accept space at the beginning and end of string
129 | var regexp=/^((-)?([0-9]+)(([\.\,]{0,1})([0-9]+))?$)/
130 | return (typeof s == "number") || regexp.test(String((s && typeof s == "string") ? jQuery.trim(s) : ''));
131 | };
132 | // OLD isNum function: (for reference only)
133 | //var isNum = function(s){ return (typeof s == "number") || String((s && typeof s == "string") ? s : '').test(/^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/); };
134 |
135 | var myArr = function(o){
136 |
137 | // http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
138 | //if(!o.length) o = [ o ]; o.length=o.length;
139 | if(!$.isArray(o)) o = [ o ]; o.length=o.length;
140 |
141 | // here is where you can attach additional functionality, such as searching and sorting...
142 | return o;
143 | };
144 | // Utility functions End
145 | //### PARSER LIBRARY END
146 |
147 | // Convert plain text to xml
148 | if(typeof xml=='string') xml = $.text2xml(xml);
149 |
150 | // Quick fail if not xml (or if this is a node)
151 | if(!xml.nodeType) return;
152 | if(xml.nodeType == 3 || xml.nodeType == 4) return xml.nodeValue;
153 |
154 | // Find xml root node
155 | var root = (xml.nodeType == 9) ? xml.documentElement : xml;
156 |
157 | // Convert xml to json
158 | var out = parseXML(root, true /* simple */);
159 |
160 | // Clean-up memory
161 | xml = null; root = null;
162 |
163 | // Send output
164 | return out;
165 | },
166 |
167 | // Convert text to XML DOM
168 | text2xml: function(str) {
169 | // NOTE: I'd like to use jQuery for this, but jQuery makes all tags uppercase
170 | //return $(xml)[0];
171 | var out;
172 | try{
173 | var xml = ((!$.support.opacity && !$.support.style))?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser();
174 | xml.async = false;
175 | }catch(e){ throw new Error("XML Parser could not be instantiated") };
176 | try{
177 | if((!$.support.opacity && !$.support.style)) out = (xml.loadXML(str))?xml:false;
178 | else out = xml.parseFromString(str, "text/xml");
179 | }catch(e){ throw new Error("Error parsing XML string") };
180 | return out;
181 | }
182 |
183 | }); // extend $
184 |
185 | })(jQuery);
186 |
--------------------------------------------------------------------------------
/task/README.md:
--------------------------------------------------------------------------------
1 | # Cisco SocialMiner - Task API Sample
2 | _Sample web-based (javascript) application to illustrate SocialMiner Task APIs_
3 |
4 | ## Overview
5 | ### About Task Routing
6 | Task Routing constitutes the ability to route tasks of any nature to human experts in a Customer Care center or even bots and programs. Tasks are actionable events which require the attention of human experts or other intelligent agents. Task Routing APIs bring the power of Cisco Contact Center Enterprise (CCE) to third-party multichannel applications. It enables these applications to send task requests to experts based on business rules, regardless of the media.
7 |
8 | Task Routing APIs provide a standard way to request, queue, route, and handle third-party multichannel tasks in the CCE environment. Contact Center customers or partners can use the Task Routing APIs to develop specialized applications that was not built by Cisco as part of the platform.
9 |
10 | For more details, check out the [Task Routing Portal](https://developer.cisco.com/site/task-routing) on Cisco DevNet.
11 |
12 | ### SocialMiner Task APIs
13 | SocialMiner provides the ability to submit multichannel tasks to Contact Center Enterprise and poll the status of individual tasks via a set of powerful, flexible RESTful APIs called **Task APIs**.
14 |
15 | This sample is a web application (built using javascript) that illustrates the following task APIs:
16 |
17 | - `GET` and `POST` APIs to initiate tasks
18 | - `GET` to poll for Task status (including estimated wait time)
19 | - `DELETE` to cancel tasks
20 |
21 | This sample also includes a node.js-based HTTP proxy. This proxy serves up the Task html page and proxies the Task API to work around cross-site scripting issues that would otherwise prevent the user from experimenting with the Task HTML page. (**NOTE:** The proxy is needed only for SocialMiner versions 11.5 and older. Starting SocialMiner 11.6, CORS support is fully implemented for task APIs)
22 |
23 | ## Pre-requisites
24 | - SocialMiner integrated with Packaged CCE or Unified CCE and Finesse. The Task Routing feature should be configured on SocialMiner (via CCE administration), CCE, and Finesse. For more information, refer [Task Routing Setup and Configuration](https://developer.cisco.com/site/task-routing/docs/#task-routing-setup-and-configuration) section in Cisco DevNet portal.
25 |
26 | - The ID of the Task feed configured to process Task requests. The ID can be obtained using the following SocialMiner REST API:
27 | ```
28 | http:///ccp-webapp/ccp/feed
29 | ```
30 | This REST API lists XML for each feed configured on SocialMiner. Feeds with type `12` are task feeds. The name given when the feed was configured is also listed. This is the easiest way to find the XML for the Task feed. Here is some sample output from the feed API:
31 | ```xml
32 |
33 |
34 | 0
35 | Task
36 | http:///ccp/task/feed/101212
37 | http:///ccp-webapp/ccp/feed/101212
38 | 1
39 |
40 | task
41 |
42 | 12
43 |
44 | ...
45 |
46 | ```
47 | The ID of the feed is the number at the end of the `refURL` field. In this example, the ID is `101212`.
48 |
49 | - Install [Node.js](https://nodejs.org/)
50 |
51 | ### Configuring Node.js
52 | Run these steps to ensure node.js has the necessary dependencies to run the proxy.
53 | - Change directory to `/node`.
54 | `` is the directory in which the sample was extracted.
55 |
56 | - Run the following command to install dependencies:
57 | ```
58 | npm install
59 | ```
60 |
61 | - At this point, `node` has the dependencies it needs to serve up the Task html page as well as proxy the SocialMiner Task API.
62 |
63 | ## Running
64 | - Open a terminal and change directory to /node
65 |
66 | - Run the following command:
67 | ```
68 | node TaskProxy.js --host
69 | ```
70 | `` is the hostname or IP address of SocialMiner
71 |
72 | - Open the following URL in your browser: http://localhost:8080/task.html
73 | _Port 8080 is the default setting for `API_PROXY_LISTEN_PORT` in TaskProxy.js._
74 | _If you changed `API_PROXY_LISTEN_PORT`, use the new setting in the URL._
75 |
76 | - Enter a Title, Name and a Script Selector identifier that is configured for the Media Routing Domain to which you want to route the task.
77 |
78 | **_How to find the Script Selector?_**
79 | - **Unified CCE:** Open _CCE Configuration Manager_. Expand _List Tools_ and select _Dialed Number/Script Selector List_. Click _Retrieve_, and then find the Script Selector option that corresponds to the correct Media Routing Domain. The Script Selector identifier is the text in the _Dialed Number / Script Selector_ field.
80 |
81 | - **Packaged CCE:** In Unified CCE Administration, navigate to _Manage_ > _Dialed Numbers_. Find the Dialed Number that corresponds to the correct Media Routing Domain. The Script Selector identifier is the text in the _Dialed Number_ field.
82 |
83 | - Enter the ID of the Task feed that is configured to process task contacts. This ID can be obtained using SocialMiner's Feed API. Please see [Pre-requisites](#pre-requisites) (above) for further details on retrieving the feed ID.
84 |
85 | - Optionally enter call variables, and ECC variables. By default, this sample uses the `user.test.task` ECC variable. The sample can be modified to use an ECC variable configured in your deployment.
86 |
87 | - Submit the task from the UI.
88 |
89 | - If everything is configured properly, the UI will display the message _"Finding the right agent for your request."_
90 |
91 | - The UI displays the estimated wait time, if configured.
92 |
93 | - When an agent is found, the UI displays the message _"Agent found for your request."_
94 |
95 | ## Modifying
96 | The sample uses GET to initiate task requests. This can be changed by modifying [task.html](html/task.html). Search for the string `'var useGet'`. You see that the variable `useGet` is set to `true`. Changing this setting to `false` makes the application use `POST` to initiate Task requests.
97 |
98 | The `taskUsingHTTPGet()` function illustrates how to use `GET` to initiate a task. The `taskUsingHTTPPost()` illustrates how to use `POST` to initiate a task.
99 |
100 | To change the Task ECC variable, search for `'user_user.test.task'`. If you are using `GET` to initiate tasks, change the `'user_user.test.task'` string in the `'if ( useGet )'` block to match the ECC variable configured in your deployment. For example, a deployment with the variable `user.accountNumber` would change `'user_user.test.task'` to `'user_user.accountNumber'`.
101 |
102 | If you are using `POST` to initiate tasks, modify the else portion of the `'if ( useGet )'` block.
103 |
104 | ## Disclaimer
105 | This task sample application is made available to Cisco partners and customers _as a convenience to help minimize the cost of Cisco SocialMiner customizations._ Please refer [SocialMiner Developer's Guide](https://developer.cisco.com/site/socialminer/documentation/) for further details about the task API. Please visit and check resources available in the [Task Routing DevNet Portal](https://developer.cisco.com/site/task-routing/) for instructions on deploying CCE Task Routing Feature using SocialMiner Task API and Cisco Finesse APIs.
106 |
107 | This is only a sample and is NOT intended to be a production quality application and will not be supported as such. It is NOT guaranteed to be bug free. It is merely provided as a guide for 3rd-party developers on best practices and usage of the SocialMiner RESTful APIs and is not intended for production use "as is".
108 |
109 | Cisco's responsibility and liability on this code is limited ONLY to the correctness and accuracy on the usage of the RESTful API interface and the quality of the RESTful API interface itself. Any omissions from this example are not to be considered capabilities that are supported or not supported by the product.
110 |
111 | For specific capabilities refer to the documentation that accompanies the latest Cisco SocialMiner release and/or request help from [DevNet](http://developer.cisco.com) or the Cisco Technical Assistance Center (TAC).
112 |
113 | ## Support Notice
114 | DevNet provides sample support on a “best effort” basis. Like any custom deployment, it is the responsibility of the partner and/or customer to ensure that the customization works correctly. Cisco reserves the right to make changes to APIs and any other published interfaces as part of the normal Cisco SocialMiner release cycle.
115 |
116 | https://developer.cisco.com/site/socialminer/overview/
--------------------------------------------------------------------------------
/customer-chat/README.md:
--------------------------------------------------------------------------------
1 | # Cisco SocialMiner - Customer-side Chat Client Sample
2 | _Sample javascript (Node.js) based chat client application to illustrate the use of SocialMiner Chat APIs_
3 |
4 | ## Overview
5 | The Customer-side Chat Client Sample is intended to serve as an example of using SocialMiner Chat REST APIs from a server-side javascript (Node.js) application.
6 |
7 | This sample illustrates the use of the following REST APIs:
8 | - `POST` to initiate chat sessions
9 | - `GET` to poll for chat events
10 | - `PUT` to send chat messages
11 | - `DELETE` to end the chat session
12 | - `GET` to download chat transcripts
13 |
14 | 🆕 _Starting CCX 11.6(2) / 12.0, the ability for chat customers to provide **post-chat ratings** is provided. This is also available as a REST API which can be used just like other chat APIs. Refer Cisco SocialMiner Developer Guide._
15 |
16 | This sample also includes a node-based HTTP proxy. This proxy serves up the callback html page and proxies the callback API to work around Cross Origin Resource Sharing (CORS) issues that would otherwise prevent the user from experimenting with the chat HTML page. (**NOTE:** The proxy is needed only for SocialMiner versions 11.5 and older. Starting SocialMiner 11.6, CORS support is fully implemented for chat APIs)
17 |
18 | ## Pre-requisites
19 | - SocialMiner server integrated with Unified CCX cluster with the approprtiate licenses. Multi-session web chat feature should be configured on Unified CCX Administration. (Please refer [Unified CCX Administration Guide](https://www.cisco.com/c/en/us/support/customer-collaboration/unified-contact-center-express/products-installation-and-configuration-guides-list.html))
20 |
21 | - The reference URL of the chat feed configured to process chat requests. The ID can be obtained using the following SocialMiner REST API:
22 | ```
23 | http:///ccp-webapp/ccp/feed
24 | ```
25 |
26 | This REST API will list XML for each feed configured on SocialMiner. Feeds with type `8` are chat feeds. The name given when the feed was configured is also listed. This is the easiest way to find the XML for the chat feed. Here is some sample output from the feed API:
27 | ```xml
28 |
29 |
30 | 3
31 | 300
32 | 60
33 |
34 | Created by CCX application as part of CCX chat configuration.
35 |
36 | CCX Chat Feed
37 | 0
38 |
39 | http://socialminer/ccp-webapp/ccp/chatfeed/100053
40 |
41 |
42 | http://socialminer/ccp-webapp/ccp/feed/100053
43 |
44 |
45 | http://socialminer/ccp-webapp/ccp/template/reply/303
46 |
47 | 1
48 |
49 | ccx_chat_req
50 |
51 | 8
52 |
53 | ...
54 |
55 | ```
56 | The reference URL of the feed is the value inside the refURL tags. In this example, the refURL is `http://socialminer/ccp-webapp/ccp/feed/100053`
57 |
58 | - Install [Node.js](https://nodejs.org/)
59 |
60 | ### Configuring Node.js
61 | Run these steps to ensure node.js has the necessary dependencies to run the HTTP server.
62 | - Change directory to `/customer-chat/`.
63 | `` is the directory in which the sample was extracted.
64 |
65 | - Run the following command to install dependencies:
66 | ```
67 | npm install
68 | ```
69 |
70 | ## Running
71 | ### Configuration
72 | - Using a REST API client, invoke the following SocialMiner API:
73 | ```
74 | GET https:///ccp-webapp/ccp/feed
75 | ```
76 | You will have to provide basic authorization credentials (SocialMiner administrator username and password) and set the header `Accept: application/xml` in your request.
77 |
78 | - The response payload contains an XML listing all feeds configured in this SocialMiner. Look for the specfic `CCX Chat Feed`, and note its `refURL` value.
79 | ```xml
80 |
81 |
82 | ...
83 | CCX Chat Feed
84 | 8
85 |
86 | http://socialminer/ccp-webapp/ccp/feed/100053
87 |
88 | ...
89 |
90 |
91 | ```
92 |
93 | - Edit [public/chat.html](public/chat.html), and replace `` with the `refURL` value of the chat feed collected in the previous step.
94 |
95 | - In CCX Administration, go to **_Subsystems --> Chat and Email --> Chat Widget List_** and open the specific chat widget HTML code of your configured web chat widget form.
96 |
97 | - In this HTML code, find `extensionField_ccxqueuetag` and copy the options (under the `