Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements #9

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ build-iPhoneSimulator/
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc

birthdays.txt
birthdays.y*ml
birthdays.json
configurations.json

.DS_Store
3 changes: 0 additions & 3 deletions Gemfile

This file was deleted.

17 changes: 0 additions & 17 deletions Gemfile.lock

This file was deleted.

60 changes: 41 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,59 @@
The purpose of this bot is to send a message to your team's Slack when is someones birthday.


## Setup & Deploy
## Setup

1. Clone this repo to a desired location on your own computer
2. Configure an [Incoming Webhook URL](https://api.slack.com/incoming-webhooks) from Slack
3. Choose your desired database structure file ( `<ext>` : YAML / JSON ).
( YAML is easier to configure as you have to bother about the indentation with spaces alone. You'll have to bother a lot more with JSON - Parentheses, commas. But in the end it's what you're more comfortable with that matters. )
1. Make a copy of the `birthdays.<ext>.example` file naming it to `birthdays.<ext>`.
2. Populate your birthdays database with the birthdays of your team members.
* NB : You can either use their real names or their usernames. Just remember to configure the mention configuration correctly.
4. Make a copy of the `configurations.json.example` file naming it `configurations.json`. Update the configuration values according to your preferences
```
{
"birthdays_path" : "birthdays.<ext>", # according to your preference
# birthdays.yaml for YAML and birthdays.json for JSON
"mention" : <true | false>, # depends on your database configuration format
# if you're using real names, set this value to false
# if you're using usernames, set this value to true
"slack_url" : "https://hooks.slack.com/...", # the webhook URL you configured in step 2.
"channel_name" : "<channel_name>", # the channel you want your wishes to be sent to
"greeting_message" : "Happy birthday!" # the wish you would like the bot to send
"bot_name" : "Birthday Bot" # the name of the bot sending the wish
"bot_emoji" : ":tada:" # the emoji the bot should use as it's icon
}
```

## Deploy

### Heroku

1. Clone this repo to a desire location at your own computer
2. Get your [Incoming Webhook URL](https://api.slack.com/incoming-webhooks) from Slack
3. Save the url at `configurations.json` file and fill in the rest of the configurations as you like
4. Set your birthdays list using the format `FirstName LastName YY MM DD` at the `birthdays.txt` file
5. Create a blank app at Heroku
6. Push your code to Heroku
7. The bot was developed with the **2.2.6** version of ruby, any other versions may require changes.
7. Run `heroku addons:create scheduler:standard` to add the Scheduler add-on to your deploy
8. Run `heroku addons:open scheduler` to configure the scheduler
9. Click **Add a new job** and type `rake congratulate` as the command
10. Set frequency to **Daily** and choose the **Time** you want to be notified
1. Create a blank app at Heroku
2. Push your code to Heroku
3. The bot was developed with the **2.2.6** version of ruby, any other versions may require changes.
4. Run `heroku addons:create scheduler:standard` to add the Scheduler add-on to your deploy
5. Run `heroku addons:open scheduler` to configure the scheduler
6. Click **Add a new job** and type `rake congratulate` as the command
7. Set frequency to **Daily** and choose the **Time** you want to be notified

### Custom Server

1. Clone this repo to a desire location at your own server
2. Get your [Incoming Webhook URL](https://api.slack.com/incoming-webhooks) from Slack
3. Save the url at `configurations.json` file and fill in the rest of the configurations as you like
4. Set your birthdays list using the format `FirstName LastName YY MM DD` at the `birthdays.txt` file
5. Run `crontab -e` to edit your crontab
6. Add this line to the crontab and save it: `0 9 * * * cd /clone/location && /usr/local/bin/rake congratulate` (replace `/clone/location` by the location where you cloned the repo)
1. Run `crontab -e` to edit your crontab
2. Add this line to the crontab and save it:
`@daily cd /clone/location && /usr/local/bin/rake congratulate`
* replace `/clone/location` with the location where you cloned the repo)
* the `@daily` `cron` shorthand might vary among servers and/or distributions.
Replace `@daily` with a time of your preference according to the [`cron` syntax](http://tldp.org/LDP/lame/LAME/linux-admin-made-easy/using-cron.html).
* Remember to verify the timezone setting of your server or you won't get the expected result.


## Contributors

This project was originally created by [Tiago Botelho](https://github.com/tiagonbotelho), while he was an intern at [jeKnowledge](http://jeknowledge.pt/).

It was later revised by [Diogo Nunes](http://www.diogonunes.com/) from [EqualExperts](https://www.equalexperts.com/) and [João Bernardo](http://jbernardo.me) from [jeKnowledge](http://jeknowledge.pt/).
It was later revised by [Diogo Nunes](http://www.diogonunes.com/) from [EqualExperts](https://www.equalexperts.com/), [João Bernardo](http://jbernardo.me) from [jeKnowledge](http://jeknowledge.pt/) and then refactored again by [Shine Nelson](https://www.shinenelson.com).

## License

Expand Down
1 change: 0 additions & 1 deletion birthdays.example.txt

This file was deleted.

17 changes: 17 additions & 0 deletions birthdays.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"01" :
{
"01" : [ "elvina.slovak" ]
},

"02" :
{
"02" : [ "john.doe", "jane.doe" ],
"28" : [ "chris.nolan" ],
},

"04" :
{
"15" : [ "erwin.down", "leora.pontious", "randy.young" ]
}
}
9 changes: 9 additions & 0 deletions birthdays.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"01" :
"01" : [ "elvina.slovak" ]

"02" :
"02" : [ "john.doe", "jane.doe" ]
"28" : [ "chris.nolan" ]

"04" :
"15" : [ "erwin.down", "leora.pontious", "randy.young" ]
2 changes: 2 additions & 0 deletions configurations.json → configurations.json.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"birthdays_path": "birthdays.yaml",
"mention": true,
"slack_url": "https://hooks.slack.com/...",
"channel_name": "general",
"greeting_message": "Happy birthday !",
Expand Down
53 changes: 42 additions & 11 deletions lib/birthday_bot.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,59 @@
require 'httparty'
require 'net/http'
require 'config_reader'
require 'birthday_reader'

class BirthdayBot
@@path = "birthdays.txt"

def initialize()
@config = ConfigReader.new
@config.load('configurations.json')
end

def start!
birthdays = BirthdayReader.get_birthdays(@@path)
today = Time.now
birthdays = BirthdayReader.get_birthdays(@config.birthdays_path)

today = Time.now
puts "Checking who was born today (#{today.to_s})"
birthdays.each do |b|
if (b[3].to_i == today.month) && (b[4].to_i == today.day)
message = "#{@config.greeting_message} #{b[0]} #{b[1]}"
HTTParty.post(@config.slack_url, body: { channel: @config.channel_name,
username: @config.bot_name,
text: message,
icon_emoji: @config.bot_emoji }.to_json)
unless birthdays.nil? || birthdays.empty?
birthdays_today = birthdays[today.month.to_s][today.day.to_s]
users = build_user_list ( birthdays_today )
message = "#{users} #{@config.greeting_message}"
payload = { channel: @config.channel_name,
username: @config.bot_name,
text: message,
icon_emoji: @config.bot_emoji }.to_json

uri = URI.parse(@config.slack_url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.path)
request.body = payload
http.request(request)
else
puts "Today is a day that no one was born"
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you looked at my previous comment with a suggestion to refactor this function ?

puts "#{birthdays.count} were born today"

today = Time.now
birthdays_today = birthdays[today.month][today.day]

unless birthdays_today.empty?
  users = build_user_list(birthdays_today)
  message = "#{users} #{@config.greeting_message}"
  HTTParty.post(@config.slack_url, body: { channel: @config.channel_name,
    username: @config.bot_name,
    text: message,
    icon_emoji: @config.bot_emoji }.to_json)
end
 
# ...

def build_user_list(birthdays)
  if birthdays.size == 1
    birthdays.first
  else
    users = birthdays.take(birthdays.count - 1).join(", ")
    users += " and #{birthdays[birthdays.count - 1]}" if birthdays.count > 1
  end
end

end

def build_user_list ( birthdays )
if birthdays.count == 1
mention birthdays.first
else
users = ""
puts "#{ birthdays.count } people were born today"
birthdays.take(birthdays.count - 2).each do | birthday |
users += mention(birthday) + ', '
end
users += "#{ mention birthdays[birthdays.count - 2] } and #{ mention birthdays[birthdays.count - 1] }" if birthdays.count > 1
end
end

def mention ( name )
if @config.mention
"<@#{ name }>"
else
name
end
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give an example where disabling mentions is useful ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The earlier version of the database stored the real names of users. The bot wished users with their real names. So, I thought that could be a valid use-case

But like my commit message said, some people might prefer wishing their team-mates by their real names (probably for more family-togetherness) and/or not choosing to spam the users with mentions on the wishes (but that wil probably be taken care of by other team-mates, anyway).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks !


end
10 changes: 3 additions & 7 deletions lib/birthday_reader.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
require 'yaml'

class BirthdayReader
def self.get_birthdays(file_path)
birthdays = []
if File.exist?(file_path)
file = File.new(file_path, 'r')
file.each_line do |line|
birthdays << line.chomp.split
end
file.close
return YAML.load_file(file_path)
end
return birthdays
end
end
6 changes: 5 additions & 1 deletion lib/config_reader.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
require 'json'

class ConfigReader
attr_accessor :slack_url,
attr_accessor :birthdays_path,
:mention,
:slack_url,
:channel_name,
:greeting_message,
:bot_name,
Expand All @@ -11,6 +13,8 @@ def load(filename)
if File.exist?(filename)
file = File.read(filename)
config = JSON.parse(file)
@birthdays_path = config['birthdays_path']
@mention = config['mention']
@slack_url = config['slack_url']
@channel_name = config['channel_name']
@greeting_message = config['greeting_message']
Expand Down