mirror of
https://github.com/zulip/zulip.git
synced 2025-11-14 10:57:58 +00:00
integrations: Add Greenhouse integration.
This commit is contained in:
BIN
static/images/integrations/greenhouse/000.png
Normal file
BIN
static/images/integrations/greenhouse/000.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
static/images/integrations/logos/greenhouse.png
Normal file
BIN
static/images/integrations/logos/greenhouse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
112
zerver/fixtures/greenhouse/greenhouse_candidate_created.json
Normal file
112
zerver/fixtures/greenhouse/greenhouse_candidate_created.json
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
{
|
||||||
|
"action": "new_candidate_application",
|
||||||
|
"payload": {
|
||||||
|
"application": {
|
||||||
|
"id": 265293,
|
||||||
|
"rejected_at": null,
|
||||||
|
"prospect": false,
|
||||||
|
"status": "active",
|
||||||
|
"applied_at": "2013-03-22T00:00:00Z",
|
||||||
|
"last_activity_at": "2015-03-18T20:28:09Z",
|
||||||
|
"source": {
|
||||||
|
"id": 27,
|
||||||
|
"public_name": "LinkedIn"
|
||||||
|
},
|
||||||
|
"credited_to": null,
|
||||||
|
"rejection_reason": null,
|
||||||
|
"current_stage": {
|
||||||
|
"id": 678901,
|
||||||
|
"name": "Application Review",
|
||||||
|
"interviews": [
|
||||||
|
{
|
||||||
|
"id": 989099,
|
||||||
|
"name":"Application Review",
|
||||||
|
"status": "collect_feedback",
|
||||||
|
"interview_kit": {
|
||||||
|
"url": "http://app.greenhouse.io/guides/67656/people/265788",
|
||||||
|
"content": "",
|
||||||
|
"questions": []
|
||||||
|
},
|
||||||
|
"interviewers": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"candidate": {
|
||||||
|
"id": 265788,
|
||||||
|
"created_at": "2013-10-04T01:24:48Z",
|
||||||
|
"first_name": "Hector",
|
||||||
|
"last_name": "Porter",
|
||||||
|
"title": null,
|
||||||
|
"company": null,
|
||||||
|
"phone_numbers": [
|
||||||
|
{
|
||||||
|
"value": "330-281-8004",
|
||||||
|
"type": "home"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"email_addresses": [
|
||||||
|
{
|
||||||
|
"value": "hector.porter.265788@example.com",
|
||||||
|
"type": "personal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"addresses": [],
|
||||||
|
"website_addresses": [],
|
||||||
|
"social_media_addresses": [],
|
||||||
|
"recruiter": null,
|
||||||
|
"coordinator": null,
|
||||||
|
"photo_url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"filename": "resume.pdf",
|
||||||
|
"url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"type": "resume"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Import from Previous ATS"
|
||||||
|
],
|
||||||
|
"custom_fields": {
|
||||||
|
"favorite_color": {
|
||||||
|
"name": "Favorite Color",
|
||||||
|
"type": "short_text",
|
||||||
|
"value": "Blue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jobs": [
|
||||||
|
{
|
||||||
|
"id": 3485,
|
||||||
|
"name": "Designer",
|
||||||
|
"requisition_id": null,
|
||||||
|
"notes": "Digital and print",
|
||||||
|
"job_post_id": 54321,
|
||||||
|
"status": "open",
|
||||||
|
"created_at": "2013-10-02T22:59:29Z",
|
||||||
|
"opened_at": "2015-01-23T00:25:04Z",
|
||||||
|
"closed_at": null,
|
||||||
|
"departments": [
|
||||||
|
{
|
||||||
|
"id": 237,
|
||||||
|
"name": "Community"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"offices": [
|
||||||
|
{
|
||||||
|
"id": 54,
|
||||||
|
"name": "New York",
|
||||||
|
"location": "New York, NY"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"custom_fields": {
|
||||||
|
"employment_type": {
|
||||||
|
"name": "Employment Type",
|
||||||
|
"type": "single_select",
|
||||||
|
"value": "Full Time"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
184
zerver/fixtures/greenhouse/greenhouse_candidate_hired.json
Normal file
184
zerver/fixtures/greenhouse/greenhouse_candidate_hired.json
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
{
|
||||||
|
"action": "hire_candidate",
|
||||||
|
"payload": {
|
||||||
|
"application": {
|
||||||
|
"id": 20,
|
||||||
|
"opening": {
|
||||||
|
"opening_id": "1234-56"
|
||||||
|
},
|
||||||
|
"credited_to": {
|
||||||
|
"id": 57,
|
||||||
|
"email": "bob_johnson1@localhost.com",
|
||||||
|
"name": "Robert Johnson"
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"id": 25,
|
||||||
|
"public_name": "Monster"
|
||||||
|
},
|
||||||
|
"candidate": {
|
||||||
|
"id": 19,
|
||||||
|
"first_name": "Johnny",
|
||||||
|
"last_name": "Smith",
|
||||||
|
"title": "Previous Title",
|
||||||
|
"external_id": "00000",
|
||||||
|
"phone_numbers": [{
|
||||||
|
"value": "518-555-1212",
|
||||||
|
"type": "work"
|
||||||
|
}, {
|
||||||
|
"value": "212-555-1212",
|
||||||
|
"type": "home"
|
||||||
|
}],
|
||||||
|
"email_addresses": [{
|
||||||
|
"value": "personal@example.com",
|
||||||
|
"type": "personal"
|
||||||
|
}, {
|
||||||
|
"value": "work@example.com",
|
||||||
|
"type": "work"
|
||||||
|
}],
|
||||||
|
"addresses": [{
|
||||||
|
"value": "455 Broadway New York, NY 10280",
|
||||||
|
"type": "home"
|
||||||
|
}],
|
||||||
|
"recruiter": {
|
||||||
|
"id": 55,
|
||||||
|
"email": "bob_johnson@localhost.com",
|
||||||
|
"name": "Bob Johnson"
|
||||||
|
},
|
||||||
|
"coordinator": {
|
||||||
|
"id": 56,
|
||||||
|
"email": "bob_johnson_approver1@localhost.com",
|
||||||
|
"name": "Robert J Approver"
|
||||||
|
},
|
||||||
|
"attachments": [{
|
||||||
|
"filename": "resume.pdf",
|
||||||
|
"url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"type": "resume"
|
||||||
|
}],
|
||||||
|
"custom_fields": {
|
||||||
|
"desired_level": {
|
||||||
|
"name": "Desired Level",
|
||||||
|
"type": "short_text",
|
||||||
|
"value": "Senior"
|
||||||
|
},
|
||||||
|
"favorite_programming_language": {
|
||||||
|
"name": "Favorite Programming Language",
|
||||||
|
"type": "short_text",
|
||||||
|
"value": "Rails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"job": {
|
||||||
|
"id": 20,
|
||||||
|
"name": "Developer",
|
||||||
|
"open_date": "2014-11-20T22:49:14Z",
|
||||||
|
"close_date": "2014-11-25T22:49:14Z",
|
||||||
|
"requisition_id": null,
|
||||||
|
"departments": [{
|
||||||
|
"id": 7,
|
||||||
|
"name": "Technology"
|
||||||
|
}],
|
||||||
|
"offices": [{
|
||||||
|
"id": 13,
|
||||||
|
"name": "New York City",
|
||||||
|
"location": {
|
||||||
|
"name": "New York, NY"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"id": 14,
|
||||||
|
"name": "St. Louis",
|
||||||
|
"location": null
|
||||||
|
}],
|
||||||
|
"custom_fields": {
|
||||||
|
"approved": {
|
||||||
|
"name": "Approved",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
"employment_type": {
|
||||||
|
"name": "Employment Type",
|
||||||
|
"type": "single_select",
|
||||||
|
"value": "Full-time"
|
||||||
|
},
|
||||||
|
"salary_range": {
|
||||||
|
"name": "SalaryRange",
|
||||||
|
"type": "currency_range",
|
||||||
|
"value": {
|
||||||
|
"unit": "USD",
|
||||||
|
"min_value": "10000.0",
|
||||||
|
"max_value": "20000.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jobs": [{
|
||||||
|
"id": 20,
|
||||||
|
"name": "Developer",
|
||||||
|
"opened_at": "2014-11-20T22:49:14Z",
|
||||||
|
"closed_at": "2014-11-25T22:49:14Z",
|
||||||
|
"requisition_id": null,
|
||||||
|
"departments": [{
|
||||||
|
"id": 7,
|
||||||
|
"name": "Technology"
|
||||||
|
}],
|
||||||
|
"offices": [{
|
||||||
|
"id": 13,
|
||||||
|
"name": "New York City",
|
||||||
|
"location": {
|
||||||
|
"name": "New York, NY"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"id": 14,
|
||||||
|
"name": "St. Louis",
|
||||||
|
"location": null
|
||||||
|
}],
|
||||||
|
"custom_fields": {
|
||||||
|
"approved": {
|
||||||
|
"name": "Approved",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
"employment_type": {
|
||||||
|
"name": "Employment Type",
|
||||||
|
"type": "single_select",
|
||||||
|
"value": "Full-time"
|
||||||
|
},
|
||||||
|
"salary_range": {
|
||||||
|
"name": "SalaryRange",
|
||||||
|
"type": "currency_range",
|
||||||
|
"value": {
|
||||||
|
"unit": "USD",
|
||||||
|
"min_value": "10000.0",
|
||||||
|
"max_value": "20000.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"offer": {
|
||||||
|
"id": 13,
|
||||||
|
"version": 2,
|
||||||
|
"created_at": "2014-11-20T22:49:14Z",
|
||||||
|
"sent_at": "2014-11-10",
|
||||||
|
"resolved_at": "2014-11-20T22:49:14Z",
|
||||||
|
"starts_at": "2015-01-23",
|
||||||
|
"custom_fields": {
|
||||||
|
"salary": {
|
||||||
|
"name": "Salary",
|
||||||
|
"type": "currency",
|
||||||
|
"value": {
|
||||||
|
"amount": 80000,
|
||||||
|
"unit": "USD"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"seasons": {
|
||||||
|
"name": "Seasons",
|
||||||
|
"type": "multi_select",
|
||||||
|
"value": [
|
||||||
|
"Season 1",
|
||||||
|
"Season 2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"action": "reject_candidate",
|
||||||
|
"payload": {
|
||||||
|
"application": {
|
||||||
|
"id": 265293,
|
||||||
|
"rejected_at": "2015-02-11T15:50:41Z",
|
||||||
|
"prospect": false,
|
||||||
|
"status": "rejected",
|
||||||
|
"applied_at": "2013-03-22T00:00:00Z",
|
||||||
|
"last_activity_at": "2015-02-11T15:50:41Z",
|
||||||
|
"source": {
|
||||||
|
"id": 27,
|
||||||
|
"public_name": "LinkedIn"
|
||||||
|
},
|
||||||
|
"credited_to": null,
|
||||||
|
"rejection_reason": {
|
||||||
|
"id": 14,
|
||||||
|
"name": "Too Junior",
|
||||||
|
"type": {
|
||||||
|
"id": 3,
|
||||||
|
"name": "Wrong skill set"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"candidate": {
|
||||||
|
"id": 265788,
|
||||||
|
"created_at": "2013-10-04T01:24:48Z",
|
||||||
|
"first_name": "Hector",
|
||||||
|
"last_name": "Porter",
|
||||||
|
"title": null,
|
||||||
|
"company": null,
|
||||||
|
"phone_numbers": [{
|
||||||
|
"value": "330-281-8004",
|
||||||
|
"type": "home"
|
||||||
|
}],
|
||||||
|
"email_addresses": [{
|
||||||
|
"value": "hector.porter.265788@example.com",
|
||||||
|
"type": "personal"
|
||||||
|
}],
|
||||||
|
"addresses": [],
|
||||||
|
"website_addresses": [],
|
||||||
|
"social_media_addresses": [],
|
||||||
|
"recruiter": null,
|
||||||
|
"coordinator": null,
|
||||||
|
"photo_url": "www.example.com/photo.png",
|
||||||
|
"attachments": [{
|
||||||
|
"filename": "resume.pdf",
|
||||||
|
"url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"type": "resume"
|
||||||
|
}],
|
||||||
|
"tags": [
|
||||||
|
"Imported"
|
||||||
|
],
|
||||||
|
"custom_fields": {
|
||||||
|
"favorite_color": {
|
||||||
|
"name": "Favorite Color",
|
||||||
|
"type": "short_text",
|
||||||
|
"value": "Blue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jobs": [{
|
||||||
|
"id": 3485,
|
||||||
|
"name": "Designer",
|
||||||
|
"requisition_id": null,
|
||||||
|
"notes": "Digital and print",
|
||||||
|
"job_post_id": 54321,
|
||||||
|
"status": "open",
|
||||||
|
"created_at": "2013-10-02T22:59:29Z",
|
||||||
|
"opened_at": "2015-01-23T00:25:04Z",
|
||||||
|
"closed_at": null,
|
||||||
|
"departments": [{
|
||||||
|
"id": 237,
|
||||||
|
"name": "Community"
|
||||||
|
}],
|
||||||
|
"offices": [{
|
||||||
|
"id": 54,
|
||||||
|
"name": "New York",
|
||||||
|
"location": "New York, NY"
|
||||||
|
}],
|
||||||
|
"custom_fields": {
|
||||||
|
"employment_type": {
|
||||||
|
"name": "Employment Type",
|
||||||
|
"type": "single_select",
|
||||||
|
"value": "Full Time"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
{
|
||||||
|
"action": "candidate_stage_change",
|
||||||
|
"payload": {
|
||||||
|
"application": {
|
||||||
|
"id": 265277,
|
||||||
|
"rejected_at": null,
|
||||||
|
"prospect": false,
|
||||||
|
"status": "active",
|
||||||
|
"applied_at": "2013-03-22T00:00:00Z",
|
||||||
|
"last_activity_at": "2015-02-09T16:38:36Z",
|
||||||
|
"source": {
|
||||||
|
"id": 31,
|
||||||
|
"name": "Agency"
|
||||||
|
},
|
||||||
|
"credited_to": {
|
||||||
|
"id": 15,
|
||||||
|
"email": "ada@example.com",
|
||||||
|
"name": "Ada Lacey"
|
||||||
|
},
|
||||||
|
"rejection_reason": null,
|
||||||
|
"current_stage": {
|
||||||
|
"id": 71416,
|
||||||
|
"name": "Assessment",
|
||||||
|
"interviews": [{
|
||||||
|
"id": 113101,
|
||||||
|
"name": "Assessment",
|
||||||
|
"status": "to_be_scheduled",
|
||||||
|
"interview_kit": {
|
||||||
|
"url": "https://app.greenhouse.io/guides/113153/people/265772",
|
||||||
|
"content": "Assess their skills",
|
||||||
|
"questions": []
|
||||||
|
},
|
||||||
|
"interviewers": [{
|
||||||
|
"id": 2622,
|
||||||
|
"display_name": "Carl Buddha",
|
||||||
|
"status": "tentative"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"candidate": {
|
||||||
|
"id": 265772,
|
||||||
|
"created_at": "2013-10-04T01:24:44Z",
|
||||||
|
"first_name": "Giuseppe",
|
||||||
|
"last_name": "Hurley",
|
||||||
|
"external_id": "241b399ce4b0fd1c84e5528d",
|
||||||
|
"title": "Great Person",
|
||||||
|
"company": null,
|
||||||
|
"photo_url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"phone_numbers": [{
|
||||||
|
"value": "330-281-8004",
|
||||||
|
"type": "home"
|
||||||
|
}],
|
||||||
|
"email_addresses": [{
|
||||||
|
"value": "giuseppe.hurley@example.com",
|
||||||
|
"type": "personal"
|
||||||
|
}],
|
||||||
|
"addresses": [{
|
||||||
|
"value": "123 Fake St.",
|
||||||
|
"type": "home"
|
||||||
|
}],
|
||||||
|
"website_addresses": [{
|
||||||
|
"value": "ghurley.example.com",
|
||||||
|
"type": "personal"
|
||||||
|
}],
|
||||||
|
"social_media_addresses": [{
|
||||||
|
"value": "linkedin.example.com/ghurley"
|
||||||
|
}],
|
||||||
|
"recruiter": {
|
||||||
|
"id": 3128,
|
||||||
|
"email": "alicia.flopple.3128@example.com",
|
||||||
|
"name": "Alicia Flopple"
|
||||||
|
},
|
||||||
|
"coordinator": {
|
||||||
|
"id": 3128,
|
||||||
|
"email": "alicia.flopple.3128@example.com",
|
||||||
|
"name": "Alicia Flopple"
|
||||||
|
},
|
||||||
|
"attachments": [{
|
||||||
|
"filename": "resume.pdf",
|
||||||
|
"url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"type": "resume"
|
||||||
|
}, {
|
||||||
|
"filename": "cover_letter.pdf",
|
||||||
|
"url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"type": "cover_letter"
|
||||||
|
}, {
|
||||||
|
"filename": "portfolio.pdf",
|
||||||
|
"url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"type": "attachment"
|
||||||
|
}],
|
||||||
|
"tags": [
|
||||||
|
"Import from Previous ATS"
|
||||||
|
],
|
||||||
|
"custom_fields": {
|
||||||
|
"favorite_color": {
|
||||||
|
"name": "Favorite Color",
|
||||||
|
"type": "short_text",
|
||||||
|
"value": "Blue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jobs": [{
|
||||||
|
"id": 3485,
|
||||||
|
"name": "Designer",
|
||||||
|
"requisition_id": null,
|
||||||
|
"notes": "Digital and print",
|
||||||
|
"status": "open",
|
||||||
|
"created_at": "2013-10-02T22:59:29Z",
|
||||||
|
"opened_at": "2015-01-23T00:25:04Z",
|
||||||
|
"closed_at": null,
|
||||||
|
"departments": [{
|
||||||
|
"id": 237,
|
||||||
|
"name": "Community"
|
||||||
|
}],
|
||||||
|
"offices": [{
|
||||||
|
"id": 54,
|
||||||
|
"name": "New York",
|
||||||
|
"location": "New York, NY"
|
||||||
|
}],
|
||||||
|
"custom_fields": {
|
||||||
|
"employment_type": {
|
||||||
|
"name": "Employment Type",
|
||||||
|
"type": "single_select",
|
||||||
|
"value": "Full Time"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
104
zerver/fixtures/greenhouse/greenhouse_prospect_created.json
Normal file
104
zerver/fixtures/greenhouse/greenhouse_prospect_created.json
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
{
|
||||||
|
"action": "new_prospect_application",
|
||||||
|
"payload": {
|
||||||
|
"application": {
|
||||||
|
"id": 979554,
|
||||||
|
"rejected_at": null,
|
||||||
|
"prospect": true,
|
||||||
|
"status": "active",
|
||||||
|
"applied_at": "2014-12-02T23:10:16Z",
|
||||||
|
"last_activity_at": "2014-12-02T23:10:16Z",
|
||||||
|
"current_stage": null,
|
||||||
|
"source": {
|
||||||
|
"id": 13,
|
||||||
|
"public_name": "Referral"
|
||||||
|
},
|
||||||
|
"credited_to": {
|
||||||
|
"id": 2622,
|
||||||
|
"email": "carl.buddha.2622@example.com",
|
||||||
|
"name": "Carl Buddha"
|
||||||
|
},
|
||||||
|
"rejection_reason": null,
|
||||||
|
"candidate": {
|
||||||
|
"id": 968190,
|
||||||
|
"created_at": "2014-12-02T23:10:16Z",
|
||||||
|
"first_name": "Trisha",
|
||||||
|
"last_name": "Troy",
|
||||||
|
"title": null,
|
||||||
|
"company": null,
|
||||||
|
"phone_numbers": [
|
||||||
|
{
|
||||||
|
"value": "123456",
|
||||||
|
"type": "other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"email_addresses": [
|
||||||
|
{
|
||||||
|
"value": "t.troy@example.com",
|
||||||
|
"type": "personal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"addresses": [],
|
||||||
|
"website_addresses": [],
|
||||||
|
"social_media_addresses": [],
|
||||||
|
"recruiter": {
|
||||||
|
"id": 3128,
|
||||||
|
"email": "alicia.flopple.3128@example.com",
|
||||||
|
"name": "Alicia Flopple"
|
||||||
|
},
|
||||||
|
"coordinator": null,
|
||||||
|
"photo_url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"filename": "resume.pdf",
|
||||||
|
"url": "https://prod-heroku.s3.amazonaws.com/...",
|
||||||
|
"type": "resume"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Import from Previous ATS"
|
||||||
|
],
|
||||||
|
"custom_fields": {
|
||||||
|
"favorite_color": {
|
||||||
|
"name": "Favorite Color",
|
||||||
|
"type": "short_text",
|
||||||
|
"value": "Blue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jobs": [
|
||||||
|
{
|
||||||
|
"id": 3485,
|
||||||
|
"name": "Designer",
|
||||||
|
"requisition_id": null,
|
||||||
|
"notes": "Digital and print",
|
||||||
|
"job_post_id": 54321,
|
||||||
|
"status": "open",
|
||||||
|
"created_at": "2013-10-02T22:59:29Z",
|
||||||
|
"opened_at": "2015-01-23T00:25:04Z",
|
||||||
|
"closed_at": null,
|
||||||
|
"departments": [
|
||||||
|
{
|
||||||
|
"id": 237,
|
||||||
|
"name": "Community"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"offices": [
|
||||||
|
{
|
||||||
|
"id": 54,
|
||||||
|
"name": "New York",
|
||||||
|
"location": "New York, NY"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"custom_fields": {
|
||||||
|
"employment_type": {
|
||||||
|
"name": "Employment Type",
|
||||||
|
"type": "single_select",
|
||||||
|
"value": "Full Time"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -133,6 +133,7 @@ WEBHOOK_INTEGRATIONS = [
|
|||||||
),
|
),
|
||||||
WebhookIntegration('gitlab', display_name='GitLab'),
|
WebhookIntegration('gitlab', display_name='GitLab'),
|
||||||
WebhookIntegration('gosquared', display_name='GoSquared'),
|
WebhookIntegration('gosquared', display_name='GoSquared'),
|
||||||
|
WebhookIntegration('greenhouse', display_name='Greenhouse'),
|
||||||
WebhookIntegration('hellosign', display_name='HelloSign'),
|
WebhookIntegration('hellosign', display_name='HelloSign'),
|
||||||
WebhookIntegration('helloworld', display_name='Hello World'),
|
WebhookIntegration('helloworld', display_name='Hello World'),
|
||||||
WebhookIntegration('heroku', display_name='Heroku'),
|
WebhookIntegration('heroku', display_name='Heroku'),
|
||||||
|
|||||||
0
zerver/webhooks/greenhouse/__init__.py
Normal file
0
zerver/webhooks/greenhouse/__init__.py
Normal file
32
zerver/webhooks/greenhouse/doc.html
Normal file
32
zerver/webhooks/greenhouse/doc.html
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<p>
|
||||||
|
First, create a stream where you would like to receive Greenhouse
|
||||||
|
notifications and subscribe all interested parties to the
|
||||||
|
stream. The integration will automatically use the default
|
||||||
|
stream <code>greenhouse</code> if no stream is supplied, though you
|
||||||
|
will still need to create the stream manually even though it's the
|
||||||
|
default.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Next, go to the Zulip settings page and create a bot named
|
||||||
|
Greenhouse. Go to the account settings page of your Greenhouse
|
||||||
|
account and under Webhooks, add the below URL and name the
|
||||||
|
integration, Zulip.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><code>{{ external_api_uri_subdomain }}/v1/external/greenhouse?api_key=abcdefgh&stream=greenhouse</code></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note: <code>api_key</code> must be reconfigured to be the API key of your Zulip bot.<br />
|
||||||
|
If you want to change the stream that receives notifications, change <code>stream=</code> in the URL. <br />
|
||||||
|
To change the topic displayed by the bot, simply append <code>&topic=name</code> to the end of the above URL.
|
||||||
|
Where <code>name</code> is your topic.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Congratulations! You're all set</b><br />
|
||||||
|
Your messages should look like this:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><img class="screenshot" src="/static/images/integrations/greenhouse/000.png" /></p>
|
||||||
|
|
||||||
70
zerver/webhooks/greenhouse/tests.py
Normal file
70
zerver/webhooks/greenhouse/tests.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from typing import Text
|
||||||
|
from zerver.lib.test_classes import WebhookTestCase
|
||||||
|
|
||||||
|
class GreenhouseHookTests(WebhookTestCase):
|
||||||
|
STREAM_NAME = 'greenhouse'
|
||||||
|
URL_TEMPLATE = "/api/v1/external/greenhouse?stream={stream}&api_key={api_key}"
|
||||||
|
FIXTURE_DIR_NAME = 'greenhouse'
|
||||||
|
CONTENT_TYPE = "application/x-www-form-urlencoded"
|
||||||
|
|
||||||
|
def test_message_candidate_hired(self):
|
||||||
|
# type: () -> None
|
||||||
|
expected_subject = "Hire Candidate - 19"
|
||||||
|
expected_message = ("Hire Candidate\n>Johnny Smith\nID: 19"
|
||||||
|
"\nApplying for role:\nDeveloper\n**Emails:**"
|
||||||
|
"\nPersonal\npersonal@example.com\nWork\nwork@example.com\n\n\n>"
|
||||||
|
"**Attachments:**\n[Resume](https://prod-heroku.s3.amazonaws.com/...)\n")
|
||||||
|
|
||||||
|
self.send_and_test_stream_message('candidate_hired',
|
||||||
|
expected_subject,
|
||||||
|
expected_message,
|
||||||
|
content_type=self.CONTENT_TYPE)
|
||||||
|
|
||||||
|
def test_message_candidate_rejected(self):
|
||||||
|
# type: () -> None
|
||||||
|
expected_subject = "Reject Candidate - 265788"
|
||||||
|
expected_message = ("Reject Candidate\n>Hector Porter\nID: "
|
||||||
|
"265788\nApplying for role:\nDesigner"
|
||||||
|
"\n**Emails:**\nPersonal\n"
|
||||||
|
"hector.porter.265788@example.com\n\n\n>"
|
||||||
|
"**Attachments:**\n[Resume](https://prod-heroku.s3.amazonaws.com/...)\n")
|
||||||
|
|
||||||
|
self.send_and_test_stream_message('candidate_rejected',
|
||||||
|
expected_subject,
|
||||||
|
expected_message,
|
||||||
|
content_type=self.CONTENT_TYPE)
|
||||||
|
|
||||||
|
def test_message_candidate_stage_change(self):
|
||||||
|
# type: () -> None
|
||||||
|
expected_subject = "Candidate Stage Change - 265772"
|
||||||
|
expected_message = ("Candidate Stage Change\n>Giuseppe Hurley"
|
||||||
|
"\nID: 265772\nApplying for role:\n"
|
||||||
|
"Designer\n**Emails:**\nPersonal"
|
||||||
|
"\ngiuseppe.hurley@example.com\n\n\n>"
|
||||||
|
"**Attachments:**\n[Resume](https://prod-heroku.s3.amazonaws.com/...)"
|
||||||
|
"\n[Cover_Letter](https://prod-heroku.s3.amazonaws.com/...)"
|
||||||
|
"\n[Attachment](https://prod-heroku.s3.amazonaws.com/...)\n")
|
||||||
|
|
||||||
|
self.send_and_test_stream_message('candidate_stage_change',
|
||||||
|
expected_subject,
|
||||||
|
expected_message,
|
||||||
|
content_type=self.CONTENT_TYPE)
|
||||||
|
|
||||||
|
def test_message_prospect_created(self):
|
||||||
|
# type: () -> None
|
||||||
|
expected_subject = "New Prospect Application - 968190"
|
||||||
|
expected_message = ("New Prospect Application\n>Trisha Troy"
|
||||||
|
"\nID: 968190\nApplying for role:\n"
|
||||||
|
"Designer\n**Emails:**\nPersonal"
|
||||||
|
"\nt.troy@example.com\n\n\n>**Attachments:**"
|
||||||
|
"\n[Resume](https://prod-heroku.s3.amazonaws.com/...)\n")
|
||||||
|
|
||||||
|
self.send_and_test_stream_message('prospect_created',
|
||||||
|
expected_subject,
|
||||||
|
expected_message,
|
||||||
|
content_type=self.CONTENT_TYPE)
|
||||||
|
|
||||||
|
def get_body(self, fixture_name):
|
||||||
|
# type: (Text) -> Text
|
||||||
|
return self.fixture_data("greenhouse", fixture_name, file_type="json")
|
||||||
64
zerver/webhooks/greenhouse/view.py
Normal file
64
zerver/webhooks/greenhouse/view.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.http import HttpRequest, HttpResponse
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from zerver.lib.actions import check_send_message
|
||||||
|
from zerver.lib.response import json_success, json_error
|
||||||
|
from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view
|
||||||
|
from zerver.models import UserProfile, Client
|
||||||
|
|
||||||
|
import ujson
|
||||||
|
|
||||||
|
MESSAGE_TEMPLATE = "Applying for role:\n{}\n**Emails:**\n{}\n\n>**Attachments:**\n{}"
|
||||||
|
|
||||||
|
def dict_list_to_string(some_list):
|
||||||
|
# type: (List[Any]) -> str
|
||||||
|
internal_template = ''
|
||||||
|
for item in some_list:
|
||||||
|
item_type = item.get('type', '').title()
|
||||||
|
item_value = item.get('value')
|
||||||
|
item_url = item.get('url')
|
||||||
|
if item_type and item_value:
|
||||||
|
internal_template += "{}\n{}\n".format(item_type, item_value)
|
||||||
|
elif item_type and item_url:
|
||||||
|
internal_template += "[{}]({})\n".format(item_type, item_url)
|
||||||
|
return internal_template
|
||||||
|
|
||||||
|
def message_creator(action, application):
|
||||||
|
# type: (str, Dict[str, Any]) -> str
|
||||||
|
message = MESSAGE_TEMPLATE.format(
|
||||||
|
application['jobs'][0]['name'],
|
||||||
|
dict_list_to_string(application['candidate']['email_addresses']),
|
||||||
|
dict_list_to_string(application['candidate']['attachments']))
|
||||||
|
return message
|
||||||
|
|
||||||
|
@api_key_only_webhook_view('Greenhouse')
|
||||||
|
@has_request_variables
|
||||||
|
def api_greenhouse_webhook(request, user_profile, client,
|
||||||
|
payload=REQ(argument_type='body'),
|
||||||
|
stream=REQ(default='greenhouse'), topic=REQ(default=None)):
|
||||||
|
# type: (HttpRequest, UserProfile, Client, Dict[str, Any], str, str) -> HttpResponse
|
||||||
|
try:
|
||||||
|
if payload['action'] == 'update_candidate':
|
||||||
|
candidate = payload['payload']['candidate']
|
||||||
|
else:
|
||||||
|
candidate = payload['payload']['application']['candidate']
|
||||||
|
action = payload['action'].replace('_', ' ').title()
|
||||||
|
body = "{}\n>{} {}\nID: {}\n{}".format(
|
||||||
|
action,
|
||||||
|
candidate['first_name'],
|
||||||
|
candidate['last_name'],
|
||||||
|
str(candidate['id']),
|
||||||
|
message_creator(payload['action'],
|
||||||
|
payload['payload']['application']))
|
||||||
|
|
||||||
|
if topic is None:
|
||||||
|
topic = "{} - {}".format(action, str(candidate['id']))
|
||||||
|
|
||||||
|
except KeyError as e:
|
||||||
|
return json_error(_("Missing key {} in JSON").format(str(e)))
|
||||||
|
|
||||||
|
check_send_message(user_profile, client, 'stream', [stream], topic, body)
|
||||||
|
return json_success()
|
||||||
Reference in New Issue
Block a user