github.com/schmorrison/Zoho@v1.1.4/recruit/jobopenings.go (about) 1 package recruit 2 3 import ( 4 "encoding/xml" 5 "fmt" 6 "strconv" 7 "time" 8 9 zoho "github.com/schmorrison/Zoho" 10 ) 11 12 // https://www.zoho.com/recruit/developer-guide/apiv2/get-records.html 13 func (c *API) GetJobOpenings( 14 params map[string]zoho.Parameter, 15 ) (data JobOpeningsResponse, err error) { 16 endpoint := zoho.Endpoint{ 17 Name: "GetJobOpenings", 18 URL: fmt.Sprintf( 19 "https://recruit.zoho.%s/recruit/v2/%s", 20 c.ZohoTLD, 21 JobOpeningsModule, 22 ), 23 Method: zoho.HTTPGet, 24 ResponseData: &JobOpeningsResponse{}, 25 URLParameters: map[string]zoho.Parameter{ 26 "fields": "", 27 "sort_order": "", 28 "sort_by": "", 29 "converted": "false", 30 "approved": "true", 31 "page": "1", 32 "per_page": "200", 33 "cvid": "", 34 "territory_id": "", 35 "include_child": "", 36 }, 37 } 38 39 if len(params) > 0 { 40 for k, v := range params { 41 endpoint.URLParameters[k] = v 42 } 43 } 44 45 err = c.Zoho.HTTPRequest(&endpoint) 46 if err != nil { 47 return JobOpeningsResponse{}, fmt.Errorf("failed to retrieve JobOpenings: %s", err) 48 } 49 50 if v, ok := endpoint.ResponseData.(*JobOpeningsResponse); ok { 51 return *v, nil 52 } 53 54 return JobOpeningsResponse{}, fmt.Errorf("no 'JobOpeningsResponse' returned") 55 } 56 57 // https://www.zoho.com/recruit/developer-guide/apiv2/get-records.html 58 func (c *API) GetJobOpeningsById(id string) (data JobOpeningsResponse, err error) { 59 endpoint := zoho.Endpoint{ 60 Name: "GetJobOpeningsById", 61 URL: fmt.Sprintf( 62 "https://recruit.zoho.%s/recruit/v2/%s/%s", 63 c.ZohoTLD, 64 JobOpeningsModule, 65 id, 66 ), 67 Method: zoho.HTTPGet, 68 ResponseData: &JobOpeningsResponse{}, 69 } 70 71 err = c.Zoho.HTTPRequest(&endpoint) 72 if err != nil { 73 return JobOpeningsResponse{}, fmt.Errorf("failed to retrieve JobOpening with id: %s", err) 74 } 75 76 if v, ok := endpoint.ResponseData.(*JobOpeningsResponse); ok { 77 return *v, nil 78 } 79 80 return JobOpeningsResponse{}, fmt.Errorf("no 'JobOpeningsResponse' returned") 81 } 82 83 // https://www.zoho.com/recruit/developer-guide/apiv2/search-records.html 84 func (c *API) SearchJobOpenings( 85 params map[string]zoho.Parameter, 86 ) (data JobOpeningsResponse, err error) { 87 endpoint := zoho.Endpoint{ 88 Name: "SearchJobOpenings", 89 URL: fmt.Sprintf( 90 "https://recruit.zoho.%s/recruit/v2/%s/search", 91 c.ZohoTLD, 92 JobOpeningsModule, 93 ), 94 Method: zoho.HTTPGet, 95 ResponseData: &JobOpeningsResponse{}, 96 URLParameters: map[string]zoho.Parameter{ 97 "per_page": "200", 98 }, 99 } 100 101 if len(params) > 0 { 102 for k, v := range params { 103 endpoint.URLParameters[k] = v 104 } 105 } 106 107 // log.Printf("%+v\n", endpoint) 108 109 err = c.Zoho.HTTPRequest(&endpoint) 110 if err != nil { 111 return JobOpeningsResponse{}, fmt.Errorf( 112 "failed to retrieve searched %s: %s", 113 JobOpeningsModule, 114 err.Error(), 115 ) 116 } 117 118 if v, ok := endpoint.ResponseData.(*JobOpeningsResponse); ok { 119 return *v, nil 120 } 121 122 return JobOpeningsResponse{}, fmt.Errorf("no 'JobOpeningsResponse' returned") 123 } 124 125 type JobOpening struct { 126 ClientName struct { 127 Name string `json:"name,omitempty"` 128 ID string `json:"id,omitempty"` 129 } `json:"Client_Name,omitempty"` 130 Salary interface{} `json:"Salary,omitempty"` 131 CurrencySymbol string `json:"$currency_symbol,omitempty"` 132 AccountManager struct { 133 Name string `json:"name,omitempty"` 134 ID string `json:"id,omitempty"` 135 } `json:"Account_Manager,omitempty"` 136 NoOfCandidatesHired int `json:"No_of_Candidates_Hired,omitempty"` 137 TargetDate string `json:"Target_Date,omitempty"` 138 LastActivityTime time.Time `json:"Last_Activity_Time,omitempty"` 139 Industry string `json:"Industry,omitempty"` 140 ModifiedBy struct { 141 Name string `json:"name,omitempty"` 142 ID string `json:"id,omitempty"` 143 } `json:"Modified_By,omitempty"` 144 ProcessFlow bool `json:"$process_flow,omitempty"` 145 ExpectedRevenue int `json:"Expected_Revenue,omitempty"` 146 IsHotJobOpening bool `json:"Is_Hot_Job_Opening,omitempty"` 147 ZipCode string `json:"Zip_Code,omitempty"` 148 ID string `json:"id,omitempty"` 149 Approved bool `json:"$approved,omitempty"` 150 Publish bool `json:"Publish,omitempty"` 151 DateOpened string `json:"Date_Opened,omitempty"` 152 Approval struct { 153 Delegate bool `json:"delegate,omitempty"` 154 Approve bool `json:"approve,omitempty"` 155 Reject bool `json:"reject,omitempty"` 156 Resubmit bool `json:"resubmit,omitempty"` 157 } `json:"$approval,omitempty"` 158 ModifiedTime time.Time `json:"Modified_Time,omitempty"` 159 ActualRevenue interface{} `json:"Actual_Revenue,omitempty"` 160 RemoteJob bool `json:"Remote_Job,omitempty"` 161 CreatedTime time.Time `json:"Created_Time,omitempty"` 162 Followed bool `json:"$followed,omitempty"` 163 NoOfCandidatesAssociated int `json:"No_of_Candidates_Associated,omitempty"` 164 Editable bool `json:"$editable,omitempty"` 165 IsLocked bool `json:"Is_Locked,omitempty"` 166 City string `json:"City,omitempty"` 167 JobOpeningStatus string `json:"Job_Opening_Status,omitempty"` 168 RevenuePerPosition int `json:"Revenue_per_Position,omitempty"` 169 ContactName struct { 170 Name string `json:"name,omitempty"` 171 ID string `json:"id,omitempty"` 172 } `json:"Contact_Name,omitempty"` 173 AssociatedTags []struct { 174 Name string `json:"name,omitempty"` 175 ID string `json:"id,omitempty"` 176 } `json:"Associated_Tags,omitempty"` 177 AssignedRecruiter []struct { 178 Name string `json:"name,omitempty"` 179 ID string `json:"id,omitempty"` 180 Email string `json:"email,omitempty"` 181 PhotoSrc string `json:"photoSrc,omitempty"` 182 } `json:"Assigned_Recruiter,omitempty"` 183 MissedRevenue interface{} `json:"Missed_Revenue,omitempty"` 184 JobOpeningID string `json:"Job_Opening_ID,omitempty"` 185 JobDescription string `json:"Job_Description,omitempty"` 186 WorkExperience string `json:"Work_Experience,omitempty"` 187 JobType string `json:"Job_Type,omitempty"` 188 JobOpeningName string `json:"Job_Opening_Name,omitempty"` 189 NumberOfPositions string `json:"Number_of_Positions,omitempty"` 190 State string `json:"State,omitempty"` 191 Country string `json:"Country,omitempty"` 192 CreatedBy struct { 193 Name string `json:"name,omitempty"` 194 ID string `json:"id,omitempty"` 195 } `json:"Created_By,omitempty"` 196 IsAttachmentPresent bool `json:"Is_Attachment_Present,omitempty"` 197 } 198 199 type JobOpeningsResponse struct { 200 Data []JobOpening `json:"data,omitempty"` 201 Info PageInfo `json:"info,omitempty"` 202 } 203 204 // https://www.zoho.com/recruit/developer-guide/apiv2/get-associated-records.html 205 func (c *API) GetAssociatedCandidates( 206 recordId string, 207 ) (data AssociatedCandidatesResponse, err error) { 208 endpoint := zoho.Endpoint{ 209 Name: "GetAssociatedCandidates", 210 URL: fmt.Sprintf( 211 "https://recruit.zoho.%s/recruit/v2/%s/%s/associate", 212 c.ZohoTLD, 213 Job_OpeningsModule, 214 recordId, 215 ), 216 Method: zoho.HTTPGet, 217 ResponseData: &AssociatedCandidatesResponse{}, 218 } 219 220 err = c.Zoho.HTTPRequest(&endpoint) 221 if err != nil { 222 return AssociatedCandidatesResponse{}, fmt.Errorf( 223 "failed to get associated candidates of %s: %s", 224 JobOpeningsModule, 225 err.Error(), 226 ) 227 } 228 229 if v, ok := endpoint.ResponseData.(*AssociatedCandidatesResponse); ok { 230 return *v, nil 231 } 232 233 return AssociatedCandidatesResponse{}, fmt.Errorf("no 'AssociatedCandidatesResponse' returned") 234 } 235 236 type AssociatedCandidatesResponse struct { 237 Data []struct { 238 Origin string `json:"Origin"` 239 Email string `json:"Email"` 240 CurrencySymbol string `json:"$currency_symbol"` 241 LastActivityTime time.Time `json:"Last_Activity_Time"` 242 HighestQualificationHeld interface{} `json:"Highest_Qualification_Held"` 243 SkillSet interface{} `json:"Skill_Set"` 244 Converted bool `json:"$converted"` 245 ProcessFlow bool `json:"$process_flow"` 246 UpdatedOn time.Time `json:"Updated_On"` 247 CurrentEmployer string `json:"Current_Employer"` 248 Street interface{} `json:"Street"` 249 ZipCode interface{} `json:"Zip_Code"` 250 ID string `json:"id"` 251 ExperienceInYears int `json:"Experience_in_Years"` 252 Approved bool `json:"$approved"` 253 Approval struct { 254 Delegate bool `json:"delegate"` 255 Approve bool `json:"approve"` 256 Reject bool `json:"reject"` 257 Resubmit bool `json:"resubmit"` 258 } `json:"$approval"` 259 CandidateStatus string `json:"Candidate_Status"` 260 CandidateID string `json:"Candidate_ID"` 261 LastMailedTime interface{} `json:"Last_Mailed_Time"` 262 CreatedTime time.Time `json:"Created_Time"` 263 Followed bool `json:"$followed"` 264 CandidateOwner struct { 265 Name string `json:"name"` 266 ID string `json:"id"` 267 } `json:"Candidate_Owner"` 268 Editable bool `json:"$editable"` 269 IsLocked bool `json:"Is_Locked"` 270 City string `json:"City"` 271 IsUnqualified bool `json:"Is_Unqualified"` 272 AssociatedTags []interface{} `json:"Associated_Tags"` 273 AdditionalInfo interface{} `json:"Additional_Info"` 274 State interface{} `json:"State"` 275 Country interface{} `json:"Country"` 276 CreatedBy struct { 277 Name string `json:"name"` 278 ID string `json:"id"` 279 } `json:"Created_By"` 280 SecondaryEmail interface{} `json:"Secondary_Email"` 281 IsAttachmentPresent bool `json:"Is_Attachment_Present"` 282 Rating interface{} `json:"Rating"` 283 AppliedWithLinkedin interface{} `json:"$applied_with_linkedin"` 284 Website interface{} `json:"Website"` 285 Twitter interface{} `json:"Twitter"` 286 CurrentJobTitle string `json:"Current_Job_Title"` 287 Salutation interface{} `json:"Salutation"` 288 Source string `json:"Source"` 289 FirstName string `json:"First_Name"` 290 FullName string `json:"Full_Name"` 291 ModifiedBy struct { 292 Name string `json:"name"` 293 ID string `json:"id"` 294 } `json:"Modified_By"` 295 SkypeID interface{} `json:"Skype_ID"` 296 Phone interface{} `json:"Phone"` 297 EmailOptOut bool `json:"Email_Opt_Out"` 298 ConvertedDetail struct { 299 } `json:"$converted_detail"` 300 CareerPageInviteStatus string `json:"Career_Page_Invite_Status"` 301 Mobile string `json:"Mobile"` 302 LastName string `json:"Last_Name"` 303 CurrentSalary interface{} `json:"Current_Salary"` 304 AssociatedAnySocialProfiles interface{} `json:"Associated_any_Social_Profiles"` 305 Fax interface{} `json:"Fax"` 306 ExpectedSalary interface{} `json:"Expected_Salary"` 307 } `json:"data"` 308 Info PageInfo `json:"info,omitempty"` 309 } 310 311 // ============================== ABANDONED DUE TO ZOHO API v1 not properly working ============================== 312 // https://help.zoho.com/portal/en/kb/recruit/developer-guide/api-methods/articles/getsearchrecords 313 func (c *API) XMLSearchJobOpenings( 314 params map[string]zoho.Parameter, 315 ) (data JobOpeningsResponse, err error) { 316 endpoint := zoho.Endpoint{ 317 Name: "XMLSearchJobOpenings", 318 URL: fmt.Sprintf( 319 "https://recruit.zoho.%s/recruit/private/xml/%s/getSearchRecords", 320 c.ZohoTLD, 321 JobOpeningsModule, 322 ), 323 Method: zoho.HTTPGet, 324 ResponseData: &XMLJobOpeningsResponse{}, 325 URLParameters: map[string]zoho.Parameter{ 326 "fromIndex": "1", // Integer | Default value - 1 327 "toIndex": "200", // Integer | Default value - 20 | Maximum value - 200 328 "version": "2", // This will fetch responses based on the latest API implementation. 329 "newFormat": "1", // 1 - To exclude fields with "null" values while inserting data from your Recruit account. 330 "selectColumns": "(ALL)", // mandatory eg: (Job Description) | Module(Job Description) 331 "searchCondition": "", // mandatory eg: (Associated Tags|=|JobIsPublished) 332 }, 333 } 334 335 if len(params) > 0 { 336 for k, v := range params { 337 endpoint.URLParameters[k] = v 338 } 339 } 340 341 // log.Printf("%s\n", endpoint) 342 343 err = c.Zoho.HTTPRequest(&endpoint) 344 if err != nil { 345 return JobOpeningsResponse{}, fmt.Errorf( 346 "failed to retrieve XML searched %s: %s", 347 JobOpeningsModule, 348 err.Error(), 349 ) 350 } 351 352 if v, ok := endpoint.ResponseData.(*XMLJobOpeningsResponse); ok { 353 // Convert to Json 354 total, _ := strconv.Atoi(v.Result.JobOpenings.Row.No) 355 dataXML := v.Result.JobOpenings.Row.FL 356 357 res := &JobOpeningsResponse{} 358 items := make([]JobOpening, 0) 359 360 for i := 0; i <= total; i++ { 361 switch dataXML[i].Val { 362 case "JOBOPENINGID": 363 items = append(items, JobOpening{ID: dataXML[i].Text}) 364 case "CLIENTID": 365 items = append(items, JobOpening{}) 366 case "Client Name": 367 items = append(items, JobOpening{}) 368 case "Posting Title": 369 items = append(items, JobOpening{JobOpeningName: dataXML[i].Text}) 370 case "Job Opening ID": 371 items = append(items, JobOpening{JobOpeningID: dataXML[i].Text}) 372 case "Job Description": 373 items = append(items, JobOpening{JobDescription: dataXML[i].Text}) 374 } 375 } 376 377 res.Data = items 378 379 return *res, nil 380 } 381 382 return JobOpeningsResponse{}, fmt.Errorf("no 'JobOpeningsResponse' returned") 383 } 384 385 // https://help.zoho.com/portal/en/kb/recruit/developer-guide/api-methods/articles/getrecordbyid#Purpose 386 func (c *API) XMLgetRecordById(params map[string]zoho.Parameter) (data JobOpening, err error) { 387 endpoint := zoho.Endpoint{ 388 Name: "XMLgetRecordById", 389 URL: fmt.Sprintf( 390 "https://recruit.zoho.%s/recruit/private/xml/%s/getRecordById", 391 c.ZohoTLD, 392 JobOpeningsModule, 393 ), 394 Method: zoho.HTTPGet, 395 ResponseData: &XMLJobOpeningsResponse{}, 396 URLParameters: map[string]zoho.Parameter{ 397 "id": "", // mandatory 398 "version": "2", // This will fetch responses based on the latest API implementation. 399 "newFormat": "1", // 1 - To exclude fields with "null" values while inserting data from your Recruit account. 400 }, 401 } 402 403 if len(params) > 0 { 404 for k, v := range params { 405 endpoint.URLParameters[k] = v 406 } 407 } 408 409 // log.Printf("%s\n", endpoint) 410 411 err = c.Zoho.HTTPRequest(&endpoint) 412 if err != nil { 413 return JobOpening{}, fmt.Errorf( 414 "failed to retrieve XML searched %s: %s", 415 JobOpeningsModule, 416 err.Error(), 417 ) 418 } 419 420 if v, ok := endpoint.ResponseData.(*XMLJobOpeningsResponse); ok { 421 // Convert to Json 422 xmlData := v.Result.JobOpenings.Row.FL 423 res := &data 424 425 for _, item := range xmlData { 426 switch item.Val { 427 case "Job Description": 428 data.JobDescription = item.Text 429 } 430 } 431 return *res, nil 432 } 433 434 return JobOpening{}, fmt.Errorf("no 'JobOpening' returned") 435 } 436 437 type XMLJobOpeningsResponse struct { 438 XMLName xml.Name `xml:"response"` 439 Text string `xml:",chardata"` 440 URI string `xml:"uri,attr"` 441 Result struct { 442 Text string `xml:",chardata"` 443 JobOpenings struct { 444 Text string `xml:",chardata"` 445 Row struct { 446 Text string `xml:",chardata"` 447 No string `xml:"no,attr"` 448 FL []struct { 449 Text string `xml:",chardata"` 450 Val string `xml:"val,attr"` 451 } `xml:"FL"` 452 } `xml:"row"` 453 } `xml:"JobOpenings"` 454 } `xml:"result"` 455 } 456 457 // https://help.zoho.com/portal/en/kb/recruit/developer-guide/api-methods/articles/getrecords#Request_Parameters 458 func (c *API) XMLGetRecords( 459 params map[string]zoho.Parameter, 460 ) (data XMLGetRecordsResponse, err error) { 461 endpoint := zoho.Endpoint{ 462 Name: "XMLGetRecords", 463 URL: fmt.Sprintf( 464 "https://recruit.zoho.%s/recruit/private/xml/%s/getRecordById", 465 c.ZohoTLD, 466 JobOpeningsModule, 467 ), 468 Method: zoho.HTTPGet, 469 ResponseData: &XMLGetRecordsResponse{}, 470 URLParameters: map[string]zoho.Parameter{ 471 "version": "2", // This will fetch responses based on the latest API implementation. 472 "id": "", // 1 - To exclude fields with "null" values while inserting data from your Recruit account. 473 "selectColumns": "", // mandatory eg: (Job Description) | Module(Job Description) 474 }, 475 } 476 477 if len(params) > 0 { 478 for k, v := range params { 479 endpoint.URLParameters[k] = v 480 } 481 } 482 483 // log.Printf("ENDPOINT: %s\n", endpoint) 484 485 err = c.Zoho.HTTPRequest(&endpoint) 486 if err != nil { 487 return XMLGetRecordsResponse{}, fmt.Errorf( 488 "failed to retrieve XML get %s: %s", 489 JobOpeningsModule, 490 err.Error(), 491 ) 492 } 493 494 if v, ok := endpoint.ResponseData.(*XMLGetRecordsResponse); ok { 495 return *v, nil 496 } 497 498 return XMLGetRecordsResponse{}, fmt.Errorf("no 'XMLGetRecordsResponse' returned") 499 } 500 501 type XMLGetRecordsResponse struct { 502 XMLName xml.Name `xml:"response"` 503 Text string `xml:",chardata"` 504 URI string `xml:"uri,attr"` 505 Result struct { 506 Text string `xml:",chardata"` 507 JobOpenings struct { 508 Text string `xml:",chardata"` 509 Row struct { 510 Text string `xml:",chardata"` 511 No string `xml:"no,attr"` 512 FL []struct { 513 Text string `xml:",chardata"` 514 Val string `xml:"val,attr"` 515 } `xml:"FL"` 516 } `xml:"row"` 517 } `xml:"JobOpenings"` 518 } `xml:"result"` 519 }