├── .rspec ├── lib ├── sdk │ ├── version.rb │ ├── constants │ │ └── constants.rb │ ├── client.rb │ └── monday_api │ │ └── monday-api-client.rb └── sdk.rb ├── README.md ├── Gemfile ├── .travis.yml ├── Rakefile ├── bin ├── setup └── console ├── spec ├── spec_helper.rb └── sdk_spec.rb ├── .rspec_status ├── Gemfile.lock ├── LICENSE.txt ├── .gitignore ├── monday-sdk-ruby.gemspec └── CODE_OF_CONDUCT.md /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /lib/sdk/version.rb: -------------------------------------------------------------------------------- 1 | module Monday 2 | VERSION = "0.1.0" 3 | end 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # monday-sdk-ruby 2 | Ruby SDK for developing over the monday.com platform 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Specify your gem's dependencies in monday-sdk-ruby.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: ruby 3 | cache: bundler 4 | rvm: 5 | - 2.6.3 6 | before_install: gem install bundler -v 2.1.4 7 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rspec/core/rake_task" 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task :default => :spec 7 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /lib/sdk.rb: -------------------------------------------------------------------------------- 1 | 2 | # Monday SDK is a client to use monday REST api 3 | module Monday 4 | end 5 | 6 | require 'sdk/client' 7 | require 'sdk/constants/constants' 8 | require 'sdk/monday_api/monday-api-client' 9 | require 'sdk/version' 10 | require 'faraday' 11 | require 'json' 12 | 13 | 14 | -------------------------------------------------------------------------------- /lib/sdk/constants/constants.rb: -------------------------------------------------------------------------------- 1 | # Constants 2 | module Monday 3 | MONDAY_PROTOCOL = "https".freeze 4 | MONDAY_DOMAIN = "monday.com".freeze 5 | MONDAY_API_URL = MONDAY_PROTOCOL+"://api."+MONDAY_DOMAIN+"/v2".freeze 6 | MONDAY_OAUTH_URL = MONDAY_PROTOCOL+"://auth."+MONDAY_DOMAIN+"/oauth2/authorize".freeze 7 | MONDAY_OAUTH_TOKEN_URL = MONDAY_PROTOCOL+"://auth."+MONDAY_DOMAIN+"/oauth2/token".freeze 8 | end 9 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "bundler/setup" 4 | require "monday/sdk/ruby" 5 | 6 | # You can add fixtures and/or initialization code here to make experimenting 7 | # with your gem easier. You can also use a different console, if you like. 8 | 9 | # (If you use this, don't forget to add pry to your Gemfile!) 10 | # require "pry" 11 | # Pry.start 12 | 13 | require "irb" 14 | IRB.start(__FILE__) 15 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "sdk" 3 | 4 | RSpec.configure do |config| 5 | # Enable flags like --only-failures and --next-failure 6 | config.example_status_persistence_file_path = ".rspec_status" 7 | 8 | # Disable RSpec exposing methods globally on `Module` and `main` 9 | config.disable_monkey_patching! 10 | 11 | config.expect_with :rspec do |c| 12 | c.syntax = :expect 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /.rspec_status: -------------------------------------------------------------------------------- 1 | example_id | status | run_time | 2 | ----------------------- | ------ | --------------- | 3 | ./spec/sdk_spec.rb[1:1] | passed | 0.00092 seconds | 4 | ./spec/sdk_spec.rb[1:2] | passed | 0.06699 seconds | 5 | ./spec/sdk_spec.rb[1:3] | passed | 0.00039 seconds | 6 | ./spec/sdk_spec.rb[1:4] | passed | 0.00052 seconds | 7 | ./spec/sdk_spec.rb[1:5] | passed | 0.0032 seconds | 8 | ./spec/sdk_spec.rb[1:6] | passed | 0.00035 seconds | 9 | ./spec/sdk_spec.rb[1:7] | passed | 0.0003 seconds | 10 | ./spec/sdk_spec.rb[1:8] | passed | 0.00154 seconds | 11 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | monday-sdk-ruby (0.1.0) 5 | faraday (~> 1.0) 6 | json (~> 2.3) 7 | 8 | GEM 9 | remote: https://rubygems.org/ 10 | specs: 11 | diff-lcs (1.3) 12 | faraday (1.0.0) 13 | multipart-post (>= 1.2, < 3) 14 | json (2.3.0) 15 | multipart-post (2.1.1) 16 | rake (12.3.3) 17 | rspec (3.9.0) 18 | rspec-core (~> 3.9.0) 19 | rspec-expectations (~> 3.9.0) 20 | rspec-mocks (~> 3.9.0) 21 | rspec-core (3.9.1) 22 | rspec-support (~> 3.9.1) 23 | rspec-expectations (3.9.1) 24 | diff-lcs (>= 1.2.0, < 2.0) 25 | rspec-support (~> 3.9.0) 26 | rspec-mocks (3.9.1) 27 | diff-lcs (>= 1.2.0, < 2.0) 28 | rspec-support (~> 3.9.0) 29 | rspec-support (3.9.2) 30 | 31 | PLATFORMS 32 | ruby 33 | 34 | DEPENDENCIES 35 | bundler (~> 2.1) 36 | monday-sdk-ruby! 37 | rake (~> 12.0) 38 | rspec (~> 3.0) 39 | 40 | BUNDLED WITH 41 | 2.1.4 42 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Dan Ofir 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. 22 | -------------------------------------------------------------------------------- /lib/sdk/client.rb: -------------------------------------------------------------------------------- 1 | 2 | # Monday Client implementation 3 | module Monday 4 | 5 | class MondayClientError < StandardError; end 6 | 7 | class Client 8 | 9 | TOKEN_MISSING_ERROR = "Should send 'token' as an option or call mondaySdk.setToken(TOKEN)".freeze 10 | 11 | def initialize(options = {}) 12 | @token = options[:token] # @type string , Client token provided by monday.com 13 | @api_domain = options[:api] # @type string (optional) monday api domain cna be changed, default defined in constants 14 | @faraday_client = options[:conn] || Faraday.new # dependency injection for testing 15 | end 16 | 17 | # Main entry point to the client 18 | def api(query, options = {}) 19 | token = options[:token] || @token 20 | 21 | if token.nil? || token.empty? 22 | raise MondayClientError.new TOKEN_MISSING_ERROR.to_s 23 | end 24 | 25 | params = {} 26 | params[:query] = query 27 | params[:variables] = options[:variables] || {} 28 | 29 | options[:api_domain] = @api_domain || MONDAY_API_URL 30 | 31 | 32 | MondayApiClient.execute(params, token, @faraday_client, options) 33 | end 34 | 35 | end 36 | 37 | end 38 | 39 | 40 | -------------------------------------------------------------------------------- /lib/sdk/monday_api/monday-api-client.rb: -------------------------------------------------------------------------------- 1 | # Monday REST API implementation 2 | module Monday 3 | class Client 4 | 5 | private 6 | class MondayApiClient 7 | 8 | class << self 9 | 10 | COULD_NOT_PARSE_JSON_RESPONSE_ERROR = 'Could not parse JSON from monday.com\'s GraphQL API response'.freeze 11 | TOKEN_IS_REQUIRED_ERROR = 'Token is required'.freeze 12 | 13 | private 14 | def apiRequest(url, conn, data, token) 15 | begin 16 | res = conn.post(url, data.to_json, 17 | 'Authorization' => token, 'Content-Type' => 'application/json') 18 | res.body.to_json 19 | rescue StandardError => e 20 | raise Monday::MondayClientError.new COULD_NOT_PARSE_JSON_RESPONSE_ERROR.to_s 21 | end 22 | 23 | end 24 | 25 | public 26 | def execute(query, token,conn, options = {}) 27 | if token.nil? || token.empty? 28 | raise Monday::MondayClientError.new TOKEN_MISSING_ERROR.to_s 29 | end 30 | 31 | url = options[:api_domain] 32 | path = options[:path] || "" 33 | full_url = url + path 34 | 35 | apiRequest(full_url, conn, query, token) 36 | end 37 | end 38 | end 39 | end 40 | end 41 | 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Ruby template 3 | *.gem 4 | *.rbc 5 | /.config 6 | /coverage/ 7 | /InstalledFiles 8 | /pkg/ 9 | /spec/reports/ 10 | /spec/examples.txt 11 | /test/tmp/ 12 | /test/version_tmp/ 13 | /tmp/ 14 | 15 | # Used by dotenv library to load environment variables. 16 | # .env 17 | 18 | # Ignore Byebug command history file. 19 | .byebug_history 20 | 21 | ## Specific to RubyMotion: 22 | .dat* 23 | .repl_history 24 | build/ 25 | *.bridgesupport 26 | build-iPhoneOS/ 27 | build-iPhoneSimulator/ 28 | 29 | ## Specific to RubyMotion (use of CocoaPods): 30 | # 31 | # We recommend against adding the Pods directory to your .gitignore. However 32 | # you should judge for yourself, the pros and cons are mentioned at: 33 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 34 | # 35 | # vendor/Pods/ 36 | 37 | ## Documentation cache and generated files: 38 | /.yardoc/ 39 | /_yardoc/ 40 | /doc/ 41 | /rdoc/ 42 | 43 | ## Environment normalization: 44 | /.bundle/ 45 | /vendor/bundle 46 | /lib/bundler/man/ 47 | 48 | # for a library or gem, you might want to ignore these files since the code is 49 | # intended to run in multiple environments; otherwise, check them in: 50 | # Gemfile.lock 51 | # .ruby-version 52 | # .ruby-gemset 53 | 54 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 55 | .rvmrc 56 | 57 | .idea/ 58 | *.iml 59 | -------------------------------------------------------------------------------- /monday-sdk-ruby.gemspec: -------------------------------------------------------------------------------- 1 | require_relative 'lib/sdk/version' 2 | 3 | Gem::Specification.new do |spec| 4 | spec.name = "monday-sdk-ruby" 5 | spec.version = Monday::VERSION 6 | spec.authors = ["Dan Ofir"] 7 | spec.email = ["dan.ofir@monday.com"] 8 | 9 | spec.summary = "Monday SDK sdk" 10 | spec.homepage = "https://github.com/mondaycom/monday-sdk-ruby" 11 | spec.license = "MIT" 12 | spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") 13 | 14 | # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'" 15 | # 16 | # spec.metadata["homepage_uri"] = spec.homepage 17 | # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here." 18 | # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." 19 | 20 | # Specify which files should be added to the gem when it is released. 21 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 22 | spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do 23 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 24 | end 25 | spec.bindir = "exe" 26 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 27 | spec.require_paths = ["lib"] 28 | 29 | 30 | spec.add_development_dependency "bundler", "~> 2.1" 31 | spec.add_development_dependency "rake", "~> 12.0" 32 | spec.add_development_dependency "rspec", "~> 3.0" 33 | 34 | spec.add_runtime_dependency "faraday", "~> 1.0" 35 | spec.add_runtime_dependency "json", "~> 2.3" 36 | end 37 | -------------------------------------------------------------------------------- /spec/sdk_spec.rb: -------------------------------------------------------------------------------- 1 | require 'faraday' 2 | require 'json' 3 | 4 | RSpec.describe Monday::Client do 5 | let(:stubs) { Faraday::Adapter::Test::Stubs.new } 6 | let(:conn) { Faraday.new { |b| b.adapter(:test, stubs) } } 7 | 8 | query = "query { 9 | me { 10 | name 11 | } 12 | }" 13 | token = "mockToken!@#" 14 | 15 | it "has a version number" do 16 | expect(Monday::VERSION).not_to be nil 17 | end 18 | 19 | it "init with api" do 20 | client = Monday::Client.new(options={api: "https://its.me"}) 21 | expect(client.instance_eval '@api_domain').to eq("https://its.me") 22 | end 23 | 24 | it "init without api" do 25 | client = Monday::Client.new 26 | expect(client.instance_eval '@api_domain').to eq(nil) 27 | end 28 | 29 | it "init with token" do 30 | client = Monday::Client.new(options={token: "u2u2u2u"}) 31 | expect(client.instance_eval '@token').to eq("u2u2u2u") 32 | end 33 | 34 | it "e2e custom api" do 35 | stubs.post('/v2') do |env| 36 | expect(env.url.host).to eq('its.me.com') 37 | [ 38 | 200, 39 | { 'Content-Type': 'application/json', }, 40 | '{"name": "monday"}' 41 | ] 42 | end 43 | 44 | client = Monday::Client.new(options={token: token,api:"https://its.me.com/v2", conn: conn}) 45 | 46 | expect(client.api(query)).to eq('"{\\"name\\": \\"monday\\"}"') 47 | stubs.verify_stubbed_calls 48 | end 49 | 50 | it "e2e default api" do 51 | stubs.post('/v2') do |env| 52 | expect(env.url.host).to eq('api.monday.com') 53 | [ 54 | 200, 55 | { 'Content-Type': 'application/json', }, 56 | '{"name": "monday"}' 57 | ] 58 | end 59 | 60 | client = Monday::Client.new(options={token: token, conn: conn}) 61 | 62 | expect(client.api(query)).to eq('"{\\"name\\": \\"monday\\"}"') 63 | stubs.verify_stubbed_calls 64 | end 65 | 66 | it "e2e default api with variables" do 67 | stubs.post('/v2') do |env| 68 | expect(env.url.host).to eq('api.monday.com') 69 | expect(env.request_body).to eq('{"query":"query {\n me {\n name\n }\n }","variables":{"name":"as"}}') 70 | [ 71 | 200, 72 | { 'Content-Type': 'application/json', }, 73 | '{"name": "monday"}' 74 | ] 75 | end 76 | 77 | client = Monday::Client.new(options={token: token, conn: conn}) 78 | 79 | expect(client.api(query,options={variables: {"name":"as",}})).to eq('"{\\"name\\": \\"monday\\"}"') 80 | stubs.verify_stubbed_calls 81 | end 82 | 83 | it "monday-api-client execute without token" do 84 | 85 | expect { 86 | Monday::Client::MondayApiClient.execute(query,nil,conn) 87 | }.to raise_error(Monday::MondayClientError) 88 | 89 | expect { 90 | Monday::Client::MondayApiClient.execute(query,"",conn) 91 | }.to raise_error(Monday::MondayClientError) 92 | end 93 | 94 | end 95 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at dan.ofir@monday.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [https://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: https://contributor-covenant.org 74 | [version]: https://contributor-covenant.org/version/1/4/ 75 | --------------------------------------------------------------------------------