Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2317503
verifies authorization
calopter Sep 10, 2019
c8ead4c
Create Recipient class and add test file
tofuandeve Sep 10, 2019
7c7af5e
Create User class and add test file
tofuandeve Sep 10, 2019
084aab1
Create Channel class and add test file
tofuandeve Sep 10, 2019
554c02c
establish Workspace class and tests
calopter Sep 10, 2019
9481b4a
implemented .get
calopter Sep 10, 2019
b1b9a01
implemented User.list
calopter Sep 10, 2019
3cc9287
Update Recipient class: .get raises error for bad responses
tofuandeve Sep 10, 2019
1d7e403
Implement .list for Channel class and update tests
tofuandeve Sep 10, 2019
c696212
Implement details method for User class and update test file
tofuandeve Sep 10, 2019
62ee8b7
Implement details method for Channel class and update test file
tofuandeve Sep 10, 2019
f84c63a
implements show_details
calopter Sep 10, 2019
542eaf6
implements wave 1 cli
calopter Sep 10, 2019
a93dbfa
refactors show_details to generalize
calopter Sep 11, 2019
c98a559
Implement find_recipient method for Workspace class
tofuandeve Sep 11, 2019
d37591c
implements select_user and select_channel
calopter Sep 11, 2019
3abe4b6
Update slack.rb to have more options
tofuandeve Sep 11, 2019
e0424d3
implements Recipient#send_message
calopter Sep 12, 2019
d831af9
Implement send_message for Workspace class
tofuandeve Sep 12, 2019
3b17b52
implements send message behavior in main
calopter Sep 12, 2019
f241e43
Remove send_message tests for Workspace since send_message is interna…
tofuandeve Sep 13, 2019
9acc681
Clean up code and improve UI
tofuandeve Sep 13, 2019
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
32 changes: 32 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require_relative 'recipient'
require 'dotenv'

class Channel < Recipient
attr_reader :topic, :member_count

def initialize(slack_id:, name:, topic:, member_count:)
super(slack_id: slack_id, name: name)
@topic = topic
@member_count = member_count
end

def self.list
Dotenv.load
params = { token: ENV['SLACK_API_KEY'] }

response = self.get('https://slack.com/api/channels.list', params)

response['channels'].map do |channel|
channel_info = { slack_id: channel['id'],
name: channel['name'],
topic: channel['topic']['value'],
member_count: channel['num_members']
}
self.new(channel_info)
end
end

def details
return "Channel's name: #{name}, Topic: #{topic}, Slack id: #{slack_id}, Member count: #{member_count}"
end
end
50 changes: 50 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'httparty'
require 'dotenv'

class Recipient
attr_reader :slack_id, :name

class SlackApiError < Exception; end

def initialize(slack_id:, name:)
raise ArgumentError unless (slack_id && name)

Choose a reason for hiding this comment

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

This is redundant, keyword arguments without defaults are required.

@slack_id = slack_id
@name = name
end

def self.list
raise NotImplementedError, "template method"

Choose a reason for hiding this comment

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

Template method! 🎉

end

def self.get(url, params)
response = HTTParty.get(url, query: params)
raise SlackApiError unless response['ok']

Choose a reason for hiding this comment

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

It would be helpful to include the error in the message and also check the response code.

Suggested change
raise SlackApiError unless response['ok']
raise SlackApiError.new(response["error"]) unless response['ok'] && response.code == 200


return response.parsed_response
end

def send_message(message)
Dotenv.load

body = {
token: ENV["SLACK_API_KEY"],
text: message,
channel: slack_id,
}

headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
url = "https://slack.com/api/chat.postMessage"

response = HTTParty.post(url, body: body, headers: headers)

unless response.code == 200 && response["ok"]
raise SlackApiError
end

return true

Choose a reason for hiding this comment

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

Returning true is redundant here, since you know this succeeded if it returns.

end

def details
raise NotImplementedError, "template method"
end
end
91 changes: 83 additions & 8 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,86 @@
#!/usr/bin/env ruby

def main
puts "Welcome to the Ada Slack CLI!"
require_relative 'workspace'

# TODO project

puts "Thank you for using the Ada Slack CLI"
end

main if __FILE__ == $PROGRAM_NAME
COMMANDS = ['list users', 'list channels', 'select user', 'select channel',
'details', 'send message', 'quit']

SEARCH_KEYS = ['name', 'id']

def show_commands
puts "Available commands:"
puts COMMANDS
puts
end

def get_command
input = gets.chomp.downcase
until COMMANDS.include? input
puts "Please enter a valid command"
show_commands
input = gets.chomp.downcase
end
return input
end

def prompt_recipient
puts "What do you like to search for: name or id:"

key = gets.chomp.downcase
until SEARCH_KEYS.include? key
puts "Invalid command \nWhat do you like to search for: name or id:"
key = gets.chomp.downcase
end

puts "Please enter #{key}:"
input = gets.chomp

key == 'name' ? {name: input} : {slack_id: input}
end

def main
puts "Welcome to the Ada Slack CLI!\n"

workspace = Workspace.new
workspace.show_details
while true
show_commands
command = get_command

case command
when 'quit'
break

when 'list users'
workspace.show_details :users

when 'list channels'
workspace.show_details :channels

when 'select channel'
channel_info = prompt_recipient
workspace.select_channel(channel_info)
workspace.selected ? workspace.show_selected : puts("Channel not found\n\n")

when 'select user'
user_info = prompt_recipient
workspace.select_user(user_info)
workspace.selected ? workspace.show_selected : puts("User not found\n\n")

when 'details'
workspace.show_selected

when 'send message'
begin
workspace.send_message
rescue Recipient::SlackApiError
puts "Unable to send message\n\n"

Choose a reason for hiding this comment

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

If you'd include a message you could print a more descriptive error here.

        rescue Recipient::SlackApiError => api_error
          puts "Unable to send message #{api_error.message}\n\n"

end
end
end

puts "Thank you for using the Ada Slack CLI"
end

main if __FILE__ == $PROGRAM_NAME

31 changes: 31 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'dotenv'
require_relative 'recipient'

class User < Recipient
attr_reader :real_name, :status_text

def initialize(slack_id:, name:, real_name:, status_text:)
super(slack_id: slack_id, name: name)
@real_name = real_name
@status_text = status_text
end

def self.list
Dotenv.load
params = { token: ENV['SLACK_API_KEY'] }

response = self.get('https://slack.com/api/users.list', params)

response['members'].map do |user|
user_info = { slack_id: user['id'], name: user['name'],
real_name: user['profile']['real_name'],
status_text: user['profile']['status_text'],
}
self.new(user_info)
end
end

def details
return "Username: #{name}, Real name: #{real_name}, Slack id: #{slack_id}"
end
end
56 changes: 56 additions & 0 deletions lib/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require_relative 'channel'
require_relative 'user'

class Workspace
attr_reader :channels, :users, :selected

def initialize
@channels = Channel.list
@users = User.list
@selected = nil
end

def show_details *recipients
recipients = [:channels, :users] if recipients.empty?

recipients.each do |recipient|
puts recipient.capitalize
puts self.send(recipient).map(&:details).join("\n")
puts
end
end

def select_user name: nil, slack_id: nil
@selected = find_recipient list: users, name: name, slack_id: slack_id
end

def select_channel name: nil, slack_id: nil
@selected = find_recipient list: channels, name: name, slack_id: slack_id
end

def find_recipient(list:, name: nil, slack_id: nil)
raise ArgumentError unless name || slack_id

return list.find do |recipient|
name ? recipient.name == name : recipient.slack_id == slack_id
end
end

def send_message
if selected
puts "Please enter message to send to #{selected.name}: "

Choose a reason for hiding this comment

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

Printing belongs in your driver code (slack.rb). Including it here makes this difficult to unit-test.

message = gets.chomp
raise Recipient::SlackApiError if message.empty?

selected.send_message(message)
else
puts "No recipient selected\n\n"
return false
end
end

def show_selected
puts selected ? selected.details : "No recipient was selected"
puts
end
end
Loading