monday_ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bd002aba608dc2f94d8203eee88629ff3185e305e09096ac6206e650b2b6f54f
4
+ data.tar.gz: b2abc595ac065fad70b823917f063cd8ffd1088c736b38ba18c5417272d6a8ae
5
+ SHA512:
6
+ metadata.gz: ab592952c05ad6fcf5c7cc2ae78039939daa46f0f7bac2cc8460e66566d6da05a123c0a9bc23cbae993cd1df6122be275528d12bf87c114bc46bb88fc094e554
7
+ data.tar.gz: 198556d5abce107ec8109f4b32eee408b618ccea654dbe45f3b0016b71f1be0a9440114aba607a6fdb49009c14f8b49607fd161dbeb246e70dea0f5237a34744
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,18 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+ NewCops: enable
4
+
5
+ Style/StringLiterals:
6
+ Enabled: true
7
+ EnforcedStyle: double_quotes
8
+
9
+ Style/StringLiteralsInInterpolation:
10
+ Enabled: true
11
+ EnforcedStyle: double_quotes
12
+
13
+ Layout/LineLength:
14
+ Max: 120
15
+
16
+ Metrics/BlockLength:
17
+ Exclude:
18
+ - "spec/**/*_spec.rb"
@@ -0,0 +1,4 @@
1
+ {
2
+ "ruby.rubocop.configFilePath": ".rubocop.yml",
3
+ "files.trimTrailingWhitespace": true
4
+ }
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.1.0 (June 28, 2023)
2
+
3
+ - Initial release
@@ -0,0 +1,84 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment for our community include:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17
+ * Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behavior include:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or
22
+ advances of any kind
23
+ * Trolling, insulting or derogatory comments, and personal or political attacks
24
+ * Public or private harassment
25
+ * Publishing others' private information, such as a physical or email
26
+ address, without their explicit permission
27
+ * Other conduct which could reasonably be considered inappropriate in a
28
+ professional setting
29
+
30
+ ## Enforcement Responsibilities
31
+
32
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
33
+
34
+ Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
35
+
36
+ ## Scope
37
+
38
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
39
+
40
+ ## Enforcement
41
+
42
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at sanifhimani92@gmail.com. All complaints will be reviewed and investigated promptly and fairly.
43
+
44
+ All community leaders are obligated to respect the privacy and security of the reporter of any incident.
45
+
46
+ ## Enforcement Guidelines
47
+
48
+ Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
49
+
50
+ ### 1. Correction
51
+
52
+ **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
53
+
54
+ **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
55
+
56
+ ### 2. Warning
57
+
58
+ **Community Impact**: A violation through a single incident or series of actions.
59
+
60
+ **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
61
+
62
+ ### 3. Temporary Ban
63
+
64
+ **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
65
+
66
+ **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
67
+
68
+ ### 4. Permanent Ban
69
+
70
+ **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
71
+
72
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
73
+
74
+ ## Attribution
75
+
76
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
77
+ available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
78
+
79
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
80
+
81
+ [homepage]: https://www.contributor-covenant.org
82
+
83
+ For answers to common questions about this code of conduct, see the FAQ at
84
+ https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Sanif Himani
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # Monday API Library for Ruby
2
+
3
+ ![Build Status](https://github.com/sanifhimani/monday_ruby/actions/workflows/ci.yml/badge.svg)
4
+
5
+ This library provides convenient access to the Monday.com API from the application written in the Ruby language. It includes a pre-defined set of actions for the API resources.
6
+
7
+ **Visit https://monday-ruby.gitbook.io/docs/ for detailed documentation on how to use the library.**
8
+
9
+ ## Installation
10
+
11
+ You don't need the source code unless you want to modify the gem. If you want to use the package, run:
12
+
13
+ ```sh
14
+ gem install monday_ruby
15
+ ```
16
+
17
+ If you want to build the gem from source:
18
+
19
+ ```sh
20
+ gem build monday_ruby.gemspec
21
+ ```
22
+
23
+ ### Requirements
24
+
25
+ * Ruby 2.6+
26
+
27
+ ### Bundler
28
+
29
+ If you are installing via bundler, you should be sure to use the https rubygems source in your Gemfile, as any gems fetched over http could potentially be compromised in transit and alter the code of gems fetched securely over https:
30
+
31
+ ```ruby
32
+ source "https://rubygems.org"
33
+
34
+ gem "monday_ruby"
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ ***Complete list of actions along with examples are provided [here](https://monday-ruby.gitbook.io/docs/).***
40
+
41
+ The library needs to be configured with your account's authentication token which is available on the Admin tab on monday.com. Elaborate documentation can be found [here](https://developer.monday.com/api-reference/docs/authentication).
42
+
43
+ ```ruby
44
+ require "monday_ruby"
45
+
46
+ client = Monday::Client.new(token: "<AUTH_TOKEN>")
47
+ ```
48
+
49
+ ### Accessing a response object
50
+
51
+ Get access to response objects by initializing a client and using the appropriate action you want to perform:
52
+
53
+ ```ruby
54
+ client = Monday::Client.new(token: "<AUTH_TOKEN>")
55
+ response = client.boards
56
+
57
+ puts response.body
58
+ ```
59
+
60
+ ### Use cases
61
+
62
+ Here are some common uses cases for the API client.
63
+
64
+ #### Fetching all the boards
65
+
66
+ Initialize the client with the auth token and call the `boards` action.
67
+
68
+ ```ruby
69
+ client = Monday::Client.new(token: <AUTH_TOKEN>)
70
+
71
+ response = client.boards
72
+ # => <Monday::Response ...>
73
+
74
+ # To check if the request was successful
75
+ response.success?
76
+ # => true
77
+
78
+ # To get the boards from the response
79
+ response.dig("data", "boards")
80
+ # => [...]
81
+ ```
82
+
83
+ #### Creating a new board
84
+
85
+ Initialize the client with the auth token and call the `create_board` action.
86
+
87
+ ```ruby
88
+ client = Monday::Client.new(token: <AUTH_TOKEN>)
89
+
90
+ args = {
91
+ board_name: "Test board",
92
+ board_kind: "public",
93
+ description: "Test board description"
94
+ }
95
+
96
+ response = client.create_board(args: args)
97
+ # => <Monday::Response ...>
98
+
99
+ # To check if the request was successful
100
+ response.success?
101
+ # => true
102
+
103
+ # To get the created board from the response
104
+ response.dig("data", "create_board")
105
+ # => { ... }
106
+ ```
107
+
108
+ #### Creating a new item on board
109
+
110
+ Initialize the client with the auth token and call the `create_item` action.
111
+
112
+ ```ruby
113
+ client = Monday::Client.new(token: <AUTH_TOKEN>)
114
+
115
+ args = {
116
+ board_id: <BOARD_ID>,
117
+ item_name: "New item",
118
+ column_values: {
119
+ status: {
120
+ label: "Working on it"
121
+ },
122
+ keywords: {
123
+ labels: ["Tech team", "DevOps team"]
124
+ }
125
+ }
126
+ }
127
+
128
+ response = client.create_item(args: args)
129
+ # => <Monday::Response ...>
130
+
131
+ # To check if the request was successful
132
+ response.success?
133
+ # => true
134
+
135
+ # To get the created item from the response
136
+ response.dig("data", "create_item")
137
+ # => { ... }
138
+ ```
139
+
140
+ ## Development
141
+
142
+ Run all tests:
143
+
144
+ ```sh
145
+ bundle exec rake spec
146
+ ```
147
+
148
+ Run linter:
149
+
150
+ ```sh
151
+ bundle exec rake rubocop
152
+ ```
153
+
154
+ ## Contributing
155
+
156
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sanifhimani/monday_ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/sanifhimani/monday_ruby/blob/main/CODE_OF_CONDUCT.md).
157
+
158
+ ## License
159
+
160
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ RuboCop::RakeTask.new
10
+
11
+ task default: %i[spec rubocop]
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+ require "net/http"
5
+ require "json"
6
+
7
+ require_relative "configuration"
8
+ require_relative "request"
9
+ require_relative "response"
10
+ require_relative "resources"
11
+ require_relative "util"
12
+
13
+ module Monday
14
+ # Client executes requests against the Monday.com API and
15
+ # allows a user to mutate and retrieve resources.
16
+ class Client
17
+ include Resources
18
+
19
+ JSON_CONTENT_TYPE = "application/json"
20
+ private_constant :JSON_CONTENT_TYPE
21
+
22
+ Monday::Configuration::CONFIGURATION_FIELDS.each do |config_key|
23
+ define_method(config_key) do
24
+ @config.public_send(config_key)
25
+ end
26
+ end
27
+
28
+ def initialize(config_args = {})
29
+ @config = Monday::Configuration.new(**config_args)
30
+ yield(@config) if block_given?
31
+ end
32
+
33
+ private
34
+
35
+ def uri
36
+ URI(@config.host)
37
+ end
38
+
39
+ def request_headers
40
+ {
41
+ "Content-Type": "application/json",
42
+ Authorization: @config.token
43
+ }
44
+ end
45
+
46
+ def make_request(body)
47
+ response = Monday::Request.post(uri, body, request_headers)
48
+ Monday::Response.new(response)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ # Encapsulates configuration for the Monday.com API.
5
+ #
6
+ # Configuration options:
7
+ #
8
+ # token: used to authenticate the requests
9
+ # host: defaults to https://api.monday.com/v2
10
+ class Configuration
11
+ DEFAULT_HOST = "https://api.monday.com/v2"
12
+ private_constant :DEFAULT_HOST
13
+
14
+ CONFIGURATION_FIELDS = %i[
15
+ token
16
+ host
17
+ ].freeze
18
+
19
+ attr_accessor(*CONFIGURATION_FIELDS)
20
+
21
+ def initialize(**config_args)
22
+ invalid_keys = config_args.keys - CONFIGURATION_FIELDS
23
+ raise ArgumentError, "Unknown arguments: #{invalid_keys}" unless invalid_keys.empty?
24
+
25
+ @host = DEFAULT_HOST
26
+
27
+ config_args.each do |key, value|
28
+ public_send("#{key}=", value)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ # Defines the HTTP request methods.
5
+ class Request
6
+ # Performs a POST request
7
+ def self.post(uri, query, headers)
8
+ http = Net::HTTP.new(uri.host, uri.port)
9
+ http.use_ssl = true
10
+ request = Net::HTTP::Post.new(uri.request_uri, headers)
11
+
12
+ request.body = {
13
+ "query" => query
14
+ }.to_json
15
+
16
+ http.request(request)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ module Resources
5
+ # Represents Monday.com's account resource.
6
+ module Account
7
+ DEFAULT_SELECT = %w[id name].freeze
8
+
9
+ # Retrieves the users account.
10
+ #
11
+ # Allows customizing the values to retrieve using the select option.
12
+ # By default, ID and name are retrieved.
13
+ def account(select: DEFAULT_SELECT)
14
+ query = "query { users { account {#{Util.format_select(select)}}}}"
15
+
16
+ make_request(query)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ module Resources
5
+ # Represents Monday.com's activity log resource.
6
+ module ActivityLog
7
+ DEFAULT_SELECT = %w[id event data].freeze
8
+
9
+ # Retrieves the activity logs for boards.
10
+ #
11
+ # Requires board_ids to retrieve the logs.
12
+ # Allows filtering activity logs using the args option.
13
+ # Allows customizing the values to retrieve using the select option.
14
+ # By default, ID, event and data are retrieved.
15
+ def activity_logs(board_ids, args: {}, select: DEFAULT_SELECT)
16
+ query = "query { boards(ids: #{board_ids}) " \
17
+ "{ activity_logs(#{Util.format_args(args)}) {#{Util.format_select(select)}}}}"
18
+
19
+ make_request(query)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ module Resources
5
+ # Represents Monday.com's board resource.
6
+ module Board
7
+ DEFAULT_SELECT = %w[id name description].freeze
8
+
9
+ # Retrieves all the boards.
10
+ #
11
+ # Allows filtering boards using the args option.
12
+ # Allows customizing the values to retrieve using the select option.
13
+ # By default, ID, name and description fields are retrieved.
14
+ def boards(args: {}, select: DEFAULT_SELECT)
15
+ query = "query { boards(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
16
+
17
+ make_request(query)
18
+ end
19
+
20
+ # Creates a new boards.
21
+ #
22
+ # Allows customizing creating a board using the args option.
23
+ # Allows customizing the values to retrieve using the select option.
24
+ # By default, ID, name and description fields are retrieved.
25
+ def create_board(args: {}, select: DEFAULT_SELECT)
26
+ query = "mutation { create_board(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
27
+
28
+ make_request(query)
29
+ end
30
+
31
+ # Duplicates a board.
32
+ #
33
+ # Allows customizing duplicating the board using the args option.
34
+ # Allows customizing the values to retrieve using the select option.
35
+ # By default, ID, name and description fields are retrieved.
36
+ def duplicate_board(args: {}, select: DEFAULT_SELECT)
37
+ query = "mutation { duplicate_board(#{Util.format_args(args)}) { board {#{Util.format_select(select)}}}}"
38
+
39
+ make_request(query)
40
+ end
41
+
42
+ # Updates a board.
43
+ #
44
+ # Allows customizing updating the board using the args option.
45
+ # Returns the ID of the updated board.
46
+ def update_board(args: {})
47
+ query = "mutation { update_board(#{Util.format_args(args)})}"
48
+
49
+ make_request(query)
50
+ end
51
+
52
+ # Archives a board.
53
+ #
54
+ # Requires board_id to archive board.
55
+ # Allows customizing the values to retrieve using the select option.
56
+ # By default, returns the ID of the board archived.
57
+ def archive_board(board_id, select: ["id"])
58
+ query = "mutation { archive_board(board_id: #{board_id}) {#{Util.format_select(select)}}}"
59
+
60
+ make_request(query)
61
+ end
62
+
63
+ # Deletes a board.
64
+ #
65
+ # Requires board_id to delete the board.
66
+ # Allows customizing the values to retrieve using the select option.
67
+ # By default, returns the ID of the board deleted.
68
+ def delete_board(board_id, select: ["id"])
69
+ query = "mutation { delete_board(board_id: #{board_id}) {#{Util.format_select(select)}}}"
70
+
71
+ make_request(query)
72
+ end
73
+
74
+ # Deletes the subscribers from a board.
75
+ #
76
+ # Requires board_id and user_ids to delete subscribers.
77
+ # Allows customizing the values to retrieve using the select option.
78
+ # By default, returns the deleted subscriber IDs.
79
+ def delete_board_subscribers(board_id, user_ids, select: ["id"])
80
+ query = "mutation { delete_subscribers_from_board(" \
81
+ "board_id: #{board_id}, user_ids: #{user_ids}) {#{Util.format_select(select)}}}"
82
+
83
+ make_request(query)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ module Resources
5
+ # Represents Monday.com's board view resource.
6
+ module BoardView
7
+ DEFAULT_SELECT = %w[id name type].freeze
8
+
9
+ # Retrieves board views from a specific board.
10
+ #
11
+ # Allows filtering views using the args option.
12
+ # Allows customizing the values to retrieve using the select option.
13
+ # By default, ID, name and type fields are retrieved.
14
+ def board_views(args: {}, select: DEFAULT_SELECT)
15
+ query = "query { boards(#{Util.format_args(args)}) { views {#{Util.format_select(select)}}}}"
16
+
17
+ make_request(query)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ module Resources
5
+ # Represents Monday.com's column resource.
6
+ module Column
7
+ DEFAULT_SELECT = %w[id title description].freeze
8
+
9
+ # Retrieves all the columns for the boards.
10
+ #
11
+ # Allows filtering columns using the args option.
12
+ # Allows customizing the values to retrieve using the select option.
13
+ # By default, ID, title and description fields are retrieved.
14
+ def columns(args: {}, select: DEFAULT_SELECT)
15
+ query = "query { boards(#{Util.format_args(args)}) { columns {#{Util.format_select(select)}}}}"
16
+
17
+ make_request(query)
18
+ end
19
+
20
+ # Retrieves metadata about one or a collection of columns.
21
+ #
22
+ # Optionally requires board ids and item ids to filter metadata for column values.
23
+ # Allows customizing the values to retrieve using the select option.
24
+ # By default, ID, title and description fields are retrieved.
25
+ def column_values(board_ids = [], item_ids = [], select: DEFAULT_SELECT)
26
+ board_args = board_ids.empty? ? "" : "ids: #{board_ids}"
27
+ item_args = item_ids.empty? ? "" : "ids: #{item_ids}"
28
+ query = "query { boards (#{board_args}) { items (#{item_args}) " \
29
+ "{ column_values {#{Util.format_select(select)}}}}}"
30
+
31
+ make_request(query)
32
+ end
33
+
34
+ # Creates a new column.
35
+ #
36
+ # Allows customizing the column creation using the args option.
37
+ # Allows customizing the values to retrieve using the select option.
38
+ # By default, ID, title and description fields are retrieved.
39
+ def create_column(args: {}, select: DEFAULT_SELECT)
40
+ query = "mutation { create_column(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
41
+
42
+ make_request(query)
43
+ end
44
+
45
+ # Updates the column title.
46
+ #
47
+ # Allows customizing the update using the args option.
48
+ # Allows customizing the values to retrieve using the select option.
49
+ # By default, ID, title and description fields are retrieved.
50
+ def change_column_title(args: {}, select: DEFAULT_SELECT)
51
+ query = "mutation { change_column_title(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
52
+
53
+ make_request(query)
54
+ end
55
+
56
+ # Updates the column metadata.
57
+ #
58
+ # Allows customizing the update using the args option.
59
+ # Allows customizing the values to retrieve using the select option.
60
+ # By default, ID, title and description fields are retrieved.
61
+ def change_column_metadata(args: {}, select: DEFAULT_SELECT)
62
+ query = "mutation { change_column_metadata(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
63
+
64
+ make_request(query)
65
+ end
66
+
67
+ # Updates the value of a column for a given item.
68
+ #
69
+ # Allows customizing the update using the args option.
70
+ # Allows customizing the item values to retrieve using the select option.
71
+ # By default, ID, and name fields are retrieved.
72
+ def change_column_value(args: {}, select: %w[id name])
73
+ query = "mutation { change_column_value(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
74
+
75
+ make_request(query)
76
+ end
77
+
78
+ # Updates the value of a column for a given item.
79
+ #
80
+ # Allows customizing the update using the args option.
81
+ # Allows customizing the item values to retrieve using the select option.
82
+ # By default, ID, and name fields are retrieved.
83
+ def change_simple_column_value(args: {}, select: %w[id name])
84
+ query = "mutation { change_simple_column_value(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
85
+
86
+ make_request(query)
87
+ end
88
+
89
+ # Updates the value of a column for a given item.
90
+ #
91
+ # Allows customizing the update using the args option.
92
+ # Allows customizing the item values to retrieve using the select option.
93
+ # By default, ID, and name fields are retrieved.
94
+ def change_multiple_column_value(args: {}, select: %w[id name])
95
+ query = "mutation { change_multiple_column_values(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
96
+
97
+ make_request(query)
98
+ end
99
+
100
+ # Deletes a column.
101
+ #
102
+ # Requires board_id and column_id to delete.
103
+ # Allows customizing the values to retrieve using the select option.
104
+ # By default, ID is retrieved.
105
+ def delete_column(board_id, column_id, select: %w[id])
106
+ query = "mutation { delete_column(board_id: #{board_id}, column_id: #{column_id}) " \
107
+ "{#{Util.format_select(select)}}}"
108
+
109
+ make_request(query)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ module Resources
5
+ # Represents Monday.com's item resource.
6
+ module Item
7
+ DEFAULT_SELECT = %w[id name created_at].freeze
8
+
9
+ # Retrieves all the items for the boards.
10
+ #
11
+ # Allows filtering items using the args option.
12
+ # Allows customizing the values to retrieve using the select option.
13
+ # By default, ID, name and created_at fields are retrieved.
14
+ def items(args: {}, select: DEFAULT_SELECT)
15
+ query = "query { items(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
16
+
17
+ make_request(query)
18
+ end
19
+
20
+ # Creates a new item.
21
+ #
22
+ # Allows customizing the item creation using the args option.
23
+ # Allows customizing the values to retrieve using the select option.
24
+ # By default, ID, name and created_at fields are retrieved.
25
+ def create_item(args: {}, select: DEFAULT_SELECT)
26
+ query = "mutation { create_item(#{Util.format_args(args)}) {#{Util.format_select(select)}}}"
27
+
28
+ make_request(query)
29
+ end
30
+
31
+ # Duplicates an item.
32
+ #
33
+ # Allows customizing the item creation using the args option.
34
+ # Allows customizing the values to retrieve using the select option.
35
+ # By default, ID, name and created_at fields are retrieved.
36
+ def duplicate_item(board_id, item_id, with_updates, select: DEFAULT_SELECT)
37
+ query = "mutation { duplicate_item(board_id: #{board_id}, item_id: #{item_id}, " \
38
+ "with_updates: #{with_updates}) {#{Util.format_select(select)}}}"
39
+
40
+ make_request(query)
41
+ end
42
+
43
+ # Archives an item.
44
+ #
45
+ # Requires item_id to archive item.
46
+ # Allows customizing the values to retrieve using the select option.
47
+ # By default, returns the ID of the archived item.
48
+ def archive_item(item_id, select: %w[id])
49
+ query = "mutation { archive_item(item_id: #{item_id}) {#{Util.format_select(select)}}}"
50
+
51
+ make_request(query)
52
+ end
53
+
54
+ # Deletes an item.
55
+ #
56
+ # Requires item_id to delete item.
57
+ # Allows customizing the values to retrieve using the select option.
58
+ # By default, returns the ID of the deleted item.
59
+ def delete_item(item_id, select: %w[id])
60
+ query = "mutation { delete_item(item_id: #{item_id}) {#{Util.format_select(select)}}}"
61
+
62
+ make_request(query)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "resources/account"
4
+ require_relative "resources/activity_log"
5
+ require_relative "resources/board"
6
+ require_relative "resources/board_view"
7
+ require_relative "resources/column"
8
+ require_relative "resources/item"
9
+
10
+ module Monday
11
+ module Resources
12
+ include Account
13
+ include ActivityLog
14
+ include Board
15
+ include BoardView
16
+ include Column
17
+ include Item
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ # Encapsulates the response that comes back from
5
+ # the Monday.com API.
6
+ #
7
+ # Returns status code, parsed body and headers.
8
+ class Response
9
+ attr_reader :status, :body, :headers
10
+
11
+ def initialize(response)
12
+ @response = response
13
+ @status = response.code.to_i
14
+ @body = parse_body
15
+ @headers = parse_headers
16
+ end
17
+
18
+ # Helper to determine if the response was successful.
19
+ # Monday.com API returns 200 status code when there are formatting errors.
20
+ def success?
21
+ (200..299).cover?(status) && !errors?
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :response
27
+
28
+ def errors?
29
+ parse_body.key?("errors") || parse_body.key?("error_message")
30
+ end
31
+
32
+ def parse_body
33
+ JSON.parse(response.body)
34
+ end
35
+
36
+ def parse_headers
37
+ response.each_header.to_h
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ # Utility class to format arguments for Monday.com API.
5
+ class Util
6
+ class << self
7
+ # Converts the arguments object into a valid string for API.
8
+ #
9
+ # input: { key: "multiple word value" }
10
+ # output: "key: \"multiple word value\""
11
+ def format_args(obj)
12
+ obj.map do |key, value|
13
+ "#{key}: #{formatted_args_value(value)}"
14
+ end.join(", ")
15
+ end
16
+
17
+ # Converts the select values into a valid string for API.
18
+ #
19
+ # input: ["id", "name", { "columns": ["id"] }]
20
+ # output: "id name columns { id }"
21
+ def format_select(value)
22
+ return format_hash(value) if value.is_a?(Hash)
23
+ return format_array(value) if value.is_a?(Array)
24
+
25
+ values
26
+ end
27
+
28
+ private
29
+
30
+ def format_array(array)
31
+ array.map do |item|
32
+ item.is_a?(Hash) ? format_hash(item) : item.to_s
33
+ end.join(" ")
34
+ end
35
+
36
+ def format_hash(hash)
37
+ hash.map do |key, value|
38
+ value.is_a?(Array) ? "#{key} { #{format_array(value)} }" : "#{key} { #{value} }"
39
+ end.join(" ")
40
+ end
41
+
42
+ def formatted_args_value(value)
43
+ return "\"#{value}\"" unless single_word?(value)
44
+ return value.to_json.to_json if value.is_a?(Hash)
45
+
46
+ value
47
+ end
48
+
49
+ def single_word?(word)
50
+ return word unless word.is_a?(String)
51
+
52
+ !word.strip.include?(" ")
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Monday
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "monday/client"
4
+ require_relative "monday/version"
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/monday/version"
4
+
5
+ version = Monday::VERSION
6
+ repository = "https://github.com/sanifhimani/monday_ruby"
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = "monday_ruby"
10
+ spec.version = version
11
+ spec.authors = ["Sanif Himani"]
12
+ spec.email = ["sanifhimani92@gmail.com"]
13
+
14
+ spec.summary = "Ruby bindings to use the monday.com API"
15
+ spec.description = "A Gem to easily interact with monday.com API using native Ruby"
16
+ spec.homepage = repository
17
+ spec.license = "MIT"
18
+ spec.required_ruby_version = ">= 2.6.0"
19
+
20
+ spec.metadata = {
21
+ "homepage_uri" => spec.homepage,
22
+ "documentation_uri" => "https://monday-ruby.gitbook.io/docs/",
23
+ "changelog_uri" => "#{repository}/blob/v#{version}/CHANGELOG.md",
24
+ "rubygems_mfa_required" => "true"
25
+ }
26
+
27
+ spec.files = Dir.chdir(__dir__) do
28
+ `git ls-files -z`.split("\x0").reject do |f|
29
+ (File.expand_path(f) == __FILE__) ||
30
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
31
+ end
32
+ end
33
+
34
+ spec.bindir = "exe"
35
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ["lib"]
37
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: monday_ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sanif Himani
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-06-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Gem to easily interact with monday.com API using native Ruby
14
+ email:
15
+ - sanifhimani92@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - ".rubocop.yml"
22
+ - ".vscode/settings.json"
23
+ - CHANGELOG.md
24
+ - CODE_OF_CONDUCT.md
25
+ - LICENSE
26
+ - README.md
27
+ - Rakefile
28
+ - lib/monday/client.rb
29
+ - lib/monday/configuration.rb
30
+ - lib/monday/request.rb
31
+ - lib/monday/resources.rb
32
+ - lib/monday/resources/account.rb
33
+ - lib/monday/resources/activity_log.rb
34
+ - lib/monday/resources/board.rb
35
+ - lib/monday/resources/board_view.rb
36
+ - lib/monday/resources/column.rb
37
+ - lib/monday/resources/item.rb
38
+ - lib/monday/response.rb
39
+ - lib/monday/util.rb
40
+ - lib/monday/version.rb
41
+ - lib/monday_ruby.rb
42
+ - monday_ruby.gemspec
43
+ homepage: https://github.com/sanifhimani/monday_ruby
44
+ licenses:
45
+ - MIT
46
+ metadata:
47
+ homepage_uri: https://github.com/sanifhimani/monday_ruby
48
+ documentation_uri: https://monday-ruby.gitbook.io/docs/
49
+ changelog_uri: https://github.com/sanifhimani/monday_ruby/blob/v0.1.0/CHANGELOG.md
50
+ rubygems_mfa_required: 'true'
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 2.6.0
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubygems_version: 3.4.14
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: Ruby bindings to use the monday.com API
70
+ test_files: []