From d1d6017f91d7ad3df7cf702d034193e2c8f1aee1 Mon Sep 17 00:00:00 2001
From: Gabriel Engel <gabriel.engel@fgsys.com>
Date: Fri, 12 Jun 2015 06:09:45 -0300
Subject: [PATCH] adding embedded hubot

---
 .../.npm/package/npm-shrinkwrap.json          | 215 ++++++++++++++++++
 packages/rocketchat-hubot/hubot.coffee        | 193 ++++++++++++++++
 packages/rocketchat-hubot/hubot.coffee.new    | 187 ---------------
 packages/rocketchat-hubot/package.js          |  11 +-
 server/methods/sendMessage.coffee             |   7 +
 5 files changed, 425 insertions(+), 188 deletions(-)
 delete mode 100644 packages/rocketchat-hubot/hubot.coffee.new

diff --git a/packages/rocketchat-hubot/.npm/package/npm-shrinkwrap.json b/packages/rocketchat-hubot/.npm/package/npm-shrinkwrap.json
index ba6a6192266..370832fe5fd 100644
--- a/packages/rocketchat-hubot/.npm/package/npm-shrinkwrap.json
+++ b/packages/rocketchat-hubot/.npm/package/npm-shrinkwrap.json
@@ -1,5 +1,220 @@
 {
   "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"
     },
diff --git a/packages/rocketchat-hubot/hubot.coffee b/packages/rocketchat-hubot/hubot.coffee
index 8492b62f8d5..c94afb708d9 100644
--- a/packages/rocketchat-hubot/hubot.coffee
+++ b/packages/rocketchat-hubot/hubot.coffee
@@ -1,4 +1,197 @@
 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)
+
+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}"
+
+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 RocketBot;
+		return message
+
+RocketBot = new Robot null, null, false, Meteor.settings?.botname ? 'rocketbot'
+RocketBot.alias = 'bot'
+RocketBot.adapter = new RocketChatAdapter 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/hubot.coffee.new b/packages/rocketchat-hubot/hubot.coffee.new
deleted file mode 100644
index 19e9a52a84d..00000000000
--- a/packages/rocketchat-hubot/hubot.coffee.new
+++ /dev/null
@@ -1,187 +0,0 @@
-hubot = Npm.require('hubot')
-
-Hubot = hubot;
-
-# Start a hubot, connected to our chat room.
-'use strict'
-model = share.model # import
-
-# 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)
-
-sendHelper = Meteor.bindEnvironment (robot, envelope, strings, map) ->
-	# be present in the room
-	try
-		Meteor.call 'setPresence',
-			nick: 'codexbot'
-			room_name: envelope.room
-			present: true
-			foreground: true
-	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 "Blackboard send error: #{err}"
-
-class BlackboardAdapter 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.room}: #{string} (#{envelope.user.id})" if DEBUG
-			return @priv envelope, string if envelope.message.private
-			Meteor.call "newMessage",
-				nick: "codexbot"
-				body: string
-				room_name: envelope.room
-
-	# 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.room}: #{string} (#{envelope.user.id})" if DEBUG
-			return @priv envelope, "*** #{string} ***" if envelope.message.private
-			Meteor.call "newMessage",
-				nick: "codexbot"
-				body: string
-				room_name: envelope.room
-				action: true
-
-	# Priv: our extension -- send a PM to user
-	priv: (envelope, strings...) ->
-		sendHelper @robot, envelope, strings, (string) ->
-			console.log "priv #{envelope.room}: #{string} (#{envelope.user.id})" if DEBUG
-			Meteor.call "newMessage",
-				nick: "codexbot"
-				to: "#{envelope.user.id}"
-				body: string
-				room_name: envelope.room
-
-	# 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.user.id}: #{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: ->
-
-Meteor.startup ->
-	robot = new Robot null, null, false, Meteor.settings?.botname ? 'codexbot'
-	robot.alias = 'bot'
-	adapter = robot.adapter = new BlackboardAdapter robot
-	# 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: 'codexbot'}
-	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',
-		nick: 'codexbot'
-		room_name: 'general/0'
-		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
-	model.Messages.find({}).observe
-		added: (msg) ->
-			return if startup
-			return if msg.nick is "codexbot" or msg.nick is ""
-			return if msg.system or msg.action or msg.oplog or msg.bodyIsHtml
-			console.log "Received from #{msg.nick} in #{msg.room_name}: #{msg.body}"\
-				if DEBUG
-			user = new Hubot.User(msg.nick, room: msg.room_name)
-			tm = new Hubot.TextMessage(user, msg.body, msg._id)
-			tm.private = msg.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 "newMessage",
-		nick: "codexbot"
-		body: 'wakes up'
-		room_name: 'general/0'
-		action: true
diff --git a/packages/rocketchat-hubot/package.js b/packages/rocketchat-hubot/package.js
index 0ce7c635438..e58d9d52e85 100644
--- a/packages/rocketchat-hubot/package.js
+++ b/packages/rocketchat-hubot/package.js
@@ -8,15 +8,24 @@ Package.describe({
 Package.onUse(function(api) {
 	api.versionsFrom('1.0');
 
-	api.use(['coffeescript']);
+	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"
 });
 
diff --git a/server/methods/sendMessage.coffee b/server/methods/sendMessage.coffee
index 0a0afdf4ffe..f9884d25e40 100644
--- a/server/methods/sendMessage.coffee
+++ b/server/methods/sendMessage.coffee
@@ -116,3 +116,10 @@ Meteor.methods
 			$unset:
 				t: 1
 				expireAt: 1
+
+		Meteor.defer ->
+
+			message._id = Random.id()
+			RocketChat.callbacks.run 'afterSaveMessage', message
+
+
-- 
GitLab