-
Notifications
You must be signed in to change notification settings - Fork 31
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 - Iris and Jessica #7
base: master
Are you sure you want to change the base?
Changes from 93 commits
69bf55b
2a08ee1
f5851a9
e722628
fdaeddf
f9e88b0
59aa085
46c2351
b67fcad
5d43a9a
ec67365
c77db13
9dc48b0
02cb338
295be86
695f407
3b78f84
7ffa394
cfcd60c
8683608
7431b06
5857759
e48e23f
548c1d1
b9c60c4
0d6d76c
70efd75
3429b39
3563aca
b13cf8c
a28b2e5
c05bec0
e1e2ece
7ee4d31
4e2572f
4c74bde
43a286f
e5cea3e
9b88f1e
986dafa
8674ed7
38ba753
d9df74c
88d201f
bf71c29
1f0bfb2
561f269
046011c
ff92f77
b156298
cbe5d66
ef8e895
96ff74a
d92b0e4
d469636
2f3a1ec
2cea429
f2df810
deb623b
1372365
9d1e3b5
93f7ee0
bef3c33
4fd4fc9
c136561
ad290fb
abe81c7
301fcfd
f88c771
a99623a
1a75b2c
b1f8312
7dad6d9
6030580
c0ce8d0
a2604eb
6efee41
a8b0ecb
d56a922
e334b4a
c590b61
52468a6
280fc43
cbaa629
8078983
a29cdb7
a25ba36
37190c4
e9a82ef
43bb11e
d9bb93e
a16f7c0
4c981ef
dbce3f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,4 @@ | |
.DS_Store | ||
|
||
# Ignore environemnt variables | ||
.env | ||
.env |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
source "https://rubygems.org" | ||
|
||
|
||
gem 'rake' | ||
gem 'minitest' | ||
gem 'minitest-spec' | ||
gem 'minitest-reporters' | ||
gem "pry" | ||
gem 'minitest-skip' | ||
gem 'httparty' | ||
gem 'dotenv' | ||
gem 'table_print' | ||
gem 'vcr' | ||
gem 'simplecov' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
GEM | ||
remote: https://rubygems.org/ | ||
specs: | ||
ansi (1.5.0) | ||
builder (3.2.4) | ||
coderay (1.1.3) | ||
docile (1.3.2) | ||
dotenv (2.7.6) | ||
httparty (0.18.1) | ||
mime-types (~> 3.0) | ||
multi_xml (>= 0.5.2) | ||
method_source (1.0.0) | ||
mime-types (3.3.1) | ||
mime-types-data (~> 3.2015) | ||
mime-types-data (3.2020.0512) | ||
minitest (5.14.2) | ||
minitest-reporters (1.4.2) | ||
ansi | ||
builder | ||
minitest (>= 5.0) | ||
ruby-progressbar | ||
minitest-skip (0.0.3) | ||
minitest (~> 5.0) | ||
minitest-spec (0.0.2.1) | ||
minitest (>= 3.0) | ||
multi_xml (0.6.0) | ||
pry (0.13.1) | ||
coderay (~> 1.1) | ||
method_source (~> 1.0) | ||
rake (13.0.1) | ||
ruby-progressbar (1.10.1) | ||
simplecov (0.19.0) | ||
docile (~> 1.1) | ||
simplecov-html (~> 0.11) | ||
simplecov-html (0.12.3) | ||
table_print (1.5.7) | ||
vcr (6.0.0) | ||
|
||
PLATFORMS | ||
ruby | ||
|
||
DEPENDENCIES | ||
dotenv | ||
httparty | ||
minitest | ||
minitest-reporters | ||
minitest-skip | ||
minitest-spec | ||
pry | ||
rake | ||
simplecov | ||
table_print | ||
vcr | ||
|
||
BUNDLED WITH | ||
2.1.4 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
require_relative 'recipient' | ||
|
||
module SlackCLI | ||
class Channel < Recipient | ||
|
||
attr_reader :slack_id, :name, :topic, :member_count | ||
|
||
def initialize(slack_id:, name:, topic:, member_count:) | ||
super(name: name, slack_id: slack_id) | ||
@topic = topic | ||
@member_count = member_count | ||
end | ||
|
||
def self.list_all | ||
return self.get("conversations.list", {token: ENV["SLACK_API_TOKEN"]})["channels"].map do |channel| | ||
self.new(slack_id: channel["id"], name: channel["name"], topic: channel["topic"]["value"], member_count: channel["num_members"]) | ||
end | ||
end | ||
|
||
def details | ||
return "ID: #{@slack_id} \nName: #{@name} \nTopic: #{@topic} \nMember Count: #{@member_count}" | ||
end | ||
|
||
def channel_history | ||
response = Channel.get("conversations.history", {token: ENV["SLACK_API_TOKEN"], channel: @slack_id}) | ||
return response["messages"].map{ |message| message["text"] } | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
require 'dotenv' | ||
require 'httparty' | ||
require_relative 'slackapierror' | ||
|
||
Dotenv.load | ||
|
||
module SlackCLI | ||
class Recipient | ||
|
||
attr_reader :name, :slack_id | ||
def initialize(slack_id:, name:) | ||
self.class.validate_id(slack_id) | ||
@slack_id = slack_id | ||
@name = name | ||
end | ||
|
||
def self.validate_id(id) | ||
if id.nil? | ||
raise ArgumentError, 'ID cannot be blank.' | ||
end | ||
end | ||
|
||
def self.get(end_point, params) | ||
raise ArgumentError.new("invalid arguments") unless (end_point.is_a?(String) && params.is_a?(Hash)) | ||
response = HTTParty.get("https://slack.com/api/#{end_point}", query: params) | ||
unless response.code == 200 && response.parsed_response["ok"] | ||
raise SlackAPIError.new("Error: #{response.parsed_response["error"]}") | ||
end | ||
return response | ||
end | ||
|
||
def details | ||
raise NotImplementedError, 'Implement me in a child class!' | ||
end | ||
|
||
def self.list_all | ||
raise NotImplementedError, 'Implement me in a child class!' | ||
end | ||
|
||
def self.select(identifier) | ||
return self.list_all.find{|recipient| recipient.slack_id == identifier || recipient.name == identifier} | ||
end | ||
|
||
def send_message(message) | ||
|
||
response = HTTParty.post( | ||
"https://slack.com/api/chat.postMessage", | ||
body: { | ||
token: ENV["SLACK_API_TOKEN"], | ||
text: message, | ||
channel: @slack_id, | ||
as_user: "true" | ||
}, | ||
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' } | ||
) | ||
|
||
unless response.code == 200 && response.parsed_response["ok"] | ||
raise SlackAPIError.new("Error: #{response.parsed_response["error"]}") | ||
end | ||
|
||
return true | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,85 @@ | ||
#!/usr/bin/env ruby | ||
require 'dotenv' | ||
require 'httparty' | ||
require 'table_print' | ||
require_relative 'workspace' | ||
|
||
def main | ||
puts "Welcome to the Ada Slack CLI!" | ||
workspace = Workspace.new | ||
Dotenv.load | ||
|
||
# TODO project | ||
puts "Welcome to the Ada Slack CLI!\n\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The user experience is fantastic. Great work breaking this CLI down into helper methods and gracefully handling bad user input. |
||
workspace = SlackCLI::Workspace.new | ||
puts "This workspace has #{workspace.channels.length} channels and #{workspace.users.length} users." | ||
|
||
option = nil | ||
current_selection = nil | ||
until option == "quit" || option == "8" | ||
if option == "list users" || option == "1" | ||
tp workspace.list_users | ||
elsif option == "list channels" || option == "2" | ||
tp workspace.list_channels | ||
elsif option == "select user" || option == "3" | ||
puts "Enter the name or id" | ||
current_selection = workspace.select(SlackCLI::User,gets.chomp) | ||
puts "Selection not found" if(current_selection.nil?) | ||
elsif option == "select channel" || option == "4" | ||
puts "Enter the name or id" | ||
current_selection = workspace.select(SlackCLI::Channel,gets.chomp) | ||
puts "Selection not found" if(current_selection.nil?) | ||
elsif option == "details" || option == "5" | ||
details(current_selection, workspace) | ||
elsif option == "send message" || option == "6" | ||
send_message(current_selection, workspace) | ||
elsif option == "channel history" || option == "7" | ||
message_history(current_selection, workspace) | ||
elsif option.nil? | ||
puts "" | ||
else | ||
puts "Please input a valid option" | ||
end | ||
menu | ||
option = gets.chomp.downcase | ||
end | ||
puts "Thank you for using the Ada Slack CLI" | ||
end | ||
|
||
def details(recipient, workspace) | ||
if recipient.nil? | ||
puts "No recipient selected" | ||
else | ||
puts workspace.show_details(recipient) | ||
end | ||
end | ||
|
||
def send_message(recipient, workspace) | ||
if recipient.nil? | ||
puts "No recipient selected" | ||
else | ||
puts "Please enter message" | ||
workspace.send_message(gets.chomp, recipient) | ||
end | ||
end | ||
|
||
def message_history(recipient, workspace) | ||
if recipient.nil? || recipient.is_a?(SlackCLI::User) | ||
puts "Please select a channel" | ||
else | ||
puts workspace.conversation_history(recipient) | ||
end | ||
end | ||
|
||
def menu | ||
puts "**" * 20 | ||
puts "Please select one of the three options: " | ||
puts "1. list users" | ||
puts "2. list channels" | ||
puts "3. select user" | ||
puts "4. select channel" | ||
puts "5. details" | ||
puts "6. send message" | ||
puts "7. channel history" | ||
puts "8. quit" | ||
puts "**" * 20 | ||
end | ||
|
||
main if __FILE__ == $PROGRAM_NAME |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module SlackCLI | ||
class SlackAPIError < StandardError | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
require_relative 'recipient' | ||
|
||
module SlackCLI | ||
class User < Recipient | ||
|
||
attr_reader :slack_id, :name, :real_name, :status_text, :status_emoji | ||
|
||
def initialize(slack_id:, name:, real_name:, status_text:, status_emoji:) | ||
super(slack_id: slack_id, name: name) | ||
@real_name = real_name | ||
@status_text = status_text | ||
@status_emoji = status_emoji | ||
end | ||
|
||
def self.list_all | ||
return self.get("users.list", {token: ENV["SLACK_API_TOKEN"]})["members"].map do |user| | ||
self.new(slack_id: user["id"], name: user["name"], real_name: user["real_name"], status_text: user["profile"]["status_text"], status_emoji: user["profile"]["status_emoji"]) | ||
end | ||
end | ||
|
||
def details | ||
return "ID: #{@slack_id} \nName: #{@name} \nReal Name: #{@real_name} \nStatus: #{@status_text} \nEmoji: #{@status_emoji}" | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
require 'httparty' | ||
require_relative 'user' | ||
require_relative 'channel' | ||
|
||
module SlackCLI | ||
class Workspace | ||
attr_reader :users, :channels | ||
|
||
def initialize | ||
@users = User.list_all | ||
@channels = Channel.list_all | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider include an instance variable |
||
end | ||
|
||
def list_users | ||
return @users.map{|user| {id: user.slack_id, name: user.name, real_name: user.real_name} } | ||
end | ||
|
||
def list_channels | ||
return @channels.map{|channel| {id: channel.slack_id, name: channel.name, topic: channel.topic, member_count: channel.member_count}} | ||
end | ||
|
||
def select(recipient_class, identifier) | ||
raise ArgumentError.new("Argument cannot be empty") if(identifier == nil) | ||
raise ArgumentError.new("Recipient class must be user or channel") unless recipient_class == SlackCLI::User || recipient_class == SlackCLI::Channel | ||
recipient_class.select(identifier) | ||
end | ||
|
||
def show_details(recipient) | ||
return recipient.details | ||
end | ||
|
||
def send_message(message, recipient) | ||
raise ArgumentError.new("recipient must be of Recipient class") unless recipient.is_a? Recipient | ||
recipient.send_message(message) | ||
end | ||
|
||
def conversation_history(channel) | ||
return channel.channel_history | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You use this code a couple places. Consider breaking out this functionality into a helper method.