From 4a204ef60b2392a65251013e762cada50bd4a777 Mon Sep 17 00:00:00 2001 From: xinpa Date: Fri, 24 Nov 2017 10:29:54 +0800 Subject: [PATCH 01/11] Add support for jabberbot. --- docs/readme-ciscojabber.md | 322 +++++++++++++++++++++++++++++++++++++ examples/jabber_bot.js | 123 ++++++++++++++ lib/Botkit.js | 2 + lib/JabberBot.js | 232 ++++++++++++++++++++++++++ lib/JabberGroupManager.js | 229 ++++++++++++++++++++++++++ package.json | 5 +- 6 files changed, 912 insertions(+), 1 deletion(-) create mode 100644 docs/readme-ciscojabber.md create mode 100644 examples/jabber_bot.js create mode 100644 lib/JabberBot.js create mode 100644 lib/JabberGroupManager.js diff --git a/docs/readme-ciscojabber.md b/docs/readme-ciscojabber.md new file mode 100644 index 000000000..89e364376 --- /dev/null +++ b/docs/readme-ciscojabber.md @@ -0,0 +1,322 @@ +# BotKit Starter for Cisco Jabber # +Botkit is designed to ease the process of designing and running useful, creative bots that live inside Cisco Jabber. +Botkit features a comprehensive set of tools to deal with Cisco Jabber, and allows developers to build interactive bots and applications that send and receive messages just like real humans. +This document covers the Cisco Jabber-specific implementation details only. + +## Getting Started ## +- Install Botkit +- Ask admin to create a Jabber user for the bot in either Cisco IM&Presence Server (on-premise deployment) or Cisco Webex Messenger (cloud deployment), then get the jid and password from the admin. +Jabber bots can send and receive messages, and in many cases, appear alongside their human counterparts as normal Jabber users. + +## Working with Cisco Jabber ## +Jabber bot uses node-xmpp to connect to Cisco Unified IM & Presence server or Cisco WebEx Messenger and can only use the password authentication methods. Cisco Jabber bot can take part in 1-1 chat or group chat conversations and can provide information or other services for the conversations. It’s better to use persist store for the Botkit controller, otherwise when restart the bot, it will lose the group information and cannot received the message from a group chat. + +The full code for a simple Cisco Jabber bot is as below: + +~~~ javascript + const Botkit = require('./lib/JabberBot.js'); + var controller = Botkit({ + json_file_store: './bot_store/' + }); + + var bot = controller.spawn({ + client: { + jid: ‘john@alpha-cup.cisco.com', + password: *, + host: "shn-alpha-cup011.cisco.com", + port: 5222 + } + }); + + controller.hears(['hello'], ['direct_mention', 'direct_message'], function (bot, message) { + bot.reply(message, 'Hi'); + }); + + controller.on('direct_mention', function (bot, message) { + bot.reply(message, 'You mentioned me in a group and said, "' + message.text + '"'); + }); + + controller.on('direct_message', function (bot, message) { + bot.reply(message, 'I got your direct message. You said, "' + message.text + '"'); + }); +~~~ + +## Bot Options ## +When spawn bot from the Botkit controller, there are several options available. + +| Argument | Description +|--- |--- +| jid | Jid of the jabber bot +| password | Password of the jabber bot +| host | host of the Cisco Unified IM & Presence server, no need for bot of Cisco WebEx Messenger +| port | Port of the Cisco Unified IM & Presence server, no need for bot of Cisco WebEx Messenger + +## Jabber Specific Events ## +Jabber support the following events + +| Event | Description +|--- |--- +| direct_message | Bot has received a direct message from a 1-1 chat +| direct_mention | Bot has received a message from a group chat and is mentioned by the message sender +| self_message | Bot has received a message it sent + +## Message Formatting ## +Cisco Jabber bot supports both plain text message and rich text message. +Below is an example for plain text message. +~~~ javascript + bot.reply(message, 'Hello'); +~~~ +Below is an example for rich text message. Jabber Bots Developer needs to compose the whole stanza for the message. He can create his own UI element to replace the UI part inside the body element in this example. +Notes: Below example just for show element clearly. It’s better to remove all empty space in the stanza. + +~~~ javascript + let reply_message = {}; + let to = message.user; + let type = message.group ? 'groupchat' : 'chat'; + let body = 'html demo(only for Jabber Windows now)'; + reply_message.text = body; + reply_message.stanza = xml`${body} + + + +
+ ${body} +
+ + +
+
+
+
+ +
`; + bot.reply(message, reply_message); +~~~ + +Cisco Jabber can support all HTML5 elements and bootstrap 3.2 CSS style. However, Bot developer cannot inject any java-script code into the rich text message because of the security reason. In addition, Cisco Jabber introduces a new attribute robot-type for the button element to enhance the interaction between Jabber and the bot. +Below is a short summary of the allow value and description. More detail and example usage can be found in later section. + +| Value | Description +|--- |--- +| robot-button | Send back a message +| robot-openlink | Open URL +| robot-executecommand | Execute predefined command in Jabber, like start group chat, start conf call and start instant meeting +| robot-submit | Send back a json message with all input name and value in a HTML form. + + + +- When value is robot-button, when user clicks the button, Jabber will send back a message defined in the attribute robot-message in the same element. Below is an example + +~~~ javascript + let reply_message = {}; + let to = message.user; + let type = message.group ? 'groupchat' : 'chat'; + let body = 'robot-button demo(only for Jabber Windows)'; + reply_message.text = body; + reply_message.stanza = xml`${body} +
${body}
`; + bot.reply(message, reply_message); +~~~ + +All the below buttons needs to be putted in a form. + +- When value is robot-openlink, when user clicks the button, cisco jabber will find an element name with openlink in the form, and open URL defined in value of the element name with openlink. Below is an example + +~~~ javascript + let reply_message = {}; + let to = message.user; + let type = message.group ? 'groupchat' : 'chat'; + let body = 'robot-openlink demo(only for Jabber Windows)'; + reply_message.text = body; + reply_message.stanza = xml`${body} +
+
${body}
+
+
+ + +
+
+
+
`; + bot.reply(message, reply_message); +~~~ + +- When value is robot-executecommand, when user clicks the button, cisco jabber will find an element name with command in the form, and execute command defined in value of the element name with command. +Jabber provide 3 kinds of command as below examples to start group chat, start an audio/video conference and start an instant Webex meeting. +startgroupchat:john@cisco.com;mick@cisco.com +startconference:john@cisco.com;mick@cisco.com +startmeeting:john@cisco.com;mick@cisco.com +Below is an example, jabber need the jid to execute the related action, generally we can extract the jid from the message received from the user, function ExtractMentionJids is used to help extract @mention jid from the message. + +~~~ javascript + function ExtractMentionJids(message) { + let direct_mention_reg = /href="xmpp:\s?(\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+)\s?"/ig; + let email_reg = /\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+/i; + let match = message.stanza.toString().match(direct_mention_reg); + let mention_jids = []; + if (match) { + for (let i = 0; i < match.length; i++) { + let jid_match = match[i].match(email_reg); + if (jid_match) { + let jid = jid_match[0]; + if (jid != bot.client_jid) { + mention_jids.push(jid); + } + } + } + } + return mention_jids; + } + + let reply_message = {}; + let to = message.user; + let type = message.group ? 'groupchat' : 'chat'; + let mention_jids = ExtractMentionJids(message); + let mentionJids = ""; + for (let i = 0; i < mention_jids.length; i++) { + mentionJids += mention_jids[i]; + mentionJids += ";"; + } + + let body = 'robot-executecommand demo(only for Jabber Windows)'; + reply_message.text = body; + reply_message.stanza = xml`${body} +
+
${body}
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
`; + bot.reply(message, reply_message); +~~~ + + +- When value is robot-submit, click the button, cisco jabber will find all element name in the form, and combine all the input into a JSON message and then send it back to the bot. +Below is an example + +~~~ javascript + let reply_message = {}; + let to = message.user; + let type = message.group ? 'groupchat' : 'chat'; + + let body = 'robot-submit demo(only for Jabber Windows)'; + reply_message.text = body; + reply_message.stanza = xml`${body} +
+
Please enter the meeting information:
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + + +
+
+
+ +
+