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

Water - Kareha & Leah #5

Open
wants to merge 42 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5fd8d97
creating workspace class, fixing test_helper to hide token
agesak Oct 6, 2020
efe46b5
untracked?
agesak Oct 6, 2020
62b013b
Merge branch 'master' of https://github.com/scottzec/slack-cli
agesak Oct 6, 2020
8e4a590
created classes
scottzec Oct 6, 2020
db879e6
repetitive
agesak Oct 6, 2020
b128e3f
Merge branch 'master' of https://github.com/scottzec/slack-cli
agesak Oct 6, 2020
1c42e9f
recipient constructor tests
agesak Oct 6, 2020
f71d4d6
user constructor tests
agesak Oct 6, 2020
b88137a
add .floo to .gitignore
agesak Oct 6, 2020
9edf491
remove unnecessary requires
agesak Oct 6, 2020
b7d28f6
Added Channel Tests
scottzec Oct 7, 2020
867e2f1
re-added driver file
scottzec Oct 7, 2020
1c9c5d7
Outline Wave 1 finished
scottzec Oct 7, 2020
28b3ded
functioning tp for Channels class
agesak Oct 7, 2020
6887969
added User tests for API
scottzec Oct 7, 2020
dd3a077
testing User.list_all
agesak Oct 7, 2020
0126e2d
adding Channel.list_all tests
agesak Oct 7, 2020
7f6c7a8
wave 1 complete
agesak Oct 8, 2020
e499158
Merge branch 'master' of github.com:scottzec/slack-cli
scottzec Oct 8, 2020
f0e8f47
yml
scottzec Oct 8, 2020
33f18dd
yml
scottzec Oct 8, 2020
e138531
refactor program_prompt in slack.rb
agesak Oct 8, 2020
d568925
Merge branch 'master' of https://github.com/scottzec/slack-cli
agesak Oct 8, 2020
25e588e
select and show channel details in workspace
agesak Oct 8, 2020
4813d03
select channel method tests
scottzec Oct 8, 2020
f4fc1b8
select channel method tests
scottzec Oct 8, 2020
0dd2c66
user select user and show details in workspace
agesak Oct 8, 2020
a332585
completed wave 2 tests
scottzec Oct 8, 2020
a4dffe6
Merge branch 'master' of github.com:scottzec/slack-cli
scottzec Oct 8, 2020
7f5f160
Removed superfluous name variable
scottzec Oct 8, 2020
f01557c
fixing bug in validate_input in slack.rb
agesak Oct 8, 2020
ce90722
send message working for channels only when already selected
agesak Oct 8, 2020
2ea8492
send message to channel done
scottzec Oct 8, 2020
9adbf30
send message to channel done
scottzec Oct 8, 2020
3c9bcc7
reverting a commit
scottzec Oct 8, 2020
cba84f3
completed channel send msg
scottzec Oct 8, 2020
b8f539d
re-added validate_post to recipient
scottzec Oct 8, 2020
16a790a
added 2 tests for send message
scottzec Oct 9, 2020
a243c78
validate name or id
agesak Oct 9, 2020
19159cd
more use channel topic output
agesak Oct 9, 2020
66f7256
final formatting
agesak Oct 9, 2020
f61aa6a
add driver to .gitignore
agesak Oct 9, 2020
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@

# Ignore environemnt variables
.env

.floo
.flooignore

driver.rb
14 changes: 14 additions & 0 deletions auth_verification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'dotenv'
require 'httparty'

Dotenv.load

query = {
token: ENV["SLACK_TOKEN"]
}

response = HTTParty.get("https://www.slack.com/api/conversations.list", query: query)

response.each do |response|

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

class Channel < Recipient
attr_reader :slack_id, :channel_name, :topic, :member_count

CHANNEL_LIST_URL = "https://slack.com/api/conversations.list"

def initialize(slack_id:, channel_name:, topic:, member_count:)
super(slack_id)

@channel_name = channel_name
@topic = topic
@member_count = member_count
end

def self.list_all
query = {
token: ENV["SLACK_TOKEN"]
}
response = self.get(CHANNEL_LIST_URL, query)

responses = response["channels"].map do |channel|
self.new(slack_id: channel["id"], channel_name: channel["name"],
topic: channel["purpose"]["value"], member_count: channel["num_members"])
end
return responses
end
end
54 changes: 54 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require 'httparty'
require 'dotenv'

require_relative 'slack_api_error'

Dotenv.load

class Recipient
attr_reader :slack_id

def initialize(slack_id)
@slack_id = slack_id
end

def self.get(url, params)
response = HTTParty.get(url, query: params)
raise SlackAPIError.new("API call failed with code #{response.code} and error #{response['error']}") if response["ok"] == false
return response
end

def send_message(message)

body_param = {
token: ENV["SLACK_TOKEN"],
text: message,
channel: @slack_id
}
response = HTTParty.post(
"https://slack.com/api/chat.postMessage",
body: body_param,
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
)

response_string = validate_post(response)

return response_string
end

def self.list_all
raise NotImplementedError.new("Implement me in a child class")
end

def details
raise NotImplementedError.new("Implement me in a child class")
end

private

def validate_post(response)
raise SlackAPIError.new("API call failed with code #{response.code} and error #{response['error']}") if response["ok"] == false
return "Thank you this message was sent"
end
Comment on lines +49 to +52

Choose a reason for hiding this comment

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

Great use of a helper method.


end
79 changes: 78 additions & 1 deletion lib/slack.rb
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,11 +1,88 @@
#!/usr/bin/env ruby
require_relative "workspace"

require "table_print"

VALID_INPUT = ["list users", "list channels", "select channel", "select user", "send message", "details", "quit"]

def validate_property_type(property_type)
property_type.downcase!
valid_property_types = ["name", "id"]
return false unless valid_property_types.include?(property_type)

Choose a reason for hiding this comment

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

Nice use of a postfix conditional.

return true
end

def recipient_details(input, workspace)
recipient_string = input.split(" ")[-1]
puts "Please enter the #{recipient_string} you want to see information for. \nDo you want to enter an ID or a name?"
property_type = gets.chomp
until validate_property_type(property_type)
puts "Please enter either name or ID"
property_type = gets.chomp
end
Comment on lines +19 to +22

Choose a reason for hiding this comment

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

Great use of a helper method.

puts "Thanks! Please enter it"
name_or_id = gets.chomp
if recipient_string == "channel"
recipient = workspace.select_channel(name_or_id, property_type)
elsif recipient_string == "user"
recipient = workspace.select_user(name_or_id, property_type)
end
if recipient == nil
puts "This #{recipient_string} doesn't exist! Exiting..."
end
Comment on lines +30 to +32

Choose a reason for hiding this comment

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

Consider writing this as a postfix conditional.

end

def program_prompt(users, channels, workspace)
puts "Please enter your selected option:"
puts "- list users"
puts "- list channels"
puts "- select channel"
puts "- select user"
puts "- send message"
puts "- details"
puts "- quit"

input = validate_input(gets.chomp)
case input
when "list users"
tp users
when "list channels"
tp channels
when "select channel"
recipient_details(input, workspace)
when "select user"
recipient_details(input, workspace)
when "details"
puts workspace.show_details
when "send message"
puts "What message would you like to send?"
message = gets.chomp
puts workspace.send_message(message)
when "quit"
exit
end
return input
end

def validate_input(input)
input.downcase!
raise ArgumentError.new("Not a valid input") unless VALID_INPUT.include?(input)

Choose a reason for hiding this comment

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

Argument errors are great to raise in your source code, but in your CLI code, you should consider how you can handle invalid user input so that the error doesn't bubble up and the user gets the opportunity to correct their mistake.

return input
end

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

# TODO project
users = workspace.users
channels = workspace.channels

puts "There are #{users.length} users and #{channels.length} channels in this workspace"

input = program_prompt(users, channels, workspace)
until input == "quit"
input = program_prompt(users, channels, workspace)
end
puts "Thank you for using the Ada Slack CLI"
end

Expand Down
1 change: 1 addition & 0 deletions lib/slack_api_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class SlackAPIError < StandardError ; end
31 changes: 31 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require_relative 'recipient'
require 'dotenv'

Dotenv.load

class User < Recipient
attr_reader :username, :real_name, :slack_id

USER_LIST_URL = "https://slack.com/api/users.list"

def initialize(slack_id:, username:, real_name:)
super(slack_id)

@username = username
@real_name = real_name
end

def self.list_all
query = {
token: ENV["SLACK_TOKEN"]
}
response = self.get(USER_LIST_URL, query)

responses = response["members"].map do |member|
self.new(slack_id: member["id"], username: member["name"],
real_name: member["real_name"],
)
end
return responses
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_relative 'user'
require_relative 'channel'

class Workspace < Recipient

attr_reader :users, :channels

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

def send_message(message)
raise SlackAPIError.new("This recipient doesn't exist") unless @selected
@selected.send_message(message)
end

def select_user(user, property)
if property == "id"
selected_user = users.find{|user_instance| user_instance.slack_id == user}
elsif property == "name"
selected_user = users.find{|user_instance| user_instance.username == user}
end
@selected = selected_user

return selected_user

Choose a reason for hiding this comment

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

Consider whether selected_user needs to be returned, as it is stored in the instance variable @selected

end

def select_channel(channel, property)
if property == "id"
selected_channel = channels.find{|channel_instance| channel_instance.slack_id == channel}
elsif property == "name"
selected_channel = channels.find{|channel_instance| channel_instance.channel_name == channel}
end
Comment on lines +31 to +35

Choose a reason for hiding this comment

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

Great use of the enumerable method `find1

@selected = selected_channel

return selected_channel
end

def show_details
if @channels.include?(@selected)
return_string = "This is channel #{@selected.channel_name}, its topic is #{@selected.topic}. Its slack_id is #{@selected.slack_id}, and it has a member count of #{@selected.member_count}"
elsif @users.include?(@selected)
return_string = "This is user #{@selected.username}. Their real name is #{@selected.real_name} and their slack id is #{@selected.slack_id}"
else
return_string = "No recipient selected"
end

return return_string
end
end
Loading