Example #1
0
 dbot.api.users.getChannel(cId, function(channel) {
     if(_.include(channel.op, req.user.id) ||
             (this.config.notifyVoice && _.include(channel.voice, req.user.id))) {
         staffedChannels.push(channel.name);
     }
     done();
 }.bind(this));
Example #2
0
        '~mergeusers': function(event) {
            var knownUsers = this.getServerUsers(event.server);
            var primaryUser = event.params[1];
            var secondaryUser = event.params[2];

            if(_.include(knownUsers.users, primaryUser) && _.include(knownUsers.users, secondaryUser)) {
                knownUsers.users = _.without(knownUsers.users, secondaryUser);
                knownUsers.aliases[secondaryUser] = primaryUser;
                this.updateAliases(event, secondaryUser, primaryUser);
                this.updateChannels(event, secondaryUser, primaryUser);

                event.reply(dbot.t('merged_users', { 
                    'old_user': secondaryUser,
                    'new_user': primaryUser
                }));
                
                return {
                    'server': event.server,
                    'secondary': secondaryUser
                };
            } else {
                event.reply(dbot.t('unprimary_error'));
            }
            return false;
        } 
Example #3
0
File: api.js Project: Rob-pw/dbot
 dbot.api.users.resolveUser(server, nick, function(user) {
     if(!_.include(user.mobile, user.currentNick)) {
         perOps = _.without(perOps, user.id);
     }
     if(nunsubs && _.include(nunsubs.users, user.id)) {
         ops = _.without(ops, user.currentNick);
     }
     next();
 }); 
Example #4
0
 'isBanned': function(user, command) {
     var banned = false;
     if(_.has(dbot.db.bans, user)) {
         if(_.include(dbot.db.bans[user], command) ||
            _.include(dbot.db.bans[user], dbot.commands[command].module) ||
            _.include(dbot.db.bans[user], '*')) {
             banned = true;
         }
     }
     return banned;
 },
Example #5
0
 this.api.getUserIgnores(user, function(err, ignores) {
     var isImpeded = false;
     if(!err && ignores) {
         if(_.has(dbot.commands, item) && !_.include(ignores[by], item)) {
             item = dbot.commands[item].module;
         }
         if(_.include(ignores[by], item)) {
             isImpeded = true;
         }
     }
     callback(isImpeded);
 });
Example #6
0
 _.each(this.events[event.action], function(listener) {
     var eventFunc = listener.listener;
     if(_.isFunction(eventFunc) && 
         (_.has(this.ignores, event.user) && _.include(this.ignores[event.user], listener.tag)) == false &&
         (_.has(this.ignores, event.channel) && _.include(this.ignores[event.channel], listener.tag)) == false) {
         try {
             eventFunc.call(this, event);
         } catch(err) {
             console.log('ERROR: ' + eventFunc + '\n' + err);
             console.log(err.stack.split('\n')[1].trim());
         }
     }
 }, this);
Example #7
0
 '~setmobilealias': function(event) {
     if(_.include(event.rUser.aliases, event.params[1])) {
         if(!_.has(event.rUser, 'mobile')) event.rUser.mobile = [];
         if(!_.include(event.rUser.mobile, event.params[1])) {
             event.rUser.mobile.push(event.params[1]);
             this.db.save('users', event.rUser.id, event.rUser, function(err) {
                 event.reply(dbot.t('added_mobile_alias', { 'alias': event.params[1] })); 
             });
         } else {
             event.reply(dbot.t('already_mobile', { 'alias': event.params[1] })); 
         }
     } else {
         event.reply(dbot.t('unknown_alias', { 'alias': event.params[1] }));
     }
 },
Example #8
0
File: api.js Project: reality/dbot
                        }, function() {
                            // Queue notifies for offline ops
                          if(this.config.offlineReporting == true) {
                            if(!_.include(this.config.noMissingChans, cName)) {
                                _.each(offlineOps, function(op) {
                                    if(!this.pending[op.id]) this.pending[op.id] = [];
                                    this.pending[op.id].push({
                                        'time': new Date().getTime(),
                                        'channel': cName,
                                        'user': user.id,
                                        'message': message
                                    });
                                    this.pNotify[op.id] = true;
                                }, this);
                            }
                          }

                            // Send notifies to online ops
                            ops = _.difference(ops, _.keys(offlineOps));
                            message = this.internalAPI.formatNotify(type, server,
                                        user, cName, message);
                            this.internalAPI.notify(server, ops, message);
                            if(_.has(this.config.chan_redirs, cName)) {
                                dbot.say(server, this.config.chan_redirs[cName], message);
                            }
                        }.bind(this));
Example #9
0
    $('tr').slice(8).each(function(index) {
        $this = $(this);
        var name = $this.find('td').eq(1).text().toLowerCase();
        /*if(name == '') {
          name = $this.find('td').eq(3).text().toLowerCase();
        }*/
        console.log('index: ' + index + ' name: ' + name);
        if(!_.include(chemicals, name)) return;
        if(name === 'nitrous oxide') name = 'nitrous';
        $this.find('td').slice(3).each(function(index) {
            $this = $(this);
            var attr = $this.attr('class');
            console.log('comparing ' + name + ' and ' + chemicals[index] + ' with attr ' + attr);

            if(attr === 's26' || attr === 's12') {
                results[name][chemicals[index]] = 'Low Risk & Synergy';
            } else if(attr === 's27') {
                results[name][chemicals[index]] = 'Caution';
            } else if(attr === 's39') {
                results[name][chemicals[index]] = 'Low Risk & No Synergy';
            } else if(attr === 's31') {
                results[name][chemicals[index]] = 'Serotonin Syndrome';
            } else if(attr === 's29') {
                results[name][chemicals[index]] = 'Unsafe';
            } else if(attr === 's30') {
                results[name][chemicals[index]] = 'Deadly';
            } else if(attr === 's28') {
                results[name][chemicals[index]] = 'Low Risk & Decrease';
            }
        });
    });  
Example #10
0
    req.db.read('ontologies', req.params.id, function(err, exOnt) { 
      if(exOnt && (_.include(exOnt.owners, req.user.username) || req.user.admin == true)) { 
        fs.readFile(req.files.ontology.path, function (err, data) {
          var newName = req.params.id + '_' + (_.size(exOnt.submissions) + 1) + '.ont',
              newPath = __dirname + '/../public/onts/' + newName;

          fs.writeFile(newPath, data, function (err) {
            var time = Date.now();
            exOnt.submissions[time] = newName;
            exOnt.lastSubDate = time;
            exOnt.status = 'untested';

            req.db.save('ontologies', req.params.id, exOnt, function(err) {
              request.get(req.aberowl + 'reloadOntology.groovy', {
                'qs': {
                  'name': req.params.id
                } // Later this will need API key
              }, function() {}); // we don't actually care about the response

              req.flash('info', 'Ontology updated successfully. Depending on the size of your ontology, you may want to grab a cup of tea while it\'s reasoning')
              res.redirect('/ontology/' + req.params.id + '/');
            });
          });
        });
      } else {
        req.flash('error', req.params.id + ' does not exist.');
        res.redirect('/ontology')
      }
    });
Example #11
0
 emitter.on('relation', function(rel) {
     if (_.include(relations, rel)) {
         relations = _.reject(relations, rel);
     } else {
         cb(JSON.stringify(rel) + ' is not in list');
     }
 });
Example #12
0
        'setconfig': function(event) {
            var configPathString = event.params[1],
                configKey = _.last(configPathString.split('.')),
                newOption = event.params[2];

            if(!_.include(noChangeConfig, configKey)) {
                var configPath = getCurrentConfig(configPathString);

                if(configPath == false || _.isUndefined(configPath.value)) {
                    event.reply(dbot.t("no_config_key"));
                    return;
                }
                var currentOption = configPath.value;

                // Convert to boolean type if config item boolean
                if(_.isBoolean(currentOption)) {
                    newOption = (newOption == "true");
                }

                if(_.isArray(currentOption)) {
                    event.reply(dbot.t("config_array",{"alternate": "pushconfig"}));
                }
                
                event.reply(configPathString + ": " + currentOption + " -> " + newOption);
                configPath['user'][configKey] = newOption;
                dbot.reloadModules();
            } else {
                event.reply(dbot.t("config_lock"));
            }
        },
Example #13
0
                    this.api.getUserIgnores(event.server, event.user, function(err, user, ignores) {
                        if(!err) {
                            if(!ignores) {
                                ignores = {
                                    'id': user.id,
                                    'ignores': [],
                                    'bans': []
                                };
                            }

                            if(!_.include(ignores.ignores, module)) {
                                ignores.ignores.push(module);
                                this.db.save('ignores', user.id, ignores, function(err) {
                                    if(!err) {
                                        dbot.instance.ignoreTag(event.user, module);
                                        event.reply(dbot.t('ignored', {
                                            'user': event.user, 
                                            'module': module
                                        }));
                                    }
                                });
                            } else {
                                event.reply(dbot.t('already_ignoring', { 'user': event.user }));
                            }
                        } else {
                            // User doesn't exist
                        }
                    }.bind(this));
Example #14
0
        '~alias': function(event) {
            var knownUsers = this.getServerUsers(event.server),
                alias = event.params[1].trim();

            if(_.include(knownUsers.users, alias)) {
                var aliases = this.api.getAliases(event.server, alias);
                var aliasCount = aliases.length;

                if(aliasCount != 0) {
                    var aliases = _.first(aliases, 10);
                    var including = 'including: ';
                    for(var i=0;i<aliases.length;i++) {
                        including += aliases[i] + ', ';
                    }
                    including = including.slice(0, -2) + '.';

                    event.reply(dbot.t('primary', { 
                        'user': alias, 
                        'count': aliasCount 
                    }) + including); 
                } else {
                    event.reply(dbot.t('primary', { 
                        'user': alias, 
                        'count': aliasCount 
                    })); 
                }
            } else if(_.has(knownUsers.aliases, alias)) {
                event.reply(dbot.t('alias', { 
                    'alias': alias, 
                    'user': knownUsers.aliases[alias] 
                }));
            } else {
                event.reply(dbot.t('unknown_alias', { 'alias': alias }));
            }
        },
 request(uri, function (error, response, body) {
   var parsedResponse;
   if (error || _.include([404], response.statusCode)) {
     callback({ 
       error : 'Unable to connect to the Echo Nest API endpoint.', 
       code : response.statusCode
     });
   } else {
     try {
       parsedResponse = JSON.parse(body);
     } catch (err) {
       callback({ error : 'Error parsing JSON answer from the Echo Nest API.', code : 'xxx'});
     }
     switch(parsedResponse.response.status.code) {
       case 0:
         callback(parsedResponse.response);
         break;
       case 1:
         callback({ error: 'Missing/Invalid API Key.', code: 'xxx' });
         break;
       case 2:
         callback({ error: 'This API key is not allowed to call this method', code: 'xxx'});
         break;
       case 4:
         callback({ error: parsedResponse.response.status.message, code: 'xxx'})
         break;
       case 5:
         console.log(parsedResponse.response);
         callback({ error: 'Invalid Parameter.', code: 'xxx' });
         break;
       default:
         callback({ error: 'Unrecognized error code', code: 'xxx'});
     }
   }
 });
Example #16
0
        '~rm': function(event) {
            if(this.rmAllowed == true || _.include(dbot.config.admins, event.user)) {
                var key = event.input[1].trim().toLowerCase();
                var quote = event.input[2];

                if(_.has(quotes, key)) {
                    var category = quotes[key];
                    var index = category.indexOf(quote);
                    if(index !== -1) {
                        category.splice(index, 1);
                        if(category.length === 0) {
                            delete quotes[key];
                        }
                        this.internalAPI.resetRemoveTimer(event, key, quote);

                        event.reply(dbot.t('removed_from', {'category': key, 'quote': quote}));
                    } else {
                        event.reply(dbot.t('q_not_exist_under', {'category': key, 'quote': quote}));
                    }
                } else {
                    event.reply(dbot.t('category_not_found', {'category': key}));
                }
            } else {
                event.reply(dbot.t('rmlast_spam'));
            }
        },
Example #17
0
        '~rmlast': function(event) {
            if(this.rmAllowed === true || _.include(dbot.config.admins, event.user)) {
                var key = event.input[1].trim().toLowerCase(),
                    category = false,
                    removedQuote;
                var quoteRemoved = function(err) {
                    this.internalAPI.resetRemoveTimer(event, key, removedQuote);
                    event.reply(dbot.t('removed_from', {
                        'quote': removedQuote, 
                        'category': key
                    }));
                }.bind(this);

                this.db.search('quote_category', { 'name': key }, function(result) {
                    category = result;    
                }, function(err) {
                    if(category) {
                        removedQuote = category.quotes.pop();
                        if(category.quotes.length == 0) {
                            this.db.del('quote_category', category.id, quoteRemoved);
                        } else {
                            this.db.save('quote_category', category.id, category, quoteRemoved);
                        }
                    } else {
                        event.reply(dbot.t('category_not_found', { 'category': key }));
                    }
                }.bind(this));
            } else {
                event.reply(dbot.t('rmlast_spam'));
            }
        },
    'test_xapi_request_child': function(test,totest_xapi_request){
        if(typeof totest_xapi_request.child !== 'undefined'){
            test.deepEqual(typeof totest_xapi_request.child.has,
			   'boolean',
			   "The function of the child predicate is not a boolean");
            test.ok(_.include (["node","way","relation","tag"],
			       totest_xapi_request.child.attribute),
		    "Invalid format of the xapi request child predicate");
            if(totest_xapi_request.object == 'node'){
                test.ok(totest_xapi_request.child.attribute !== 'node',
			"Child predicate of node cannot be a node");
            }

            if(totest_xapi_request.object == 'way'){
                test.ok(totest_xapi_request.child.attribute !== 'way',
			"Child predicate of way cannot be a way");
            }

            if(totest_xapi_request.child.attribute == 'tag'){
                test.deepEqual(totest_xapi_request.tag,
			       'undefined',
			       "Tag child predicate and tag predicate cannot exist simultaneously");
            }
        }
    },
Example #19
0
                }, function(err) {
                    if(!channel) {
                        var id = uuid.v4();
                        channel = {
                            'id': id,
                            'server': event.server,
                            'name': channelName,
                            'ignores': []
                        };
                    }

                    if(!_.include(channel.ignores, module)) {
                        channel.ignores.push(module);
                        this.db.save('channel_ignores', channel.id, channel, function(err) {
                            dbot.instance.ignoreTag(channel.name, module);
                            event.reply(dbot.t('ignoring_channel', {
                                'module': module,
                                'channel': channelName
                            }));
                        }); 
                    } else {
                        event.reply(dbot.t('already_ignoring_channel', {
                            'module': module,
                            'channel': channelName
                        }));
                    }
                }.bind(this));
Example #20
0
 this.api.getUserIgnores(event.rUser, function(err, ignores) {
     if(err || !ignores || _.isUndefined(module)) {
         if(ignores) {
             event.reply(dbot.t('unignore_usage', {
                 'user': event.user, 
                 'modules': ignores.ignores.join(', ')
             }));
         } else {
             event.reply(dbot.t('empty_unignore_usage', {
                 'user': event.user
             }));
         }
     } else {
         if(_.include(ignores.ignores, module)) {
             ignores.ignores = _.without(ignores.ignores, module);
             this.db.save('ignores', event.rUser.id, ignores, function(err) {
                 if(!err) {
                     dbot.instance.removeIgnore(event.user, module)
                     event.reply(dbot.t('unignored', {
                         'user': event.user, 
                         'module': module
                     }));
                 }
             });
         } else {
             event.reply(dbot.t('invalid_unignore', { 'user': event.user }));
         }
     }
 }.bind(this));
Example #21
0
                    this.api.getUserIgnores(user, function(err, ignores) {
                        if(!err) {
                            if(!ignores) {
                                ignores = {
                                    'id': user.id,
                                    'ignores': [],
                                    'bans': [] 
                                };
                            }

                            if(!_.include(ignores.bans, item)) {
                                ignores.bans.push(item);
                                this.db.save('ignores', user.id, ignores, function(err) {
                                    if(!err) {
                                        event.reply(dbot.t('banned_success', {
                                            'user': event.user, 
                                            'banned': nick,
                                            'module': item 
                                        }));
                                    }
                                });
                            } else {
                                event.reply(dbot.t('already_banned', {
                                    'user': event.user,
                                    'banned': nick
                                }));
                            }
                        }
                    }.bind(this));
Example #22
0
 _.each(tokens, function(token2) {
     if (token2 != token && token2.indexOf(' ') != -1 && !_.include(containedTokens, token2)) {
         if (token.indexOf(token2) != -1) {
             containedTokens.push(token2);
         }
     }
 });
Example #23
0
        'setconfig': function(event) {
            var configPathString = event.params[1],
                configKey = _.last(configPathString.split('.')),
                newOption = event.params[2];

            if(!_.include(noChangeConfig, configKey)) {
                var configPath = getCurrentConfig(configPathString);

                if(configPath == false || _.isUndefined(configPath.value)) {
                    event.reply("Config key doesn't exist bro");
                    return;
                }
                var currentOption = configPath.value;

                // Convert to boolean type if config item boolean
                if(_.isBoolean(currentOption)) {
                    newOption = (newOption == "true");
                }

                if(_.isArray(currentOption)) {
                    event.reply("Config option is an array. Try 'pushconfig'.");
                }
                
                event.reply(configPathString + ": " + currentOption + " -> " + newOption);
                configPath['user'][configKey] = newOption;
                dbot.reloadModules();
            } else {
                event.reply("This config option cannot be altered while the bot is running.");
            }
        },
Example #24
0
                            _.each(nunsubs.users, function(user) {
                                var uPart = user.split('.')[0];
                                if(_.include(ops, uPart)) {
console.log('removing ' + uPart);
                                    ops = _.without(ops, uPart);
                                }
                            });
Example #25
0
 _.reduce(initial, function(memo, el, i) {
   if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
     memo[memo.length] = el;
     result[result.length] = array[i];
   }
   return memo;
 }, []);
    'testrelation': function(test,toTestRelation){
        //necessary attributes
        test.deepEqual(typeof toTestRelation.id, "number", "Relation id is not a number!");
        test.ok(toTestRelation.id >= 1, "Test relation id is negative");
        test.strictEqual(toTestRelation.id, Math.round(toTestRelation.id),"Relation.id not an integer");

        test.notDeepEqual(typeof toTestRelation.members, "undefined", "Relation has no members!");
        test.notDeepEqual(typeof toTestRelation.members[0], "undefined", "Relation has no members!");
        for (var i=0; i<toTestRelation.members.length; i++){
            test.ok(_.include(["node","way","relation"],toTestRelation.members[i].type), "Relation type is neither node, nor way, nor relation!");
           //test.deepEqual(toTestRelation.members[i].type, "node" || "way" || "relation");
            test.deepEqual(typeof toTestRelation.members[i].reference, "number", "Relation member reference is not a number!");
            test.ok(toTestRelation.members[i].reference >=1, "Reference of a relation member is negative");
            test.strictEqual(toTestRelation.members[i].reference, Math.round(toTestRelation.members[i].reference),"Relation member reference not an integer");

            test.deepEqual(typeof toTestRelation.members[i].role, "string", "Relation member role is not a string!");
            //test.notDeepEqual(toTestRelation.members[i].role, "", "Relation member role is empty!");
        }

        //optional attributes
        if(typeof toTestRelation.version != "undefined"){
            test.deepEqual(typeof toTestRelation.version, "number", "Relation version is not a number!");
            test.ok(toTestRelation.version >= 1, "Test relation version is negative");
            test.strictEqual(toTestRelation.version, Math.round(toTestRelation.version),"Relation.version not an integer");
        }

        if(typeof toTestRelation.uid != "undefined"){
            test.deepEqual(typeof toTestRelation.uid, "number", "Relation uid is not a number!");
            test.ok(toTestRelation.uid >= 1, "Test relation uid is negative");
            test.strictEqual(toTestRelation.uid, Math.round(toTestRelation.uid),"Relation.uid not an integer");
        }

        if(typeof toTestRelation.user != "undefined"){
            test.deepEqual(typeof toTestRelation.user, "string", "Relation user is not a string!");
            test.notDeepEqual(toTestRelation.user, "", "Relation user is empty");
        }

        if(typeof toTestRelation.changeset != "undefined"){
            test.deepEqual(typeof toTestRelation.changeset, "number", "Relation changeset is not a number!");
            test.ok(toTestRelation.changeset >= 1, "Test relation changeset is negative");
            test.strictEqual(toTestRelation.changeset, Math.round(toTestRelation.changeset),"Relation.changeset not an integer");
        }

        if(typeof toTestRelation.timestamp != "undefined"){
            test.notDeepEqual(toTestRelation.timestamp.getDate(), "undefined", "Relation timestamp is not a Date!");
        }

        if(typeof toTestRelation.tags != "undefined"){
            if(typeof toTestRelation.tags[0] != "undefined"){
                for (var x=0; x<toTestRelation.tags.length; x++){
                test.deepEqual(typeof toTestRelation.tags[x].key, "string", "Relation tags key is not a string!");
                test.deepEqual(typeof toTestRelation.tags[x].value, "string", "Relation tags value is not a string!");
                test.notDeepEqual(toTestRelation.tags[x].key, "", "Relation tags key is empty!");
                test.notDeepEqual(toTestRelation.tags[x].value, "", "Relation tags value is empty!");
                }
            }
        }
    //test.finish();
    }
Example #27
0
 _.each(moduleNames, function(moduleName) {
     var modulePath = '/' + moduleName;
     if(_.include(routes, modulePath)) {
         moduleName = moduleName.charAt(0).toUpperCase() +
             moduleName.slice(1);
         this.indexLinks[modulePath] = moduleName;
     }
 }.bind(this));
Example #28
0
    this.listener = function(event) {
        if(!_.isNull(this.game) && this.game.channel === event.channel.name) {
            if(_.include(this.game.solutions, event.message) && !_.include(this.game.found, event.message)) {
                if(!_.has(this.game.scores, event.user)) this.game.scores[event.user] = 0;
                this.game.scores[event.user]++;
                this.game.found.push(event.message);
                event.reply(event.user + ': ' + event.message.toUpperCase() + ' IS CORRECT. ' + 
                    this.game.found.length + '/' + this.game.solutions.length + ' WORDS FOUND');

                if(this.game.found.length === this.game.solutions.length) {
                    var winner = _.invert(this.game.scores)[_.max(this.game.scores)];
                    event.reply('ALL WORDS FOUND. THE WINNER IS ' + winner.toUpperCase() + ' WITH ' + this.game.scores[winner]);
                    this.game = null;
                }
            }
        }
    }.bind(this);
Example #29
0
        'hasAccess': function(user, command) {
            var access = true;
            var accessNeeded = dbot.commands[command].access;

            if(accessNeeded == 'admin') {
                if(!_.include(dbot.config.admins, user)) {
                    access = false;
                }
            } else if(accessNeeded == 'moderator') {
                if(!_.include(dbot.config.moderators, user) && 
                        !_.include(dbot.config.admins, user)) {
                    access = false;
                }
            }

            return access;
        },
Example #30
0
            feedparser.on('readable', function() {
                // This is where the action is!
                var stream = this, 
                    meta = this.meta, // **NOTE** the "meta" is always available in the context of the feedparser instance
                    item;

                while (item = stream.read()) {
                    // If the feed does not give a pubdate for this post, ignore it...
                    if(!item.pubdate) {
                        return;
                    }
                    if(dbot.config.debugMode) {
                        dbot.say(feed.server,feed.channel,"RSS: Should post question: Is "+(item.pubdate.getTime()-feed.lastPosted)+" > 0?");
                    }
                    if(item.pubdate.getTime() - feed.lastPosted > 0) {
                        if(item.pubdate.getTime() > feed.newTime) {
                            feed.newTime = item.pubdate.getTime();
                        }
                        var rss = item;
                        if(dbot.config.debugMode) {
                            dbot.say(feed.server,feed.channel,"RSS: I shall post a new link! PERFECT.");
                        }
                        if(!_.include(self.titleCache, rss.title)) {
                            var options = {
                                uri: 'https://www.googleapis.com/urlshortener/v1/url',
                                method: 'POST',
                                json: {
                                    "longUrl": rss.link
                                }
                            };

                            request(options, function (error, response, body) {
                                if (!error && response.statusCode === 200) {
                                    var rString = "["+feed.name+"] ["+rss.title+"] "; 
                                    if(rss.author !== null && !_.isUndefined(rss.categories[0])) {
                                        rString += "[Post by "+rss.author+" in "+rss.categories[0]+"] ";
                                    }
                                    rString += "- "+body.id;
                                    dbot.say(feed.server,feed.channel, rString);
                                } else {
                                    var rString = "["+feed.name+"] ["+rss.title+"] "; 
                                    if(rss.author !== null && !_.isUndefined(rss.categories[0])) {
                                        rString += "[Post by "+rss.author+" in "+rss.categories[0]+"] ";
                                    }
                                    rString += "- "+rss.link;
                                    dbot.say(feed.server,feed.channel, rString);
                                    console.log("RSS: Url shortener request returned error statuscode "+response.statusCode+": "+body.error.message);
                                }
                            });

                            if(self.titleCache.length > 30) {
                                self.titleCache.splice(0, 1); 
                            }
                            self.titleCache.push(rss.title);
                        }
                    }
                }
            });