Skip to content
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
26 changes: 26 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require_relative "recipient"

class Channel < Recipient
attr_reader :id, :name, :details, :topic, :member_count

def initialize(id, name, details = "", topic = "", member_count = "")
super(id, name)
@details = details
@topic = topic
@member_count = member_count
end

def self.load_all(url, token)
recipients = HTTParty.get(url, query: { token: token })
Copy link

Choose a reason for hiding this comment

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

What happens if this get request gives back an error response? What would happen when we did recipients["channels"] in the next line?

all_recipients = recipients["channels"].map do |recipient|
recipient = new(recipient["id"], recipient["name"], recipient["info"], topic = recipient["topic"]["value"], member_count = recipient["num_members"])
end
return all_recipients
end

def load_details
# inherits ID & Name from Recipient
super
return super + "\nTopic: #{@topic}" + "\nMember Count: #{@member_count}"
end
end
25 changes: 25 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require "dotenv"

Dotenv.load

class Recipient
attr_reader :id, :name

def initialize(id, name)
@id = id
@name = name
end

def self.load_all(url, token)
recipients = HTTParty.get(url, query: { token: token })
all_recipients = recipients["members"].map do |recipient|
recipient = new(recipient["id"], recipient["name"])
end
return all_recipients
end

def load_details
# inherited by Channel & User
return "#{self.class} Details\nID: #{self.id}\nName: #{self.name}"
end
end
64 changes: 58 additions & 6 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,63 @@
#!/usr/bin/env ruby
require "dotenv"
require "httparty"
require "vcr"
require "awesome_print"
require_relative "workspace"
Dotenv.load

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

# TODO project

puts "Thank you for using the Ada Slack CLI"
workspace = Workspace.new
puts workspace.get_channels
puts "Hello. Welcome, friend. Please enjoy our Slack CLI."
puts "What would you like to do? Please select an option"
puts "1. List Channels\n2. List Users\n3. Select Channel\n4. Select User\n5. List Details\n6. Send Message\n7. Quit"
user_selection = gets.chomp.downcase
while user_selection
case user_selection
when "1" || "list channels"
puts "list_channels"
puts workspace.list_channels
when "2" || "list users"
puts "list_users"
puts workspace.list_users
when "3" || "select channel"
puts "select_channel"
selection = gets.chomp
while workspace.valid_selection?("channel", selection) == false
puts "Please enter a channel name or id."
selection = gets.chomp
end
puts workspace.find_by_id_or_name("channel", selection)
when "4" || "select user"
puts "select_user"
selection = gets.chomp
while workspace.valid_selection?("user", selection) == false
puts "Please enter a user name or id."
selection = gets.chomp
end
puts workspace.find_by_id_or_name("user", selection)
when "5" || "details"
puts "list_details_on_current_recipient"
workspace.list_details_on_current_recipient
Copy link

Choose a reason for hiding this comment

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

This doesn't puts the details on the current recipient!

Copy link

Choose a reason for hiding this comment

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

Also, even if you add puts here, it just prints the recipient. There's a bug in your list_details_on_current_recipient method!

when "6" || "send message"
puts "send_message"
puts "Do you want cats with that? (yes/no)"
cats = gets.chomp.downcase
puts "Please enter your message:"
message = gets.chomp
puts workspace.send_message(message, cats)
when "7" || "quit"
puts "Thank you for using the Ada Slack CLI"
exit
else
puts "Please select a valid input."
user_selection = gets.chomp
end
puts "What would you like to do? Please select an option"
puts "1. List Channels\n2. List Users\n3. Select Channel\n4. Select User\n5. List Details\n6. Send Message\n7. Quit"
user_selection = gets.chomp.downcase
end
end

main if __FILE__ == $PROGRAM_NAME
main if __FILE__ == $PROGRAM_NAME
24 changes: 24 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require_relative "recipient"

class User < Recipient
attr_reader :id, :name, :details, :username

def initialize(id, name, details = "", username = "")
super(id, name)
@details = details
@username = username
end

def self.load_all(url, token)
Copy link

Choose a reason for hiding this comment

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

Seems like there isn't a test for this?

recipients = HTTParty.get(url, query: { token: token })
all_recipients = recipients["members"].map do |recipient|
recipient = new(recipient["id"], recipient["real_name"], details = recipient["info"], username = recipient["name"])
end
return all_recipients
end

def load_details
# inherits ID & Name from Recipient
return super + "\nUsername: #{@username}"
end
end
116 changes: 116 additions & 0 deletions lib/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
require "dotenv"
require "httparty"
require "uri"
Dotenv.load

require_relative "recipient"
require_relative "channel"
require_relative "user"

class Workspace
TOKEN = ENV["SLACK_TOKEN"]

attr_accessor :users, :channels, :current_recipient, :user_url, :channel_url, :message_url

def initialize
@channel_url = "https://slack.com/api/conversations.list"
@user_url = "https://slack.com/api/users.list"
@message_url = "https://slack.com/api/chat.postMessage"
@channel_member_url = "https://slack.com/api/conversations.members"
Copy link

Choose a reason for hiding this comment

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

Consider making these constant variables!

@users = get_users
@channels = get_channels
@current_recipient = nil
end

def get_users
User.load_all(@user_url, TOKEN)
end

def get_channels
Channel.load_all(@channel_url, TOKEN)
end

def valid_selection?(selection_type, selection)
case selection_type
when "channel"
@channels.find { |channel| channel.id == selection || channel.name == selection } ? true : false
when "user"
@users.find { |user| user.id == selection || user.name == selection } ? true : false
end
end

def find_by_id_or_name(recipient_type, search_arg)
Copy link

Choose a reason for hiding this comment

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

This method is great!

if recipient_type.downcase != "user" && recipient_type.downcase != "channel"
raise ArgumentError, "Recipient must be either a user or a channel."
end

recipient_list = []
if (recipient_type.downcase == "user")
recipient_list = @users
else
recipient_list = @channels
end
Copy link

Choose a reason for hiding this comment

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

Possible refactor: Consider recipient_list = recipient_type.downcase == "user" ? @users : @channels -- your tests still pass!


recipient = recipient_list.find do |recipient|
recipient.id == search_arg || recipient.name == search_arg
end

if recipient == nil
raise ArgumentError, "Recipient not found."
else
@current_recipient = recipient
end
end

def list_details_on_current_recipient
if @current_recipient == nil
raise ArgumentError, "No recipient is currently selected."
else
@current_recipient.load_details
Copy link

Choose a reason for hiding this comment

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

This line evaluates into a string with some details, but it doesn't return anything meaningful overall; it doesn't puts anything either. In the end, this method just returns @current_recipient below

Copy link

Choose a reason for hiding this comment

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

I wish your tests checked on this behavior!

end
return @current_recipient
end

def send_message(message, cats)
id = @current_recipient.id
if cats == "yes"
cat_block = '[{"type": "image", "alt_text": "cat", "image_url": "https://cataas.com/cat/says/' + URI.encode(message) + '"}]'
new_message = HTTParty.post(@message_url,
headers: { "Content-Type" => "application/x-www-form-urlencoded" },
body: {
"token" => TOKEN,
"channel" => id,
"text" => message,
"blocks" => cat_block,
})
else
new_message = HTTParty.post(@message_url,
Copy link

Choose a reason for hiding this comment

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

What happens if this POST request comes back with an error response? That is not handled!

headers: { "Content-Type" => "application/x-www-form-urlencoded" },
body: {
"token" => TOKEN,
"channel" => id,
"text" => message,
})
end
new_message
end

def list_users
user_list = HTTParty.get(@user_url, query: { token: TOKEN })
user_list["members"].map do |user|
"ID: #{user["id"]}
Username: #{user["name"]}
Name: #{user["real_name"]}"
end
end

def list_channels
channel_list = HTTParty.get(@channel_url, query: { token: TOKEN })
channel_list["channels"].map do |channel|
Copy link

Choose a reason for hiding this comment

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

I'd like a more explicit return statement here so it's more readable!

"ID: #{channel["id"]}
Name: #{channel["name"]}
Topic: #{channel["topic"]["value"]}
Member Count: #{channel["num_members"]}"
end
end
end
Loading