diff --git a/client/views/username/prompt.html b/client/views/username/prompt.html
index 7ba513529e6a6..ba81c004f7b7c 100644
--- a/client/views/username/prompt.html
+++ b/client/views/username/prompt.html
@@ -23,7 +23,7 @@
{{#if username.ready}}
-
+
{{else}}
diff --git a/packages/rocketchat-autolinker/autolinker.coffee b/packages/rocketchat-autolinker/autolinker.coffee
index b07f24796213d..6dac64a854794 100644
--- a/packages/rocketchat-autolinker/autolinker.coffee
+++ b/packages/rocketchat-autolinker/autolinker.coffee
@@ -10,4 +10,4 @@ class AutoLinker
return message
-RocketChat.callbacks.add 'beforeSaveMessage', AutoLinker
+RocketChat.callbacks.add 'renderMessage', AutoLinker
diff --git a/packages/rocketchat-emojione/emojione.coffee b/packages/rocketchat-emojione/emojione.coffee
index d03163aea9d9b..492dc943e8acc 100644
--- a/packages/rocketchat-emojione/emojione.coffee
+++ b/packages/rocketchat-emojione/emojione.coffee
@@ -10,4 +10,4 @@ class Emojione
return message
-RocketChat.callbacks.add 'beforeSaveMessage', Emojione, RocketChat.callbacks.priority.LOW
\ No newline at end of file
+RocketChat.callbacks.add 'renderMessage', Emojione, RocketChat.callbacks.priority.LOW
\ No newline at end of file
diff --git a/packages/rocketchat-file/package.js b/packages/rocketchat-file/package.js
index e6ad9edd950bf..7ed4a9d40ff39 100644
--- a/packages/rocketchat-file/package.js
+++ b/packages/rocketchat-file/package.js
@@ -5,22 +5,22 @@ Package.describe({
git: ''
});
-Npm.depends({
- 'mkdirp': '0.3.5',
- 'gridfs-stream': '0.5.3',
- 'gm' :'1.18.1'
-});
-
Package.onUse(function(api) {
api.versionsFrom('1.0');
- api.use('coffeescript');
+ api.use(['coffeescript']);
- api.addFiles('file.server.coffee', 'server');
+ api.addFiles('file.server.coffee', ['server']);
api.export(['RocketChatFile'], ['server']);
});
+Npm.depends({
+ 'mkdirp': '0.3.5',
+ 'gridfs-stream': '0.5.3',
+ 'gm': '1.18.1'
+});
+
Package.onTest(function(api) {
});
diff --git a/packages/rocketchat-highlight/highlight.coffee b/packages/rocketchat-highlight/highlight.coffee
index 4e987d9c80801..27b00da7e62c8 100644
--- a/packages/rocketchat-highlight/highlight.coffee
+++ b/packages/rocketchat-highlight/highlight.coffee
@@ -4,7 +4,7 @@
###
class Highlight
-
+
# If message starts with ```, replace it for text formatting
constructor: (message) ->
@@ -18,7 +18,7 @@ class Highlight
if codeMatch?
# Process highlight if this part is code
lang = codeMatch[1]
- code = codeMatch[2]
+ code = _.unescapeHTML codeMatch[2]
if lang not in hljs.listLanguages()
result = hljs.highlightAuto code
else
@@ -26,8 +26,6 @@ class Highlight
msgParts[index] = "
" + result.value + ""
else
# Escape html and fix line breaks for non code blocks
- part = _.escapeHTML part
- part = part.replace /\n/g, '
'
msgParts[index] = part
# Re-mount message
@@ -35,4 +33,4 @@ class Highlight
return message
-RocketChat.callbacks.add 'beforeSaveMessage', Highlight, RocketChat.callbacks.priority.HIGH
\ No newline at end of file
+RocketChat.callbacks.add 'renderMessage', Highlight, RocketChat.callbacks.priority.HIGH
diff --git a/packages/rocketchat-hubot/.npm/package/.gitignore b/packages/rocketchat-hubot/.npm/package/.gitignore
new file mode 100644
index 0000000000000..3c3629e647f5d
--- /dev/null
+++ b/packages/rocketchat-hubot/.npm/package/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/packages/rocketchat-hubot/.npm/package/README b/packages/rocketchat-hubot/.npm/package/README
new file mode 100644
index 0000000000000..3d492553a438e
--- /dev/null
+++ b/packages/rocketchat-hubot/.npm/package/README
@@ -0,0 +1,7 @@
+This directory and the files immediately inside it are automatically generated
+when you change this package's NPM dependencies. Commit the files in this
+directory (npm-shrinkwrap.json, .gitignore, and this README) to source control
+so that others run the same versions of sub-dependencies.
+
+You should NOT check in the node_modules directory that Meteor automatically
+creates; if you are using git, the .gitignore file tells git to ignore it.
diff --git a/packages/rocketchat-hubot/.npm/package/npm-shrinkwrap.json b/packages/rocketchat-hubot/.npm/package/npm-shrinkwrap.json
new file mode 100644
index 0000000000000..370832fe5fd8e
--- /dev/null
+++ b/packages/rocketchat-hubot/.npm/package/npm-shrinkwrap.json
@@ -0,0 +1,744 @@
+{
+ "dependencies": {
+ "codex-blackboard-hubot-scripts": {
+ "version": "https://github.com/cscott/codex-blackboard-hubot-scripts/tarball/f57c178a2faee9b36d07a7905c29093b9824e0b0",
+ "dependencies": {
+ "hubot-calculator": {
+ "version": "0.4.0",
+ "dependencies": {
+ "coffee-script": {
+ "version": "1.6.3"
+ },
+ "mathjs": {
+ "version": "1.7.0",
+ "dependencies": {
+ "decimal.js": {
+ "version": "4.0.2"
+ }
+ }
+ }
+ }
+ },
+ "hubot-google-hangouts": {
+ "version": "0.7.1",
+ "dependencies": {
+ "coffee-script": {
+ "version": "1.6.3"
+ },
+ "googleapis": {
+ "version": "0.4.7",
+ "dependencies": {
+ "request": {
+ "version": "2.25.0",
+ "dependencies": {
+ "qs": {
+ "version": "0.6.6"
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1"
+ },
+ "forever-agent": {
+ "version": "0.5.2"
+ },
+ "tunnel-agent": {
+ "version": "0.3.0"
+ },
+ "http-signature": {
+ "version": "0.10.1",
+ "dependencies": {
+ "assert-plus": {
+ "version": "0.1.5"
+ },
+ "asn1": {
+ "version": "0.1.11"
+ },
+ "ctype": {
+ "version": "0.5.3"
+ }
+ }
+ },
+ "hawk": {
+ "version": "1.0.0",
+ "dependencies": {
+ "hoek": {
+ "version": "0.9.1"
+ },
+ "boom": {
+ "version": "0.4.2"
+ },
+ "cryptiles": {
+ "version": "0.2.2"
+ },
+ "sntp": {
+ "version": "0.2.4"
+ }
+ }
+ },
+ "aws-sign": {
+ "version": "0.3.0"
+ },
+ "oauth-sign": {
+ "version": "0.3.0"
+ },
+ "cookie-jar": {
+ "version": "0.3.0"
+ },
+ "node-uuid": {
+ "version": "1.4.3"
+ },
+ "mime": {
+ "version": "1.2.11"
+ },
+ "form-data": {
+ "version": "0.1.4",
+ "dependencies": {
+ "combined-stream": {
+ "version": "0.0.7",
+ "dependencies": {
+ "delayed-stream": {
+ "version": "0.0.5"
+ }
+ }
+ },
+ "async": {
+ "version": "0.9.2"
+ }
+ }
+ }
+ }
+ },
+ "async": {
+ "version": "0.2.6"
+ },
+ "gapitoken": {
+ "version": "0.1.0",
+ "dependencies": {
+ "jws": {
+ "version": "0.0.2",
+ "dependencies": {
+ "tap": {
+ "version": "0.3.3",
+ "dependencies": {
+ "inherits": {
+ "version": "1.0.0"
+ },
+ "yamlish": {
+ "version": "0.0.5"
+ },
+ "slide": {
+ "version": "1.1.6"
+ },
+ "runforcover": {
+ "version": "0.0.2",
+ "dependencies": {
+ "bunker": {
+ "version": "0.1.2",
+ "dependencies": {
+ "burrito": {
+ "version": "0.2.12",
+ "dependencies": {
+ "traverse": {
+ "version": "0.5.2"
+ },
+ "uglify-js": {
+ "version": "1.1.1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "nopt": {
+ "version": "2.2.1",
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.7"
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.3.5"
+ },
+ "difflet": {
+ "version": "0.2.6",
+ "dependencies": {
+ "traverse": {
+ "version": "0.6.6"
+ },
+ "charm": {
+ "version": "0.1.2"
+ },
+ "deep-is": {
+ "version": "0.1.3"
+ }
+ }
+ },
+ "deep-equal": {
+ "version": "0.0.0"
+ },
+ "buffer-equal": {
+ "version": "0.0.1"
+ }
+ }
+ },
+ "base64url": {
+ "version": "0.0.3"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "hubot-google-images": {
+ "version": "0.1.5"
+ },
+ "hubot-google-translate": {
+ "version": "0.1.0"
+ },
+ "hubot-help": {
+ "version": "0.1.1"
+ },
+ "hubot-scripts": {
+ "version": "2.16.1",
+ "dependencies": {
+ "redis": {
+ "version": "0.8.4"
+ }
+ }
+ },
+ "hubot-youtube": {
+ "version": "0.1.2"
+ }
+ }
+ },
+ "coffee-script": {
+ "version": "1.9.3"
+ },
+ "hubot": {
+ "version": "2.13.1",
+ "dependencies": {
+ "chalk": {
+ "version": "1.0.0",
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.0.1"
+ },
+ "escape-string-regexp": {
+ "version": "1.0.3"
+ },
+ "has-ansi": {
+ "version": "1.0.3",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "1.1.1"
+ },
+ "get-stdin": {
+ "version": "4.0.1"
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "2.0.1",
+ "dependencies": {
+ "ansi-regex": {
+ "version": "1.1.1"
+ }
+ }
+ },
+ "supports-color": {
+ "version": "1.3.1"
+ }
+ }
+ },
+ "cline": {
+ "version": "0.8.2"
+ },
+ "coffee-script": {
+ "version": "1.6.3"
+ },
+ "connect-multiparty": {
+ "version": "1.2.5",
+ "dependencies": {
+ "multiparty": {
+ "version": "3.3.2",
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.1.13",
+ "dependencies": {
+ "core-util-is": {
+ "version": "1.0.1"
+ },
+ "isarray": {
+ "version": "0.0.1"
+ },
+ "string_decoder": {
+ "version": "0.10.31"
+ },
+ "inherits": {
+ "version": "2.0.1"
+ }
+ }
+ },
+ "stream-counter": {
+ "version": "0.2.0"
+ }
+ }
+ },
+ "on-finished": {
+ "version": "2.1.1",
+ "dependencies": {
+ "ee-first": {
+ "version": "1.1.0"
+ }
+ }
+ },
+ "qs": {
+ "version": "2.2.5"
+ },
+ "type-is": {
+ "version": "1.5.7",
+ "dependencies": {
+ "media-typer": {
+ "version": "0.3.0"
+ },
+ "mime-types": {
+ "version": "2.0.14",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.12.0"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "express": {
+ "version": "3.18.1",
+ "dependencies": {
+ "basic-auth": {
+ "version": "1.0.0"
+ },
+ "connect": {
+ "version": "2.27.1",
+ "dependencies": {
+ "basic-auth-connect": {
+ "version": "1.0.0"
+ },
+ "body-parser": {
+ "version": "1.9.3",
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.4.5"
+ },
+ "on-finished": {
+ "version": "2.1.1",
+ "dependencies": {
+ "ee-first": {
+ "version": "1.1.0"
+ }
+ }
+ },
+ "qs": {
+ "version": "2.3.3"
+ },
+ "raw-body": {
+ "version": "1.3.1"
+ }
+ }
+ },
+ "bytes": {
+ "version": "1.0.0"
+ },
+ "cookie-parser": {
+ "version": "1.3.5",
+ "dependencies": {
+ "cookie": {
+ "version": "0.1.3"
+ },
+ "cookie-signature": {
+ "version": "1.0.6"
+ }
+ }
+ },
+ "compression": {
+ "version": "1.2.2",
+ "dependencies": {
+ "accepts": {
+ "version": "1.1.4",
+ "dependencies": {
+ "mime-types": {
+ "version": "2.0.14",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.12.0"
+ }
+ }
+ },
+ "negotiator": {
+ "version": "0.4.9"
+ }
+ }
+ },
+ "compressible": {
+ "version": "2.0.3",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.13.0"
+ }
+ }
+ }
+ }
+ },
+ "connect-timeout": {
+ "version": "1.4.0",
+ "dependencies": {
+ "ms": {
+ "version": "0.6.2"
+ }
+ }
+ },
+ "csurf": {
+ "version": "1.6.6",
+ "dependencies": {
+ "csrf": {
+ "version": "2.0.7",
+ "dependencies": {
+ "base64-url": {
+ "version": "1.2.1"
+ },
+ "rndm": {
+ "version": "1.1.0"
+ },
+ "scmp": {
+ "version": "1.0.0"
+ },
+ "uid-safe": {
+ "version": "1.1.0",
+ "dependencies": {
+ "native-or-bluebird": {
+ "version": "1.1.2"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "errorhandler": {
+ "version": "1.2.4",
+ "dependencies": {
+ "accepts": {
+ "version": "1.1.4",
+ "dependencies": {
+ "mime-types": {
+ "version": "2.0.14",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.12.0"
+ }
+ }
+ },
+ "negotiator": {
+ "version": "0.4.9"
+ }
+ }
+ }
+ }
+ },
+ "express-session": {
+ "version": "1.9.3",
+ "dependencies": {
+ "crc": {
+ "version": "3.2.1"
+ },
+ "uid-safe": {
+ "version": "1.0.1",
+ "dependencies": {
+ "mz": {
+ "version": "1.3.0",
+ "dependencies": {
+ "native-or-bluebird": {
+ "version": "1.2.0"
+ },
+ "thenify": {
+ "version": "3.1.0"
+ },
+ "thenify-all": {
+ "version": "1.6.0"
+ }
+ }
+ },
+ "base64-url": {
+ "version": "1.2.1"
+ }
+ }
+ }
+ }
+ },
+ "finalhandler": {
+ "version": "0.3.2",
+ "dependencies": {
+ "on-finished": {
+ "version": "2.1.1",
+ "dependencies": {
+ "ee-first": {
+ "version": "1.1.0"
+ }
+ }
+ }
+ }
+ },
+ "http-errors": {
+ "version": "1.2.8",
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1"
+ },
+ "statuses": {
+ "version": "1.2.1"
+ }
+ }
+ },
+ "method-override": {
+ "version": "2.3.3",
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.1"
+ }
+ }
+ },
+ "methods": {
+ "version": "1.1.1"
+ }
+ }
+ },
+ "morgan": {
+ "version": "1.4.1",
+ "dependencies": {
+ "on-finished": {
+ "version": "2.1.1",
+ "dependencies": {
+ "ee-first": {
+ "version": "1.1.0"
+ }
+ }
+ }
+ }
+ },
+ "multiparty": {
+ "version": "3.3.2",
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.1.13",
+ "dependencies": {
+ "core-util-is": {
+ "version": "1.0.1"
+ },
+ "isarray": {
+ "version": "0.0.1"
+ },
+ "string_decoder": {
+ "version": "0.10.31"
+ },
+ "inherits": {
+ "version": "2.0.1"
+ }
+ }
+ },
+ "stream-counter": {
+ "version": "0.2.0"
+ }
+ }
+ },
+ "on-headers": {
+ "version": "1.0.0"
+ },
+ "qs": {
+ "version": "2.3.0"
+ },
+ "response-time": {
+ "version": "2.2.0"
+ },
+ "serve-favicon": {
+ "version": "2.1.7",
+ "dependencies": {
+ "ms": {
+ "version": "0.6.2"
+ }
+ }
+ },
+ "serve-index": {
+ "version": "1.5.3",
+ "dependencies": {
+ "accepts": {
+ "version": "1.1.4",
+ "dependencies": {
+ "negotiator": {
+ "version": "0.4.9"
+ }
+ }
+ },
+ "batch": {
+ "version": "0.5.1"
+ },
+ "mime-types": {
+ "version": "2.0.14",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.12.0"
+ }
+ }
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.7.2"
+ },
+ "type-is": {
+ "version": "1.5.7",
+ "dependencies": {
+ "mime-types": {
+ "version": "2.0.14",
+ "dependencies": {
+ "mime-db": {
+ "version": "1.12.0"
+ }
+ }
+ }
+ }
+ },
+ "vhost": {
+ "version": "3.0.0"
+ },
+ "pause": {
+ "version": "0.0.1"
+ }
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.0"
+ },
+ "commander": {
+ "version": "1.3.2",
+ "dependencies": {
+ "keypress": {
+ "version": "0.1.0"
+ }
+ }
+ },
+ "cookie-signature": {
+ "version": "1.0.5"
+ },
+ "debug": {
+ "version": "2.1.3",
+ "dependencies": {
+ "ms": {
+ "version": "0.7.0"
+ }
+ }
+ },
+ "depd": {
+ "version": "1.0.1"
+ },
+ "escape-html": {
+ "version": "1.0.1"
+ },
+ "etag": {
+ "version": "1.5.1",
+ "dependencies": {
+ "crc": {
+ "version": "3.2.1"
+ }
+ }
+ },
+ "fresh": {
+ "version": "0.2.4"
+ },
+ "media-typer": {
+ "version": "0.3.0"
+ },
+ "methods": {
+ "version": "1.1.0"
+ },
+ "mkdirp": {
+ "version": "0.5.0",
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8"
+ }
+ }
+ },
+ "parseurl": {
+ "version": "1.3.0"
+ },
+ "proxy-addr": {
+ "version": "1.0.8",
+ "dependencies": {
+ "forwarded": {
+ "version": "0.1.0"
+ },
+ "ipaddr.js": {
+ "version": "1.0.1"
+ }
+ }
+ },
+ "range-parser": {
+ "version": "1.0.2"
+ },
+ "send": {
+ "version": "0.10.1",
+ "dependencies": {
+ "destroy": {
+ "version": "1.0.3"
+ },
+ "mime": {
+ "version": "1.2.11"
+ },
+ "ms": {
+ "version": "0.6.2"
+ },
+ "on-finished": {
+ "version": "2.1.1",
+ "dependencies": {
+ "ee-first": {
+ "version": "1.1.0"
+ }
+ }
+ }
+ }
+ },
+ "utils-merge": {
+ "version": "1.0.0"
+ },
+ "vary": {
+ "version": "1.0.0"
+ },
+ "cookie": {
+ "version": "0.1.2"
+ },
+ "merge-descriptors": {
+ "version": "0.0.2"
+ }
+ }
+ },
+ "log": {
+ "version": "1.4.0"
+ },
+ "optparse": {
+ "version": "1.0.4"
+ },
+ "scoped-http-client": {
+ "version": "0.11.0"
+ }
+ }
+ }
+ }
+}
diff --git a/packages/rocketchat-hubot/hubot.coffee b/packages/rocketchat-hubot/hubot.coffee
new file mode 100644
index 0000000000000..10cb37d54040f
--- /dev/null
+++ b/packages/rocketchat-hubot/hubot.coffee
@@ -0,0 +1,200 @@
+CoffeeScript = Npm.require('coffee-script')
+CoffeeScript.register()
+
+HubotScripts = Npm.require('codex-blackboard-hubot-scripts');
+Hubot = Npm.require('hubot')
+
+# Start a hubot, connected to our chat room.
+'use strict'
+
+# Log messages?
+DEBUG = true
+
+# Monkey-patch Hubot to support private messages
+Hubot.Response::priv = (strings...) ->
+ @robot.adapter.priv @envelope, strings...
+
+# More monkey-patching
+Hubot.Robot::loadAdapter = -> # disable
+
+# grrrr, Meteor.bindEnvironment doesn't preserve `this` apparently
+bind = (f) ->
+ g = Meteor.bindEnvironment (self, args...) -> f.apply(self, args)
+ (args...) -> g @, args...
+
+class Robot extends Hubot.Robot
+ constructor: (args...) ->
+ super args...
+ @hear = bind @hear
+ @respond = bind @respond
+ @enter = bind @enter
+ @leave = bind @leave
+ @topic = bind @topic
+ @error = bind @error
+ @catchAll = bind @catchAll
+ loadAdapter: -> false
+ hear: (regex, callback) -> super regex, Meteor.bindEnvironment callback
+ respond: (regex, callback) -> super regex, Meteor.bindEnvironment callback
+ enter: (callback) -> super Meteor.bindEnvironment(callback)
+ leave: (callback) -> super Meteor.bindEnvironment(callback)
+ topic: (callback) -> super Meteor.bindEnvironment(callback)
+ error: (callback) -> super Meteor.bindEnvironment(callback)
+ catchAll: (callback) -> super Meteor.bindEnvironment(callback)
+
+class RocketChatAdapter extends Hubot.Adapter
+ # Public: Raw method for sending data back to the chat source. Extend this.
+ #
+ # envelope - A Object with message, room and user details.
+ # strings - One or more Strings for each message to send.
+ #
+ # Returns nothing.
+ send: (envelope, strings...) ->
+ sendHelper @robot, envelope, strings, (string) =>
+ console.log "send #{envelope.rid}: #{string} (#{envelope.u.username})" if DEBUG
+ return @priv envelope, string if envelope.message.private
+ Meteor.call "sendMessage",
+ u:
+ username: "rocketbot"
+ msg: string
+ rid: envelope.rid
+
+ # Public: Raw method for sending emote data back to the chat source.
+ #
+ # envelope - A Object with message, room and user details.
+ # strings - One or more Strings for each message to send.
+ #
+ # Returns nothing.
+ emote: (envelope, strings...) ->
+ sendHelper @robot, envelope, strings, (string) =>
+ console.log "emote #{envelope.rid}: #{string} (#{envelope.u.username})" if DEBUG
+ return @priv envelope, "*** #{string} ***" if envelope.message.private
+ Meteor.call "sendMessage",
+ u:
+ username: "rocketbot"
+ msg: string
+ rid: envelope.rid
+ action: true
+
+ # Priv: our extension -- send a PM to user
+ priv: (envelope, strings...) ->
+ sendHelper @robot, envelope, strings, (string) ->
+ console.log "priv #{envelope.rid}: #{string} (#{envelope.u.username})" if DEBUG
+ Meteor.call "sendMessage",
+ u:
+ username: "rocketbot"
+ to: "#{envelope.u.username}"
+ msg: string
+ rid: envelope.rid
+
+ # Public: Raw method for building a reply and sending it back to the chat
+ # source. Extend this.
+ #
+ # envelope - A Object with message, room and user details.
+ # strings - One or more Strings for each reply to send.
+ #
+ # Returns nothing.
+ reply: (envelope, strings...) ->
+ if envelope.message.private
+ @priv envelope, strings...
+ else
+ @send envelope, strings.map((str) -> "#{envelope.u.username}: #{str}")...
+
+ # Public: Raw method for setting a topic on the chat source. Extend this.
+ #
+ # envelope - A Object with message, room and user details.
+ # strings - One more more Strings to set as the topic.
+ #
+ # Returns nothing.
+ topic: (envelope, strings...) ->
+
+ # Public: Raw method for playing a sound in the chat source. Extend this.
+ #
+ # envelope - A Object with message, room and user details.
+ # strings - One or more strings for each play message to send.
+ #
+ # Returns nothing
+ play: (envelope, strings...) ->
+
+ # Public: Raw method for invoking the bot to run. Extend this.
+ #
+ # Returns nothing.
+ run: ->
+
+ # Public: Raw method for shutting the bot down. Extend this.
+ #
+ # Returns nothing.
+ close: ->
+
+class RocketBotReceiver
+ constructor: (message) ->
+ RocketBotUser = new Hubot.User(message.u.username, rid: message.rid)
+ RocketBotTextMessage = new Hubot.TextMessage(RocketBotUser, message.msg, message._id)
+ RocketBot.adapter.receive RocketBotTextMessage
+ console.log 'message: ', message if DEBUG
+ console.log 'RocketBot: ', RocketBot if DEBUG
+ return message
+
+sendHelper = Meteor.bindEnvironment (robot, envelope, strings, map) ->
+ while strings.length > 0
+ string = strings.shift()
+ if typeof(string) == 'function'
+ string()
+ else
+ try
+ map(string)
+ catch err
+ console.error "Hubot error: #{err}" if DEBUG
+ robot.logger.error "RocketChat send error: #{err}"
+
+RocketBot = new Robot null, null, false, 'rocketbot'
+RocketBot.alias = 'bot'
+RocketBot.adapter = new RocketChatAdapter RocketBot
+HubotScripts(RocketBot)
+
+RocketChat.callbacks.add 'afterSaveMessage', RocketBotReceiver, RocketChat.callbacks.priority.LOW
+
+# Meteor.startup ->
+ # console.log RocketBot;
+ # # what's (the regexp for) my name?
+ # robot.respond /(?:)/, -> false
+ # mynameRE = robot.listeners.pop().regex
+ # # register scripts
+ # HubotScripts(robot)
+ # Object.keys(share.hubot).forEach (scriptName) ->
+ # console.log "Loading hubot script: #{scriptName}"
+ # share.hubot[scriptName](robot)
+ # # register our nick
+ # n = Meteor.call 'newNick', {name: 'rocketbot'}
+ # Meteor.call 'setTag', {type:'nicks', object:n._id, name:'Gravatar', value:'codex@printf.net', who:n.canon}
+ # # register our presence in general chat
+ # keepalive = -> Meteor.call 'setPresence',
+ # u:
+ # username: 'rocketbot'
+ # rid: '57om6EQCcFami9wuT'
+ # present: true
+ # foreground: true
+ # keepalive()
+ # Meteor.setInterval keepalive, 30*1000 # every 30s refresh presence
+ # # listen to the chat room, ignoring messages sent before we startup
+ # startup = true
+ # ChatMessage.find({}).observe
+ # added: (message) ->
+ # return if startup
+ # return if message.u.username is "rocketbot" or message.u.username is ""
+ # return if message.system or message.action or message.oplog or message.bodyIsHtml
+ # console.log "Received from #{message.u.username} in #{message.rid}: #{message.body}"\
+ # if DEBUG
+ # user = new Hubot.User(message.u.username, room: message.rid)
+ # tm = new Hubot.TextMessage(user, message.body, message._id)
+ # tm.private = message.to?
+ # # if private, ensure it's treated as a direct address
+ # if tm.private and not mynameRE.test(tm.text)
+ # tm.text = "#{robot.name} #{tm.text}"
+ # adapter.receive tm
+ # startup = false
+ # Meteor.call "sendMessage",
+ # rid: '57om6EQCcFami9wuT'
+ # msg: 'wakes up'
+ # u:
+ # username: "rocketbot"
+ # action: true
diff --git a/packages/rocketchat-hubot/package.js b/packages/rocketchat-hubot/package.js
new file mode 100644
index 0000000000000..e58d9d52e85c8
--- /dev/null
+++ b/packages/rocketchat-hubot/package.js
@@ -0,0 +1,32 @@
+Package.describe({
+ name: 'rocketchat:hubot',
+ version: '0.0.1',
+ summary: 'Package hubot for Meteor server',
+ git: ''
+});
+
+Package.onUse(function(api) {
+ api.versionsFrom('1.0');
+
+ api.use([
+ 'coffeescript',
+ 'rocketchat:lib@0.0.1'
+ ]);
+
+ api.addFiles('hubot.coffee', ['server']);
+
+ api.export('Hubot', ['server']);
+ api.export('HubotScripts', ['server']);
+ api.export('RocketBot', ['server']);
+ api.export('RocketBotReceiver', ['server']);
+ api.export('RocketChatAdapter', ['server']);
+
+});
+
+Npm.depends({
+ "coffee-script": "1.9.3",
+ "codex-blackboard-hubot-scripts": "https://github.com/cscott/codex-blackboard-hubot-scripts/tarball/f57c178a2faee9b36d07a7905c29093b9824e0b0",
+ "hubot": "2.13.1"
+});
+
+Package.onTest(function(api) {});
diff --git a/packages/rocketchat-markdown/markdown.coffee b/packages/rocketchat-markdown/markdown.coffee
index c471f30485404..d83e780e2bc3f 100644
--- a/packages/rocketchat-markdown/markdown.coffee
+++ b/packages/rocketchat-markdown/markdown.coffee
@@ -5,14 +5,22 @@
class Markdown
constructor: (message) ->
- msg = message.html or ''
- # Process MD like for strong, italic and strike
- msg = msg.replace(/\*([^*]+)\*/g, '
$1 ')
- msg = msg.replace(/\_([^_]+)\_/g, '
$1 ')
- msg = msg.replace(/\~{1,2}([^~]+)\~{1,2}/g, '
$1 ')
+ if _.trim message.html
+
+ msg = message.html
+
+ # Process MD like for strong, italic and strike
+ msg = msg.replace(/(\ |^)\*([^*]+)\*(\ |$)/gm, '$1
$2 $3')
+ msg = msg.replace(/(\ |^)\_([^_]+)\_(\ |$)/gm, '$1
$2 $3')
+ msg = msg.replace(/(\ |^)\`([^`]+)\`(\ |$)/gm, '$1
$2$3')
+ msg = msg.replace(/(\ |^)\~{1,2}([^~]+)\~{1,2}(\ |$)/gm, '$1
$2 $3')
+ msg = msg.replace(/^>(.*)$/gm, '
$1 ')
+
+ message.html = msg
+
+ console.log 'Markdown', message if window.rocketDebug
- message.html = msg
return message
-RocketChat.callbacks.add 'beforeSaveMessage', Markdown, RocketChat.callbacks.priority.LOW
\ No newline at end of file
+RocketChat.callbacks.add 'renderMessage', Markdown, RocketChat.callbacks.priority.LOW
diff --git a/packages/rocketchat-me/me.coffee b/packages/rocketchat-me/me.coffee
index 3a80168a5186f..965b2b6d296cd 100644
--- a/packages/rocketchat-me/me.coffee
+++ b/packages/rocketchat-me/me.coffee
@@ -11,4 +11,4 @@ class Me
message.html = '_' + message.html.replace('/me ','') + '_'
return message
-RocketChat.callbacks.add 'beforeSaveMessage', Me
+RocketChat.callbacks.add 'renderMessage', Me
diff --git a/packages/rocketchat-mentions/client.coffee b/packages/rocketchat-mentions/client.coffee
index fdd889c5678c4..c0307b507ad64 100644
--- a/packages/rocketchat-mentions/client.coffee
+++ b/packages/rocketchat-mentions/client.coffee
@@ -20,4 +20,4 @@ class MentionsClient
message.html = msg
return message
-RocketChat.callbacks.add 'beforeSaveMessage', MentionsClient
\ No newline at end of file
+RocketChat.callbacks.add 'renderMessage', MentionsClient
\ No newline at end of file
diff --git a/packages/rocketchat-mentions/package.js b/packages/rocketchat-mentions/package.js
index f2b4100101ca8..51266c3fd9c04 100644
--- a/packages/rocketchat-mentions/package.js
+++ b/packages/rocketchat-mentions/package.js
@@ -13,8 +13,8 @@ Package.onUse(function(api) {
'rocketchat:lib@0.0.1'
]);
- api.addFiles('client.coffee', 'client');
api.addFiles('server.coffee', 'server');
+ api.addFiles('client.coffee', 'client');
});
Package.onTest(function(api) {
diff --git a/packages/rocketchat-tmpembed/package.js b/packages/rocketchat-tmpembed/package.js
new file mode 100644
index 0000000000000..e15a73497b9bd
--- /dev/null
+++ b/packages/rocketchat-tmpembed/package.js
@@ -0,0 +1,21 @@
+Package.describe({
+ name: 'rocketchat:tmpembed',
+ version: '0.0.1',
+ summary: 'Message pre-processor that handles embedding of images and maps',
+ git: ''
+});
+
+Package.onUse(function(api) {
+ api.versionsFrom('1.0');
+
+ api.use([
+ 'coffeescript',
+ 'rocketchat:lib@0.0.1'
+ ]);
+
+ api.addFiles('tmpembed.coffee', ['server','client']);
+});
+
+Package.onTest(function(api) {
+
+});
diff --git a/packages/rocketchat-tmpembed/tmpembed.coffee b/packages/rocketchat-tmpembed/tmpembed.coffee
new file mode 100644
index 0000000000000..f3e52a6e3005c
--- /dev/null
+++ b/packages/rocketchat-tmpembed/tmpembed.coffee
@@ -0,0 +1,29 @@
+###
+# ObjEmbedder is a temporary image and map embedder for bots development
+# @param {Object} msg - The message object
+# to be replaced by proper implementation in 1.0
+###
+
+class ObjEmbedder
+ constructor: (message) ->
+ console.log "ObjEmbedder constructor" if window.rocketDebug
+
+ if _.trim message.msg
+ console.log "ObjEmbedder trim" if window.rocketDebug
+
+ picmatch = message.msg.match(/^https?:\/\/(?:[a-z0-9\-]+\.)+[a-z0-9]{2,6}(?:\/[^\/#?]+)+\.(?:jpe?g|gif|png)$/i)
+ if picmatch?
+ # inline style to limit code pollution
+ console.log "ObjEmbedder picmatch" if window.rocketDebug
+ message.html = "
"
+
+ else
+ mapmatch = message.msg.match(/^https?\:\/\/maps\.(google|googleapis)\.[a-z]+\/maps\/api.*format=png$/i)
+ if mapmatch?
+ console.log "ObjEmbedder mapmatch" if window.rocketDebug
+ message.html = "
"
+
+ # end of temporary pre-1.0 image embed
+ return message
+
+RocketChat.callbacks.add 'renderMessage', ObjEmbedder, RocketChat.callbacks.priority.HIGH
diff --git a/public/images/logo/512x512.jpg b/public/images/logo/512x512.jpg
new file mode 100644
index 0000000000000..454376c0d331a
Binary files /dev/null and b/public/images/logo/512x512.jpg differ
diff --git a/server/methods/sendMessage.coffee b/server/methods/sendMessage.coffee
index 54c126f46221c..f9884d25e40c9 100644
--- a/server/methods/sendMessage.coffee
+++ b/server/methods/sendMessage.coffee
@@ -8,13 +8,16 @@ Meteor.methods
if not room
return false
- # console.log '[methods] sendMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
+ console.log '[methods] sendMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
- message.u = Meteor.users.findOne Meteor.userId(), fields: username: 1
message.ts = new Date()
+ message.u = Meteor.users.findOne Meteor.userId(), fields: username: 1
message.html = message.msg
+ if _.trim(message.html) isnt ''
+ message.html = _.escapeHTML message.html
message = RocketChat.callbacks.run 'beforeSaveMessage', message
+ message.html = message.html.replace /\n/gm, '
'
###
Defer other updated as their return is not interesting to the user
@@ -113,3 +116,10 @@ Meteor.methods
$unset:
t: 1
expireAt: 1
+
+ Meteor.defer ->
+
+ message._id = Random.id()
+ RocketChat.callbacks.run 'afterSaveMessage', message
+
+