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

Earth - Maha & Sophie - Slack API #22

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@

# Ignore environemnt variables
.env
coverage
37 changes: 37 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'httparty'
require 'prettyprint'
require 'dotenv'

require_relative 'recipient'

Dotenv.load

class Channel < Recipient

attr_reader :topic,:member_count

def initialize(slack_id, name, topic, member_count)
super(slack_id, name)
@topic = topic
@member_count = member_count
end
def self.list_all
channel_url = 'https://slack.com/api/conversations.list'
response = self.get(channel_url, query: { token: ENV['SLACK_API_TOKEN']})

channels = response["channels"]

list = []
channels.each do |channel|
list << Channel.new(channel["id"], channel["name"], channel["purpose"]["value"], channel["num_members"])
end
return list
end

def details
return "\n channel name: #{self.name} \n topic: #{self.topic} \n user count: #{self.member_count} \n slack_id: #{self.slack_id}"
end


end

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

Dotenv.load

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.get(url, params)
return HTTParty.get(url, params)
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
})
unless response.code == 200 && response.parsed_response["ok"]
raise SlackApiError, "Error when posting #{message} to #{@name}, error: #{response.parsed_response["error"]}"
end
end
end
108 changes: 103 additions & 5 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,110 @@
#!/usr/bin/env ruby

require 'prettyprint'
require 'awesome_print'
require 'httparty'
require 'dotenv'

Dotenv.load

require_relative 'workspace'

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

begin
workspace = Workspace.new
rescue SlackApiError => error
puts "error occurred: #{error.message}"
return
end
Comment on lines +13 to +18
Copy link

Choose a reason for hiding this comment

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

this is awesome, great thinking!


puts "\nWelcome to the Ada Slack CLI!"
puts "There are #{workspace.users.length} users and #{workspace.channels.length} channels."

statement = "\nPlease enter one of the following commands:\n• list users\n• list channels\n• select user\n• select channel\n• show details\n• send a message\n• quit\n"

until false

puts statement
puts "\n"
input = gets.chomp.downcase

begin
case input
when "list users"
puts workspace.list_users
when "list channels"
puts workspace.list_channels

when "select channel"
puts "Please enter a channel name or ID:"
input = gets.chomp
workspace.select_channel(input)

# TODO project
until workspace.select_channel(input) != nil
puts "Invalid channel #{input}. Please try again."
input = gets.chomp
workspace.select_channel(input)
end

puts "Thank you for using the Ada Slack CLI"
puts "\n Selected channel: #{workspace.selected.name} \n ID: #{workspace.selected.slack_id}"
puts " Enter #{"show details"} for more details on #{workspace.selected.name}"

when "select user"
puts "Please enter a username or ID:"
input = gets.chomp
workspace.select_user(input)

until workspace.select_user(input) != nil
puts "Invalid user #{input}. Please try again."
input = gets.chomp
workspace.select_user(input)
end

puts "\n Selected user: #{workspace.selected.name} \n ID: #{workspace.selected.slack_id}"
puts " Enter #{"show details"} for more details on #{workspace.selected.name}"

when "show details"
if workspace.selected == nil
puts "Details for whom? Please enter a user or channel"
input = gets.chomp
workspace.ask_to_select(input)
until workspace.ask_to_select(input) != nil
puts "Invalid input #{input}. Please try again."
input = gets.chomp
workspace.ask_to_select(input)
end
end

puts workspace.show_details

when "send a message"
if workspace.selected == nil
puts "To whom?"
input = gets.chomp
workspace.ask_to_select(input)
until workspace.ask_to_select(input) != nil
puts "Invalid input #{input}. Please try again."
input = gets.chomp
workspace.ask_to_select(input)
end
end

puts "What message would you like to send?"
message = gets.chomp.to_s
puts workspace.send_message(message)
puts "message #{message} sent successfully!"

when "quit"
puts "Thank you for using the Ada Slack CLI"
break
else
puts "Invalid input #{input}"
end
rescue SlackApiError => error
puts "error occurred: #{error.message}"
end
end
end

main if __FILE__ == $PROGRAM_NAME

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

require_relative 'recipient'

Dotenv.load

class User < Recipient

attr_reader :real_name, :status_text, :status_emoji

def initialize(slack_id, name, real_name, status_text, status_emoji)
super(slack_id, name)
@real_name = real_name
@status_text = status_text
@status_emoji = status_emoji
end

def self.list_all
user_url = 'https://slack.com/api/users.list'
Copy link

Choose a reason for hiding this comment

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

potential refactoring: because we never expect to re-assign user_url, it might be worth making this into a constant variable, USER_URL

response = self.get(user_url, query: { token: ENV['SLACK_API_TOKEN']})

raise ArgumentError.new("invalid request") if response["ok"] == false

users = response["members"]

list = []
users.each do |user|
list << User.new(user["id"], user["name"], user["profile"]["real_name"], user["profile"]["status_text"], user["profile"]["status_emoji"])
end
return list
end

def details
return "\n username: #{self.name} \n real name: #{self.real_name} \n slack ID: #{self.slack_id} \n status: #{self.status_text} \n emoji: #{self.status_emoji}"
end

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

require_relative 'user'
require_relative 'channel'

Dotenv.load

class Workspace

attr_reader :users,:channels,:selected

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

def list_users
user_data = []
@users.each do |user|
user_data << user.details
end
return user_data
end

def list_channels
channel_data = []
@channels.each do |channel|
channel_data << channel.details
end
return channel_data
end

def select_channel(input)
@selected = @channels.find { |channel| input == channel.name || input == channel.slack_id}
Copy link

Choose a reason for hiding this comment

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

Great work refactoring this find to include the ||. This method looks great.

return @selected
end

def select_user(input)
@selected = @users.find { |user| input == user.name || input == user.slack_id}
return @selected
end

def ask_to_select(input)
select_channel(input)
if @selected == nil
Copy link

Choose a reason for hiding this comment

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

For fun, just as an FYI: Ruby has a method .nil? you can attach to most objects, so here you could do if @selected.nil? .

nil? returns true only if the attached object is nil.

select_user(input)
end
return @selected
end

def show_details
raise SlackApiError.new("no user or channel selected") if @selected == nil
return @selected.details
end

def send_message(message)
raise SlackApiError.new("no user or channel selected") if @selected == nil
@selected.send_message(message)
end
end


66 changes: 66 additions & 0 deletions test/cassettes/channel_send_not_authed.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading