{"id":22010166,"url":"https://github.com/beldar/alfred","last_synced_at":"2025-05-06T18:49:51.466Z","repository":{"id":44505838,"uuid":"59905290","full_name":"beldar/alfred","owner":"beldar","description":"Just a Slack butler","archived":false,"fork":false,"pushed_at":"2022-12-03T08:59:15.000Z","size":435,"stargazers_count":9,"open_issues_count":7,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-31T01:51:17.289Z","etag":null,"topics":["alfred","bot","botkit","botkit-bots","butler","helper","slack","slack-bot"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beldar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-28T16:57:48.000Z","updated_at":"2023-12-05T13:53:46.000Z","dependencies_parsed_at":"2023-01-22T15:25:14.554Z","dependency_job_id":null,"html_url":"https://github.com/beldar/alfred","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beldar%2Falfred","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beldar%2Falfred/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beldar%2Falfred/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beldar%2Falfred/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beldar","download_url":"https://codeload.github.com/beldar/alfred/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252750183,"owners_count":21798663,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alfred","bot","botkit","botkit-bots","butler","helper","slack","slack-bot"],"created_at":"2024-11-30T02:12:10.451Z","updated_at":"2025-05-06T18:49:51.424Z","avatar_url":"https://github.com/beldar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Alfred Slack Bot\n\nYour personal butler created using [BotKit](https://github.com/howdyai/botkit)\n\n## Installation\n\nTo install all dependencies just run\n\n    npm install\n\nYou also need a [mongo database running](https://docs.mongodb.com/manual/installation/)\n\nTo run Alfred you need some environment variables:\n\n- `FORECAST_API_KEY` for the weather service, get one [from here](https://developer.forecast.io/)\n- `GM_API_KEY` for the geocoding service used by time or weather, get one [from here](console.developers.google.com)\n- `WOLFRAM_APPID` for the wolfram integration, get one [from here](http://products.wolframalpha.com/api/)\n- `SLACK_TOKEN` to be able to receive and send messages from slack\n\nTo set up Alfred on your Slack team you need to add the `Bots` integration, you can search on it or go to `http://\u003cyour slack domain\u003e/apps/new/A0F7YS25R-bots`. You will be able to set your bot's name, handle and you will get the `SLACK_TOKEN`.\n\n## Run\n\nTo run Alfred just do\n\n    npm start\n\n## Current commands\n\n• Say `hi` or `hello` to receive a greating\n\n• Say `my name is {name}` or `call me {name}` if you want me to remember your name\n\n• Say `help` to get these options\n\n• Say `subscribe to my PRs` to get messages about the updates on your PRs\n\n• Say `unsubscribe from PRs` to stop receiving the updates on your PRs\n\n• Say `weather {location}` to get a forecast\n\n• Say `greet` or `greetings` to make me greet everyone\n\n• Say `time {location}` to get a local time\n\n• Say `stackoverflow {language/tag} {query}` to get the first result on stackoverflow for that query\n\n• Say `random pick set {comma separated list}` to set up the list for a random pick, this could be people's names or any other list of things\n\n• Say `random pick get` to get a random pick from a list set before hand\n\n• Say `rota pick set {comma separated list}` to set up the list for a rota pick, this could be people's names or any other list of things\n\n• Say `rota pick get` to get a rota pick from a list set before hand\n\nAll non matched commands will be resolved using the [`wolfram`](lib/commands/wolfram.js) command.\n\n## Collaborate\n\nAdding new features to Alfred is really easy and can be done in two steps:\n\nThe first step is to add your feature on `lib/commands/index.js` like this:\n\n    {\n      patterns: ['call me (.*)', 'my name is (.*)'],\n      scope   : normalScope,\n      handler : 'name',\n      help    : 'Say `my name is {name}` or `call me {name}` if you want me to remember your name'\n    }\n\n- `patterns` is an array with all things you want Alfred to be listening to as a trigger, these really are regular expressions so you can take advantage to matching patterns, in this example we want to match whatever comes after `call me` or `my name is`.\n\n- `scope` are the events when Alfred should be listening, the `normalScope` is `direct_message,direct_mention,mention` which should work for most cases.\n\n- `handler` is the name of the file of your handler and it should be placed inside the `lib/commands` folder, on this example the file is `lib/commands/name.js`.\n\n- `help` is the explanation for your feature that will appear when someone asks for `help`.\n\n\n\nThe second step is to create the `handle` function, lets look at the example:\n\n    const { controller } = require('../controller');\n    const utils          = require('../utils');\n\n    module.exports = (bot, message) =\u003e {\n      let name = message.match[1];\n\n      controller.storage.users.get(message.user, function(err, user) {\n        if (err) return utils.handleStorageError(err, bot, message);\n\n        if (!user) {\n          user = {\n            userId: message.user\n          };\n        }\n        user.name = name;\n        controller.storage.users.save(user, function(err, id) {\n          if (err) return utils.handleStorageError(err, bot, message);\n\n          utils.addReaction(bot, message, '+1');\n          bot.reply(message, 'Understood. I will call you ' + user.name + ' from now on.');\n        });\n      });\n    };\n\nLike you see our handler receives two arguments `bot` and `message`.\n\nThe `bot` variable will allow us to reply to the message.\n\nThe `message` is an object that contains several things like:\n\n- All the matched strings from our regexp\n- The text of the message\n- The user id who triggered the message\n- The channel\n- etc\n\nIf we need to access the storage to save or retrieve information about the current user we need to import the controller (as seen on the first line).\n\nAnd also import the utils module to handle possible storage errors for us and add a reaction to the message.\n\nYou can also do more complex things like a [multi-message conversation](https://github.com/howdyai/botkit#botstartprivateconversation) check an example on the [subscribePR file](lib/commands/subscribePR.js).\n\nOnce you've created your feature, submit a PR!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeldar%2Falfred","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeldar%2Falfred","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeldar%2Falfred/lists"}