Skip to content
Open
31 changes: 31 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# channel's name, topic, member count, and Slack ID

class Channel < Recipient
attr_reader :topic, :member_count

def initialize(slack_id, name, topic, member_count)
super(slack_id, name)

@topic = topic
@member_count = member_count
end

def self.list
url = "https://slack.com/api/channels.list"
query = {token: ENV['SLACK_TOKEN']}

channels_list = []
response = Recipient.get(url, query)
response["channels"].each do |channel|
new_channel = Channel.new(channel["id"], channel["name"], channel["topic"], channel["members"].length)
# binding.pry
channels_list << new_channel
end
return channels_list
end

def details
return {slack_id: @slack_id, name: @name, topic: @topic, member_count: @member_count}
end

end
40 changes: 40 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require "pry"
class SlackAPIError < StandardError ; end

class Recipient
attr_reader :slack_id, :name

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

def self.get(url, query)
response = HTTParty.get(url, query: query)
return response
end

def details
raise NotImplementedError, 'Implement me in a child class!'
end

def self.list
raise NotImplementedError, 'Implement me in a child class!'
end

def send_message(message)
url = "https://slack.com/api/chat.postMessage"
body = {token: ENV['SLACK_TOKEN'],
text: message,
channel: @slack_id}

message_post = HTTParty.post(url, body: body)

unless message_post.code == 200 && message_post["ok"]
raise SlackAPIError.new("Error when posting #{message} to #{@slack_id}")
end

return true
end

end
64 changes: 62 additions & 2 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,70 @@
#!/usr/bin/env ruby
require 'dotenv'
require 'httparty'
require 'table_print'

require_relative 'recipient'
require_relative 'channel'
require_relative 'user'
require_relative 'workspace'

# Tell dotenv to look for the .env file
Dotenv.load

def main
puts "Welcome to the Ada Slack CLI!"
new_workspace = Workspace.new(User.list, Channel.list)

while true
puts "Welcome to the Ada Slack CLI!"
puts "Select an option: list users, list channels, select user, select channel, details, send message to channel, send message to user or quit"
option = gets.chomp

until option == "list users" || option == "list channels" || option == "quit" || option == "select user" || option == "select channel" || option == "details" || option == "send message to channel" || option == "send message to user"
puts "Select a valid option: list users, list channels, select user, select channel, details, send message or quit"
option = gets.chomp.downcase
end

break if option == "quit"

if option == "list users"
tp User.list

elsif option == "list channels"
tp Channel.list

Choose a reason for hiding this comment

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

This doesn't easily surface the name of the channel, making it hard to use!


elsif option == "select user"
puts "Enter the username or Slack ID"
selection = gets.chomp
new_workspace.select_user(selection)

elsif option == "select channel"
puts "Enter the channel name or Slack ID"
selection = gets.chomp
new_workspace.select_channel(selection)

# TODO project
elsif option == "details"
if new_workspace.show_details == nil
puts "You haven't enter the name or Slack ID"
end
tp [new_workspace.show_details]

elsif option == "send message to channel"
puts "Please enter the channel name or Slack ID"
selection = gets.chomp
channel = new_workspace.select_channel(selection)

Choose a reason for hiding this comment

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

What is the purpose of having a select channel and select user option above if we just ask them to select again here?

The design intent was for the person using the CLI to pick a user or channel, then use the same method to send a message to whatever they had selected!

puts "Please enter the message:"
message = gets.chomp
channel.send_message(message)

elsif option == "send message to user"

Choose a reason for hiding this comment

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

why do you have a different entry for sending to user and channel? they work the same, and you could use polymorphism to DRY this code to a single block! This also reduces the number of tests you need to write!

puts "Please enter the user name or Slack ID"
selection = gets.chomp
user = new_workspace.select_user(selection)
puts "Please enter the message:"
message = gets.chomp
user.send_message(message)
end
end
puts "Thank you for using the Ada Slack CLI"
end

Expand Down
32 changes: 32 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# username, real name, and Slack ID.
require "pry"
require 'dotenv'
Dotenv.load


class User < Recipient
attr_reader :real_name

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

def self.list
url = "https://slack.com/api/users.list"
query = {token: ENV['SLACK_TOKEN']}

users_list = []
response = Recipient.get(url, query)
response["members"].each do |member|
new_user = User.new(member["id"], member["name"], member["real_name"])
users_list << new_user
end
return users_list
end

def details
return {slack_id: @slack_id, name: @name, real_name: @real_name}
end

end
52 changes: 52 additions & 0 deletions lib/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require 'dotenv'
require "pry"
Dotenv.load

class Workspace
attr_reader :users, :channels
attr_accessor :selected
def initialize(users, channels, selected: nil)
@users = users
@channels = channels
@selected = selected
end

def select_channel(selection)
value = 0

Channel.list.each do |channel|
if channel.name == selection || channel.slack_id == selection
value = 1
@selected = channel
return channel
end
end

if value == 0
raise ArgumentError.new("Please provide a valid selection for channel. ")
end
end

def select_user(selection)
value = 0

User.list.each do |user|
if user.name == selection || user.slack_id == selection
value = 1
@selected = user
return user
end
end

if value == 0
raise ArgumentError.new("Please provide a valid selection for user.")

Choose a reason for hiding this comment

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

It's fine to throw an error here, but if you don't catch it, then the program just crashes on bad input.

end
end

def show_details
if @selected == nil
return nil
end
return @selected.details
end
end
Loading