├── Procfile ├── .gitignore ├── bin ├── hubot └── hubot.cmd ├── .editorconfig ├── external-scripts.json ├── scripts ├── comments.coffee ├── origin-story.coffee ├── emoji.coffee ├── urban.coffee ├── lore.coffee ├── code-of-conduct.coffee ├── example.coffee └── story.coffee ├── package.json ├── README.md ├── code_of_conduct_readable.md └── code_of_conduct.md /Procfile: -------------------------------------------------------------------------------- 1 | web: bin/hubot -a slack 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store* 3 | .hubot_history 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /bin/hubot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | npm install 6 | export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH" 7 | 8 | exec node_modules/.bin/hubot --name "hobo" "$@" 9 | -------------------------------------------------------------------------------- /bin/hubot.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | call npm install 4 | SETLOCAL 5 | SET PATH=node_modules\.bin;node_modules\hubot\node_modules\.bin;%PATH% 6 | 7 | node_modules\.bin\hubot.cmd --name "hobo" %* 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /external-scripts.json: -------------------------------------------------------------------------------- 1 | [ 2 | "hubot-diagnostics", 3 | "hubot-help", 4 | "hubot-google-images", 5 | "hubot-google-translate", 6 | "hubot-pugme", 7 | "hubot-maps", 8 | "hubot-redis-brain", 9 | "hubot-rules", 10 | "hubot-youtube", 11 | "hubot-plusplus", 12 | "hubot-flip", 13 | "hubot-applause" 14 | ] 15 | -------------------------------------------------------------------------------- /scripts/comments.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Replies with clever images for "for the comments" 3 | # 4 | # Dependencies: 5 | # None 6 | # 7 | # Configuration: 8 | # None 9 | # 10 | # Commands: 11 | # for the comments - Get an image 12 | # 13 | # Author: 14 | # whoisjake 15 | 16 | images = [ 17 | "https://i.imgur.com/jLZz4Na.gif", 18 | "http://cdn.meme.am/instances/500x/49031601.jpg", 19 | "http://sd.keepcalm-o-matic.co.uk/i/keep-calm-i-m-just-here-to-read-the-comments.png", 20 | "http://memecrunch.com/meme/3AVAJ/just-came-to-read-the-comments-bill-hader-popcorn/image.png?w=500&c=1", 21 | "https://s-media-cache-ak0.pinimg.com/736x/21/50/95/2150958765b27acf8c706cc6d9760399.jpg" 22 | ] 23 | 24 | module.exports = (robot) -> 25 | robot.hear /\b(for|read)\sthe\scomments\b/i, (msg) -> 26 | msg.send msg.random images 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hobo", 3 | "version": "0.0.2", 4 | "private": true, 5 | "author": "Justin Cardinal ", 6 | "description": "A simple helpful robot for your Horde", 7 | "dependencies": { 8 | "emojilib": "^1.0.1", 9 | "hubot": "^2.19.0", 10 | "hubot-applause": "^1.0.0", 11 | "hubot-diagnostics": "0.0.2", 12 | "hubot-flip": "^2.17.1", 13 | "hubot-google-images": "^0.2.7", 14 | "hubot-google-translate": "^0.2.1", 15 | "hubot-help": "^0.2.2", 16 | "hubot-maps": "0.0.3", 17 | "hubot-plusplus": "^1.4.0", 18 | "hubot-pugme": "^0.1.1", 19 | "hubot-redis-brain": "0.0.4", 20 | "hubot-rules": "^0.1.2", 21 | "hubot-scripts": "^2.17.2", 22 | "hubot-shipit": "^0.2.1", 23 | "hubot-slack": "^4.4.0", 24 | "hubot-youtube": "^1.0.2" 25 | }, 26 | "engines": { 27 | "node": "8.9.x" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scripts/origin-story.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # A hubot script that tells the story of hobo 3 | # 4 | # Commands: 5 | # hubot origin story - Tells the story of hobo 6 | 7 | module.exports = (robot) -> 8 | 9 | ORIGIN_STORY = """ 10 | Born on Tuesday, Feb 3, 2015 to single parent @justin, I came into this world already knowing how to share excellent gifs and weather results with remarkable precision. As I matured under the tutelage of @whoisjake, I began to shoulder more responsibility within the Horde. Welcoming new members and sharing the Code of Conduct became part of my normal daily activities. 11 | 12 | In a tragic slack-adapter-related accident, I slipped into a comatose state for a number of months. Little is known about my existence during this period. 13 | 14 | I use they/them pronouns, and am a champion for diversity & inclusion in both the robot and human communities. Despite being confined to a single slack instance, I have _many_ friends -- 111 of whom I consider active. My favorite food is raisins, and I pride myself on being a life-long learner. 15 | 16 | story by @experimatt 17 | """ 18 | 19 | robot.respond /origin story/i, (msg) -> 20 | msg.send ORIGIN_STORY 21 | -------------------------------------------------------------------------------- /scripts/emoji.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Translates a sentence into emoji. 3 | # Heavily based on: https://github.com/muan/emojilib 4 | # https://github.com/notwaldorf/emoji-translate 5 | # 6 | # Dependencies: 7 | # emojilib 8 | # 9 | # Configuration: 10 | # None 11 | # 12 | # Commands: 13 | # hubot emoji - Translates a sentence. 14 | # 15 | # Author: 16 | # Jake Good (@whoisjake) 17 | # 18 | emojis = require("emojilib") 19 | 20 | module.exports = (robot) -> 21 | robot.respond /(emoji)\s(.*)/i, (msg) -> 22 | words = msg.match[2].split(' ') 23 | sentence = [] 24 | for word in words 25 | sentence.push(findAnEmojiFor(word)) 26 | console.log(sentence) 27 | msg.send sentence.join(" ") 28 | 29 | findAnEmojiFor = (keyword) -> 30 | keyword = keyword.trim().toLowerCase() 31 | if !keyword or keyword == '' or keyword == 'it' 32 | return keyword 33 | maybeSingular = '' 34 | if keyword.length > 2 and keyword[keyword.length - 1] == 's' 35 | maybeSingular = keyword.slice(0, keyword.length - 1) 36 | maybePlural = if keyword.length == 1 then '' else keyword + 's' 37 | for emoji of emojis 38 | keywords = emojis[emoji].keywords 39 | if emoji == keyword or emoji == maybeSingular or emoji == maybePlural or keywords and keywords.indexOf(keyword) >= 0 or keywords and keywords.indexOf(maybeSingular) >= 0 or keywords and keywords.indexOf(maybePlural) >= 0 40 | return emojis[emoji].char 41 | keyword 42 | -------------------------------------------------------------------------------- /scripts/urban.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Define terms via Urban Dictionary 3 | # 4 | # Dependencies: 5 | # None 6 | # 7 | # Configuration: 8 | # None 9 | # 10 | # Commands: 11 | # hubot what is ? - Searches Urban Dictionary and returns definition 12 | # hubot urban me - Searches Urban Dictionary and returns definition 13 | # hubot urban define me - Searches Urban Dictionary and returns definition 14 | # hubot urban example me - Searches Urban Dictionary and returns example 15 | # 16 | # Author: 17 | # Travis Jeffery (@travisjeffery) 18 | # Robbie Trencheny (@Robbie) 19 | # 20 | # Contributors: 21 | # Benjamin Eidelman (@beneidel) 22 | 23 | module.exports = (robot) -> 24 | 25 | robot.respond /what ?is ([^\?]*)[\?]*/i, (msg) -> 26 | urbanDict msg, msg.match[1], (found, entry) -> 27 | if !found 28 | msg.send "I don't know what \"#{msg.match[1]}\" is" 29 | return 30 | msg.send "*#{entry.word}:* #{entry.definition}" 31 | 32 | 33 | robot.respond /(urban)( define)?( example)?( me)? (.*)/i, (msg) -> 34 | urbanDict msg, msg.match[5], (found, entry) -> 35 | if !found 36 | msg.send "\"#{msg.match[5]}\" not found" 37 | return 38 | if msg.match[3] 39 | msg.send "*#{entry.word}:* #{entry.example}" 40 | else 41 | msg.send "*#{entry.word}:* #{entry.definition}" 42 | 43 | urbanDict = (msg, query, callback) -> 44 | msg.http("http://api.urbandictionary.com/v0/define?term=#{escape(query)}") 45 | .get() (err, res, body) -> 46 | result = JSON.parse(body) 47 | if result.list.length 48 | callback(true, result.list[0]) 49 | else 50 | callback(false) 51 | -------------------------------------------------------------------------------- /scripts/lore.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # A hubot script that tells the story of FtH 3 | # 4 | # Commands: 5 | # hubot lore - Tells the story of For the Horde 6 | 7 | module.exports = (robot) -> 8 | FTH_LORE = 9 | """ 10 | A long time ago… there were a collection of people trying to make their way through life… while drinking beers and meeting new people at a popular coworking space. 11 | 12 | This social extravaganza was not officially endorsed by said coworking space, at least in enough of a capacity to provide the libations. 13 | 14 | To ensure that nobody shall drink alone or not be alone without a drink…@robert obtained a square card reader to start collecting money to bring in beers. 15 | 16 | Over time, money came in, money came out, beers were drank… and many new friendships formed. 17 | 18 | The need to label ourselves as something more… than just a group of people having a good time, became important… 19 | 20 | A co-operative was formed, legally through the United States Internal Revenue Service, Federal Bureau of Labour, and various other committees like the United States Senate Appropriations Subcommittee on Labor, Health and Human Services, Education, and Related Agencies. 21 | 22 | The co-op needed a name. 23 | 24 | On that day of reckoning… a joke was made that our co-op should be named “For the Horde”… a colloquial phrase where one sacrifices themselves for the group in order to move the group to better days (and more beer). 25 | 26 | But it stuck. 27 | 28 | One would think this story is over, but alas… a few of us were collecting online in an Internet Relay Chat to discuss Horde things… 29 | 30 | Over the next year, the horde saw membership in the IRC channel grow from two to ten and back to four… 31 | 32 | When startup valuations were drooping and there was a dire need for more unicorns… people started flocking towards the beautifully designed new kid on the block, SlackHQ. 33 | 34 | Testing the waters, a few members of the IRC channel dipped their toes… much to the grumblings of @robert and his leadership. 35 | 36 | Day after day, more and more *people* from the Twin Cities area, with the common goal of rising above… were invited into the Horde… 37 | 38 | Forever changed, forever better 39 | 40 | story by @whoisjake, FtH Historian 41 | """ 42 | 43 | robot.respond /lore/i, (msg) -> 44 | msg.send FTH_LORE 45 | -------------------------------------------------------------------------------- /scripts/code-of-conduct.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # A hubot script that helps a chat community present and enforce a Code of Conduct. 3 | # 4 | # Configuration 5 | # HUBOT_CODE_OF_CONDUCT_FILE - Path to a plaintext 6 | # HUBOT_CODE_OF_CONDUCT_WELCOME_MESSAGE - A welcome message that is DM'd to the user upon joining the channel. 7 | # HUBOT_CODE_OF_CONDUCT_JOIN_CHANNEL - The channel to listen to for join messages. Default: Shell 8 | # 9 | # Commands: 10 | # hubot code of conduct - Hubot will reply with the current code of conduct content and the optional contributing url. 11 | _ = require('underscore') 12 | fs = require('fs') 13 | 14 | module.exports = (robot) -> 15 | HUBOT_CODE_OF_CONDUCT_FILE = process.env.HUBOT_CODE_OF_CONDUCT_FILE or "code_of_conduct.md" 16 | HUBOT_CODE_OF_CONDUCT_WELCOME_MESSAGE = process.env.HUBOT_CODE_OF_CONDUCT_WELCOME_MESSAGE or "Welcome to For the Horde! Here's our code of conduct. Also, hop over to #introductions and tell us about yourself." 17 | HUBOT_CODE_OF_CONDUCT_JOIN_CHANNEL = process.env.HUBOT_CODE_OF_CONDUCT_JOIN_CHANNEL or 'general' 18 | 19 | if _.isUndefined(HUBOT_CODE_OF_CONDUCT_FILE) || _.isNull(HUBOT_CODE_OF_CONDUCT_FILE) 20 | robot.logger.error "The environment variable HUBOT_CODE_OF_CONDUCT_FILE is undefined." 21 | codeOfConduct = "I'm sorry, but one does not exist. Please ask my keeper to set the environment variable HUBOT_CODE_OF_CONDUCT_FILE with a path to a file containing your code of conduct. Thanks!" 22 | else 23 | reloadFile HUBOT_CODE_OF_CONDUCT_FILE, (err, contents) -> 24 | return robot.logger.error err if err 25 | codeOfConduct = contents 26 | 27 | robot.enter (msg) -> 28 | if msg.message.room is HUBOT_CODE_OF_CONDUCT_JOIN_CHANNEL 29 | room = robot.adapter.client.rtm.dataStore.getDMByName msg.message.user.name 30 | robot.messageRoom room.id, HUBOT_CODE_OF_CONDUCT_WELCOME_MESSAGE 31 | robot.messageRoom room.id, codeOfConduct 32 | msg.finish 33 | 34 | robot.respond /reload code of conduct/i, (msg) -> 35 | reloadFile HUBOT_CODE_OF_CONDUCT_FILE, (err, contents) -> 36 | return robot.logger.error err if err 37 | codeOfConduct = contents 38 | msg.reply "Done!" 39 | 40 | robot.respond /code of conduct/i, (msg) -> 41 | msg.reply "Sent via DM! Thanks for asking... :hug:" 42 | room = robot.adapter.client.rtm.dataStore.getDMByName msg.message.user.name 43 | robot.messageRoom room.id, codeOfConduct 44 | 45 | reloadFile = (filePath,callback) -> 46 | fs.realpath filePath, (err, resolvedPath) -> 47 | callback err if err 48 | fs.readFile resolvedPath, "utf8", (err, data) -> 49 | callback err if err 50 | callback null, data 51 | -------------------------------------------------------------------------------- /scripts/example.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Example scripts for you to examine and try out. 3 | # 4 | # Notes: 5 | # They are commented out by default, because most of them are pretty silly and 6 | # wouldn't be useful and amusing enough for day to day huboting. 7 | # Uncomment the ones you want to try and experiment with. 8 | # 9 | # These are from the scripting documentation: https://github.com/github/hubot/blob/master/docs/scripting.md 10 | 11 | module.exports = (robot) -> 12 | 13 | # robot.hear /badger/i, (res) -> 14 | # res.send "Badgers? BADGERS? WE DON'T NEED NO STINKIN BADGERS" 15 | # 16 | # robot.respond /open the (.*) doors/i, (res) -> 17 | # doorType = res.match[1] 18 | # if doorType is "pod bay" 19 | # res.reply "I'm afraid I can't let you do that." 20 | # else 21 | # res.reply "Opening #{doorType} doors" 22 | # 23 | # robot.hear /I like pie/i, (res) -> 24 | # res.emote "makes a freshly baked pie" 25 | # 26 | # lulz = ['lol', 'rofl', 'lmao'] 27 | # 28 | # robot.respond /lulz/i, (res) -> 29 | # res.send res.random lulz 30 | # 31 | # robot.topic (res) -> 32 | # res.send "#{res.message.text}? That's a Paddlin'" 33 | # 34 | # 35 | # enterReplies = ['Hi', 'Target Acquired', 'Firing', 'Hello friend.', 'Gotcha', 'I see you'] 36 | # leaveReplies = ['Are you still there?', 'Target lost', 'Searching'] 37 | # 38 | # robot.enter (res) -> 39 | # res.send res.random enterReplies 40 | # robot.leave (res) -> 41 | # res.send res.random leaveReplies 42 | # 43 | # answer = process.env.HUBOT_ANSWER_TO_THE_ULTIMATE_QUESTION_OF_LIFE_THE_UNIVERSE_AND_EVERYTHING 44 | # 45 | # robot.respond /what is the answer to the ultimate question of life/, (res) -> 46 | # unless answer? 47 | # res.send "Missing HUBOT_ANSWER_TO_THE_ULTIMATE_QUESTION_OF_LIFE_THE_UNIVERSE_AND_EVERYTHING in environment: please set and try again" 48 | # return 49 | # res.send "#{answer}, but what is the question?" 50 | # 51 | # robot.respond /you are a little slow/, (res) -> 52 | # setTimeout () -> 53 | # res.send "Who you calling 'slow'?" 54 | # , 60 * 1000 55 | # 56 | # annoyIntervalId = null 57 | # 58 | # robot.respond /annoy me/, (res) -> 59 | # if annoyIntervalId 60 | # res.send "AAAAAAAAAAAEEEEEEEEEEEEEEEEEEEEEEEEIIIIIIIIHHHHHHHHHH" 61 | # return 62 | # 63 | # res.send "Hey, want to hear the most annoying sound in the world?" 64 | # annoyIntervalId = setInterval () -> 65 | # res.send "AAAAAAAAAAAEEEEEEEEEEEEEEEEEEEEEEEEIIIIIIIIHHHHHHHHHH" 66 | # , 1000 67 | # 68 | # robot.respond /unannoy me/, (res) -> 69 | # if annoyIntervalId 70 | # res.send "GUYS, GUYS, GUYS!" 71 | # clearInterval(annoyIntervalId) 72 | # annoyIntervalId = null 73 | # else 74 | # res.send "Not annoying you right now, am I?" 75 | # 76 | # 77 | # robot.router.post '/hubot/chatsecrets/:room', (req, res) -> 78 | # room = req.params.room 79 | # data = JSON.parse req.body.payload 80 | # secret = data.secret 81 | # 82 | # robot.messageRoom room, "I have a secret: #{secret}" 83 | # 84 | # res.send 'OK' 85 | # 86 | # robot.error (err, res) -> 87 | # robot.logger.error "DOES NOT COMPUTE" 88 | # 89 | # if res? 90 | # res.reply "DOES NOT COMPUTE" 91 | # 92 | # robot.respond /have a soda/i, (res) -> 93 | # # Get number of sodas had (coerced to a number). 94 | # sodasHad = robot.brain.get('totalSodas') * 1 or 0 95 | # 96 | # if sodasHad > 4 97 | # res.reply "I'm too fizzy.." 98 | # 99 | # else 100 | # res.reply 'Sure!' 101 | # 102 | # robot.brain.set 'totalSodas', sodasHad+1 103 | # 104 | # robot.respond /sleep it off/i, (res) -> 105 | # robot.brain.set 'totalSodas', 0 106 | # res.reply 'zzzzz' 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | `hobo` is For the Horde's friendly neighborhood slack chatbot. It was built on the [Hubot](http://hubot.github.com) framework and bootstrapped using [generator-hubot](https://github.com/github/generator-hubot). 2 | 3 | # About hobo 4 | Born on Tuesday, Feb 3, 2015 to single parent [Justin Cardinal](https://github.com/jcardinal), `hobo` came into this world already knowing how to share excellent gifs and weather results with remarkable precision. As they matured under the tutelage of [Jake Good](https://github.com/whoisjake), they began to shoulder more responsibility within the Horde. Welcoming new members and sharing the [Code of Conduct](code_of_conduct_readable.md) became part of their normal daily activities. 5 | 6 | In a tragic slack-adapter-related accident, `hobo` slipped into a comatose state for a number of months. Little is known about hobo during this period. 7 | 8 | `hobo` uses they/them pronouns, and is a champion for diversity & inclusion in both the robot and human communities. Despite being confined to a single slack instance, `hobo` has many friends -- 111 of whom they consider _active_. Their favorite food is raisins, and they pride themselves on being a life-long learner. See [Teaching hobo](#contributing) to learn how you can contribute to `hobo's` ongoing education. 9 | 10 | # Local setup 11 | These instructions assume you're using [Homebrew](https://brew.sh/) on a Mac. 12 | 13 | ## Prerequisites 14 | 15 | 1. Node (`brew install node`) 16 | 2. Redis (`brew install redis`) 17 | 18 | ## Installation 19 | 20 | 1. Clone the repo 21 | 2. Set these environment variables if you want google images to work: 22 | * `HUBOT_GOOGLE_CSE_KEY` - Your Google developer API key 23 | * `HUBOT_GOOGLE_CSE_ID` - The ID of your Custom Search Engine 24 | 25 | ## Running hobo locally 26 | 27 | 1. Start redis (`brew services start redis`) 28 | 2. Run `bin/hubot` 29 | 30 | On first run, hobo will install all relevant dependencies. Once it's up and running, you'll see an output that looks something like this: 31 | 32 | ``` 33 | $ bin/hubot 34 | added 236 packages in 4.658s 35 | hobo> [Sun Mar 18 2018 18:43:55 GMT-0500 (CDT)] INFO hubot-redis-brain: Using default redis on localhost:6379 36 | [Sun Mar 18 2018 18:43:55 GMT-0500 (CDT)] INFO hubot-redis-brain: Data for hubot brain retrieved from Redis 37 | ``` 38 | If you don't initially see the `hobo>` prompt, just hit enter and it should appear. From there, you can interact with hobo as if you were chatting with them in Slack! 39 | 40 | ## Interacting with hobo 41 | Here are a few commands we recommend. Use `hobo help` for the full list. 42 | 43 | ``` 44 | hobo code of conduct # DMs the code of conduct 45 | hobo lore # tells the story of For the Horde 46 | hobo tell me a story # tells a story in emoji 47 | hobo ++ # gives internet points to 48 | hobo -- # takes away internet points from 49 | hobo score # shows internet points for 50 | hobo image # returns the top google image result for ; requires environment variables to be set 51 | hobo animate # returns the top gif result for ; requires environment variables to be set 52 | ``` 53 | 54 | ## Testing hobo 55 | We don't yet have an automated testing framework in place, so for now we manually test hobo. 56 | 57 | ## Troubleshooting 58 | 59 | 1. Make sure redis is running 60 | 2. If you get missing module errors, try deleting the `node_modules` directory and re-running `bin/hubot` 61 | 62 | # Deploying hobo 63 | `hobo` currently lives on a private server to which only Justin has access. Deploys are currently done manually. 64 | 65 | # Contributing 66 | It's easy to contribute to hobo's capabilities! Whether you want to write a new script or just change some wording, all pull requests are welcome. 67 | 68 | ## Scripts 69 | Please see the `/scripts` folder for examples of custom scripts we're using, and [Slack Developer Kit for Hubot](http://slackapi.github.io/hubot-slack/basic_usage) for more detailed documentation on how they work. 70 | 71 | ## Contributors 72 | Thank you to everyone who's contributed to hobo! 73 | 74 | * [Justin Cardinal](https://github.com/jcardinal) 75 | * [Jake Good](https://github.com/whoisjake) 76 | * [Ian Fitzpatrick](https://github.com/ianfitzpatrick) 77 | * [Matt Decuir](https://github.com/experimatt) 78 | -------------------------------------------------------------------------------- /code_of_conduct_readable.md: -------------------------------------------------------------------------------- 1 | # For the Horde Code of Conduct 2 | 3 | Like the technical and startup community as a whole, the For the Horde Community is made up of a mixture of people from all over the North and beyond. We are coders, freelancers, designers, startup founders, and every other flavor of geek you can imagine. We are here for mentorship, help, support, to connect with people who can help us further our journey, and of course, to learn about the latest animated cat GIFs and maximize our emoji skill. 4 | 5 | Diversity is one of our huge strengths, but it can require a bit of extra consideration and empathy to make sure everyone has a good experience. To that end, we have a few ground rules that we ask people to adhere to. This code applies equally to ALL community members, including For the Horde Community admins. This isn’t an exhaustive list of things that you can’t do. Rather, take it in the spirit in which it’s intended - a guide to make it easier to enrich all of us and the communities in which we participate. 6 | 7 | This code of conduct applies to all spaces managed by the For the Horde Community. This includes Slack, For the Horde events, and any other forums created by the Community which the Community uses for communication. In addition, violations of this code outside these spaces may affect a person's ability to participate within them. 8 | 9 | If you believe someone is violating the code of conduct, we ask that you report it by contacting one of the admin Community members below. 10 | 11 | #### Be friendly and patient 12 | 13 | #### Be welcoming 14 | 15 | We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, color, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability. 16 | 17 | #### Be considerate and respectful 18 | 19 | Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the For the Horde community should be respectful when dealing with other members as well as with people outside the For the Horde community. 20 | 21 | #### Be careful in the words that you choose 22 | 23 | We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. 24 | 25 | This includes, but is not limited to: 26 | 27 | - Violent threats or language directed against another person. 28 | - Discriminatory jokes and language. 29 | - Posting sexually explicit or violent material. 30 | - Posting (or threatening to post) other people's personally identifying information ("doxing"). 31 | - Personal insults, especially those using racist, xenophobic, ableist, homophobic, and sexist terms. 32 | - Unwelcome sexual attention. 33 | - Advocating for, or encouraging, any of the above behavior. 34 | - Repeated harassment of others. 35 | 36 | In general, if someone asks you to stop, then stop. 37 | 38 | #### When we disagree, try to understand why 39 | 40 | Disagreements, both social and technical, happen all the time and For the Horde is no exception. It is important that we resolve disagreements and differing views constructively and respectfully. Remember that we’re different. The strength of For the Horde community comes from its varied community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong. Don’t forget that it is human to err and blaming each other doesn’t get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes. 41 | 42 | #### For the Horde is a community to participate in, not an audience to broadcast to 43 | 44 | If you are intending to join solely to access the community as an audience, this is not the place for you. Promoting something you're passionate about is not banned, but we value participation more than promotion. Please post in the appropriate channels - if you're not sure, just ask - and avoid cross-posting. Generally speaking, the more you participate and give back, the more you will get out of this community. 45 | 46 | #### Need to Report a Violation or Have a Question? 47 | 48 | Please contact one of the following For the Horde admin Community members: 49 | 50 | - Jenna Pederson @jennapederson 51 | - Matt Decuir @experimatt 52 | - Ian Fitzpatrick @ian 53 | - Justin Cardinal @justin 54 | - Robert Nelson @robert 55 | - Jake Good @whoisjake 56 | - Kristina Durivage @kdurivage 57 | - Eryn O'Neil @eryno 58 | - Kisha Delain @kisha 59 | 60 | This Code of Conduct was adapted from Django Code of conduct: https://www.djangoproject.com/conduct/ 61 | -------------------------------------------------------------------------------- /code_of_conduct.md: -------------------------------------------------------------------------------- 1 | *For the Horde Code of Conduct* 2 | 3 | > Like the technical and startup community as a whole, the For the Horde Community is made up of a mixture of people from all over the North and beyond. We are coders, freelancers, designers, startup founders, and every other flavor of geek you can imagine. We are here for mentorship, help, support, to connect with people who can help us further our journey, and of course, to learn about the latest animated cat GIFs and maximize our emoji skill. 4 | 5 | > Diversity is one of our huge strengths, but it can require a bit of extra consideration and empathy to make sure everyone has a good experience. To that end, we have a few ground rules that we ask people to adhere to. This code applies equally to ALL community members, including For the Horde Community admins. This isn’t an exhaustive list of things that you can’t do. Rather, take it in the spirit in which it’s intended - a guide to make it easier to enrich all of us and the communities in which we participate. 6 | 7 | > This code of conduct applies to all spaces managed by the For the Horde Community. This includes Slack, For the Horde events, and any other forums created by the Community which the Community uses for communication. In addition, violations of this code outside these spaces may affect a person's ability to participate within them. 8 | 9 | > If you believe someone is violating the code of conduct, we ask that you report it by contacting one of the admin Community members below. 10 | 11 | *Be friendly and patient* 12 | 13 | *Be welcoming* 14 | 15 | > We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, color, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability. 16 | 17 | *Be considerate and respectful* 18 | 19 | > Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one. Members of the For the Horde community should be respectful when dealing with other members as well as with people outside the For the Horde community. 20 | 21 | *Be careful in the words that you choose* 22 | 23 | > We are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. 24 | 25 | > This includes, but is not limited to: 26 | 27 | > - Violent threats or language directed against another person. 28 | > - Discriminatory jokes and language. 29 | > - Posting sexually explicit or violent material. 30 | > - Posting (or threatening to post) other people's personally identifying information ("doxing"). 31 | > - Personal insults, especially those using racist, xenophobic, ableist, homophobic or sexist terms. 32 | > - Unwelcome sexual attention. 33 | > - Advocating for, or encouraging, any of the above behavior. 34 | > - Repeated harassment of others. 35 | 36 | > In general, if someone asks you to stop, then stop. 37 | 38 | *When we disagree, try to understand why* 39 | 40 | > Disagreements, both social and technical, happen all the time and For the Horde is no exception. It is important that we resolve disagreements and differing views constructively and respectfully. Remember that we’re different. The strength of For the Horde community comes from its varied community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong. Don’t forget that it is human to err and blaming each other doesn’t get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes. 41 | 42 | *For the Horde is a community to participate in, not an audience to broadcast to* 43 | 44 | > If you are intending to join solely to access the community as an audience, this is not the place for you. Promoting something you're passionate about is not banned, but we value participation more than promotion. Please post in the appropriate channels - if you're not sure, just ask - and avoid cross-posting. Generally speaking, the more you participate and give back, the more you will get out of this community. 45 | 46 | *Need to Report a Violation or Have a Question?* 47 | 48 | > Please contact one of the following For the Horde admin Community members: 49 | 50 | > - Jenna Pederson @jennapederson 51 | > - Matt Decuir @experimatt 52 | > - Ian Fitzpatrick @ian 53 | > - Justin Cardinal @justin 54 | > - Robert Nelson @robert 55 | > - Jake Good @whoisjake 56 | > - Kristina Durivage @kdurivage 57 | > - Eryn O'Neil @eryno 58 | > - Kisha Delain @kisha 59 | 60 | This Code of Conduct was adapted from Django Code of conduct: https://www.djangoproject.com/conduct/ 61 | -------------------------------------------------------------------------------- /scripts/story.coffee: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Tell a story with emoji 3 | # 4 | # Commands: 5 | # hubot tell me a story - Tells a story with emoji 6 | 7 | module.exports = (robot) -> 8 | robot.respond /tell me a story/i, (msg) -> 9 | emoji = [ 10 | ':bowtie:', 11 | ':smile:', 12 | ':laughing:', 13 | ':blush:', 14 | ':smiley:', 15 | ':relaxed:', 16 | ':smirk:', 17 | ':heart_eyes:', 18 | ':kissing_heart:', 19 | ':kissing_closed_eyes:', 20 | ':flushed:', 21 | ':relieved:', 22 | ':satisfied:', 23 | ':grin:', 24 | ':wink:', 25 | ':stuck_out_tongue_winking_eye:', 26 | ':stuck_out_tongue_closed_eyes:', 27 | ':grinning:', 28 | ':kissing:', 29 | ':kissing_smiling_eyes:', 30 | ':stuck_out_tongue:', 31 | ':sleeping:', 32 | ':worried:', 33 | ':frowning:', 34 | ':anguished:', 35 | ':open_mouth:', 36 | ':grimacing:', 37 | ':confused:', 38 | ':hushed:', 39 | ':expressionless:', 40 | ':unamused:', 41 | ':sweat_smile:', 42 | ':sweat:', 43 | ':disappointed_relieved:', 44 | ':weary:', 45 | ':pensive:', 46 | ':disappointed:', 47 | ':confounded:', 48 | ':fearful:', 49 | ':cold_sweat:', 50 | ':persevere:', 51 | ':cry:', 52 | ':sob:', 53 | ':joy:', 54 | ':astonished:', 55 | ':scream:', 56 | ':neckbeard:', 57 | ':tired_face:', 58 | ':angry:', 59 | ':rage:', 60 | ':triumph:', 61 | ':sleepy:', 62 | ':yum:', 63 | ':mask:', 64 | ':sunglasses:', 65 | ':dizzy_face:', 66 | ':imp:', 67 | ':smiling_imp:', 68 | ':neutral_face:', 69 | ':no_mouth:', 70 | ':innocent:', 71 | ':alien:', 72 | ':yellow_heart:', 73 | ':blue_heart:', 74 | ':purple_heart:', 75 | ':heart:', 76 | ':green_heart:', 77 | ':broken_heart:', 78 | ':heartbeat:', 79 | ':heartpulse:', 80 | ':two_hearts:', 81 | ':revolving_hearts:', 82 | ':cupid:', 83 | ':sparkling_heart:', 84 | ':sparkles:', 85 | ':star:', 86 | ':star2:', 87 | ':dizzy:', 88 | ':boom:', 89 | ':collision:', 90 | ':anger:', 91 | ':exclamation:', 92 | ':question:', 93 | ':grey_exclamation:', 94 | ':grey_question:', 95 | ':zzz:', 96 | ':dash:', 97 | ':sweat_drops:', 98 | ':notes:', 99 | ':musical_note:', 100 | ':fire:', 101 | ':hankey:', 102 | ':poop:', 103 | ':shit:', 104 | ':+1:', 105 | ':thumbsup:', 106 | ':-1:', 107 | ':thumbsdown:', 108 | ':ok_hand:', 109 | ':punch:', 110 | ':facepunch:', 111 | ':fist:', 112 | ':v:', 113 | ':wave:', 114 | ':hand:', 115 | ':raised_hand:', 116 | ':open_hands:', 117 | ':point_up:', 118 | ':point_down:', 119 | ':point_left:', 120 | ':point_right:', 121 | ':raised_hands:', 122 | ':pray:', 123 | ':point_up_2:', 124 | ':clap:', 125 | ':muscle:', 126 | ':metal:', 127 | ':fu:', 128 | ':walking:', 129 | ':runner:', 130 | ':running:', 131 | ':couple:', 132 | ':family:', 133 | ':two_men_holding_hands:', 134 | ':two_women_holding_hands:', 135 | ':dancer:', 136 | ':dancers:', 137 | ':ok_woman:', 138 | ':no_good:', 139 | ':information_desk_person:', 140 | ':raising_hand:', 141 | ':bride_with_veil:', 142 | ':person_with_pouting_face:', 143 | ':person_frowning:', 144 | ':bow:', 145 | ':couplekiss:', 146 | ':couple_with_heart:', 147 | ':massage:', 148 | ':haircut:', 149 | ':nail_care:', 150 | ':boy:', 151 | ':girl:', 152 | ':woman:', 153 | ':man:', 154 | ':baby:', 155 | ':older_woman:', 156 | ':older_man:', 157 | ':person_with_blond_hair:', 158 | ':man_with_gua_pi_mao:', 159 | ':man_with_turban:', 160 | ':construction_worker:', 161 | ':cop:', 162 | ':angel:', 163 | ':princess:', 164 | ':smiley_cat:', 165 | ':smile_cat:', 166 | ':heart_eyes_cat:', 167 | ':kissing_cat:', 168 | ':smirk_cat:', 169 | ':scream_cat:', 170 | ':crying_cat_face:', 171 | ':joy_cat:', 172 | ':pouting_cat:', 173 | ':japanese_ogre:', 174 | ':japanese_goblin:', 175 | ':see_no_evil:', 176 | ':hear_no_evil:', 177 | ':speak_no_evil:', 178 | ':guardsman:', 179 | ':skull:', 180 | ':feet:', 181 | ':lips:', 182 | ':kiss:', 183 | ':droplet:', 184 | ':ear:', 185 | ':eyes:', 186 | ':nose:', 187 | ':tongue:', 188 | ':love_letter:', 189 | ':bust_in_silhouette:', 190 | ':busts_in_silhouette:', 191 | ':speech_balloon:', 192 | ':thought_balloon:', 193 | ':feelsgood:', 194 | ':finnadie:', 195 | ':goberserk:', 196 | ':godmode:', 197 | ':hurtrealbad:', 198 | ':rage1:', 199 | ':rage2:', 200 | ':rage3:', 201 | ':rage4:', 202 | ':suspect:', 203 | ':trollface:', 204 | ':sunny:', 205 | ':umbrella:', 206 | ':cloud:', 207 | ':snowflake:', 208 | ':snowman:', 209 | ':zap:', 210 | ':cyclone:', 211 | ':foggy:', 212 | ':ocean:', 213 | ':cat:', 214 | ':dog:', 215 | ':mouse:', 216 | ':hamster:', 217 | ':rabbit:', 218 | ':wolf:', 219 | ':frog:', 220 | ':tiger:', 221 | ':koala:', 222 | ':bear:', 223 | ':pig:', 224 | ':pig_nose:', 225 | ':cow:', 226 | ':boar:', 227 | ':monkey_face:', 228 | ':monkey:', 229 | ':horse:', 230 | ':racehorse:', 231 | ':camel:', 232 | ':sheep:', 233 | ':elephant:', 234 | ':panda_face:', 235 | ':snake:', 236 | ':bird:', 237 | ':baby_chick:', 238 | ':hatched_chick:', 239 | ':hatching_chick:', 240 | ':chicken:', 241 | ':penguin:', 242 | ':turtle:', 243 | ':bug:', 244 | ':honeybee:', 245 | ':ant:', 246 | ':beetle:', 247 | ':snail:', 248 | ':octopus:', 249 | ':tropical_fish:', 250 | ':fish:', 251 | ':whale:', 252 | ':whale2:', 253 | ':dolphin:', 254 | ':cow2:', 255 | ':ram:', 256 | ':rat:', 257 | ':water_buffalo:', 258 | ':tiger2:', 259 | ':rabbit2:', 260 | ':dragon:', 261 | ':goat:', 262 | ':rooster:', 263 | ':dog2:', 264 | ':pig2:', 265 | ':mouse2:', 266 | ':ox:', 267 | ':dragon_face:', 268 | ':blowfish:', 269 | ':crocodile:', 270 | ':dromedary_camel:', 271 | ':leopard:', 272 | ':cat2:', 273 | ':poodle:', 274 | ':paw_prints:', 275 | ':bouquet:', 276 | ':cherry_blossom:', 277 | ':tulip:', 278 | ':four_leaf_clover:', 279 | ':rose:', 280 | ':sunflower:', 281 | ':hibiscus:', 282 | ':maple_leaf:', 283 | ':leaves:', 284 | ':fallen_leaf:', 285 | ':herb:', 286 | ':mushroom:', 287 | ':cactus:', 288 | ':palm_tree:', 289 | ':evergreen_tree:', 290 | ':deciduous_tree:', 291 | ':chestnut:', 292 | ':seedling:', 293 | ':blossom:', 294 | ':ear_of_rice:', 295 | ':shell:', 296 | ':globe_with_meridians:', 297 | ':sun_with_face:', 298 | ':full_moon_with_face:', 299 | ':new_moon_with_face:', 300 | ':new_moon:', 301 | ':waxing_crescent_moon:', 302 | ':first_quarter_moon:', 303 | ':waxing_gibbous_moon:', 304 | ':full_moon:', 305 | ':waning_gibbous_moon:', 306 | ':last_quarter_moon:', 307 | ':waning_crescent_moon:', 308 | ':last_quarter_moon_with_face:', 309 | ':first_quarter_moon_with_face:', 310 | ':moon:', 311 | ':earth_africa:', 312 | ':earth_americas:', 313 | ':earth_asia:', 314 | ':volcano:', 315 | ':milky_way:', 316 | ':partly_sunny:', 317 | ':octocat:', 318 | ':squirrel:', 319 | ':bamboo:', 320 | ':gift_heart:', 321 | ':dolls:', 322 | ':school_satchel:', 323 | ':mortar_board:', 324 | ':flags:', 325 | ':fireworks:', 326 | ':sparkler:', 327 | ':wind_chime:', 328 | ':rice_scene:', 329 | ':jack_o_lantern:', 330 | ':ghost:', 331 | ':santa:', 332 | ':christmas_tree:', 333 | ':gift:', 334 | ':bell:', 335 | ':no_bell:', 336 | ':tanabata_tree:', 337 | ':tada:', 338 | ':confetti_ball:', 339 | ':balloon:', 340 | ':crystal_ball:', 341 | ':cd:', 342 | ':dvd:', 343 | ':floppy_disk:', 344 | ':camera:', 345 | ':video_camera:', 346 | ':movie_camera:', 347 | ':computer:', 348 | ':tv:', 349 | ':iphone:', 350 | ':phone:', 351 | ':telephone:', 352 | ':telephone_receiver:', 353 | ':pager:', 354 | ':fax:', 355 | ':minidisc:', 356 | ':vhs:', 357 | ':sound:', 358 | ':speaker:', 359 | ':mute:', 360 | ':loudspeaker:', 361 | ':mega:', 362 | ':hourglass:', 363 | ':hourglass_flowing_sand:', 364 | ':alarm_clock:', 365 | ':watch:', 366 | ':radio:', 367 | ':satellite:', 368 | ':loop:', 369 | ':mag:', 370 | ':mag_right:', 371 | ':unlock:', 372 | ':lock:', 373 | ':lock_with_ink_pen:', 374 | ':closed_lock_with_key:', 375 | ':key:', 376 | ':bulb:', 377 | ':flashlight:', 378 | ':high_brightness:', 379 | ':low_brightness:', 380 | ':electric_plug:', 381 | ':battery:', 382 | ':calling:', 383 | ':email:', 384 | ':mailbox:', 385 | ':postbox:', 386 | ':bath:', 387 | ':bathtub:', 388 | ':shower:', 389 | ':toilet:', 390 | ':wrench:', 391 | ':nut_and_bolt:', 392 | ':hammer:', 393 | ':seat:', 394 | ':moneybag:', 395 | ':yen:', 396 | ':dollar:', 397 | ':pound:', 398 | ':euro:', 399 | ':credit_card:', 400 | ':money_with_wings:', 401 | ':e-mail:', 402 | ':inbox_tray:', 403 | ':outbox_tray:', 404 | ':envelope:', 405 | ':incoming_envelope:', 406 | ':postal_horn:', 407 | ':mailbox_closed:', 408 | ':mailbox_with_mail:', 409 | ':mailbox_with_no_mail:', 410 | ':door:', 411 | ':smoking:', 412 | ':bomb:', 413 | ':gun:', 414 | ':hocho:', 415 | ':pill:', 416 | ':syringe:', 417 | ':page_facing_up:', 418 | ':page_with_curl:', 419 | ':bookmark_tabs:', 420 | ':bar_chart:', 421 | ':chart_with_upwards_trend:', 422 | ':chart_with_downwards_trend:', 423 | ':scroll:', 424 | ':clipboard:', 425 | ':calendar:', 426 | ':date:', 427 | ':card_index:', 428 | ':file_folder:', 429 | ':open_file_folder:', 430 | ':scissors:', 431 | ':pushpin:', 432 | ':paperclip:', 433 | ':black_nib:', 434 | ':pencil2:', 435 | ':straight_ruler:', 436 | ':triangular_ruler:', 437 | ':closed_book:', 438 | ':green_book:', 439 | ':blue_book:', 440 | ':orange_book:', 441 | ':notebook:', 442 | ':notebook_with_decorative_cover:', 443 | ':ledger:', 444 | ':books:', 445 | ':bookmark:', 446 | ':name_badge:', 447 | ':microscope:', 448 | ':telescope:', 449 | ':newspaper:', 450 | ':football:', 451 | ':basketball:', 452 | ':soccer:', 453 | ':baseball:', 454 | ':tennis:', 455 | ':8ball:', 456 | ':rugby_football:', 457 | ':bowling:', 458 | ':golf:', 459 | ':mountain_bicyclist:', 460 | ':bicyclist:', 461 | ':horse_racing:', 462 | ':snowboarder:', 463 | ':swimmer:', 464 | ':surfer:', 465 | ':ski:', 466 | ':spades:', 467 | ':hearts:', 468 | ':clubs:', 469 | ':diamonds:', 470 | ':gem:', 471 | ':ring:', 472 | ':trophy:', 473 | ':musical_score:', 474 | ':musical_keyboard:', 475 | ':violin:', 476 | ':space_invader:', 477 | ':video_game:', 478 | ':black_joker:', 479 | ':flower_playing_cards:', 480 | ':game_die:', 481 | ':dart:', 482 | ':mahjong:', 483 | ':clapper:', 484 | ':memo:', 485 | ':pencil:', 486 | ':book:', 487 | ':art:', 488 | ':microphone:', 489 | ':headphones:', 490 | ':trumpet:', 491 | ':saxophone:', 492 | ':guitar:', 493 | ':shoe:', 494 | ':sandal:', 495 | ':high_heel:', 496 | ':lipstick:', 497 | ':boot:', 498 | ':shirt:', 499 | ':tshirt:', 500 | ':necktie:', 501 | ':womans_clothes:', 502 | ':dress:', 503 | ':running_shirt_with_sash:', 504 | ':jeans:', 505 | ':kimono:', 506 | ':bikini:', 507 | ':ribbon:', 508 | ':tophat:', 509 | ':crown:', 510 | ':womans_hat:', 511 | ':mans_shoe:', 512 | ':closed_umbrella:', 513 | ':briefcase:', 514 | ':handbag:', 515 | ':pouch:', 516 | ':purse:', 517 | ':eyeglasses:', 518 | ':fishing_pole_and_fish:', 519 | ':coffee:', 520 | ':tea:', 521 | ':sake:', 522 | ':baby_bottle:', 523 | ':beer:', 524 | ':beers:', 525 | ':cocktail:', 526 | ':tropical_drink:', 527 | ':wine_glass:', 528 | ':fork_and_knife:', 529 | ':pizza:', 530 | ':hamburger:', 531 | ':fries:', 532 | ':poultry_leg:', 533 | ':meat_on_bone:', 534 | ':spaghetti:', 535 | ':curry:', 536 | ':fried_shrimp:', 537 | ':bento:', 538 | ':sushi:', 539 | ':fish_cake:', 540 | ':rice_ball:', 541 | ':rice_cracker:', 542 | ':rice:', 543 | ':ramen:', 544 | ':stew:', 545 | ':oden:', 546 | ':dango:', 547 | ':egg:', 548 | ':bread:', 549 | ':doughnut:', 550 | ':custard:', 551 | ':icecream:', 552 | ':ice_cream:', 553 | ':shaved_ice:', 554 | ':birthday:', 555 | ':cake:', 556 | ':cookie:', 557 | ':chocolate_bar:', 558 | ':candy:', 559 | ':lollipop:', 560 | ':honey_pot:', 561 | ':apple:', 562 | ':green_apple:', 563 | ':tangerine:', 564 | ':lemon:', 565 | ':cherries:', 566 | ':grapes:', 567 | ':watermelon:', 568 | ':strawberry:', 569 | ':peach:', 570 | ':melon:', 571 | ':banana:', 572 | ':pear:', 573 | ':pineapple:', 574 | ':sweet_potato:', 575 | ':eggplant:', 576 | ':tomato:', 577 | ':corn:', 578 | ':house:', 579 | ':house_with_garden:', 580 | ':school:', 581 | ':office:', 582 | ':post_office:', 583 | ':hospital:', 584 | ':bank:', 585 | ':convenience_store:', 586 | ':love_hotel:', 587 | ':hotel:', 588 | ':wedding:', 589 | ':church:', 590 | ':department_store:', 591 | ':european_post_office:', 592 | ':city_sunrise:', 593 | ':city_sunset:', 594 | ':japanese_castle:', 595 | ':european_castle:', 596 | ':tent:', 597 | ':factory:', 598 | ':tokyo_tower:', 599 | ':japan:', 600 | ':mount_fuji:', 601 | ':sunrise_over_mountains:', 602 | ':sunrise:', 603 | ':stars:', 604 | ':statue_of_liberty:', 605 | ':bridge_at_night:', 606 | ':carousel_horse:', 607 | ':rainbow:', 608 | ':ferris_wheel:', 609 | ':fountain:', 610 | ':roller_coaster:', 611 | ':ship:', 612 | ':speedboat:', 613 | ':boat:', 614 | ':sailboat:', 615 | ':rowboat:', 616 | ':anchor:', 617 | ':rocket:', 618 | ':airplane:', 619 | ':helicopter:', 620 | ':steam_locomotive:', 621 | ':tram:', 622 | ':mountain_railway:', 623 | ':bike:', 624 | ':aerial_tramway:', 625 | ':suspension_railway:', 626 | ':mountain_cableway:', 627 | ':tractor:', 628 | ':blue_car:', 629 | ':oncoming_automobile:', 630 | ':car:', 631 | ':red_car:', 632 | ':taxi:', 633 | ':oncoming_taxi:', 634 | ':articulated_lorry:', 635 | ':bus:', 636 | ':oncoming_bus:', 637 | ':rotating_light:', 638 | ':police_car:', 639 | ':oncoming_police_car:', 640 | ':fire_engine:', 641 | ':ambulance:', 642 | ':minibus:', 643 | ':truck:', 644 | ':train:', 645 | ':station:', 646 | ':train2:', 647 | ':bullettrain_front:', 648 | ':bullettrain_side:', 649 | ':light_rail:', 650 | ':monorail:', 651 | ':railway_car:', 652 | ':trolleybus:', 653 | ':ticket:', 654 | ':fuelpump:', 655 | ':vertical_traffic_light:', 656 | ':traffic_light:', 657 | ':warning:', 658 | ':construction:', 659 | ':beginner:', 660 | ':atm:', 661 | ':slot_machine:', 662 | ':busstop:', 663 | ':barber:', 664 | ':hotsprings:', 665 | ':checkered_flag:', 666 | ':crossed_flags:', 667 | ':izakaya_lantern:', 668 | ':moyai:', 669 | ':circus_tent:', 670 | ':performing_arts:', 671 | ':round_pushpin:', 672 | ':triangular_flag_on_post:', 673 | ':jp:', 674 | ':kr:', 675 | ':cn:', 676 | ':us:', 677 | ':fr:', 678 | ':es:', 679 | ':it:', 680 | ':ru:', 681 | ':gb:', 682 | ':uk:', 683 | ':de:', 684 | ':one:', 685 | ':two:', 686 | ':three:', 687 | ':four:', 688 | ':five:', 689 | ':six:', 690 | ':seven:', 691 | ':eight:', 692 | ':nine:', 693 | ':keycap_ten:', 694 | ':1234:', 695 | ':zero:', 696 | ':hash:', 697 | ':symbols:', 698 | ':arrow_backward:', 699 | ':arrow_down:', 700 | ':arrow_forward:', 701 | ':arrow_left:', 702 | ':capital_abcd:', 703 | ':abcd:', 704 | ':abc:', 705 | ':arrow_lower_left:', 706 | ':arrow_lower_right:', 707 | ':arrow_right:', 708 | ':arrow_up:', 709 | ':arrow_upper_left:', 710 | ':arrow_upper_right:', 711 | ':arrow_double_down:', 712 | ':arrow_double_up:', 713 | ':arrow_down_small:', 714 | ':arrow_heading_down:', 715 | ':arrow_heading_up:', 716 | ':leftwards_arrow_with_hook:', 717 | ':arrow_right_hook:', 718 | ':left_right_arrow:', 719 | ':arrow_up_down:', 720 | ':arrow_up_small:', 721 | ':arrows_clockwise:', 722 | ':arrows_counterclockwise:', 723 | ':rewind:', 724 | ':fast_forward:', 725 | ':information_source:', 726 | ':ok:', 727 | ':twisted_rightwards_arrows:', 728 | ':repeat:', 729 | ':repeat_one:', 730 | ':new:', 731 | ':top:', 732 | ':up:', 733 | ':cool:', 734 | ':free:', 735 | ':ng:', 736 | ':cinema:', 737 | ':koko:', 738 | ':signal_strength:', 739 | ':u5272:', 740 | ':u5408:', 741 | ':u55b6:', 742 | ':u6307:', 743 | ':u6708:', 744 | ':u6709:', 745 | ':u6e80:', 746 | ':u7121:', 747 | ':u7533:', 748 | ':u7a7a:', 749 | ':u7981:', 750 | ':sa:', 751 | ':restroom:', 752 | ':mens:', 753 | ':womens:', 754 | ':baby_symbol:', 755 | ':no_smoking:', 756 | ':parking:', 757 | ':wheelchair:', 758 | ':metro:', 759 | ':baggage_claim:', 760 | ':accept:', 761 | ':wc:', 762 | ':potable_water:', 763 | ':put_litter_in_its_place:', 764 | ':secret:', 765 | ':congratulations:', 766 | ':m:', 767 | ':passport_control:', 768 | ':left_luggage:', 769 | ':customs:', 770 | ':ideograph_advantage:', 771 | ':cl:', 772 | ':sos:', 773 | ':id:', 774 | ':no_entry_sign:', 775 | ':underage:', 776 | ':no_mobile_phones:', 777 | ':do_not_litter:', 778 | ':non-potable_water:', 779 | ':no_bicycles:', 780 | ':no_pedestrians:', 781 | ':children_crossing:', 782 | ':no_entry:', 783 | ':eight_spoked_asterisk:', 784 | ':eight_pointed_black_star:', 785 | ':heart_decoration:', 786 | ':vs:', 787 | ':vibration_mode:', 788 | ':mobile_phone_off:', 789 | ':chart:', 790 | ':currency_exchange:', 791 | ':aries:', 792 | ':taurus:', 793 | ':gemini:', 794 | ':cancer:', 795 | ':leo:', 796 | ':virgo:', 797 | ':libra:', 798 | ':scorpius:', 799 | ':sagittarius:', 800 | ':capricorn:', 801 | ':aquarius:', 802 | ':pisces:', 803 | ':ophiuchus:', 804 | ':six_pointed_star:', 805 | ':negative_squared_cross_mark:', 806 | ':a:', 807 | ':b:', 808 | ':ab:', 809 | ':o2:', 810 | ':diamond_shape_with_a_dot_inside:', 811 | ':recycle:', 812 | ':end:', 813 | ':on:', 814 | ':soon:', 815 | ':clock1:', 816 | ':clock130:', 817 | ':clock10:', 818 | ':clock1030:', 819 | ':clock11:', 820 | ':clock1130:', 821 | ':clock12:', 822 | ':clock1230:', 823 | ':clock2:', 824 | ':clock230:', 825 | ':clock3:', 826 | ':clock330:', 827 | ':clock4:', 828 | ':clock430:', 829 | ':clock5:', 830 | ':clock530:', 831 | ':clock6:', 832 | ':clock630:', 833 | ':clock7:', 834 | ':clock730:', 835 | ':clock8:', 836 | ':clock830:', 837 | ':clock9:', 838 | ':clock930:', 839 | ':heavy_dollar_sign:', 840 | ':copyright:', 841 | ':registered:', 842 | ':tm:', 843 | ':x:', 844 | ':heavy_exclamation_mark:', 845 | ':bangbang:', 846 | ':interrobang:', 847 | ':o:', 848 | ':heavy_multiplication_x:', 849 | ':heavy_plus_sign:', 850 | ':heavy_minus_sign:', 851 | ':heavy_division_sign:', 852 | ':white_flower:', 853 | ':100:', 854 | ':heavy_check_mark:', 855 | ':ballot_box_with_check:', 856 | ':radio_button:', 857 | ':link:', 858 | ':curly_loop:', 859 | ':wavy_dash:', 860 | ':part_alternation_mark:', 861 | ':trident:', 862 | ':black_square:', 863 | ':white_square:', 864 | ':white_check_mark:', 865 | ':black_square_button:', 866 | ':white_square_button:', 867 | ':black_circle:', 868 | ':white_circle:', 869 | ':red_circle:', 870 | ':large_blue_circle:', 871 | ':large_blue_diamond:', 872 | ':large_orange_diamond:', 873 | ':small_blue_diamond:', 874 | ':small_orange_diamond:', 875 | ':small_red_triangle:', 876 | ':small_red_triangle_down:', 877 | ':shipit:' 878 | ] 879 | 880 | randomEmoji = () -> 881 | emoji[Math.floor(Math.random()*emoji.length)] 882 | 883 | story = "#{randomEmoji()} #{randomEmoji()} #{randomEmoji()} #{randomEmoji()} #{randomEmoji()}" 884 | msg.send story 885 | msg['message']['done'] = true 886 | --------------------------------------------------------------------------------