NodeJS ATSを作成するためのスポンサー求人API連携ガイド
採用企業がATSでスポンサー求人キャンペーンを作成できるアプリを構築します。
Indeed の API の使用について Indeed と書面による契約を締結していない場合、この API またはそのドキュメントを使用することにより、Indeed の API の使用には Indeed API Terms (新しいウィンドウで開きます) および Additional API Terms and Guidelines が適用されることに同意したものとみなされます。
連携の概要
#このガイドでは、ATSパートナー向けに、採用企業がATSでスポンサー求人キャンペーンを作成できるNodeJS Expressアプリの構築方法を説明します。
- Framework: Node.jsを使用します。
- OAuth: 3-legged OAuthを使用します。
- Sample code: Sponsored Job Campaigns API (新しいウィンドウで開きます)をご覧ください。
サンプルアプリでは、次の方法を示します。
- XML求人フィードを使用してATSの求人をIndeedと共有する
- 3-legged OAuthを使用して、採用企業に代わってATSがスポンサー求人APIを呼び出せるように認可する
/campaignsエンドポイントを呼び出してスポンサー求人キャンペーンを作成する
GitHubのindeedeng/sponsored-jobs-nodejs-auth-code (新しいウィンドウで開きます)からサンプルアプリのコードをダウンロードします。
連携手順
#1. Indeedアカウントを作成する
#アプリケーション用のIndeedユーザーアカウントを作成します。
- jp.indeed.com (新しいウィンドウで開きます)にアクセスします。
- サインインしている場合は、Profileメニューを開き、Sign outを選択します。
- Sign inを選択します。
- **New to Indeed?**を選択します。
- メールアドレスとパスワードを入力します。
2. アプリを登録する
#Indeed パートナーになると、Indeed が連携用のアプリを作成します。Partner Console (新しいウィンドウで開きます) にサインインすると、アプリと OAuth 認証情報(クライアント ID とシークレット)を確認できます。API 呼び出しを認証するには、これらの認証情報をアクセストークンと交換します。
OAuth 2.0クレデンシャルタイプには、次の値を入力します。
アプリを登録する 項目 値 Public client アプリがパブリッククライアントかどうかを指定します。
アプリがATSサイトにATS JavaScriptプラグインを組み込む場合は、This application is a public clientを選択します。
Allowed grant types 認可コード付与タイプを選択します。 Redirect URL 1つ以上のリダイレクトURLです。
アプリがATSサイトにATS JavaScriptプラグインを組み込む場合は、プラグインを読み込むページのURLを追加します。
Save and continueを選択します。
Indeedがアプリをレビューするかどうかを選択し、Save and continueを選択します。レビューを省略すると、アプリがレビューされていないことを示す警告がユーザーに表示されます。
必要に応じて会社情報を追加し、Save and continueを選択します。
アプリ情報をプレビューし、Complete registrationを選択します。
ページにはクライアントIDと、パブリッククライアント以外の場合はクライアントシークレットが表示されます。これらのクレデンシャルは安全に保管してください。共有したり、公開Gitリポジトリにコミットしたりしないでください。
3. NodeJS Expressアプリを作成する
#サンプルのNode.js Expressアプリでは、Indeed APIを呼び出すために、オープンソースのopenid-clientライブラリを使用します。
-
Node.jsとnpmをダウンロードしてインストールします。
Downloading and installing Node.js and npm (新しいウィンドウで開きます)をご覧ください。
-
HandlebarsJSビューエンジンを使用して
Find-TalentExpressアプリを生成します。npx express-generator Find-Talent --view=hbs --git--gitオプションにより、Express用の.gitignoreファイ ルが生成されます。 -
package.jsonがあるディレクトリに移動します。 -
必要なnpmパッケージをインストールします。
npm install -
package.jsonにopenid-clientライブラリを追加します。npm install openid-client -
オープンソースのAxiosライブラリを追加します。
npm install axios -
Expressアプリを起動します。
npm start -
http://localhost:3000/ (新しいウィンドウで開きます)を開きます。
Welcome to Expressというメッセージが表示された、デフォルトのExpressインデックスページが表示されます。
4. アプリを設定する
#Expressアプリを設定するには、設定ファイルを作成し、セッション状態を設定して、Bootstrapを有効にします。
config.jsファイルを作成する
#シークレットを保存するには、Find-Talentアプリのルートにconfig.jsファイルを作成します。
const config = { oysterBaseURL: 'https://apis.indeed.com/ads/v1', oauthDiscovery: 'https://secure.indeed.com/.well-known/openid-configuration', oauthClientId: '90f9f4bd6a34cac31daebe1a093a606ce6b34e91ae6cfa139432ae387269a529', oauthClientSecret: 'bML2BGshr8mLng6d1c1qCujH2PgblxEJwW5WqLxpr32XWfAFSonlhIE07buG7Nlr', oauthRedirectURL: 'http://localhost:3000/oauth-callback', scope: 'employer_access offline_access employer.advertising.account.read employer.advertising.campaign', sessionSecret: 'Something Secret!',};
module.exports = config;scope設定には、OAuthアプリに必要な権限を指定します。たとえば、スポンサー求人キャンペーンを作成するには、employer.advertising.campaignを含めます。スコープの一覧については、ATS連携向けスポンサー求人APIスコープをご覧ください。
oauthClientIdとoauthClientSecretは、登録済みOAuthアプリのクライアントIDとシ ークレットに置き換えてください。Manage app credentials (新しいウィンドウで開きます)ページで確認できます。
Expressは、セッション状態にsessionSecretを使用します。Something Secret!は、独自のシークレットに置き換えてください。
config.jsにはシークレットが含まれているため、このファイルを公開しないでください。たとえば、公開GitHubリポジトリに保存しないでください。
セッション状態を設定する
#アクセストークンを繰り返し要求しないようにするには、トークンをセッション状態に保存します。セッション状態を有効にするには、次のコマンドを実行します。
npm install express-sessionこのコマンドにより、package.jsonに依存関係が追加されます。
次に、app.jsでセッション状態を設定します。ファイルの先頭付近に次のコードを追加します。
const config = require('./config');const session = require('express-session');次に、この行を探します。
var app=express(); その下に次のコードを追加します。
// session setupapp.use(session({ secret: config.sessionSecret, resave: false, saveUninitialized: true, cookie: { secure: false },}));コントローラーでは、req.sessionを使用してリクエスト間でデータを保存します。
Bootstrapを設定する
#アプリをすばやくスタイリングするには、オープンソースのBootstrap CSSフレームワークを使用します。views/layout.hbsで、<title>タグの下に次のコードを追加します。
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>完全なlayout.hbsテンプレートは次のとおりです。
<!DOCTYPE html><html> <head> <title>Sponsor Jobs</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
<link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> {{>header}} <div class="container"> {{{body}}} </div> </body></html>5. XML求人フィードを公開する
#採用企業がIndeedで求人をスポンサーするには、Indeedがその求人を認識している必要があります。ATSでホストしている求人をIndeedで利用できるようにするには 、このセクションで説明する形式でXML求人フィードを公開します。
静的な求人一覧を返す
#実際のATSでは、採用企業の求人はデータベースに保存されます。サンプルアプリを簡潔に保つために、静的な求人一覧を返すメソッドを作成します。
static listJobs() { return [ { id: 2312, title: 'Product Manager', description: 'Manage products', posted: new Date('1/12/2021'), url: 'https://example.com/job/2312', city: 'Seattle', state: 'WA', country: 'USA', }, { id: 2313, title: 'Python Engineer', description: 'Must be an expert in Django.', posted: new Date('1/12/2021'), url: 'https://example.com/job/2313', city: 'Seattle', state: 'WA', country: 'USA', }, { id: 2314, title: 'Senior Python Engineer', description: 'Must be an expert in Django.', posted: new Date('1/12/2021'), url: 'https://example.com/job/2314', city: 'Seattle', state: 'WA', country: 'USA', }, ];}このメソッドは、\services\JobService.jsにあります。
npm XMLライブラリをインストールする
#求人一覧をXMLに変換するには、Node Package Manager(npm)のXMLライブラリをインストールします。
npm install xml各求人にsourceNameを追加する
#各求人には、Indeedが必要とするすべてのデータ、特にreferenceNumberとsourceNameが含まれている必要があります。services\JobService.jsにもあるこのメソッドが 、そのデータを追加します。
static listJobsAsXML() { const jobs = this.listJobs().map((j) => ({ job: [ { title: { _cdata: j.title } }, { description: { _cdata: j.description } }, { date: { _cdata: j.posted } }, { referenceNumber: { _cdata: j.id } }, { url: { _cdata: j.url } }, { company: { _cdata: 'US Robotics and Mechanical Men' } }, { sourceName: { _cdata: 'Apple' } }, { city: { _cdata: j.city } }, { state: { _cdata: j.state } }, { country: { _cdata: j.country } }, { email: { _cdata: 'your_email@your_company.com' } }, { metadata: { _cdata: '' } }, ], }));
return [ { source: [ { publisher: 'Superhero ATS' }, { publisherurl: 'https://example.com' }, { lastBuildDate: Date() }, ...jobs, ], }, ];}listJobsAsXML()メソッドは、各求人をIndeedが読み取れる形式に変換します。各求人には、一意のIDであるreferenceNumberと、Appleに設定したsourceNameの両方が含まれます。IndeedはsourceNameを使用して、各求人を正しい採用企業に関連付けます。
XML求人フィードのルートを追加する
#次に、求人一覧をXMLとして公開します。アプリのroutesフォルダに、次のjobFeed.jsファイルを追加します。
const express = require('express');const xml = require('xml');const JobService = require('../services/JobService');
const router = express.Router();
router.get('/', async (req, res) => { res.contentType('application/xml'); res.send(xml(JobService.listJobsAsXML(), true));});
module.exports = router;このルートはlistJobsAsXML()メソッドを呼び出し、その結果をXMLライブラリに渡します。これにより、Indeedが読み取れる形式のXMLとして求人一覧を公開します。
<source> <publisher>Superhero ATS</publisher> <publisherurl>https://example.com</publisherurl> <lastBuildDate>Mon May 24 2021 14:43:59 GMT-0700 (Pacific Daylight Time)</lastBuildDate> <job> <title><![CDATA[Product Manager]]></title> <description><![CDATA[Manage products]]></description> <date><![CDATA[Tue Jan 12 2021 00:00:00 GMT-0800 (Pacific Standard Time)]]></date> <referenceNumber><![CDATA[2312]]></referenceNumber> <url><![CDATA[https://example.com/job/2312]]></url> <company><![CDATA[US Robotics and Mechanical Men]]></company> <sourceName><![CDATA[Apple]]></sourceName> <city><![CDATA[Seattle]]></city> <state><![CDATA[WA]]></state> <country><![CDATA[USA]]></country> <email><![CDATA[your_email@your_company.com]]></email> <metadata/> </job> <job> <title><![CDATA[Python Engineer]]></title> <description><![CDATA[Must be an expert in Django.]]></description> <date><![CDATA[Tue Jan 12 2021 00:00:00 GMT-0800 (Pacific Standard Time)]]></date> <referenceNumber><![CDATA[2313]]></referenceNumber> <url><![CDATA[https://example.com/job/2313]]></url> <company><![CDATA[US Robotics and Mechanical Men]]></company> <sourceName><![CDATA[Apple]]></sourceName> <city><![CDATA[Seattle]]></city> <state><![CDATA[WA]]></state> <country><![CDATA[USA]]></country> <email><![CDATA[your_email@your_company.com]]></email> <metadata/> </job> <job> <title><![CDATA[Senior Python Engineer]]></title> <description><![CDATA[Must be an expert in Django.]]></description> <date><![CDATA[Tue Jan 12 2021 00:00:00 GMT-0800 (Pacific Standard Time)]]></date> <referenceNumber><![CDATA[2314]]></referenceNumber> <url><![CDATA[https://example.com/job/2314]]></url> <company><![CDATA[US Robotics and Mechanical Men]]></company> <sourceName><![CDATA[Apple]]></sourceName> <city><![CDATA[Seattle]]></city> <state><![CDATA[WA]]></state> <country><![CDATA[USA]]></country> <email><![CDATA[your_email@your_company.com]]></email> <metadata/> </job></source>6. アプリのホームページを作成する
#サンプルアプリのホームページには、各求人の横にSponsor with Indeedボタンが表示されます。
ホームページでは、JobServiceのlistJobs()メソッドを使用します。routes\index.jsにあるJavaScriptコードは次のとおりです。
const express = require('express');const JobService = require('../services/JobService');
const router = express.Router();
/* GET home page. */router.get('/', async (req, res) => { const jobs = JobService.listJobs(); res.render('index', { jobs, });});
module.exports = router;ホームページのビューは次のとおりです。
<h1>Your Jobs</h1>
{{#unless jobs}} <div class="alert alert-primary mt-3" role="alert"> <p> You don't have any jobs. </p> </div>{{else}}<table class="table"> <thead> <tr> <th scope="col">Title</th> <th scope="col">City</th> <th scope="col">Country</th> <th scope="col">Action</th> </tr> </thead> <tbody> {{#each jobs}} <tr> <th scope="row">{{this.title}}</th> <td>{{this.city}}</td> <td>{{this.country}}</td> <td><a href="/campaign/create/{{this.id}}" class="btn btn-primary btn-sm" role="button">Sponsor with Indeed</a></td> </tr> {{/each}} </tbody></table>{{/unless}}採用企業がSponsor with Indeedを選択すると、アプリは採用企業を/campaign/createルートに送ります。
7. Indeed APIを呼び出せるようにアプリを認可する
#サンプルアプリでは、Expressミドルウェアを使用してOAuth認可を強制します。ミドルウェアは、現在のユーザーがOAuthアクセストークンを持っているかどうかを確認し、持っていない場合はIndeed OAuth同意画面にリダイレクトします。
このミドルウェアは、middleware\IndeedOAuthAuthorize.jsにあります。
const config = require('../config');const IndeedOAuthService = require('../services/IndeedOAuthService');
async function IndeedOAuthAuthorize(req, res, next) { const indeedOAuth = new IndeedOAuthService(config, req.session); const tokenSet = await indeedOAuth.getTokenSet(null);
if (!tokenSet) { req.session.returnUrl = req.originalUrl; const authorizeURL = await indeedOAuth.getAuthorizeURL('employer_access offline_access'); res.redirect(authorizeURL); } else { res.locals.tokenSet = tokenSet; next(); }}
module.exports = IndeedOAuthAuthorize;IndeedOAuthAuthorizeは、OAuthアクセストークンが必要なすべてのルートで認可を強制します。たとえば、Sponsor with Indeedボタンは、このミドルウェアを使用する/campaign/createルートにリンクします。
router.get('/create/:jobId', IndeedOAuthAuthorize, async (req, res) => { ....ommited...}採用企業が/campaign/createをリクエストし、アプリにその採用企業の代理として動作する認可がない場合、アプリはOAuth同意画面にリダイレクトします。
採用企業がAllowを選択すると、採用企業の選択画面が表示されます。この画面で、US Robotics and Mechanical Menのように、OAuthアクセストークンに関連付ける採用企業を選択します。
採用企業がContinueを選択すると、アプリはIndeedからOAuthアクセストークンを取得し、セッション状態に保存します。その後、認可が必要なルートでは、ミドルウェアがセッション状態からアクセストークンを読み取るため、採用企業がアプリを再度認可する必要はありません。
8. スポンサー求人キャンペーンを作成する
#採用企業がIndeedの求人の1つをスポンサーできるようにするには、Indeedのスポンサー求人キャンペーンを作成します。
GET /campaign/createルートを作成する
#HTTP GETリクエストを処理するcampaign.jsルートを作成します。
router.get('/create/:jobId', IndeedOAuthAuthorize, async (req, res) => { const jobId = Number(req.params.jobId); const job = JobService.getJob(jobId); const campaignService = new CampaignService(config, req.session, res.locals.tokenSet);
// get account const account = await campaignService.getAccount(); if (!account.jobSourceList || account.jobSourceList.length === 0) { res.redirect('/campaign/no-job-source'); } else { // create campaign defaults const newCampaign = { startDate: getISODateString(new Date()), targetEndDate: getISODateString(getFutureDate(3)), budgetMonthlyLimit: 100.00, budgetOneTimeLimit: 100.00, };
res.render('campaign-create', { job, newCampaign, }); }});このコードは、採用企業のIndeedアカウントを取得するためにcampaignService.getAccount()を呼び出します。このメソッドは次のようなレスポンスを返します。
{ "jobSourceList": [{ "id": "67c9fd651aff79bf", "siteName": "Apple" }], "contact": "Susan Calvin", "company": "US Robotics and Mechanical Men", "id": "5266416001932948", "email": "indeed.sample.app+employer@gmail.com"}アカウント情報にはjobSourceListが含まれ、各求人ソースにはidとsiteNameがあります。siteNameは、XML求人フィード内の各求人のsourceNameと一致している必要があります。キャンペーンを作成するには、idとsiteNameを使用します。
このルートは、アカウントに少なくとも1つの求人ソースがあることを確認します。ない場合、採用企業は求人をスポンサーできないため、サンプルアプリはエラーページを表示します。
campaign-createビューを作成する
#アカウントに少なくとも1つの求人ソースがある場合、サンプルアプリはcreate-campaignビューを表示します。このビューで、採用企業は求人をスポンサーするための予算を設定します。採用企業は月次予算を設定できます。
または、開始日と終了日を指定した一括予算を設定します。
create-campaignビューのマークアップは次のとおりです。
<h1>Sponsor with Indeed</h1>
<p> Sponsor the <b>{{job.title}}</b> job with Indeed by completing the following form.</p>
<form method="post" action="/campaign/create/{{job.id}}">
<div class="row g-3"> <div class="col"> <p> Select how you want to spend your advertising budget. </p> <div class="form-check form-check-inline"> <input class="form-check-input" name="selectBudgetType" type="radio" id="monthlyRadio" value="monthly" checked /> <label class="form-check-label" for="monthlyRadio">Monthly Budget Limit</label> </div>
<div class="form-check form-check-inline"> <input class="form-check-input" name="selectBudgetType" type="radio" id="oneTimeRadio" value="oneTime"> <label class="form-check-label" for="oneTimeRadio">One Time Budget Limit</label> </div> </div> </div>
<fieldset id="monthly" class="mt-2"> <legend>Monthly Budget Limit</legend>
<div class="row mb-3"> <div class="col"> <label for="budgetMonthlyLimit" class="form-label">Budget</label> <div class="input-group mb-3"> <span class="input-group-text">$</span> <input name="budgetMonthlyLimit" id="budgetMonthlyLimit" type="number" min="50" step="any" class="form-control" placeholder="Budget" value="{{newCampaign.budgetMonthlyLimit}}" /> </div> </div> </div>
</fieldset>
<fieldset id="oneTime" style="display:none" class="mt-2"> <legend>One Time Budget Limit</legend>
<div class="row mb-3"> <div class="col form-group"> <label for="budgetOneTimeLimit" class="form-label">Budget</label> <div class="input-group mb-3"> <span class="input-group-text">$</span> <input name="budgetOneTimeLimit" id="budgetOneTimeLimit" type="number" min="50" step="any" class="form-control" value="{{newCampaign.budgetOneTimeLimit}}" /> </div> </div> </div>
<div class="row mb-3"> <div class="col"> <label for="startDate" class="form-label">Start Date</label> <input name="startDate" id="startDate" type="date" class="form-control" placeholder="Start Date" value="{{newCampaign.startDate}}" /> </div> <div class="col"> <label for="targetEndDate" class="form-label">Target End Date</label> <input name="targetEndDate" id="targetEndDate" type="date" class="form-control" placeholder="Target End Date" value="{{newCampaign.targetEndDate}}" /> </div> </div>
</fieldset>
<div class="row mb-3"> <div class="col"> <a class="btn btn-secondary mr-2" href="/">Cancel</a> <button type="submit" class="btn btn-primary">Submit</button> </div> </div>
</form>
<script> const monthly = document.getElementById('monthly'); const oneTime = document.getElementById('oneTime');
document.getElementById('oneTimeRadio').addEventListener('click', (e) => { monthly.style.display = 'none'; oneTime.style.display = 'block'; });
document.getElementById('monthlyRadio').addEventListener('click', (e) => { monthly.style.display = 'block'; oneTime.style.display = 'none'; });</script>このマークアップでは、Bootstrapを使用して、月次予算用と一括予算用の2つのフィールドセットを含むHTMLフォームを作成します。ビューの下部にあるJavaScriptにより、一度に1つのフィールドセットだけが表示されます。
POST /campaign/createルートを作成する
#採用企業がcreate-campaignフォームを送信すると、サンプルアプリはPOST /campaign/createルートを呼び出します。このルートはフォームの値を読み取り、JobServiceのcreateCampaign()メソッドを呼び出し てキャンペーンを作成します。
router.post('/create/:jobId', IndeedOAuthAuthorize, async (req, res) => { const campaignService = new CampaignService(config, req.session, res.locals.tokenSet);
// get job const jobId = Number(req.params.jobId); const job = JobService.getJob(jobId);
// get form fields const newCampaign = { name: `${job.title} - ${new Date().toUTCString()}`, budgetType: req.body.selectBudgetType, budgetMonthlyLimit: Number(req.body.budgetMonthlyLimit), budgetOneTimeLimit: Number(req.body.budgetOneTimeLimit), startDate: getISODateString(new Date(req.body.startDate)), targetEndDate: getISODateString(new Date(req.body.targetEndDate)), };
// get account const account = await campaignService.getAccount();
// sponsor job campaignService.createCampaign(account, job, newCampaign);
res.redirect('/');});createCampaignメソッドを作成する
#services\JobService.jsのcreateCampaign()メソッドは、スポンサー求人APIを呼び 出して求人キャンペーンを作成します。
このメソッドは、採用企業アカウントから取得した求人ソースIDとsiteNameを使用し、XML求人フィードの参照番号である求人IDをリクエストに含めます。
async createCampaign(account, job, newCampaign) { let request = { name: newCampaign.name, jobsSourceId: account.jobSourceList[0].id, jobsSourceName: account.jobSourceList[0].siteName, jobsToInclude: 'query', jobsQuery: `refnum:${job.id}`, };
if (newCampaign.budgetType === 'monthly') { request = { ...request, ...{ budgetMonthlyLimit: newCampaign.budgetMonthlyLimit, budgetFirstMonthBehavior: 'startNowProratedAmount', }, }; } if (newCampaign.budgetType === 'oneTime') { request = { ...request, ...{ budgetOnetimeLimit: newCampaign.budgetOneTimeLimit, startDate: newCampaign.startDate, targetEndDate: newCampaign.targetEndDate, }, }; } const url = `${this.config.oysterBaseURL}/campaigns`; const results = await this.requestResource(url, 'POST', request); return results;}createCampaign()は、Axios を使用してHTTPリクエストを行うrequestResource()を通じてスポンサー求人APIを呼び出します。
サンプルコードは、AuthorizationヘッダーでOAuthアクセストークンを渡します。Indeedは、これが含まれないリクエストを拒否します。
async requestResource(url, method = 'GET', data) { console.info(`Axios ${method}: ${url}`); try { const results = await axios({ url, method, headers: { Authorization: `Bearer ${this.tokenSet.access_token}`, }, data, }); return results.data.data; } catch (err) { console.error('Error when making request'); console.dir(err.response.data, { depth: null }); throw err; }}採用企業がフォームを送信した後、採用企業をサンプルアプリのホームページにリダイレクトします。
9. スポンサー求人キャンペーンを表示する
#すべてのキャンペーンを一覧表示するには、採用企業はヘッダーのManage Sponsored Jobs Campaignsを選択します。
キャンペーンを一覧表示したり、1つのキャンペーンの詳細を取得したり、キャンペーンを一時停止、再開、削除したりできます。
キャンペーン を一覧表示する
#採用企業のキャンペーンを一覧表示するには、/campaignsにGETリクエストを行います。
CampaignService.jsのgetCampaigns()メソッドは次のとおりです。
async getCampaigns() { const url = `${this.config.oysterBaseURL}/campaigns`; const results = await this.requestResource(url); // filter out deleted campaigns return results.Campaigns.filter((c) => c.Status !== 'DELETED');}このメソッドは、JSONレスポンスを返します。
[{ "Name": "Senior Python Engineer - Sat, 01 May 2021 16:58:47 GMT", "Id": "a6fde835690ecf9d", "Status": "PAUSED" }, { "Name": "Senior Python Engineer - Thu, 06 May 2021 17:42:40 GMT", "Id": "d0fb6cf60753eef3", "Status": "ACTIVE" },
{ "Name": "Product Manager - Fri, 21 May 2021 21:10:14 GMT", "Id": "8881f81292b2bf48", "Status": "ACTIVE" }]レスポンスには、各キャンペーンのName、Id、Statusが含まれます。キャンペーンはACTIVE、PAUSED、またはDELETEDのいずれかになります。getCampaigns()メソッドは、削除済みのキャンペーンを除外します。
スポンサー求人キャンペーンの詳細を取得する
#キャンペーンの詳細を表示するには、採用企業はViewを選択します。
サンプルアプリは、CampaignServiceのgetCampaignDetails()メソッドでキャンペーンの詳細を取得します。
async getCampaignDetails(campaignId) { // get campaign general info const generalUrl = `${this.config.oysterBaseURL}/campaigns/${campaignId}`; const general = await this.requestResource(generalUrl);
// get campaign budget info const budgetUrl = `${this.config.oysterBaseURL}/campaigns/${campaignId}/budget`; const budget = await this.requestResource(budgetUrl);
// get campaign properties info const propertiesUrl = `${this.config.oysterBaseURL}/campaigns/${campaignId}/properties`; const properties = await this.requestResource(propertiesUrl);
return { ...general, ...budget, ...properties, };}getCampaignDetails()は、次のIndeedエンドポイントを呼び出します。
/campaigns/<id>を呼び出して一般的なキャンペーン情報を取得します。/campaigns/<id>/budgetを呼び出してキャンペーン予算情報を取得します。/campaigns/<id>/propertiesを呼び出してキャンペーンプロパティ情報を取得します。
ビューは、これらのエンドポイントから取得したデータを結合して表示します。
キャンペーンを一時停止、再開、削除する
#採用企業は、ステータスを変更することで、キャンペーンを一時停止、再開、削除します。updateCampaignStatus()メソッドは、/campaigns/<id>にPATCHリクエストを送信します。
async updateCampaignStatus(campaignId, newStatus) { const url = `${this.config.oysterBaseURL}/campaigns/${campaignId}`; const results = await this.requestResource(url, 'PATCH', { status: newStatus, }); return results.Campaigns;}キャンペーンを削除すると、ステータスはDELETEDに変わりますが、キャンペーン自体は削除されません。