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
Binary file added .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# Used by dotenv library to load environment variables.
# .env

Choose a reason for hiding this comment

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

You should uncomment this line to include it in your .gitignore file.


coverage

## Specific to RubyMotion:
.dat*
.repl_history
Expand Down
50 changes: 50 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require 'dotenv'
require_relative 'recipient'

module Slack
class Channel < Recipient
attr_reader :topic, :members, :creator, :privacy_status

def initialize(slack_id, name, topic, members, creator, privacy_status)
super(slack_id, name)
@topic = topic
@members = members
@creator = creator
@privacy_status = privacy_status
end

def self.list
url = "https://slack.com/api/channels.list"
query_parameters = {
token: ENV["SLACK_TOKEN"]
}
channel_objects = Recipient.get(url, query_parameters)

channel_list = []
channel_objects["channels"].each do |channel|
channel_basic = self.new(channel["id"], channel["name"], channel["topic"], channel["members"].length, channel["creator"], channel["is_private"])
channel_list << channel_basic
end
return channel_list
end

def send_msg(message)
Recipient.send_msg(message, @slack_id)
end

def details
channel_details = {}

channel_details["slack_id"] = self.slack_id
channel_details["name"] = self.name
channel_details["topic"] = self.topic

Choose a reason for hiding this comment

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

the "topic" key provides this hash: {"value"=>"Non-work banter and water cooler conversation", "creator"=>"UMZNG8T8R", "last_set"=>1568061999} It seems that you just want "value" in this case.

channel_details["members"] = self.members
channel_details["creator"] = self.creator
channel_details["privacy_status"] = self.privacy_status

return channel_details
end


end
end
47 changes: 47 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'httparty'

module Slack
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.send_msg(message, channel)
# BASE_URL = "https://slack.com/api/chat.postMessage"
response = HTTParty.post(
"#{"https://slack.com/api/chat.postMessage"}",
body: {
token: ENV["SLACK_TOKEN"],
text: message,
channel: channel
},
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
)

unless response.code == 200 && response.parsed_response["ok"]
raise SlackApiError, "Error when posting #{message} to #{channel}, error: #{response.parsed_response["error"]}"
end

return true
end


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

def self.get(url, params)
return HTTParty.get(url, query: params)

Choose a reason for hiding this comment

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

What is this isn't a success? Make sure you are prepared for something to go wrong and raise a SlackAPIError.

end

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

end
end
153 changes: 149 additions & 4 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,156 @@
#!/usr/bin/env ruby
require_relative "user"
require_relative "channel"
require_relative 'workspace'
require 'dotenv'
Dotenv.load
# require_relative "channel"

def main
puts "Welcome to the Ada Slack CLI!"
workspace = Slack::Workspace.new
user_choice = nil

until user_choice == "3"
puts "\nWelcome to the Ada Slack CLI! Put quit to exit the program"

# user can list users, chanels, or quit
user_choice = prompt(
"\nWhat would you like to do?",
["List users", "List channels", "Quit"]
)

# path for list users

Choose a reason for hiding this comment

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

Consider using case/when for this control structure.

if user_choice == "1"
list = Slack::User.list
print_user_list(list)

search_choice = prompt(
"\nDo you want to find a user by:",
["Slack id", "User name"]
)

# user decides how they want to look up recipient
if search_choice == "1"

Choose a reason for hiding this comment

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

With these nested conditionals, make sure that users always have the option to quit.

puts "\nPlease enter that person's slack id: "
slack_id = validate(gets.chomp)
workspace.select_user_slack_id(slack_id: slack_id)
elsif search_choice == "2"
puts "\nPlease enter the person's user name:"
user_name = validate(gets.chomp)
response = workspace.select_user_username(user_name: user_name)
while response.nil?
puts "Couldn't find user :("
print "Please make a valid selection: > "
user_name = validate(gets.chomp)
response = workspace.select_user_username(user_name: user_name)
end
end

# prompts the user after recipient has been selected
# built in helper methods to validate inputs
communication_choice = prompt(
"Do you want to:",
["See this user's details", "Send them a message"]
)

# sends messages or shows details for selected client
if communication_choice == "1"
puts "\n---DETAILS---"
workspace.show_details
elsif communication_choice == "2"
puts "Please enter a message: "
message = gets.chomp
workspace.send_message(message)
end

# path for lists channels
elsif user_choice == "2"
list = Slack::Channel.list
print_channel_list(list)

search_choice = prompt(
"\nDo you want to find a channel by:",
["Slack id", "Channel name"]
)

# user decides how to look up channel
if search_choice == "1"
print "\nPlease enter that channel's slack id: > "
slack_id = validate(gets.chomp)
workspace.select_channel_slack_id(slack_id: slack_id)
elsif search_choice == "2"
print "\nPlease enter the name of that channel: > "
user_name = validate(gets.chomp)
workspace.select_channel_username(user_name: user_name)
end

# prompts user for selection
# built in validate methods with helper methods
communication_choice = prompt(
"Do you want to:",
["See this channel's details", "Send a message to the channel?"]
)

if communication_choice == "1"
puts "\n---DETAILS---"
workspace.show_details
elsif communication_choice == "2"
"\nPlease enter a message: > "
message = gets.chomp
workspace.send_message(message)
end


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

# TODO project
def prompt(message, options)
puts
puts message
options.each_with_index do |option, index|
puts "#{index + 1}. #{option}"
end
input = gets.chomp

until input.to_i <= options.length && input.to_i > 0
print "Invalid selection. > "
input = gets.chomp
end
return input
end

puts "Thank you for using the Ada Slack CLI"
def print_user_list(list)

Choose a reason for hiding this comment

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

print_user_list and print_channel_list are quite similar. Is there a way to dry up this code?

list.each do |member_object|
puts
puts "slack id: #{member_object.slack_id}"
puts "name: #{member_object.name}"
puts "real name: #{member_object.real_name}\n"
end
end

main if __FILE__ == $PROGRAM_NAME
def print_channel_list(list)
list.each do |member_object|
puts
puts "slack id: #{member_object.slack_id}"
puts "name: #{member_object.name}"
puts "topic: #{member_object.topic}"
puts "member_count: #{member_object.members}"
end
end

def validate(input)
while input.empty? || input.nil?
print "please make a valid selection: >"
input = gets.chomp
end
return input
end

main



main if __FILE__ == $SLACK
49 changes: 49 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require 'dotenv'
require_relative 'recipient'

module Slack
class User < Recipient
attr_reader :real_name, :display_name, :time_zone

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

def self.list
url = "https://slack.com/api/users.list"
query_parameters = {
token: ENV["SLACK_TOKEN"]
}
user_objects = Recipient.get(url, query_parameters)

user_list = []
user_objects["members"].each do |member|
# @users << member
user_basic = self.new(member["id"], member["name"], member["real_name"], member["profile"]["display_name"], member["tz"])
user_list << user_basic
end
return user_list
end

def send_msg(message)
Recipient.send_msg(message, @slack_id)
end


def details
user_details = {}
user_details["slack_id"] = self.slack_id
user_details["name"] = self.name
user_details["real_name"] = self.real_name
user_details["display_name"] = self.display_name
user_details["time_zone"] = self.time_zone

return user_details
end

end

end
47 changes: 47 additions & 0 deletions lib/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require_relative 'user'
require_relative 'channel'

module Slack
class Workspace

attr_reader :users, :channels, :selected

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

def select_user_slack_id(slack_id: nil)

Choose a reason for hiding this comment

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

The following 4 methods are all quite similar. Is there a way to DRY up this code?

user_object = @users.find { |user| user.slack_id == slack_id }
@selected = user_object unless user_object.nil?
end

def select_user_username(user_name: nil)
user_object = @users.find { |user| user.name == user_name }
@selected = user_object unless user_object.nil?
end

def select_channel_slack_id(slack_id: nil)
channel_object = @channels.find { |channel| channel.slack_id == slack_id }
@selected = channel_object unless channel_object.nil?
end

def select_channel_username(user_name: nil)
channel_object = @channels.find { |channel| channel.name == user_name }
@selected = channel_object unless channel_object.nil?
end


def show_details
@selected.details.each do |detail, value|
puts "#{detail}: #{value}"
end
end

def send_message(message)
return @selected.send_msg(message)
end

end
end
Loading