Created
October 3, 2023 07:19
-
-
Save fpaint/eadb52de55f72670f7c7c22e77c8b149 to your computer and use it in GitHub Desktop.
My tiny slack client
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # frozen_string_literal: true | |
| class Slack::ApiClient | |
| class Error < StandardError; end | |
| API_URL = 'https://slack.com/api' | |
| attr_reader :token | |
| def initialize(token = nil) | |
| @token = token | |
| end | |
| def post_request(endpoint, payload = {}) | |
| response = RestClient.post "#{API_URL}/#{endpoint}", payload.merge(token: token) | |
| data = JSON.parse response | |
| if data['ok'] | |
| data | |
| else | |
| raise Error, data['error'] | |
| end | |
| end | |
| def get_request(endpoint, payload) | |
| response = RestClient.get "#{API_URL}/#{endpoint}", payload.merge(token: token) | |
| JSON.parse response | |
| end | |
| def channel(channel_id) | |
| Slack::Channel.new(self, channel_id) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # frozen_string_literal: true | |
| require 'test_helper' | |
| describe Slack::ApiClient do | |
| let(:token) { 'some_secret_api_token' } | |
| let(:client) { Slack::ApiClient.new(token) } | |
| describe '#post_request' do | |
| let(:data) { {'param' => 'value'} } | |
| let(:good_response) { data.merge({'ok' => true}) } | |
| let(:bad_response) { data.merge({'ok' => false, 'error' => 'wrong_request'}) } | |
| it 'should send http with token and return response' do | |
| RestClient.expects(:post).returns(good_response.to_json).with do |url, payload| | |
| assert_equal 'https://slack.com/api/chat.method', url | |
| assert_equal({token: token, text: 'the text param'}, payload) | |
| end | |
| result = client.post_request('chat.method', {text: 'the text param'}) | |
| assert result | |
| assert_equal 'value', result['param'] | |
| end | |
| it 'should allow to send get requests' do | |
| RestClient.expects(:get).returns(good_response.to_json).with do |url, payload| | |
| assert_equal 'https://slack.com/api/chat.method', url | |
| assert_equal({token: token, text: 'the text param'}, payload) | |
| end | |
| result = client.get_request('chat.method', {text: 'the text param'}) | |
| assert result | |
| assert_equal 'value', result['param'] | |
| end | |
| it 'should raise proper error' do | |
| RestClient.expects(:post).returns(bad_response.to_json) | |
| assert_raises Slack::ApiClient::Error, 'wrong_request' do | |
| client.post_request('chat.method', {text: 'the text param'}) | |
| end | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # frozen_string_literal: true | |
| class Slack::Channel | |
| def initialize(client, channel_id) | |
| @client = client | |
| @channel_id = channel_id | |
| end | |
| def message(timestamp) | |
| Slack::Message.new(@client, @channel_id, timestamp) | |
| end | |
| def create_message(text) | |
| payload = {channel: @channel_id, as_user: true, text: text} | |
| result = @client.post_request 'chat.postMessage', payload | |
| raise ArgumentError, result['error'] if result['ok'] == false | |
| result['ts'] | |
| end | |
| def has_message?(timestamp) | |
| result = @client.get_request('chat.getPermalink', channel: @channel_id, message_ts: timestamp) | |
| raise ArgumentError, result['error'] if result['ok'] == false && result['error'] != 'message_not_found' | |
| result['ok'] | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # frozen_string_literal: true | |
| require 'test_helper' | |
| describe Slack::Channel do | |
| let(:text) { 'Here is a message for you' } | |
| let(:channel_id) { 'C123456' } | |
| let(:msg_ts) { '1503435956.000247' } | |
| let(:client) { mock('SlackApi') } | |
| let(:channel) { Slack::Channel.new(client, channel_id) } | |
| describe 'posting message' do | |
| let(:response) do | |
| { | |
| 'ok' => true, | |
| 'channel' => channel_id, | |
| 'ts' => msg_ts, | |
| 'message' => { | |
| 'text' => text, | |
| 'type' => 'message' | |
| } | |
| } | |
| end | |
| it 'should send request and return message timestamp' do | |
| client.expects(:post_request).returns(response).with do |endpoint, payload| | |
| assert_equal 'chat.postMessage', endpoint | |
| assert_equal({channel: channel_id, as_user: true, text: text}, payload) | |
| end | |
| result = channel.create_message(text) | |
| assert_equal msg_ts, result | |
| end | |
| end | |
| describe 'checking message exists' do | |
| let(:response) do | |
| { | |
| 'ok' => true, | |
| 'channel' => channel_id, | |
| 'permalink' => 'https://myslack.slack.com/archives/C123456/p135854651500008' | |
| } | |
| end | |
| it 'should return true' do | |
| client.expects(:get_request).returns(response).with do |endpoint, payload| | |
| assert_equal 'chat.getPermalink', endpoint | |
| assert_equal({channel: channel_id, message_ts: msg_ts}, payload) | |
| end | |
| result = channel.has_message?(msg_ts) | |
| assert result | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # frozen_string_literal: true | |
| class Slack::Message | |
| def initialize(client, channel_id, timestamp) | |
| @client = client | |
| @channel_id = channel_id | |
| @timestamp = timestamp | |
| end | |
| def comment(text) | |
| payload = {channel: @channel_id, thread_ts: @timestamp, as_user: true, text: text} | |
| @client.post_request 'chat.postMessage', payload | |
| end | |
| def delete | |
| @client.post_request 'chat.delete', channel: @channel_id, ts: @timestamp, as_user: true | |
| end | |
| def add_reaction(emoji_name) | |
| @client.post_request 'reactions.add', channel: @channel_id, timestamp: @timestamp, name: emoji_name | |
| rescue Slack::ApiClient::Error => e | |
| raise e unless e.message.in? %w[message_not_found already_reacted] | |
| end | |
| def remove_reaction(emoji_name) | |
| @client.post_request 'reactions.remove', channel: @channel_id, timestamp: @timestamp, name: emoji_name | |
| rescue Slack::ApiClient::Error => e | |
| raise e unless e.message.in? %w[message_not_found no_reaction] | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # frozen_string_literal: true | |
| require 'test_helper' | |
| describe Slack::Message do | |
| let(:text) { 'Here is a message for you' } | |
| let(:channel_id) { 'C123456' } | |
| let(:msg_ts) { '1503435956.000247' } | |
| let(:client) { Slack::ApiClient.new } | |
| let(:msg) { Slack::Message.new(client, channel_id, msg_ts) } | |
| let(:good_response) do | |
| {'ok' => true} | |
| end | |
| let(:bad_response) do | |
| { | |
| 'ok' => false, | |
| 'error' => expected_error | |
| } | |
| end | |
| describe 'adding comment' do | |
| it 'should send request' do | |
| client.expects(:post_request).returns(good_response).with do |endpoint, payload| | |
| assert_equal 'chat.postMessage', endpoint | |
| assert_equal({channel: channel_id, as_user: true, thread_ts: msg_ts, text: text}, payload) | |
| end | |
| msg.comment(text) | |
| end | |
| end | |
| describe 'deleting message' do | |
| it 'should send request' do | |
| client.expects(:post_request).returns(good_response).with do |endpoint, payload| | |
| assert_equal 'chat.delete', endpoint | |
| assert_equal({channel: channel_id, as_user: true, ts: msg_ts}, payload) | |
| end | |
| msg.delete | |
| end | |
| end | |
| describe 'add reaction' do | |
| let(:emoji) { 'heavy_check_mark' } | |
| it 'should send request' do | |
| client.expects(:post_request).returns(good_response).with do |endpoint, payload| | |
| assert_equal 'reactions.add', endpoint | |
| assert_equal({channel: channel_id, timestamp: msg_ts, name: emoji}, payload) | |
| end | |
| msg.add_reaction(emoji) | |
| end | |
| describe 'errors' do | |
| let(:expected_error) { 'invalid_name' } | |
| it 'should raise an error if api call fails' do | |
| RestClient.expects(:post).returns(bad_response.to_json) | |
| assert_raises Slack::ApiClient::Error, expected_error do | |
| msg.add_reaction(emoji) | |
| end | |
| end | |
| describe 'specific error' do | |
| let(:expected_error) { 'already_reacted' } | |
| it 'should not raise on specific errors' do | |
| RestClient.expects(:post).returns(bad_response.to_json) | |
| msg.add_reaction(emoji) | |
| end | |
| end | |
| end | |
| end | |
| describe 'remove reaction' do | |
| let(:emoji) { 'heavy_check_mark' } | |
| it 'should send request' do | |
| client.expects(:post_request).returns(good_response).with do |endpoint, payload| | |
| assert_equal 'reactions.remove', endpoint | |
| assert_equal({channel: channel_id, timestamp: msg_ts, name: emoji}, payload) | |
| end | |
| msg.remove_reaction(emoji) | |
| end | |
| describe 'errors' do | |
| let(:expected_error) { 'invalid_name' } | |
| it 'should raise an error if api call fails' do | |
| RestClient.expects(:post).returns(bad_response.to_json) | |
| assert_raises Slack::ApiClient::Error, expected_error do | |
| msg.remove_reaction(emoji) | |
| end | |
| end | |
| describe 'specific error' do | |
| let(:expected_error) { 'no_reaction' } | |
| it 'should not raise on specific errors' do | |
| RestClient.expects(:post).returns(bad_response.to_json) | |
| msg.remove_reaction(emoji) | |
| end | |
| end | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment