Skip to content
Open
74 changes: 74 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require 'httparty'
require 'awesome_print'
require 'dotenv'
Dotenv.load

Choose a reason for hiding this comment

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

Your Channel class here is just a collection of class methods. It would be better if you had a class to represent a channel with instance variables etc. The get_channels method could then return an array of channel instances. That would also allow you to have an instance method to send messages, or get details.

class Channel
def self.get_channels
url = 'https://slack.com/api/channels.list'
query_parameters = {
token: ENV['SLACK_API_TOKEN']
}

response = HTTParty.get(url, query: query_parameters).to_s
response = JSON.parse(response)

return response["channels"]
end

def self.list_channels(channels)
channels.each do |channel|
puts "Channel name: #{channel["name"]}"

Choose a reason for hiding this comment

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

You are also mixing the presentation parts of the program with your business logic. It's advisable to put the parts that deal with data and application logic separate from code that presents an interface to the user.

puts "Topic: #{channel["topic"]["value"]}"
puts "Member Count: #{channel["members"].length}"
puts "Slack ID: #{channel["id"]}"
puts
end
end

def self.select_channel(channels)
continue = true
selected_channel = nil

while(continue)
ap "Select your channel with one of the following: "
puts "a. channel name"
puts "b. SlackID"
puts "c. quit\n"
print "> "
select_channel_response = gets.chomp.downcase

if select_channel_response == "a" || select_channel_response == "channel name"
print "\nChannel name > "
requested_channel_name = gets.chomp.downcase

channels.each do |channel|
if channel["name"] == requested_channel_name
selected_channel = channel
end
end

continue = false

elsif select_channel_response == "b" || select_channel_response == "slackid"
print "\nSlackID > "
requested_id = gets.chomp.upcase

channels.each do |channel|
if channel["id"] == requested_id
selected_channel = channel
end
end

continue = false

elsif select_channel_response == "c" || select_channel_response == "quit"
continue = false
else
puts "Inaccurate response.\n\n"
end
end

return selected_channel
end
end
55 changes: 55 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require "httparty"
require "awesome_print"
require "dotenv"
Dotenv.load

class Recipient

Choose a reason for hiding this comment

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

You'll notice the code for this class is pretty repetitive. That's a clear sign that you can refactor this method to simplify the logic a bit.

Check out the instructor reference design and ask me questions if you have them.

attr_reader :is_user

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

def self.details(slack_id)

Choose a reason for hiding this comment

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

This method would make more sense as an instance method where you could get the details of that specific instance of Recipient.

if @is_user
url = "https://slack.com/api/users.list"
query_parameters = {
token: ENV["SLACK_API_TOKEN"],
}

response = HTTParty.get(url, query: query_parameters).to_s
response = JSON.parse(response)

users = response["members"]

users.each do |user|
if user["id"] == @slack_id
puts "Your selected user has the following details:"
puts "Name: #{user["real_name"]}"
puts "Username: #{user["name"]}"
puts "SlackID: #{user["id"]}"
end
end
else
url = "https://slack.com/api/channels.list"
query_parameters = {
token: ENV["SLACK_API_TOKEN"],
}

response = HTTParty.get(url, query: query_parameters).to_s
response = JSON.parse(response)
channels = response["channels"]

channels.each do |channel|
if channel["id"] == @slack_id
puts "Your selected channel has the following details:"
puts "Channel name: #{channel["name"]}"
puts "Topic: #{channel["topic"]["value"]}"
puts "Member Count: #{channel["members"].length}"
puts "Slack ID: #{channel["id"]}"
end
end
end
end
end
98 changes: 95 additions & 3 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,103 @@
#!/usr/bin/env ruby
require 'httparty'
require 'awesome_print'
require 'dotenv'
require_relative '../lib/recipient'
require_relative '../lib/channel'
require_relative '../lib/user'
Dotenv.load
# require 'table_print'

class SlackApiError < StandardError; end


def main
puts "Welcome to the Ada Slack CLI!"
ap "Welcome to the Ada Slack CLI!"

def menu
puts
ap "Main Menu"
puts "a. list users"
puts "b. select user"
puts "c. list channels"
puts "d. select channel"
puts "e. details for selected user and channel"
puts "f. send message"
puts "g. quit\n\n"

ap "What would you like to do?"

Choose a reason for hiding this comment

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

BTW thank you for letting me select a letter for an option rather than typing out the entire "list users" etc.

print "> "
@menu_response = gets.chomp.downcase.delete(".")
puts
end

users = User.get_users
channels = Channel.get_channels
recipient = nil
continue = true

# TODO project
puts "There are #{channels.length} channels and #{users.length} users."

puts "Thank you for using the Ada Slack CLI"
while (continue)
menu
if @menu_response == "a" || @menu_response == "list users"
ap "All users in the Slack workspace: "
User.list_users(users)
elsif @menu_response == "b" || @menu_response == "select user"
user = User.select_user(users)
if user.nil?
puts "Error. User not found."
else
recipient = Recipient.new(user["id"], true)
end
elsif @menu_response == "c" || @menu_response == "list channels"
ap "All channels in the Slack workspace: "
Channel.list_channels(channels)
elsif @menu_response == "d" || @menu_response == "select channel"
channel = Channel.select_channel(channels)
if channel.nil?
puts "Error. Channel not found."
else
recipient = Recipient.new(channel["id"], false)
end
elsif @menu_response == "e" || @menu_response == "details"
if recipient.nil?
puts "No details to show, please select a channel or user."
else
if user.nil?
recipient.details(channel["id"])

Choose a reason for hiding this comment

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

Your recipient class doesn't have an instance method called details. You made a class method instead.

else
recipient.details(user["id"])
end
end
elsif @menu_response == "f" || @menu_response == "send message"
puts "Okay, you want to send a message."
puts "What is the SlackID or name of the channel?"
print "> "
channel = gets.chomp

puts "What is the message you want to send?"
print "> "
text = gets.chomp

url = 'https://slack.com/api/chat.postMessage'
query_parameters = {
token: ENV['SLACK_API_TOKEN'],
channel: channel,
text: text,
}

HTTParty.post(url, query: query_parameters)

elsif @menu_response == "g" || @menu_response == "quit"
ap "Okay, good-bye! Thank you for using the Ada Slack CLI!"
continue = false
else
ap "Invalid input. To quit, choose c."
menu
end
end
end


main if __FILE__ == $PROGRAM_NAME
73 changes: 73 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require 'httparty'
require 'awesome_print'
require 'dotenv'
Dotenv.load

class User

Choose a reason for hiding this comment

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

This class has a lot of the same issues Channel has.

def self.get_users
url = 'https://slack.com/api/users.list'
query_parameters = {
token: ENV['SLACK_API_TOKEN']
}

response = HTTParty.get(url, query: query_parameters).to_s
response = JSON.parse(response)

return response["members"]
end

def self.list_users(users)
users.each do |user|
puts "Name: #{user["real_name"]}"
puts "Username: #{user["name"]}"
puts "SlackID: #{user["id"]}"
puts
end
end

def self.select_user(users)
continue = true
selected_user = nil

while(continue)
ap "Select your user with one of the following: "
puts "a. username"
puts "b. SlackID"
puts "c. quit\n"
print "> "
select_user_response = gets.chomp.downcase

if select_user_response == "a" || select_user_response == "username"
print "\nUsername > "
requested_username = gets.chomp.downcase

users.each do |user|
if user["name"] == requested_username
selected_user = user
end
end

continue = false

elsif select_user_response == "b" || select_user_response == "slackid"
print "\nSlackID > "
requested_id = gets.chomp.upcase

users.each do |user|
if user["id"] == requested_id
selected_user = user
end
end

continue = false

elsif select_user_response == "c" || select_user_response == "quit"
continue = false
else
puts "Invalid response.\n\n"
end
end

return selected_user
end
end
19 changes: 19 additions & 0 deletions specs/channel_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require "simplecov"
SimpleCov.start

require_relative "test_helper"
require_relative "../lib/channel.rb"

describe "Channel class" do
before do
VCR.use_cassette("channel_list") do
@response = Channel.get_channels
end
end

it "can retrieve a list of channels" do
expect(@response).must_be_kind_of Array
expect(@response[0]).must_be_kind_of Hash
expect(@response[0]["members"].length).must_be_kind_of Integer
end
end
18 changes: 18 additions & 0 deletions specs/recipient_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
require "simplecov"
SimpleCov.start

require_relative "test_helper"
require_relative "../lib/recipient.rb"

# File always wants to make GET request to channel API regardless of @is_user status.
# Not sure how to make tests work for this.

# describe "Recipient class" do
# before do
# @is_user = true
# end
# it "Can get details about a user" do
# slack_id = "USLACKBOT"
# expect(Recipient.details(slack_id)).must_be_kind_of Hash
# end
# end
35 changes: 26 additions & 9 deletions specs/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
require 'simplecov'
require "simplecov"
SimpleCov.start

require 'minitest'
require 'minitest/autorun'
require 'minitest/reporters'
require 'minitest/skip_dsl'
require 'vcr'
require "minitest"
require "minitest/skip_dsl"

require "minitest/autorun"
require "minitest/reporters"
require "vcr"
require "webmock/minitest"
require "dotenv"
Dotenv.load

require_relative "../lib/recipient"
require_relative "../lib/channel"
require_relative "../lib/user"
require_relative "../lib/slack"

Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new

VCR.configure do |config|
config.cassette_library_dir = "specs/cassettes"
config.hook_into :webmock
end
config.cassette_library_dir = "specs/cassettes" # folder where casettes will be located
config.hook_into :webmock # tie into this other tool called webmock
config.default_cassette_options = {
:record => :new_episodes, # record new data when we don't have it yet
:match_requests_on => [:method, :uri, :body], # The http method, URI and body of a request all need to match
}
# Don't leave our token lying around in a cassette file.
config.filter_sensitive_data("<LOCATIONIQ_TOKEN>") do
ENV["LOCATIONIQ_TOKEN"]
end
end
Loading