-
Notifications
You must be signed in to change notification settings - Fork 31
Earth - Kal and Christina #18
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
base: master
Are you sure you want to change the base?
Changes from all commits
389399d
eff8ec3
62408c6
8d7e462
fc7c35b
b492512
b557dda
06ff6d5
f7f186f
f243d73
13cabaf
3be0854
f887c19
61ab59b
5929293
2f70d14
a658619
eba96d0
1eb5efa
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 |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "url": "https://floobits.com/christinaminh/slack-cli" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| extern | ||
| node_modules | ||
| tmp | ||
| vendor | ||
| .idea |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| {"icon_emoji":":sparkle:","username":"bot"} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| require_relative "recipient" | ||
|
|
||
| CONVERSATIONS_URL = "https://slack.com/api/conversations.list" | ||
|
|
||
| class Channel < Recipient | ||
| attr_reader :id, :name, :topic, :member_count | ||
|
|
||
| def initialize(id:, name:, topic: nil, member_count: nil) | ||
| super(id, name) | ||
|
|
||
| @topic = topic | ||
| @member_count = member_count | ||
| end | ||
|
|
||
|
|
||
| def self.list_all | ||
| response = get(CONVERSATIONS_URL) | ||
|
|
||
| channels_list = response["channels"].map do |channel| | ||
| Channel.new( | ||
| id: channel["id"], | ||
| name: channel["name"], | ||
| topic: channel["topic"]["value"], | ||
| member_count: channel["num_members"] | ||
| ) | ||
| end | ||
|
|
||
| return channels_list | ||
| end | ||
|
|
||
| def details | ||
| return "\nSlack ID: #{self.id}\nName: #{self.name}\nTopic: #{self.topic}\nMember count: #{self.member_count}" | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,58 @@ | ||||||
| require 'dotenv' | ||||||
| require 'json' | ||||||
|
|
||||||
| # require_relative '../lib/bot_settings.json' | ||||||
| Dotenv.load | ||||||
|
|
||||||
| class SlackApiError < StandardError; end | ||||||
| class NoMessageError < StandardError; end | ||||||
|
|
||||||
| class Recipient | ||||||
| attr_reader :id, :name | ||||||
|
|
||||||
| def initialize(id, name) | ||||||
| @id = id | ||||||
| @name = name | ||||||
| end | ||||||
|
|
||||||
| API_KEY = ENV["SLACK_API_TOKEN"] | ||||||
|
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 README said that this should be named
Suggested change
|
||||||
| def self.get(url) | ||||||
| response = HTTParty.get(url, query: { token: API_KEY }) | ||||||
|
|
||||||
| raise SlackApiError.new(response["error"]) unless response.parsed_response["ok"] | ||||||
|
|
||||||
| return response | ||||||
| end | ||||||
|
|
||||||
| CHAT_URL = "https://slack.com/api/chat.postMessage" | ||||||
| BOT_API_KEY = ENV["SLACK_BOT_API_TOKEN"] | ||||||
|
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. You should use a single token for getting and sending.
Suggested change
|
||||||
| def send_message(message) | ||||||
| raise NoMessageError, "No message to send." if message.nil? || message.empty? | ||||||
|
|
||||||
| settings_json = File.read("bot_settings.json") | ||||||
| settings = JSON.parse(settings_json) | ||||||
|
|
||||||
| response = HTTParty.post(CHAT_URL, | ||||||
| headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }, | ||||||
| body:{ | ||||||
| token: BOT_API_KEY, | ||||||
| channel: self.id, | ||||||
| text: message, | ||||||
| icon_emoji: settings["icon_emoji"], | ||||||
| username: settings["username"] | ||||||
| }) | ||||||
|
|
||||||
| raise SlackApiError, "Error occurred when sending #{message} to #{self.name}: #{response.parsed_response["error"]}" unless response.parsed_response["ok"] | ||||||
|
|
||||||
| return true | ||||||
| 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 | ||||||
| end | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,138 @@ | ||
| #!/usr/bin/env ruby | ||
| require 'httparty' | ||
| require 'table_print' | ||
| require 'json' | ||
|
|
||
| require_relative 'workspace' | ||
|
|
||
| def find(dataset, workspace) | ||
| print "Would you like to enter a name or id? " | ||
| input = gets.chomp.downcase | ||
|
|
||
| until input == "name"|| input == "id" | ||
| puts "Please enter 'name' or 'id': " | ||
| input = gets.chomp.downcase | ||
| end | ||
|
|
||
| if input == "name" | ||
| if dataset[0].instance_of? User | ||
| print "Enter username: " | ||
| elsif dataset[0].instance_of? Channel | ||
| print"Enter channel name: " | ||
| end | ||
|
|
||
| input = gets.chomp.downcase | ||
|
|
||
| return workspace.select(dataset: dataset ,name: input) | ||
|
|
||
| elsif input == "id" | ||
| print "Enter id: " | ||
| input = gets.chomp.upcase | ||
|
|
||
| return workspace.select(dataset: dataset ,id: input) | ||
| end | ||
|
|
||
| rescue ArgumentError => error_message | ||
| puts "Encountered an error: #{error_message}\n\n" | ||
| end | ||
|
|
||
| def message | ||
| print "Enter message => " | ||
| message = gets.chomp | ||
|
|
||
| if message.empty? | ||
| puts "Invalid message (no content). Please enter a VALID message or hit 'ENTER' to return to main menu. => " | ||
| message = gets.chomp.downcase | ||
| end | ||
|
|
||
| return message | ||
| end | ||
|
|
||
| def change_settings | ||
| settings_json = File.read("bot_settings.json") | ||
| settings = JSON.parse(settings_json) | ||
|
Comment on lines
+51
to
+52
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 bot settings file is a nice touch. 🤖 |
||
|
|
||
| puts "Do you want to change username or emoji?" | ||
| input = gets.chomp.downcase | ||
|
|
||
| if input == "username" | ||
| print "Enter new username: " | ||
| new_setting = gets.chomp | ||
|
|
||
| settings["username"] = new_setting | ||
| File.write("bot_settings.json", settings.to_json) | ||
|
|
||
| elsif input == "emoji" | ||
| print "Enter new emoji: " | ||
| new_setting = gets.chomp | ||
|
|
||
| settings["icon_emoji"] = new_setting | ||
| File.write("bot_settings.json", settings.to_json) | ||
| end | ||
|
|
||
| end | ||
|
|
||
| def main | ||
| puts "Welcome to the Ada Slack CLI!" | ||
| workspace = Workspace.new | ||
|
|
||
| # TODO project | ||
| while true | ||
| puts "\nWhat would you like to do? | ||
| - LIST USERS | ||
| - LIST CHANNELS | ||
| - SELECT USER | ||
| - SELECT CHANNEL | ||
| - DETAILS | ||
| - SEND MESSAGE | ||
| - CHANGE SETTINGS | ||
| - QUIT" | ||
|
|
||
| print "\nPlease enter a request: " | ||
| input = gets.chomp.downcase | ||
|
|
||
| case input | ||
| when "list users" | ||
| tp workspace.users, "id", "name", "real_name" | ||
|
|
||
| when "list channels" | ||
| tp workspace.channels, "id", "name", "topic", "member_count" | ||
|
|
||
| when "select user" | ||
| find(workspace.users, workspace) | ||
| puts "You've selected '#{workspace.selected.name}'!" unless workspace.selected.nil? | ||
|
|
||
| when "select channel" | ||
| find(workspace.channels, workspace) | ||
| puts "You've selected '#{workspace.selected.name}'!" unless workspace.selected.nil? | ||
|
|
||
| when "details" | ||
| if workspace.selected | ||
| puts workspace.show_details | ||
| else | ||
| puts "No user or channel selected.\n" | ||
| end | ||
| when "change settings" | ||
| change_settings | ||
| when "send message" | ||
| begin | ||
| if workspace.selected | ||
| workspace.send_message(message) | ||
| else | ||
| puts "No user or channel selected.\n" | ||
| end | ||
| rescue NoMessageError | ||
| puts "No message entered." | ||
| rescue SlackApiError => error_message | ||
| puts "Encountered an error: #{error_message}\n\n" | ||
| end | ||
|
|
||
| when "quit" | ||
| puts "\n👋 👋 Thank you for using the Ada Slack CLI...exiting." | ||
| exit | ||
|
|
||
| puts "Thank you for using the Ada Slack CLI" | ||
| else | ||
| puts "Invalid choice." | ||
| end | ||
| end | ||
| end | ||
|
|
||
| main if __FILE__ == $PROGRAM_NAME | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| require_relative "recipient" | ||
|
|
||
| USERS_URL = "https://slack.com/api/users.list" | ||
|
|
||
| class User < Recipient | ||
| attr_reader :id, :name, :real_name | ||
|
|
||
| def initialize(id:, name:, real_name: nil) | ||
| super(id, name) | ||
|
|
||
| @real_name = real_name | ||
| end | ||
|
|
||
|
|
||
| def self.list_all | ||
| response = get(USERS_URL) | ||
|
|
||
| users_list = response["members"].map do |user| | ||
| User.new(id: user["id"], name: user["name"], real_name: user["real_name"]) | ||
| end | ||
|
|
||
| return users_list | ||
| end | ||
|
|
||
| def details | ||
| return "\nSlack ID: #{self.id}\nUsername: #{self.name}\nReal Name: #{self.real_name}" | ||
| end | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| require_relative 'user' | ||
| require_relative 'channel' | ||
|
|
||
|
|
||
| class Workspace | ||
| attr_reader :users, :channels, :selected | ||
|
|
||
| def initialize | ||
| @users = User.list_all | ||
| @channels = Channel.list_all | ||
| @selected = nil | ||
| end | ||
|
|
||
| def select(dataset: , id: nil, name: nil) | ||
| @selected = dataset.find do |recipient| | ||
| recipient.id == id || recipient.name == name | ||
| end | ||
|
|
||
| raise ArgumentError.new ("User not found.") if @selected == nil && dataset == @users | ||
| raise ArgumentError.new ("Channel not found.") if @selected == nil && dataset == @channels | ||
|
|
||
| return @selected | ||
| end | ||
|
|
||
| def show_details | ||
| raise ArgumentError.new ("No user or channel selected.") unless @selected | ||
|
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. I think I would prefer this to be something like a |
||
|
|
||
| return @selected.details | ||
| end | ||
|
|
||
| def send_message(message) | ||
| raise ArgumentError.new ("No user or channel selected.") unless @selected | ||
|
|
||
| return @selected.send_message(message) | ||
| 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.
Good use of a constant!