ashby 0.1.3
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 +7 -0
- data/.idea/.gitignore +8 -0
- data/.idea/ashby.iml +97 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.rspec +3 -0
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +27 -0
- data/.vscode/settings.json +1 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +50 -0
- data/Rakefile +12 -0
- data/lib/ashby/applications.rb +32 -0
- data/lib/ashby/candidates.rb +63 -0
- data/lib/ashby/client.rb +75 -0
- data/lib/ashby/close_reasons.rb +19 -0
- data/lib/ashby/configuration.rb +42 -0
- data/lib/ashby/custom_fields.rb +35 -0
- data/lib/ashby/departments.rb +29 -0
- data/lib/ashby/error.rb +38 -0
- data/lib/ashby/feedback.rb +17 -0
- data/lib/ashby/hiring_teams.rb +45 -0
- data/lib/ashby/interviews.rb +44 -0
- data/lib/ashby/job_boards.rb +10 -0
- data/lib/ashby/job_postings.rb +45 -0
- data/lib/ashby/jobs.rb +75 -0
- data/lib/ashby/offers.rb +43 -0
- data/lib/ashby/openings.rb +76 -0
- data/lib/ashby/postings.rb +83 -0
- data/lib/ashby/users.rb +42 -0
- data/lib/ashby/version.rb +5 -0
- data/lib/ashby.rb +29 -0
- data/sig/.DS_Store +0 -0
- data/sig/ashby.rbs +4 -0
- metadata +116 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::CustomFields manages setting custom field values for objects
|
5
|
+
# in the Ashby API, such as jobs or candidates.
|
6
|
+
#
|
7
|
+
# This class provides a method to assign a specific value to a custom field
|
8
|
+
# identified by field ID, for a particular object type and ID.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# Ashby::CustomFields.set_field(
|
12
|
+
# object_id: 'job_abc123',
|
13
|
+
# object_type: 'job',
|
14
|
+
# field_id: 'cf_custom_location',
|
15
|
+
# field_value: 'Remote'
|
16
|
+
# )
|
17
|
+
#
|
18
|
+
class CustomFields < Client
|
19
|
+
def self.set_field(object_id: nil, object_type: nil, field_id: nil, field_value: nil)
|
20
|
+
raise ArgumentError, '`object_id` is required' if object_id.blank?
|
21
|
+
raise ArgumentError, '`object_type` is required' if object_type.blank?
|
22
|
+
raise ArgumentError, '`field_id` is required' if field_id.blank?
|
23
|
+
raise ArgumentError, '`field_value` is required' if field_value.blank?
|
24
|
+
|
25
|
+
payload = {
|
26
|
+
objectId: object_id,
|
27
|
+
objectType: object_type,
|
28
|
+
fieldId: field_id,
|
29
|
+
fieldValue: field_value
|
30
|
+
}
|
31
|
+
|
32
|
+
post('customField.setValue', payload)['results']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::Departments provides methods to interact with the
|
5
|
+
# Ashby API's department-related endpoints.
|
6
|
+
#
|
7
|
+
# Includes fetching a list of departments and retrieving a specific department by ID.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# Ashby::Departments.all
|
11
|
+
# Ashby::Departments.find(id: 'abc123')
|
12
|
+
#
|
13
|
+
class Departments < Client
|
14
|
+
# Fetches all departments
|
15
|
+
def self.all
|
16
|
+
response = post('department.list')
|
17
|
+
response['results']
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finds a department by its Ashby ID
|
21
|
+
def self.find(id: nil)
|
22
|
+
raise ArgumentError, 'Department ID is required' if id.to_s.strip.empty?
|
23
|
+
|
24
|
+
payload = { departmentId: id }
|
25
|
+
response = post('department.info', payload)
|
26
|
+
response['results']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/ashby/error.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Custom error class for the Ashby module that extends StandardError
|
5
|
+
# with optional error code support.
|
6
|
+
#
|
7
|
+
# This class provides a standardized way to handle errors within the Ashby
|
8
|
+
# module by allowing both error messages and optional error codes to be
|
9
|
+
# associated with exceptions.
|
10
|
+
#
|
11
|
+
# @example Basic usage with message only
|
12
|
+
# raise Ashby::Error.new("Something went wrong")
|
13
|
+
#
|
14
|
+
# @example Usage with message and error code
|
15
|
+
# raise Ashby::Error.new("API request failed", 500)
|
16
|
+
#
|
17
|
+
# @example Accessing the error code
|
18
|
+
# begin
|
19
|
+
# raise Ashby::Error.new("Not found", 404)
|
20
|
+
# rescue Ashby::Error => e
|
21
|
+
# puts e.message # => "Not found"
|
22
|
+
# puts e.code # => 404
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# @attr_reader [Object, nil] code The optional error code associated with this error
|
26
|
+
class Error < StandardError
|
27
|
+
attr_reader :code
|
28
|
+
|
29
|
+
# Initialize a new Ashby::Error instance
|
30
|
+
#
|
31
|
+
# @param message [String] The error message
|
32
|
+
# @param code [Object, nil] Optional error code (typically an integer, but can be any object)
|
33
|
+
def initialize(message, code = nil)
|
34
|
+
super(message)
|
35
|
+
@code = code
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
#
|
5
|
+
# Ashby::Feedback provides access to feedback-related operations via the Ashby API.
|
6
|
+
# # Supported functionality includes:
|
7
|
+
# - Retrieving a paginated list of all feedback
|
8
|
+
# # Example usage:
|
9
|
+
# Ashby::Feedback.all
|
10
|
+
#
|
11
|
+
class Feedback < Client
|
12
|
+
# Fetches all feedback with pagination support
|
13
|
+
def self.all(payload = {})
|
14
|
+
paginated_post('applicationFeedback.list', payload)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::HiringTeams provides access to hiring team management functionality in the Ashby API.
|
5
|
+
#
|
6
|
+
# Includes support for:
|
7
|
+
# - Adding a member to a hiring team
|
8
|
+
# - Removing a member from a hiring team
|
9
|
+
#
|
10
|
+
# Example usage:
|
11
|
+
# Ashby::HiringTeams.add_hiring_team_member(type: :job, id: 'job_123', member_id: 'user_456', role_id: 'role_789')
|
12
|
+
# Ashby::HiringTeams.remove_hiring_team_member(type: :application, id: 'app_123', member_id: 'user_456',
|
13
|
+
# role_id: 'role_789')
|
14
|
+
#
|
15
|
+
class HiringTeams < Client
|
16
|
+
def self.remove_hiring_team_member(type, id, member_id, role_id)
|
17
|
+
payload = build_hiring_team_payload(type, id, member_id, role_id)
|
18
|
+
response = post('hiringTeam.removeMember', payload)
|
19
|
+
response['results']
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.add_hiring_team_member(type, id, member_id, role_id)
|
23
|
+
payload = build_hiring_team_payload(type, id, member_id, role_id)
|
24
|
+
response = post('hiringTeam.addMember', payload)
|
25
|
+
response['results']
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.build_hiring_team_payload(type, id, member_id, role_id) # rubocop:disable Metrics/MethodLength
|
29
|
+
payload = {}
|
30
|
+
case type
|
31
|
+
when :job
|
32
|
+
payload[:jobId] = id.to_s if id
|
33
|
+
when :application
|
34
|
+
payload[:applicationId] = id.to_s
|
35
|
+
when :opening
|
36
|
+
payload[:openingId] = id.to_s
|
37
|
+
else
|
38
|
+
raise ArgumentError, "Invalid type: #{type}. Must be one of :job, :application, or :opening."
|
39
|
+
end
|
40
|
+
payload[:teamMemberId] = member_id if member_id
|
41
|
+
payload[:roleId] = role_id if role_id
|
42
|
+
payload
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::InterviewSchedules provides access to Interview Schedule-related functionality in the Ashby API.
|
5
|
+
#
|
6
|
+
# Includes support for:
|
7
|
+
# - Fetching all interviews (with pagination)
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# Ashby::InterviewSchedules.all
|
11
|
+
#
|
12
|
+
class Interviews < Client
|
13
|
+
# Fetches all interview schedules with pagination support
|
14
|
+
def self.schedule_all(payload = {})
|
15
|
+
paginated_post('interviewSchedule.list', payload)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.plans_all
|
19
|
+
response = post('interviewPlan.list')
|
20
|
+
response['results']
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.stages_all
|
24
|
+
response = post('interviewStage.list')
|
25
|
+
response['results']
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.interview_by_id(id: nil)
|
29
|
+
raise ArgumentError, 'Interview ID is required' if id.to_s.strip.empty?
|
30
|
+
|
31
|
+
payload = { id: id }
|
32
|
+
response = post('interview.info', payload)
|
33
|
+
response['results']
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.stage_by_id(id: nil)
|
37
|
+
raise ArgumentError, 'Stage ID is required' if id.to_s.strip.empty?
|
38
|
+
|
39
|
+
payload = { interviewStageId: id }
|
40
|
+
response = post('interviewStage.info', payload)
|
41
|
+
response['results']
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::JobPostings provides access to job posting-related functionality in the Ashby API.
|
5
|
+
#
|
6
|
+
# Includes support for:
|
7
|
+
# - Fetching all job postings (active only by default, can include inactive)
|
8
|
+
# - Looking up a job posting by its Ashby ID
|
9
|
+
#
|
10
|
+
# Example usage:
|
11
|
+
# Ashby::JobPostings.all
|
12
|
+
# Ashby::JobPostings.all(active_only: false)
|
13
|
+
# Ashby::JobPostings.find_by_id(id: 'jp_abc456')
|
14
|
+
#
|
15
|
+
class JobPostings < Client
|
16
|
+
# Fetches all job postings
|
17
|
+
def self.all(active_only: true, job_board_id: nil)
|
18
|
+
payload = { listedOnly: active_only }
|
19
|
+
payload[:jobBoardId] = job_board_id if job_board_id
|
20
|
+
|
21
|
+
response = post('jobPosting.list', payload)
|
22
|
+
response['results']
|
23
|
+
end
|
24
|
+
|
25
|
+
# Finds a Job Posting by the Ashby ID
|
26
|
+
def self.find_by_id(id: nil)
|
27
|
+
raise ArgumentError, 'Job Posting ID is required' if id.to_s.strip.empty?
|
28
|
+
|
29
|
+
payload = { jobPostingId: id }
|
30
|
+
response = post('jobPosting.info', payload)
|
31
|
+
response['results']
|
32
|
+
end
|
33
|
+
|
34
|
+
# Finds all Job Postings associated with a given Job ID
|
35
|
+
def self.by_job_id(job_id: nil)
|
36
|
+
raise ArgumentError, 'Job ID is required' if job_id.to_s.strip.empty?
|
37
|
+
|
38
|
+
payload = { id: job_id }
|
39
|
+
response = post('job.info', payload)
|
40
|
+
job_posting_ids = response.dig('results', 'jobPostingIds') || []
|
41
|
+
|
42
|
+
job_posting_ids.map { |jp_id| find_by_id(id: jp_id) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/ashby/jobs.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::Jobs handles interactions with job-related endpoints in the Ashby API.
|
5
|
+
#
|
6
|
+
# Supports fetching all jobs with pagination, finding a job by ID, and searching
|
7
|
+
# jobs based on requisition ID or title.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# Ashby::Jobs.all
|
11
|
+
# Ashby::Jobs.find('job_abc123')
|
12
|
+
# Ashby::Jobs.search(req_id: 'REQ-001')
|
13
|
+
#
|
14
|
+
class Jobs < Client
|
15
|
+
# Fetches all jobs with pagination support
|
16
|
+
def self.all(payload = {})
|
17
|
+
paginated_post('job.list', payload)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finds a job by its Ashby ID
|
21
|
+
def self.find(id, expand: '')
|
22
|
+
raise ArgumentError, 'Job ID is required' if id.to_s.strip.empty?
|
23
|
+
|
24
|
+
payload = {
|
25
|
+
id: id,
|
26
|
+
expand: expand.strip.empty? ? [] : [expand]
|
27
|
+
}
|
28
|
+
post('job.info', payload)['results']
|
29
|
+
end
|
30
|
+
|
31
|
+
# Searches for jobs based on requisition ID or title
|
32
|
+
def self.search(req_id: nil, title: nil)
|
33
|
+
payload = {}
|
34
|
+
payload[:requisitionId] = req_id.to_s if req_id
|
35
|
+
payload[:title] = title if title
|
36
|
+
|
37
|
+
raise ArgumentError, 'You must provide at least a job title or a requisition id' if payload.empty?
|
38
|
+
|
39
|
+
post('job.search', payload)['results']
|
40
|
+
end
|
41
|
+
|
42
|
+
# Fetches all job templates
|
43
|
+
def self.templates
|
44
|
+
paginated_post('jobTemplate.list')
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.create(payload)
|
48
|
+
required_fields = %i[title teamId locationId]
|
49
|
+
missing = required_fields.select { |f| payload[f].to_s.strip.empty? }
|
50
|
+
raise ArgumentError, "Missing required fields: #{missing.join(', ')}" if missing.any?
|
51
|
+
|
52
|
+
post('job.create', payload)['results']
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.update(id: nil, payload: {})
|
56
|
+
raise ArgumentError, 'You must provide a job id' if id.nil?
|
57
|
+
|
58
|
+
payload[:jobId] = id
|
59
|
+
post('job.update', payload)['results']
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.set_status(job_id:, status:)
|
63
|
+
valid_statuses = %w[Draft Open Closed Archived]
|
64
|
+
raise ArgumentError, 'Job ID is required' if job_id.to_s.strip.empty?
|
65
|
+
raise ArgumentError, "Invalid status: #{status}" unless valid_statuses.include?(status)
|
66
|
+
|
67
|
+
payload = {
|
68
|
+
jobId: job_id,
|
69
|
+
status: status
|
70
|
+
}
|
71
|
+
|
72
|
+
post('job.setStatus', payload)['results']
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/ashby/offers.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::Offers provides access to offer-related endpoints in the Ashby API.
|
5
|
+
#
|
6
|
+
# Supports fetching all offers with pagination and retrieving a specific offer by ID.
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# Ashby::Offers.all
|
10
|
+
# Ashby::Offers.find(id: 'offer_xyz789')
|
11
|
+
#
|
12
|
+
class Offers < Client
|
13
|
+
# Fetches all offers with pagination support
|
14
|
+
def self.all
|
15
|
+
paginated_post('offer.list')
|
16
|
+
end
|
17
|
+
|
18
|
+
# Finds an offer by its Ashby ID
|
19
|
+
def self.find(id: nil)
|
20
|
+
raise ArgumentError, 'Offer ID is required' if id.to_s.strip.empty?
|
21
|
+
|
22
|
+
payload = { id: id }
|
23
|
+
response = post('offer.info', payload)
|
24
|
+
response['results']
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.offers_by_application_id(application_id: nil)
|
28
|
+
raise ArgumentError, 'Application ID is required' if application_id.to_s.strip.empty?
|
29
|
+
|
30
|
+
payload = { applicationId: application_id }
|
31
|
+
response = post('offer.list', payload)
|
32
|
+
response['results']
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.most_recent_offer_by_application_id(application_id: nil)
|
36
|
+
raise ArgumentError, 'Application ID is required' if application_id.to_s.strip.empty?
|
37
|
+
|
38
|
+
payload = { applicationId: application_id }
|
39
|
+
response = post('offer.list', payload)
|
40
|
+
response['results'].max_by { |o| o['latestVersion']['createdAt'] }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::Candidates provides access to candidate-related functionality in the Ashby API.
|
5
|
+
#
|
6
|
+
# Includes support for:
|
7
|
+
# - Fetching all candidates (with pagination)
|
8
|
+
# - Searching by email or name
|
9
|
+
# - Looking up by ID
|
10
|
+
# - Adding notes to candidate profiles in plain text or HTML
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# Ashby::Candidates.all
|
14
|
+
# Ashby::Candidates.find(email: 'jane@company.com')
|
15
|
+
# Ashby::Candidates.find_by_id(id: 'cand_abc123')
|
16
|
+
#
|
17
|
+
# client = Ashby::Candidates.new
|
18
|
+
# client.create_candidate_note('cand_abc123', 'Reached out via email.')
|
19
|
+
# client.create_formatted_candidate_note('cand_abc123', title: 'Initial Contact',
|
20
|
+
# content: 'Spoke with Jane over Zoom.')
|
21
|
+
#
|
22
|
+
class Openings < Client
|
23
|
+
# Fetches all openings with pagination support
|
24
|
+
def self.all
|
25
|
+
paginated_post('opening.list')
|
26
|
+
end
|
27
|
+
|
28
|
+
# Finds an opening by email or name
|
29
|
+
def self.find(email: nil, name: nil)
|
30
|
+
payload = {}
|
31
|
+
payload[:email] = email if email
|
32
|
+
payload[:name] = name if name
|
33
|
+
|
34
|
+
raise ArgumentError, 'You must provide at least an email or a name' if payload.empty?
|
35
|
+
|
36
|
+
response = post('opening.search', payload)
|
37
|
+
response['results']
|
38
|
+
end
|
39
|
+
|
40
|
+
# Searches for openings by the identifier
|
41
|
+
def self.search(identifier: nil)
|
42
|
+
raise ArgumentError, 'You must provide an identifier' if identifier.to_s.strip.empty?
|
43
|
+
|
44
|
+
payload = { identifier: identifier.to_s }
|
45
|
+
response = post('opening.search', payload)
|
46
|
+
response['results']
|
47
|
+
end
|
48
|
+
|
49
|
+
# Finds an opening by its Ashby ID
|
50
|
+
def self.find_by_id(id: nil)
|
51
|
+
raise ArgumentError, 'Opening ID is required' if id.to_s.strip.empty?
|
52
|
+
|
53
|
+
payload = { openingId: id }
|
54
|
+
response = post('opening.info', payload)
|
55
|
+
response['results']
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.set_status(id, state)
|
59
|
+
payload = {}
|
60
|
+
payload[:openingId] = id if id
|
61
|
+
payload[:openingState] = state if state
|
62
|
+
|
63
|
+
raise ArgumentError, 'You must provide the opening ID and the state' if payload.empty?
|
64
|
+
|
65
|
+
response = post('opening.setOpeningState', payload)
|
66
|
+
response['results']
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.create(payload)
|
70
|
+
raise ArgumentError, 'No payload provided' if payload.empty?
|
71
|
+
|
72
|
+
response = post('opening.create', payload)
|
73
|
+
response['results']
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::Postings provides access to job posting related functionality in the Ashby API.
|
5
|
+
#
|
6
|
+
# It wraps the `jobPosting.info` and `jobPosting.list` endpoints and exposes a few
|
7
|
+
# convenience helpers for commonly accessed nested fields such as `linkedData`
|
8
|
+
# (for SEO rich results) and `applicationFormDefinition`.
|
9
|
+
#
|
10
|
+
# Endpoints referenced:
|
11
|
+
# - jobPosting.info -> Retrieve a single job posting by ID
|
12
|
+
# - jobPosting.list -> List job postings (optionally only those that are publicly listed)
|
13
|
+
# - jobPosting.update -> Update an existing job posting
|
14
|
+
#
|
15
|
+
# Example usage:
|
16
|
+
# Ashby::Postings.list # list all postings (listed + unlisted)
|
17
|
+
# Ashby::Postings.list(listed_only: true) # only postings publicly listed
|
18
|
+
# Ashby::Postings.all # (deprecated) alias to .list
|
19
|
+
# Ashby::Postings.find('jp_abc123') # posting hash
|
20
|
+
# Ashby::Postings.linked_data('jp_abc123') # structured data for SEO
|
21
|
+
# Ashby::Postings.application_form_definition('jp_abc123')
|
22
|
+
# Ashby::Postings.update(id: 'jp_abc123', payload: { title: 'Updated Title' })
|
23
|
+
#
|
24
|
+
# Note: A `Ashby::JobPostings` class already exists; this class provides a
|
25
|
+
# cleaner name (`Postings`) and a couple of ergonomic helpers while delegating
|
26
|
+
# to the same underlying API endpoints. Either class can be used interchangeably.
|
27
|
+
#
|
28
|
+
class Postings < Client
|
29
|
+
# Lists job postings. By default returns both listed and unlisted job postings.
|
30
|
+
# Pass listed_only: true to restrict to those safe for public display.
|
31
|
+
# @param listed_only [Boolean, nil] When true only include publicly listed postings; when nil omit filter.
|
32
|
+
def self.list(listed_only: nil)
|
33
|
+
payload = {}
|
34
|
+
payload[:listedOnly] = true if listed_only == true
|
35
|
+
post('jobPosting.list', payload)['results']
|
36
|
+
end
|
37
|
+
|
38
|
+
# Deprecated: Use .list(listed_only: ...) instead. Retained for backward compatibility.
|
39
|
+
def self.all(listed_only: nil, **_deprecated)
|
40
|
+
Kernel.warn('[DEPRECATION] Ashby::Postings.all is deprecated. Use Ashby::Postings.list(listed_only: ...) instead.')
|
41
|
+
list(listed_only: listed_only)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Retrieve a single job posting by its Ashby Job Posting ID.
|
45
|
+
# @param id [String] The Ashby Job Posting ID (e.g., "jp_abc123")
|
46
|
+
# @return [Hash] The job posting object
|
47
|
+
def self.find(id)
|
48
|
+
raise ArgumentError, 'Job Posting ID is required' if id.to_s.strip.empty?
|
49
|
+
|
50
|
+
payload = { jobPostingId: id }
|
51
|
+
post('jobPosting.info', payload)['results']
|
52
|
+
end
|
53
|
+
class << self
|
54
|
+
alias find_by_id find
|
55
|
+
alias info find
|
56
|
+
end
|
57
|
+
|
58
|
+
# Convenience: Returns the `linkedData` section (for SEO rich results) of a posting.
|
59
|
+
def self.linked_data(id)
|
60
|
+
find(id)['linkedData']
|
61
|
+
end
|
62
|
+
|
63
|
+
# Convenience: Returns the `applicationFormDefinition` of a posting.
|
64
|
+
def self.application_form_definition(id)
|
65
|
+
find(id)['applicationFormDefinition']
|
66
|
+
end
|
67
|
+
|
68
|
+
# Update a job posting via jobPosting.update.
|
69
|
+
# You must supply at least one field to update in the payload.
|
70
|
+
#
|
71
|
+
# @param id [String] The Ashby Job Posting ID
|
72
|
+
# @param payload [Hash] Fields to update (see Ashby API docs for allowed keys)
|
73
|
+
# @return [Hash] Updated job posting object
|
74
|
+
def self.update(id:, payload: {})
|
75
|
+
raise ArgumentError, 'Job Posting ID is required' if id.to_s.strip.empty?
|
76
|
+
raise ArgumentError, 'Update payload cannot be empty' if payload.empty?
|
77
|
+
|
78
|
+
body = payload.dup
|
79
|
+
body[:jobPostingId] = id
|
80
|
+
post('jobPosting.update', body)['results']
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/ashby/users.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ashby
|
4
|
+
# Ashby::Users provides access to user-related functionality in the Ashby API.
|
5
|
+
#
|
6
|
+
# Includes support for:
|
7
|
+
# - Fetching all users with pagination
|
8
|
+
# - Searching users by email
|
9
|
+
# - Looking up users by their Ashby ID
|
10
|
+
#
|
11
|
+
# Example usage:
|
12
|
+
# Ashby::Users.all
|
13
|
+
# Ashby::Users.find_by_email(email: 'recruiter@company.com')
|
14
|
+
# Ashby::Users.find_by_id(id: 'user_xyz789')
|
15
|
+
#
|
16
|
+
class Users < Client
|
17
|
+
# Fetches all users with pagination support
|
18
|
+
def self.all
|
19
|
+
paginated_post('user.list')
|
20
|
+
end
|
21
|
+
|
22
|
+
# Find a user by their email
|
23
|
+
def self.find_by_email(email: nil)
|
24
|
+
payload = {}
|
25
|
+
payload[:email] = email if email
|
26
|
+
|
27
|
+
raise ArgumentError, 'You must provide an email' if payload.empty?
|
28
|
+
|
29
|
+
response = post('user.search', payload)
|
30
|
+
response['results']
|
31
|
+
end
|
32
|
+
|
33
|
+
# Finds a user by their Ashby ID
|
34
|
+
def self.find_by_id(id: nil)
|
35
|
+
raise ArgumentError, 'User ID is required' if id.to_s.strip.empty?
|
36
|
+
|
37
|
+
payload = { userId: id }
|
38
|
+
response = post('user.info', payload)
|
39
|
+
response['results']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/ashby.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'ashby/version'
|
4
|
+
require_relative 'ashby/configuration'
|
5
|
+
require_relative 'ashby/client'
|
6
|
+
require_relative 'ashby/candidates'
|
7
|
+
require_relative 'ashby/departments'
|
8
|
+
require_relative 'ashby/jobs'
|
9
|
+
require_relative 'ashby/offers'
|
10
|
+
require_relative 'ashby/applications'
|
11
|
+
require_relative 'ashby/openings'
|
12
|
+
require_relative 'ashby/users'
|
13
|
+
require_relative 'ashby/job_postings'
|
14
|
+
require_relative 'ashby/hiring_teams'
|
15
|
+
require_relative 'ashby/error'
|
16
|
+
require_relative 'ashby/close_reasons'
|
17
|
+
require_relative 'ashby/interviews'
|
18
|
+
require_relative 'ashby/custom_fields'
|
19
|
+
require_relative 'ashby/feedback'
|
20
|
+
require_relative 'ashby/postings'
|
21
|
+
require_relative 'ashby/job_boards'
|
22
|
+
|
23
|
+
# This module handles integration with Ashby's API
|
24
|
+
# for recruitment and hiring processes
|
25
|
+
module Ashby
|
26
|
+
extend Configuration
|
27
|
+
|
28
|
+
class Error < StandardError; end
|
29
|
+
end
|
data/sig/.DS_Store
ADDED
Binary file
|
data/sig/ashby.rbs
ADDED