Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4349d08
Started token verification.
krismosk Sep 9, 2019
6bced36
Completed API token verification script.
krismosk Sep 10, 2019
0913ab4
Modified token verification loop sytax for readability.
krismosk Sep 10, 2019
f9e9110
Added filter for sensitive data to protect Slack token identity.
krismosk Sep 10, 2019
185bc2a
Created acceptor, user lib files.
krismosk Sep 10, 2019
55e1d8a
Instantiated User class, created first test. Commented out Acceptor f…
krismosk Sep 10, 2019
361380a
Added .get_api method to User class. Passed corresponding test.
krismosk Sep 10, 2019
b41d1da
Created .list method for User and passed corresponding test.
krismosk Sep 10, 2019
20bf96d
Created a .print_list method for User, to print the username, real na…
krismosk Sep 10, 2019
14588c4
Added new channel and workspace files.
krismosk Sep 10, 2019
9ffa927
Formatted CLI Main to re-print commands when given bad input
krismosk Sep 11, 2019
f5e5b96
Removed line in .gitignore so that VCR cassettes can be tracked.
krismosk Sep 11, 2019
1dbdd9f
Created scaffolding for Workspace
krismosk Sep 11, 2019
59afa96
Scaffolding workspace/user composition.
krismosk Sep 11, 2019
f4fe774
Moved user methods inside of Workspace. Work in progress.
krismosk Sep 11, 2019
f7a7f41
Successfully instantiated Workspace, creates users within instance va…
krismosk Sep 11, 2019
02c4e54
Wrote test for workspace intialize and workspace get_api test passing
krismosk Sep 11, 2019
006161e
Modified user test to only test for intialized attributes.
krismosk Sep 11, 2019
26454d6
Created Channel class, tested instantation of class. Test passing.
krismosk Sep 11, 2019
5d0d7c1
Wave 1 completed.
krismosk Sep 11, 2019
1edf180
work in progress
krismosk Sep 12, 2019
202adb8
Created search method in Workspace to search across users, passed cor…
krismosk Sep 12, 2019
2e5fbb4
Created show_details method, implemented for User. Passed correspondi…
krismosk Sep 12, 2019
f98a3b2
Modified search method to search through channels. Passed correspondi…
krismosk Sep 12, 2019
7520454
Modified show details to work for channels. Passed corresponding test…
krismosk Sep 12, 2019
9f8acc0
Created send message method in Workspace. Successfully called API and…
krismosk Sep 12, 2019
8e750a9
Modified CLI program to allow user to send a message to a channel via…
krismosk Sep 12, 2019
b71f28a
Modified CLI program to allow user to send a message to selected user…
krismosk Sep 13, 2019
3ba429c
Removed acceptor class and file.
krismosk Sep 13, 2019
22c9cf2
Cleaned up workspace test.
krismosk Sep 13, 2019
a8df6c0
Removed all references to acceptor.rb
krismosk Sep 13, 2019
a55e36f
Completed project.
krismosk Sep 13, 2019
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
11 changes: 4 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
/tmp/

# Used by dotenv library to load environment variables.
# .env
.env

# Ignore environment variables
.env

## Specific to RubyMotion:
.dat*
Expand Down Expand Up @@ -48,9 +51,3 @@ build-iPhoneSimulator/

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc

# Ignore environemnt variables
.env

# Ignore cassette files
/specs/cassettes/
12 changes: 12 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Slack
class Channel
attr_reader :channel_name, :topic, :member_count, :slack_id

def initialize(channel_name:, topic:, member_count:, slack_id:)
@channel_name = channel_name
@topic = topic
@member_count = member_count
@slack_id = slack_id
end
end
end
116 changes: 112 additions & 4 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,119 @@
#!/usr/bin/env ruby
require_relative "workspace"
require_relative "user"
require_relative "channel"
require 'httparty'
require "dotenv"
Dotenv.load

def main
puts "Welcome to the Ada Slack CLI!"
puts "Welcome to the Ada Slack CLI!\n"
workspace = Slack::Workspace.new
workspace.user_list
workspace.channel_list

puts "\nDarn Cute Puppers has #{workspace.users.count} users and #{workspace.channels.count} channels.\n"

# TODO project
prompt = "\nPlease select from the following options:
List Users
List Channels
Select User
Select Channel
Quit\n"

puts prompt

while command = gets.chomp.downcase

Choose a reason for hiding this comment

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

Consider using helper methods to encapsulate some of the functionality in this CLI.

case command
when "quit"
exit
when "list users"
puts workspace.print_user_list
puts prompt
when "list channels"
puts workspace.print_channel_list
puts prompt
when "select user"
puts "Please enter a username or Slack ID."
username = gets.chomp.downcase
search_result = workspace.search("user", username)
if search_result == nil
puts "User not found. Returning to main menu..."
puts prompt
break
else
puts "User found."
options = "Please select from the following options:
Show Details
Send Message
Main Menu"
puts options
while selected_command = gets.chomp.downcase
case selected_command
when "main menu"

Choose a reason for hiding this comment

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

Consider adding the options "show details" and "send message" to the main menu so that user of the CLI can send a second message to an already selected recipient.

puts prompt
break
when "show details"
puts workspace.show_details(search_result)
puts options
when "send message"
puts "What message do you want to send?"
message_body = gets.chomp
convert_to_username = workspace.selected.username
workspace.send_message(message_body, "@#{convert_to_username}")
puts "Message sent. Returning to main menu..."
puts prompt
break
else
puts "Invalid input. Returning to main menu..."
puts prompt
break
end
end
end
when "select channel"
puts "Please enter a channel name or Slack ID."
channel_name = gets.chomp.downcase
search_result = workspace.search("channel", channel_name)
if search_result == nil
puts "Channel not found. Returning to main menu..."
puts prompt
break
else
puts "Channel found."
options = "Please select from the following options:
Show Details
Send Message
Main Menu"
puts options
while selected_command = gets.chomp.downcase
case selected_command
when "main menu"
puts prompt
break
when "show details"
puts workspace.show_details(search_result)
puts options
when "send message"
puts "What message do you want to send?"
message_body = gets.chomp
convert_to_channel_name = workspace.selected.channel_name
workspace.send_message(message_body, convert_to_channel_name)
puts "Message sent. Returning to main menu..."
puts prompt
break
else
puts "Invalid input. Returning to main menu..."
puts prompt
break

Choose a reason for hiding this comment

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

Consider allowing users to re-enter their input rather than breaking the program when the user input is invalid.

end
end
end
else
puts "Invalid input. Returning to main menu..."
break
end
end
puts "Thank you for using the Ada Slack CLI"
end

main if __FILE__ == $PROGRAM_NAME
main if __FILE__ == $PROGRAM_NAME
11 changes: 11 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Slack
class User
attr_reader :username, :real_name, :slack_id

def initialize(username:, real_name:, slack_id:)
@username = username
@real_name = real_name
@slack_id = slack_id
end
end
end
118 changes: 118 additions & 0 deletions lib/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
require_relative "user"
require_relative "channel"

module Slack
class SlackApiError < StandardError; end
class Workspace
USER_URL = "https://slack.com/api/users.list"
CHANNEL_URL = "https://slack.com/api/channels.list"
POST_MSG_URL = "https://slack.com/api/chat.postMessage"

attr_reader :users, :channels, :selected

def initialize
@users = []
@channels = []
@selected = nil
end

def get_api(url)
query_parameters = {
token: ENV['SLACK_TOKEN']
}
return HTTParty.get(url, query: query_parameters)

Choose a reason for hiding this comment

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

Make sure you handle bad requests appropriately.

end

def user_list

Choose a reason for hiding this comment

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

What you've done here works. Nice work! However, the recommendation to put this method in the user class was there to reduce dependencies between classes. When you instantiate a new User below, this means that Workspace needs to know everything about User. This is a perfect situation for a class method.

api_user_response = get_api(USER_URL)
api_members = api_user_response["members"]
api_members.each do |each_member|
username = each_member["name"]
real_name = each_member["real_name"]
slack_id = each_member["id"]
@users << Slack::User.new(username: username, real_name: real_name, slack_id: slack_id)
end
end

def print_user_list
user_counter = 0
result = ''
@users.each do |each_user|
user_counter += 1
result = result + "User #{user_counter} - username: #{each_user.username}, real name: #{each_user.real_name}, Slack ID: #{each_user.slack_id}\n"
end
return result
end

def channel_list
api_channel_response = get_api(CHANNEL_URL)
api_channels = api_channel_response["channels"]
api_channels.each do |each_channel|
channel_name = each_channel["name"]
topic = each_channel["topic"]["value"]
member_count = each_channel["num_members"]
slack_id = each_channel["id"]
@channels << Channel.new(channel_name: channel_name, topic: topic, member_count: member_count, slack_id: slack_id)
end
end

def print_channel_list
channel_counter = 0
result = ''
@channels.each do |each_channel|
channel_counter += 1
result = result + "Channel #{channel_counter} - channel name: #{each_channel.channel_name}, topic: #{each_channel.topic}, member count: #{each_channel.member_count}, Slack ID: #{each_channel.slack_id}\n"
end
return result
end

def search(data_source, query_term)

Choose a reason for hiding this comment

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

This code is very similar to select a user and select a channel. Could you DRY this up somehow?

@selected = nil
if data_source == "user"
@users.each do |current_user|
if current_user.username == query_term || current_user.slack_id == query_term.upcase
@selected = current_user
break
end
end
return @selected
elsif data_source == "channel"
@channels.each do |current_channel|
if current_channel.channel_name == query_term || current_channel.slack_id == query_term.upcase
@selected = current_channel
break
end
end
return @selected
end
end

def show_details(selected_receiver)
details = ""
if selected_receiver.class == Slack::User
details = details + "Username: #{@selected.username}, Real name: #{@selected.real_name}, Slack ID: #{@selected.slack_id}"
return details
elsif selected_receiver.class == Slack::Channel
details = details + "Channel name: #{@selected.channel_name}, Topic: #{@selected.topic}, Member count: #{@selected.member_count}, Slack ID: #{@selected.slack_id}"
return details
end
end

def send_message(message, selected_receiver)
response = HTTParty.post(
POST_MSG_URL,
body: {
token: ENV['SLACK_TOKEN'],
text: message,
channel: selected_receiver
},
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
)

unless response.parsed_response["ok"]
raise SlackApiError, "Error when posting #{message} to #{selected_receiver}, error: #{response.parsed_response["error"]}"
end
return response
end
end
end
Loading