diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c25ec13 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +CHATWORK_API_TOKEN= +CHATWORK_ACCESS_TOKEN= +CHATWORK_CLIENT_ID= +CHATWORK_CLIENT_SECRET= diff --git a/.gitignore b/.gitignore index adb50aa..937c612 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ test/version_tmp tmp .ruby-gemset .ruby-version +.env diff --git a/README.md b/README.md index 5e5cea9..63b0d8c 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,14 @@ ChatWork::Message.create(room_id: 1234, body: "Hello, ChatWork!") $ CHATWORK_CLIENT_ID=xxx CHATWORK_CLIENT_SECRET=xxx REFRESH_TOKEN=xxx ruby refresh_access_token.rb ``` +## Development +```bash +cp .env.example .env +vi .env + +./bin/console +``` + ## Contributing 1. Fork it diff --git a/bin/console b/bin/console new file mode 100755 index 0000000..1bad6ee --- /dev/null +++ b/bin/console @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "chatwork" +require "dotenv" + +Dotenv.load + +require "pry" +Pry.start diff --git a/chatwork.gemspec b/chatwork.gemspec index f0f14e0..b70a4d2 100644 --- a/chatwork.gemspec +++ b/chatwork.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |spec| spec.license = "MIT" spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR) - spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] @@ -22,11 +22,13 @@ Gem::Specification.new do |spec| spec.add_development_dependency "activesupport" spec.add_development_dependency "bundler", "~> 1.3" spec.add_development_dependency "coveralls" + spec.add_development_dependency "dotenv" spec.add_development_dependency "onkcop", "0.52.1.0" spec.add_development_dependency "pry-byebug" spec.add_development_dependency "rake" spec.add_development_dependency "rspec" spec.add_development_dependency "rspec-its" + spec.add_development_dependency "rspec-parameterized" spec.add_development_dependency "rubocop", "0.52.1" spec.add_development_dependency "rubocop-rspec", "1.21.0" spec.add_development_dependency "webmock" diff --git a/lib/chatwork.rb b/lib/chatwork.rb index f1448b2..f813c33 100644 --- a/lib/chatwork.rb +++ b/lib/chatwork.rb @@ -7,13 +7,15 @@ module ChatWork autoload :ChatWorkError, "chatwork/chatwork_error" autoload :Client, "chatwork/client" autoload :Contacts, "chatwork/contacts" - autoload :Entity, "chatwork/entity" + autoload :EntityMethods, "chatwork/entity_methods" + autoload :File, "chatwork/file" + autoload :IncomingRequest, "chatwork/incoming_request" autoload :Me, "chatwork/me" autoload :Member, "chatwork/member" autoload :Message, "chatwork/message" + autoload :MyStatus, "chatwork/my_status" autoload :MyTask, "chatwork/my_task" autoload :OAuthClient, "chatwork/oauth_client" - autoload :Operations, "chatwork/operations" autoload :Room, "chatwork/room" autoload :Task, "chatwork/task" autoload :Token, "chatwork/token" diff --git a/lib/chatwork/base_client.rb b/lib/chatwork/base_client.rb index bea92b5..aad01fe 100644 --- a/lib/chatwork/base_client.rb +++ b/lib/chatwork/base_client.rb @@ -20,7 +20,8 @@ def initialize(api_base, api_version, header) def handle_response(response) case response.status when 204 - ChatWork::ChatWorkError.from_response(response.status, response.body, response.headers) + # HTTP status 204 doesn't return json + response.body when 200..299 begin JSON.parse(response.body) diff --git a/lib/chatwork/chatwork_error.rb b/lib/chatwork/chatwork_error.rb index 3ece01f..ec56e8c 100644 --- a/lib/chatwork/chatwork_error.rb +++ b/lib/chatwork/chatwork_error.rb @@ -2,9 +2,6 @@ module ChatWork class ChatWorkError < StandardError def self.from_response(status, body, headers) - # HTTP status 204 don't have body. - return APIError.new(status, "") if status == 204 - hash = begin JSON.parse(body) diff --git a/lib/chatwork/contacts.rb b/lib/chatwork/contacts.rb index af49c4d..de6ce93 100644 --- a/lib/chatwork/contacts.rb +++ b/lib/chatwork/contacts.rb @@ -1,10 +1,11 @@ module ChatWork - class Contacts < Entity - install_class_operations :_get + module Contacts + extend EntityMethods # Get the list of your contacts # # @see http://developer.chatwork.com/ja/endpoint_contacts.html#GET-contacts + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @return [Array] # @@ -22,15 +23,7 @@ class Contacts < Entity # } # ] def self.get - _get - end - - def self.path - "/contacts" - end - - def path - "/contacts" + _get("/contacts") end end end diff --git a/lib/chatwork/entity.rb b/lib/chatwork/entity.rb deleted file mode 100644 index 9ccee99..0000000 --- a/lib/chatwork/entity.rb +++ /dev/null @@ -1,33 +0,0 @@ -module ChatWork - class Entity - class << self - include Operations - def convert(hash) - # not implement - # converter = ResponseConverter.new - # converter.convert(hash) - hash - end - - def hash_compact(hash) - hash.reject { |_k, v| v.nil? } - end - end - - attr_reader :attributes - - def initialize(attributes) - @attributes = attributes - end - - private - - # not implement - def update_attributes(attributes) - raise "unexpected object" if attributes["object"] != @attributes["object"] - new_object = ResponseConverter.new.convert(attributes) - @attributes = new_object.attributes - self - end - end -end diff --git a/lib/chatwork/entity_methods.rb b/lib/chatwork/entity_methods.rb new file mode 100644 index 0000000..91db6aa --- /dev/null +++ b/lib/chatwork/entity_methods.rb @@ -0,0 +1,36 @@ +module ChatWork + module EntityMethods + private + + def _get(path, params = {}, &block) + ChatWork.client.get(path, hash_compact(params), &block) + end + + def _post(path, params = {}, &block) + ChatWork.client.post(path, hash_compact(params), &block) + end + + def _put(path, params = {}, &block) + ChatWork.client.put(path, hash_compact(params), &block) + end + + def _delete(path, params = {}, &block) + ChatWork.client.delete(path, hash_compact(params), &block) + end + + def hash_compact(hash) + hash.reject { |_k, v| v.nil? } + end + + def boolean_to_integer(value) + case value + when true + 1 + when false + 0 + else + value + end + end + end +end diff --git a/lib/chatwork/file.rb b/lib/chatwork/file.rb new file mode 100644 index 0000000..0755824 --- /dev/null +++ b/lib/chatwork/file.rb @@ -0,0 +1,63 @@ +module ChatWork + module File + extend EntityMethods + + # Get the list of files associated with the specified chat + # + # @param room_id [Integer] + # @param account_id [Integer] + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms-room_id-files + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @return [Array] + # + # @example response format + # [ + # { + # "file_id": 3, + # "account": { + # "account_id": 123, + # "name": "Bob", + # "avatar_image_url": "https://example.com/ico_avatar.png" + # }, + # "message_id": "22", + # "filename": "README.md", + # "filesize": 2232, + # "upload_time": 1384414750 + # } + # ] + def self.get(room_id:, account_id:) + _get("/rooms/#{room_id}/files", account_id: account_id) + end + + # Get information about the specified file + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms-room_id-files-file_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param file_id [Integer] + # @param create_download_url [Boolean] whether or not to create a download link. + # If set to true, download like will be created for 30 seconds + # + # @return [Array] + # + # @example response format + # { + # "file_id":3, + # "account": { + # "account_id":123, + # "name":"Bob", + # "avatar_image_url": "https://example.com/ico_avatar.png" + # }, + # "message_id": "22", + # "filename": "README.md", + # "filesize": 2232, + # "upload_time": 1384414750 + # } + def self.find(room_id:, file_id:, create_download_url: nil) + _get("/rooms/#{room_id}/files/#{file_id}", create_download_url: boolean_to_integer(create_download_url)) + end + end +end diff --git a/lib/chatwork/incoming_request.rb b/lib/chatwork/incoming_request.rb new file mode 100644 index 0000000..c9f16e3 --- /dev/null +++ b/lib/chatwork/incoming_request.rb @@ -0,0 +1,71 @@ +module ChatWork + module IncomingRequest + extend EntityMethods + + # You can get the list of contact approval request you received + # + # (*This method returns up to 100 entries. We are planning to implement pagination to support larger number of data retrieval) + # + # @see http://developer.chatwork.com/ja/endpoint_incoming_requests.html#GET-incoming_requests + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @return [Array] + # + # @example response format + # [ + # { + # "request_id": 123, + # "account_id": 363, + # "message": "hogehoge", + # "name": "John Smith", + # "chatwork_id": "tarochatworkid", + # "organization_id": 101, + # "organization_name": "Hello Company", + # "department": "Marketing", + # "avatar_image_url": "https://example.com/abc.png" + # } + # ] + def self.get + _get("/incoming_requests") + end + + # You can approve a contact approval request you received + # + # @see http://developer.chatwork.com/ja/endpoint_incoming_requests.html#PUT-incoming_requests-request_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param request_id [Integer] + # + # @return [Hash] + # + # @example response format + # { + # "account_id": 363, + # "room_id": 1234, + # "name": "John Smith", + # "chatwork_id": "tarochatworkid", + # "organization_id": 101, + # "organization_name": "Hello Company", + # "department": "Marketing", + # "avatar_image_url": "https://example.com/abc.png" + # } + def self.update(request_id:) + _put("/incoming_requests/#{request_id}") + end + + # You can decline a contact approval request you received + # + # @see http://developer.chatwork.com/ja/endpoint_incoming_requests.html#DELETE-incoming_requests-request_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param request_id [Integer] + def self.destroy(request_id:) + _delete("/incoming_requests/#{request_id}") + end + + class << self + alias_method :approve, :update + alias_method :decline, :destroy + end + end +end diff --git a/lib/chatwork/me.rb b/lib/chatwork/me.rb index dbedba5..c7b57bb 100644 --- a/lib/chatwork/me.rb +++ b/lib/chatwork/me.rb @@ -1,10 +1,11 @@ module ChatWork - class Me < Entity - install_class_operations :_get + module Me + extend EntityMethods # Get your account information # # @see http://developer.chatwork.com/ja/endpoint_me.html#GET-me + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @return [Hash] # @@ -31,15 +32,7 @@ class Me < Entity # "login_mail": "account@example.com" # } def self.get - _get - end - - def self.path - "/me" - end - - def path - "/me" + _get("/me") end end end diff --git a/lib/chatwork/member.rb b/lib/chatwork/member.rb index 03ff70f..c580ea9 100644 --- a/lib/chatwork/member.rb +++ b/lib/chatwork/member.rb @@ -1,10 +1,11 @@ module ChatWork - class Member < Entity - install_class_operations :_get + module Member + extend EntityMethods # Get the list of all chat members associated with the specified chat # # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms-room_id-members + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @param room_id [Integer] # @@ -24,11 +25,36 @@ class Member < Entity # } # ] def self.get(room_id:) - _get(room_id: room_id) + _get("/rooms/#{room_id}/members") end - def self.path - "/rooms/%d/members" + # Change associated members of group chat at once + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#PUT-rooms-room_id-members + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param members_admin_ids [Array, String] List of user IDs who will be given administrator permission for the group chat. + # At least one user must be specified as an administrator. + # @param members_member_ids [Array, String] List of user IDs who will be given member permission for the group chat. + # @param members_readonly_ids [Array, String] List of user IDs who will be given read-only permission for the group chat. + # + # @return [Hash] + # + # @example response format + # { + # "admin": [123, 542, 1001], + # "member": [10, 103], + # "readonly": [6, 11] + # } + def self.update_all(room_id:, members_admin_ids:, members_member_ids: nil, members_readonly_ids: nil) + params = { + members_admin_ids: Array(members_admin_ids).join(","), + } + params[:members_member_ids] = Array(members_member_ids).join(",") if members_member_ids + params[:members_readonly_ids] = Array(members_readonly_ids).join(",") if members_readonly_ids + + _put("/rooms/#{room_id}/members", params) end end end diff --git a/lib/chatwork/message.rb b/lib/chatwork/message.rb index c9bf857..264b34d 100644 --- a/lib/chatwork/message.rb +++ b/lib/chatwork/message.rb @@ -1,12 +1,13 @@ module ChatWork - class Message < Entity - install_class_operations :_create, :_get + module Message + extend EntityMethods # Get all messages associated with the specified chat (returns up to 100 entries). # # If the parameter is not set, it returns the next 100 entries from previous call. # # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms-room_id-messages + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @param room_id [Integer] # @param force [Boolean, Integer] Flag which forces to get 100 newest entries regardless of previous calls. @@ -28,21 +29,13 @@ class Message < Entity # } # ] def self.get(room_id:, force: nil) - params = { room_id: room_id } - - case force - when 1, true - params[:force] = 1 - when 0, false - params[:force] = 0 - end - - _get(params) + _get("/rooms/#{room_id}/messages", force: boolean_to_integer(force)) end # Add new message to the chat # # @see http://developer.chatwork.com/ja/endpoint_rooms.html#POST-rooms-room_id-messages + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @param room_id [Integer] # @param body [String] message body @@ -54,15 +47,108 @@ def self.get(room_id:, force: nil) # "message_id": "1234" # } def self.create(room_id:, body:) - _create(room_id: room_id, body: body) + _post("/rooms/#{room_id}/messages", body: body) + end + + # Mark messages as read + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#PUT-rooms-room_id-messages-read + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param message_id [String] + # + # @return [Hash] + # + # @example response format + # { + # "unread_num": 461, + # "mention_num": 0 + # } + def self.read(room_id:, message_id: nil) + _put("/rooms/#{room_id}/messages/read", message_id: message_id) end - def self.path - "/rooms/%d/messages" + # Mark messages as unread + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#PUT-rooms-room_id-messages-unread + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param message_id [String] + # + # @return [Hash] + # + # @example response format + # { + # "unread_num": 3, + # "mention_num": 0 + # } + def self.unread(room_id:, message_id:) + _put("/rooms/#{room_id}/messages/unread", message_id: message_id) end - def path - "/rooms/%d/messages" + # Get information about the specified message + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms-room_id-messages-message_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param message_id [String] + # + # @return [Hash] + # + # @example response format + # { + # "message_id": "5", + # "account": { + # "account_id": 123, + # "name": "Bob", + # "avatar_image_url": "https://example.com/ico_avatar.png" + # }, + # "body": "Hello Chatwork!", + # "send_time": 1384242850, + # "update_time": 0 + # } + def self.find(room_id:, message_id:) + _get("/rooms/#{room_id}/messages/#{message_id}") + end + + # Update the specified message + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#PUT-rooms-room_id-messages-message_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param message_id [String] + # @param body [String] message body + # + # @return [Hash] + # + # @example response format + # { + # "message_id": "1234" + # } + def self.update(room_id:, message_id:, body:) + _put("/rooms/#{room_id}/messages/#{message_id}", body: body) + end + + # Destroy the specified message + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#PUT-rooms-room_id-messages-message_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param message_id [String] + # + # @return [Hash] + # + # @example response format + # { + # "message_id": "1234" + # } + def self.destroy(room_id:, message_id:) + _delete("/rooms/#{room_id}/messages/#{message_id}") end end end diff --git a/lib/chatwork/my_status.rb b/lib/chatwork/my_status.rb new file mode 100644 index 0000000..3785a5f --- /dev/null +++ b/lib/chatwork/my_status.rb @@ -0,0 +1,25 @@ +module ChatWork + module MyStatus + extend EntityMethods + + # Get the number of: unread messages, unread To messages, and unfinished tasks. + # + # @see http://developer.chatwork.com/ja/endpoint_my.html#GET-my-status + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @return [Hash] + # + # @example response format + # { + # "unread_room_num": 2, + # "mention_room_num": 1, + # "mytask_room_num": 3, + # "unread_num": 12, + # "mention_num": 1, + # "mytask_num": 8 + # } + def self.get + _get("/my/status") + end + end +end diff --git a/lib/chatwork/my_task.rb b/lib/chatwork/my_task.rb index 45399c6..5097f37 100644 --- a/lib/chatwork/my_task.rb +++ b/lib/chatwork/my_task.rb @@ -1,12 +1,13 @@ module ChatWork - class MyTask < Entity - install_class_operations :_get + module MyTask + extend EntityMethods # Get the list of all unfinished tasks # # (*This method returns up to 100 entries. We are planning to implement pagination to support larger number of data retrieval) # # @see http://developer.chatwork.com/ja/endpoint_my.html#GET-my-tasks + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @param assigned_by_account_id [Integer] Account ID of the person who assigned task # @param status [String] Task status (open, done) @@ -34,20 +35,7 @@ class MyTask < Entity # } # ] def self.get(assigned_by_account_id: nil, status: nil) - params = { - assigned_by_account_id: assigned_by_account_id, - status: status, - } - - _get(hash_compact(params)) - end - - def self.path - "/my/tasks" - end - - def path - "/my/tasks" + _get("/my/tasks", assigned_by_account_id: assigned_by_account_id, status: status) end end end diff --git a/lib/chatwork/operations.rb b/lib/chatwork/operations.rb deleted file mode 100644 index f088e06..0000000 --- a/lib/chatwork/operations.rb +++ /dev/null @@ -1,49 +0,0 @@ -module ChatWork - module Operations - ACCEPT_PARAMS_ID = %i[file_id task_id message_id].freeze - - attr_accessor :assign_path - - def install_class_operations(*operations) - define_create if operations.include?(:_create) - define_get if operations.include?(:_get) - end - - def define_get - instance_eval do - def _get(params = {}, &block) - @assign_path = parse_if_hash_key_exists(path, params, :room_id) - attach_nested_resource_id(params) - convert(ChatWork.client.get(@assign_path, params, &block)) - end - end - end - - def define_create - instance_eval do - def _create(params = {}, &block) - @assign_path = parse_if_hash_key_exists(path, params, :room_id) - attach_nested_resource_id(params) - convert(ChatWork.client.post(@assign_path, params, &block)) - end - end - end - - private - - def parse_if_hash_key_exists(string, hash, key) - if hash.include?(key) - string % hash.delete(key) - else - string - end - end - - def attach_nested_resource_id(params) - ACCEPT_PARAMS_ID.each do |id_name| - next unless params.include? id_name - @assign_path += "/#{params.delete(id_name)}" - end - end - end -end diff --git a/lib/chatwork/room.rb b/lib/chatwork/room.rb index ed1dd8d..5244f2f 100644 --- a/lib/chatwork/room.rb +++ b/lib/chatwork/room.rb @@ -1,10 +1,11 @@ module ChatWork - class Room < Entity - install_class_operations :_create, :_get + module Room + extend EntityMethods # Get the list of all chats on your account # # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @return [Array] # @@ -27,7 +28,7 @@ class Room < Entity # } # ] def self.get - _get + _get("/rooms") end # rubocop:disable Metrics/ParameterLists @@ -35,6 +36,7 @@ def self.get # Create a new group chat # # @see http://developer.chatwork.com/ja/endpoint_rooms.html#POST-rooms + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @param description [String] Description of the group chat # @param icon_preset [String] Type of the group chat icon (group, check, document, meeting, event, project, business, @@ -61,17 +63,64 @@ def self.create(description: nil, icon_preset: nil, members_admin_ids:, members_ params[:members_member_ids] = Array(members_member_ids).join(",") if members_member_ids params[:members_readonly_ids] = Array(members_readonly_ids).join(",") if members_readonly_ids - _create(hash_compact(params)) + _post("/rooms", params) end # rubocop:enable Metrics/ParameterLists - def self.path - "/rooms" + # Get chat name, icon, and Type (my, direct, or group) + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms-room_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # + # @return [Hash] + # + # @example response format + # { + # "room_id": 123, + # "name": "Group Chat Name", + # "type": "group", + # "role": "admin", + # "sticky": false, + # "unread_num": 10, + # "mention_num": 1, + # "mytask_num": 0, + # "message_num": 122, + # "file_num": 10, + # "task_num": 17, + # "icon_path": "https://example.com/ico_group.png", + # "last_update_time": 1298905200, + # "description": "room description text" + # } + def self.find(room_id:) + _get("/rooms/#{room_id}") + end + + # Change the title and icon type of the specified chat + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#PUT-rooms-room_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param description [String] Description of the group chat + # @param icon_preset [String] Type of the group chat icon (group, check, document, meeting, event, project, business, + # study, security, star, idea, heart, magcup, beer, music, sports, travel) + # @param name [String] Title of the group chat. + def self.update(room_id:, description: nil, icon_preset: nil, name: nil) + _put("/rooms/#{room_id}", description: description, icon_preset: icon_preset, name: name) end - def path - "/rooms" + # Leave/Delete a group chat + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#DELETE-rooms-room_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param action_type [String] leave from a room or delete a room (leave, delete) + def self.destroy(room_id:, action_type:) + _delete("/rooms/#{room_id}", action_type: action_type) end end end diff --git a/lib/chatwork/task.rb b/lib/chatwork/task.rb index 3bc0860..b8569fe 100644 --- a/lib/chatwork/task.rb +++ b/lib/chatwork/task.rb @@ -1,14 +1,16 @@ module ChatWork - class Task < Entity - install_class_operations :_get, :_create + module Task + extend EntityMethods # Get the list of tasks associated with the specified chat # # (*This method returns up to 100 entries. We are planning to implement pagination to support larger number of data retrieval) # # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms-room_id-tasks + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @param room_id [Integer] + # @param account_id [Integer] # @param assigned_by_account_id [Integer] Account ID of the person who assigned task # @param status [String] Task status (open, done) # @@ -35,18 +37,13 @@ class Task < Entity # } # ] def self.get(room_id:, account_id:, assigned_by_account_id: nil, status: nil) - params = { - room_id: room_id, - account_id: account_id, - assigned_by_account_id: assigned_by_account_id, - status: status, - } - _get(hash_compact(params)) + _get("/rooms/#{room_id}/tasks", account_id: account_id, assigned_by_account_id: assigned_by_account_id, status: status) end # Add a new task to the chat # # @see http://developer.chatwork.com/ja/endpoint_rooms.html#POST-rooms-room_id-tasks + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf # # @param room_id [Integer] # @param body [String] Task description @@ -61,16 +58,44 @@ def self.get(room_id:, account_id:, assigned_by_account_id: nil, status: nil) # } def self.create(room_id:, body:, to_ids:, limit: nil) params = { - room_id: room_id, - body: body, - to_ids: Array(to_ids).join(","), + body: body, + to_ids: Array(to_ids).join(","), } params[:limit] = limit.to_i if limit - _create(hash_compact(params)) + + _post("/rooms/#{room_id}/tasks", params) end - def self.path - "/rooms/%d/tasks" + # Get information about the specified task + # + # @see http://developer.chatwork.com/ja/endpoint_rooms.html#GET-rooms-room_id-tasks-task_id + # @see http://download.chatwork.com/ChatWork_API_Documentation.pdf + # + # @param room_id [Integer] + # @param task_id [Integer] + # + # @return [Hash] + # + # @example response format + # { + # "task_id": 3, + # "account": { + # "account_id": 123, + # "name": "Bob", + # "avatar_image_url": "https://example.com/abc.png" + # }, + # "assigned_by_account": { + # "account_id": 456, + # "name": "Anna", + # "avatar_image_url": "https://example.com/def.png" + # }, + # "message_id": "13", + # "body": "buy milk", + # "limit_time": 1384354799, + # "status": "open" + # } + def self.find(room_id:, task_id:) + _get("/rooms/#{room_id}/tasks/#{task_id}") end end end diff --git a/lib/chatwork/token.rb b/lib/chatwork/token.rb index 87cc6d1..057ff09 100644 --- a/lib/chatwork/token.rb +++ b/lib/chatwork/token.rb @@ -1,5 +1,5 @@ module ChatWork - class Token + module Token # refresh access_token with refresh_token # # @param refresh_token [String] diff --git a/spec/lib/chatwork/entity_methods_spec.rb b/spec/lib/chatwork/entity_methods_spec.rb new file mode 100644 index 0000000..1e78b45 --- /dev/null +++ b/spec/lib/chatwork/entity_methods_spec.rb @@ -0,0 +1,21 @@ +describe ChatWork::EntityMethods do + include ChatWork::EntityMethods + + describe "#boolean_to_integer" do + subject { boolean_to_integer(value) } + + using RSpec::Parameterized::TableSyntax + + where(:value, :expected) do + false | 0 + true | 1 + 0 | 0 + 1 | 1 + nil | nil + end + + with_them do + it { should eq expected } + end + end +end diff --git a/spec/lib/chatwork/file_spec.rb b/spec/lib/chatwork/file_spec.rb new file mode 100644 index 0000000..f078d00 --- /dev/null +++ b/spec/lib/chatwork/file_spec.rb @@ -0,0 +1,37 @@ +describe ChatWork::File do + describe ".get", type: :api do + subject { ChatWork::File.get(room_id: room_id, account_id: account_id) } + + before do + stub_chatwork_request(:get, "/rooms/#{room_id}/files", "/rooms/{room_id}/files") + end + + let(:room_id) { 123 } + let(:account_id) { 101 } + + it_behaves_like :a_chatwork_api, :get, "/rooms/{room_id}/files" + end + + describe ".find", type: :api do + subject { ChatWork::File.find(room_id: room_id, file_id: file_id, create_download_url: create_download_url) } + + before do + stub_chatwork_request(:get, "/rooms/#{room_id}/files/#{file_id}", "/rooms/{room_id}/files/{file_id}") + end + + let(:room_id) { 123 } + let(:file_id) { 101 } + + context "when force is Integer" do + let(:create_download_url) { 1 } + + it_behaves_like :a_chatwork_api, :get, "/rooms/{room_id}/files/{file_id}" + end + + context "when force is boolean" do + let(:create_download_url) { true } + + it_behaves_like :a_chatwork_api, :get, "/rooms/{room_id}/files/{file_id}" + end + end +end diff --git a/spec/lib/chatwork/incoming_request_spec.rb b/spec/lib/chatwork/incoming_request_spec.rb new file mode 100644 index 0000000..e4926b6 --- /dev/null +++ b/spec/lib/chatwork/incoming_request_spec.rb @@ -0,0 +1,35 @@ +describe ChatWork::IncomingRequest do + describe ".get", type: :api do + subject { ChatWork::IncomingRequest.get } + + before do + stub_chatwork_request(:get, "/incoming_requests") + end + + it_behaves_like :a_chatwork_api, :get, "/incoming_requests" + end + + describe ".update", type: :api do + subject { ChatWork::IncomingRequest.update(request_id: request_id) } + + let(:request_id) { 123 } + + before do + stub_chatwork_request(:put, "/incoming_requests/#{request_id}", "/incoming_requests/{request_id}") + end + + it_behaves_like :a_chatwork_api, :put, "/incoming_requests/{request_id}" + end + + describe ".destroy", type: :api do + subject { ChatWork::IncomingRequest.destroy(request_id: request_id) } + + let(:request_id) { 123 } + + before do + stub_chatwork_request(:delete, "/incoming_requests/#{request_id}", "/incoming_requests/{request_id}", 204) + end + + it_behaves_like :a_chatwork_api, :delete, "/incoming_requests/{request_id}", 204 + end +end diff --git a/spec/lib/chatwork/member_spec.rb b/spec/lib/chatwork/member_spec.rb index 7caeb7e..34405d4 100644 --- a/spec/lib/chatwork/member_spec.rb +++ b/spec/lib/chatwork/member_spec.rb @@ -10,4 +10,37 @@ it_behaves_like :a_chatwork_api, :get, "/rooms/{room_id}/members" end + + describe ".update_all", type: :api do + subject do + ChatWork::Member.update_all( + room_id: room_id, + members_admin_ids: members_admin_ids, + members_member_ids: members_member_ids, + members_readonly_ids: members_readonly_ids, + ) + end + + let(:room_id) { 123 } + + before do + stub_chatwork_request(:put, "/rooms/#{room_id}/members", "/rooms/{room_id}/members") + end + + context "with String" do + let(:members_admin_ids) { "123,542,1001" } + let(:members_member_ids) { "21,344" } + let(:members_readonly_ids) { "15,103" } + + it_behaves_like :a_chatwork_api, :put, "/rooms/{room_id}/members" + end + + context "with Array" do + let(:members_admin_ids) { [123, 542, 1001] } + let(:members_member_ids) { [21, 344] } + let(:members_readonly_ids) { [15, 103] } + + it_behaves_like :a_chatwork_api, :put, "/rooms/{room_id}/members" + end + end end diff --git a/spec/lib/chatwork/message_spec.rb b/spec/lib/chatwork/message_spec.rb index 1e3d6cc..6d5783a 100644 --- a/spec/lib/chatwork/message_spec.rb +++ b/spec/lib/chatwork/message_spec.rb @@ -33,4 +33,70 @@ it_behaves_like :a_chatwork_api, :post, "/rooms/{room_id}/messages" end + + describe ".read", type: :api do + subject { ChatWork::Message.read(room_id: room_id, message_id: message_id) } + + let(:room_id) { 123 } + let(:message_id) { "101" } + + before do + stub_chatwork_request(:put, "/rooms/#{room_id}/messages/read", "/rooms/{room_id}/messages/read") + end + + it_behaves_like :a_chatwork_api, :put, "/rooms/{room_id}/messages/read" + end + + describe ".unread", type: :api do + subject { ChatWork::Message.unread(room_id: room_id, message_id: message_id) } + + let(:room_id) { 123 } + let(:message_id) { "101" } + + before do + stub_chatwork_request(:put, "/rooms/#{room_id}/messages/unread", "/rooms/{room_id}/messages/unread") + end + + it_behaves_like :a_chatwork_api, :put, "/rooms/{room_id}/messages/unread" + end + + describe ".find", type: :api do + subject { ChatWork::Message.find(room_id: room_id, message_id: message_id) } + + let(:room_id) { 123 } + let(:message_id) { "101" } + + before do + stub_chatwork_request(:get, "/rooms/#{room_id}/messages/#{message_id}", "/rooms/{room_id}/messages/{message_id}") + end + + it_behaves_like :a_chatwork_api, :get, "/rooms/{room_id}/messages/{message_id}" + end + + describe ".update", type: :api do + subject { ChatWork::Message.update(room_id: room_id, message_id: message_id, body: body) } + + let(:room_id) { 123 } + let(:message_id) { "101" } + let(:body) { "Hello ChatWork!" } + + before do + stub_chatwork_request(:put, "/rooms/#{room_id}/messages/#{message_id}", "/rooms/{room_id}/messages/{message_id}") + end + + it_behaves_like :a_chatwork_api, :put, "/rooms/{room_id}/messages/{message_id}" + end + + describe ".destroy", type: :api do + subject { ChatWork::Message.destroy(room_id: room_id, message_id: message_id) } + + let(:room_id) { 123 } + let(:message_id) { "101" } + + before do + stub_chatwork_request(:delete, "/rooms/#{room_id}/messages/#{message_id}", "/rooms/{room_id}/messages/{message_id}") + end + + it_behaves_like :a_chatwork_api, :delete, "/rooms/{room_id}/messages/{message_id}" + end end diff --git a/spec/lib/chatwork/my_status_spec.rb b/spec/lib/chatwork/my_status_spec.rb new file mode 100644 index 0000000..630cf9d --- /dev/null +++ b/spec/lib/chatwork/my_status_spec.rb @@ -0,0 +1,13 @@ +describe ChatWork::MyStatus do + describe ".get", type: :api do + subject do + ChatWork::MyStatus.get + end + + before do + stub_chatwork_request(:get, "/my/status") + end + + it_behaves_like :a_chatwork_api, :get, "/my/status" + end +end diff --git a/spec/lib/chatwork/room_spec.rb b/spec/lib/chatwork/room_spec.rb index 792a11f..3cd7997 100644 --- a/spec/lib/chatwork/room_spec.rb +++ b/spec/lib/chatwork/room_spec.rb @@ -47,4 +47,56 @@ it_behaves_like :a_chatwork_api, :post, "/rooms" end end + + describe ".find", type: :api do + subject { ChatWork::Room.find(room_id: room_id) } + + let(:room_id) { 123 } + + before do + stub_chatwork_request(:get, "/rooms/#{room_id}", "/rooms/{room_id}") + end + + it_behaves_like :a_chatwork_api, :get, "/rooms/{room_id}" + end + + describe ".update", type: :api do + subject do + ChatWork::Room.update( + room_id: room_id, + description: description, + icon_preset: icon_preset, + name: name, + ) + end + + let(:room_id) { 123 } + let(:description) { "group chat description" } + let(:icon_preset) { "meeting" } + let(:name) { "Website renewal project" } + + before do + stub_chatwork_request(:put, "/rooms/#{room_id}", "/rooms/{room_id}") + end + + it_behaves_like :a_chatwork_api, :put, "/rooms/{room_id}" + end + + describe ".destroy", type: :api do + subject do + ChatWork::Room.destroy( + room_id: room_id, + action_type: action_type, + ) + end + + let(:room_id) { 123 } + let(:action_type) { "leave" } + + before do + stub_chatwork_request(:delete, "/rooms/#{room_id}", "/rooms/{room_id}", 204) + end + + it_behaves_like :a_chatwork_api, :delete, "/rooms/{room_id}", 204 + end end diff --git a/spec/lib/chatwork/task_spec.rb b/spec/lib/chatwork/task_spec.rb index cd9cb2f..1b39c49 100644 --- a/spec/lib/chatwork/task_spec.rb +++ b/spec/lib/chatwork/task_spec.rb @@ -56,4 +56,22 @@ it_behaves_like :a_chatwork_api, :post, "/rooms/{room_id}/tasks" end end + + describe ".find", type: :api do + subject do + ChatWork::Task.find( + room_id: room_id, + task_id: task_id, + ) + end + + let(:room_id) { 123 } + let(:task_id) { 3 } + + before do + stub_chatwork_request(:get, "/rooms/#{room_id}/tasks/#{task_id}", "/rooms/{room_id}/tasks/{task_id}") + end + + it_behaves_like :a_chatwork_api, :get, "/rooms/{room_id}/tasks/{task_id}" + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ef678e1..02d9c9d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,6 +7,7 @@ require "chatwork" +require "rspec-parameterized" require "rspec/its" require "webmock/rspec" require "pry" diff --git a/spec/support/contexts/api_context.rb b/spec/support/contexts/api_context.rb index 81abb9b..8e05441 100644 --- a/spec/support/contexts/api_context.rb +++ b/spec/support/contexts/api_context.rb @@ -28,7 +28,7 @@ def stub_chatwork_request(expected_verb, expected_path, resource_path = nil, sta query_example = RamlParser.find_query_parameter_example(expected_verb, resource_path) unless query_example.empty? case expected_verb - when :get + when :get, :delete query_string = "?" + query_example.to_query when :post, :put request_options[:headers]["Content-Type"] = "application/x-www-form-urlencoded" diff --git a/spec/support/matchers/match_example.rb b/spec/support/matchers/match_example.rb index e3c4c08..5882c86 100644 --- a/spec/support/matchers/match_example.rb +++ b/spec/support/matchers/match_example.rb @@ -8,6 +8,6 @@ description do expected_example = RamlParser.find_response_example(verb, resource, status) - "match #{expected_example}" + "match '#{expected_example}'" end end diff --git a/spec/support/utils/raml_parser.rb b/spec/support/utils/raml_parser.rb index 750aa0b..0d36bd0 100644 --- a/spec/support/utils/raml_parser.rb +++ b/spec/support/utils/raml_parser.rb @@ -10,7 +10,7 @@ def self.find_response_example(verb, path, status = 200) return nil unless resource response_json = resource.dig("responses", status, "body", "application/json", "example") - return JSON.parse(response_json) if response_json + return parse_response(response_json) if response_json return nil unless resource["is"] @@ -19,7 +19,7 @@ def self.find_response_example(verb, path, status = 200) next unless trait response_json = trait.dig("responses", status, "body", "application/json", "example") - return JSON.parse(response_json) if response_json + return parse_response(response_json) if response_json end nil @@ -76,4 +76,11 @@ def self.raml @raml = YAML.safe_load(yaml_data) end + + def self.parse_response(response_json) + JSON.parse(response_json) + rescue JSON::ParserError + response_json + end + private_class_method :parse_response end