Apply with Indeed
パートナーATSと雇用主向けのApply with Indeedボタンの作成とデプロイ。
- このAPIおよびそのドキュメントを使用し、統合を構築することで、追加のAPI利用規約およびガイドラインに同意したものとみなされます。
はじめに
Apply with Indeed(AWI)を使用すると、Job Sync APIまたはXML連携経由で投稿した求人にApply with Indeedボタンを作成・デプロイできます。AWIを連携した後、求職者は雇用主のキャリアページの掲載でApply with Indeedボタンをクリックすると、Indeedアカウントに保存されたIndeedプロフィールデータで応募できます。
前提条件
始める前に
-
AWIを使用するには、求人がJob Sync APIまたはXMLフィードで投稿されており、Indeed Applyが有効化されている必要があります。求人の投稿方法とIndeed Applyの有効化方法については、Job Sync APIガイドまたはXMLフ ィードガイドをご覧ください。
-
AWIの連携リクエストを開きます。
- 新規パートナーシップをリクエストするには、このリクエストフォームを使用します。
- IndeedはAWI用の
partnerApiTokenを生成します。
AWIのプロビジョニング
認証情報はPartner Console経由でアクセスできます。
- IndeedがAWIアクセス認証情報をプロビジョニングします。
- OAuthトークン/シークレット:これらの認証情報を使用してアクセストークンを生成し、GraphQL APIへのリクエストを認証します。
- パートナーAPIトークン/シークレット:これらの認証情報をAWIで使用します。これらの認証情報は、Indeedで求人を投稿する際に使用するIndeed Apply APIトークンとは別物です。Partner Consoleでは、このトークンはApply With Indeed Tokenとして表示されます。
AWI連携オプションの推奨
ATSページでApply with Indeedボタンを有効化するには、次のいずれかの方法を使用し ます。
-
IndeedのSDK/JavaScriptをウェブページのコードに追加することで、高速かつ簡単に開発できます。
フロントエンドコードを簡単に変更でき、ボタンデザインとエラー処理をSDKに任せたい場合は、この方法を使用します。
-
この方法は、ウェブページの任意の場所に統合できる応募フォームURLを返すため、より柔軟性があります。
バックエンドシステムからIndeed GraphQL APIを簡単に呼び出すことができ、ボタンUIの実装とエラー処理を行うことに抵抗がない場合は、この方法を使用します。
Indeedパートナーは、Indeedに求人を投稿してIndeed Applyを有効化する方法(Job Sync APIまたはXMLフィードのどちらを使用するか)を明確にする必要があります。Apply with Indeedボタンを追加する際の入力パラメーターはこの違いによって異なります。
AWI JavaScript
AWI JavaScriptは、ATSの求人ページでApply with Indeedボタンを有効化します。
JavaScriptを読み込む
AWI JavaScriptをATSの求人ページに読み込むには、次のコードサンプルが示すように、ページに<script>タグを追加します。
ページのエンコードに必要な場合は、<meta charset>タグを含めることもできます。
<!DOCTYPE html><html> <head> ... <!-- Load the AWI JavaScript --> <script src="https://apply.indeed.com/indeedapply/static/scripts/app/awi-bootstrap.js"></script> ... </head>...</html>Apply with Indeedボタンを有効化する
スクリプトを読み込んだ後、適切な属性を持つHTML要素を追加することで、Apply with Indeedボタンを有効化できます。次のコードサンプルにその方法を示します。
パラメーターは、使用する求人投稿方法(Job Sync APIまたはXMLフィード)によって異なります。
Job Sync APIのコードサンプル
<!DOCTYPE html><html> <head> ... <!-- Step 1: Load the script --> <script src="https://apply.indeed.com/indeedapply/static/scripts/app/awi-bootstrap.js"></script> ... </head> <body> ... <!-- Step 2: Specify where to display the **Apply with Indeed** button --> <div data-indeed-apply-widget-type="<WIDGET-TYPE>" data-indeed-apply-sourceJobPostingId="<JobId>" data-indeed-apply-partnerApiToken="<PartnerApiToken>" data-indeed-apply-encryptedJobUrl="<Encrypted Job URL>" data-indeed-apply-encryptedContinueUrl="<ContinueURL>" data-indeed-apply-hl="en" data-indeed-apply-co="US" data-indeed-apply-newTab="true" ></div> ... </body></html>XMLフィードのコードサンプル
<body> ... <!-- Step 2: Specify where to display the **Apply with Indeed** button --> <div data-indeed-apply-widget-type="<WIDGET-TYPE>" data-indeed-apply-encryptedSourceName="<SourceName>" data-indeed-apply-encryptedFeedUrl="<FeedUrl>" data-indeed-apply-encryptedReferenceId="<ReferenceId or ReferenceNumber>" data-indeed-apply-partnerApiToken="<PartnerApiToken>" data-indeed-apply-encryptedJobUrl="<Encrypted Job URL>" data-indeed-apply-encryptedContinueUrl="<ContinueURL>" data-indeed-apply-hl="en" data-indeed-apply-co="US" data-indeed-apply-newTab="true" ></div> ... </body>パラメーターを指定する
前のコードスニペットで山括弧(<>)内のパラメーターを自分の値に置き換えます。
必須パラメーターはJob Sync APIとXMLフィードで異なります。
次の表は、data-indeed-apply-*属性を説明しています。
| 属性 | 必須/任意 | 暗号化 | 説明 | 例 |
|---|---|---|---|---|
タイプ:文字列 | 必須 | いいえ | Apply with Indeedボタンのタイプ。現時点で対応している値は「AWI」のみです。 | AWI |
タイプ:文字列 | Job Sync APIで必須 | いいえ | Indeed雇用主の求人ID。求人投稿を作成する際にJob Sync APIが生成します。data-indeed-apply-sourceJobPostingIdは、Job Sync APIガイド - レスポンス - 求人投稿を作成するではsourcePostingIdとも呼ばれます。 | 57caad99-6441-46ec-913c-e018e5013689 |
タ イプ:文字列 | XMLフィードで必須 | はい | XMLフィードの暗号化されたソース名。役職を募集している親組織です。 | 1d76ab187297cf4c284e2621c2c7462fbfb216704ed0fdc325de0baf6dca5718 |
タイプ:文字列 | XMLフィードで必須 | はい | XMLフィードの暗号化されたフィードURL。自社サイト上の求人掲載のURLです。 | 0906256350d8ed657d9f70ffe91e84d4a117328ab5d42c22ccbac1689af2d1cb |
タイプ:文字列 | XMLフィードで必須 | はい | 暗号化されたXMLフィード求人のリファレンスID。求人インスタンスを一意に識別する番号です。 | 1d76ab187297cf4c284e2621c2c7462fbfb216704ed0fdc325de0baf6dca5718 |
タイプ:文字列 | 必須 | いいえ | パートナーAPIトークン | 98922e8fa1355c944b0f7efc6ae9b182ebb1f3ed8ce0b36ea40b33a9b73e2211 |
タイプ:文字列 | 必須 | はい | Apply with Indeedボタンが読み込まれた、暗号化された公開求人説明ページのURL | 0906256350d8ed657d9f70ffe91e84d4a117328ab5d42c22ccbac1689af2d1cb |
タイプ:文字列 | 任意 | はい | 応募を正常に送信した後、応募完了画面のContinueボタンをクリックした際に応募者がリダイレクトされる、暗号化された続行URL | 0906256350d8ed657d9f70ffe91e84d4a117328ab5d42c22ccbac1689af2d1cb |
タイプ:文字列 | 任意 | はい | 応募者がIndeed Applyフォームの終了リンクをクリックして応募を完了せずに退出する際にリダイレクトされる、暗号化された終了URL | 0906256350d8ed657d9f70ffe91e84d4a117328ab5d42c22ccbac1689af2d1cb |
タイプ:文字列 | 任意 | いいえ | 応募フォームが提供される言語。対応言語 | en |
タイプ:文字列 | 任意 | いいえ | 応募者の国コード。[対応国] | US |
タイプ:文字列 | 任意 | いいえ | 応募者がApply with Indeedを選択した際に実行されるJavaScriptメソッド名 | _onClick |
タイプ:文字列 | 任意 | いいえ | Apply with Indeedボタンが正常に読み込まれた後に実行されるJavaScriptメソッド名 | _onButtonReady |
タイプ:ブール値 | 任意 | いいえ | ボタンのCSSは読み込まれず、ボタンのスタイル設定はパートナーが行います。 | true |
タイプ:ブール値 | 任意 | いいえ | 応募フォームを新規タブで開くかどうか | false |
上記のパラメーターの一部は、partnerApiTokenに関連付けられたシークレットを使用して暗号化する必要があります。
コールバックメソッド
onClick:- コールバックメソッドは、唯一の引数として
HTMLElementボタンを受け取ります。このコールバックはHTMLElementボタンとともに呼び出されます。
- コールバックメソッドは、唯一の引数として
onReady:- コールバックメソッドは、
HTMLElementボタンとbuttonLoadStatusの2つの引数を受け取ります。buttonLoadStatusは次のフィールドを含むオブジェクトです。success:ボタンの読み込みが成功したか失敗したかmessage:成功/エラーメッセージerror_code:ボタンの読み込みが失敗した際のエラーコード
- コールバックメソッドは、
属性の暗号化を処理する
- 前の表の暗号化列が
はいの属性を指定する場合は、属性を暗号化します。属性を暗号化するには、128ビットのシークレットキー(生成されたpartnerApiTokenに関連付けられたシークレット)でAESアルゴリズムを使用します。暗号モードはCBCで、パディングはPKCS5です。初期化ベクトルは00 の16バイトです。 - 属性を暗号化するには、次を行います。
- シークレットキーの最初の16バイトを使用して128ビットのシークレットキーを生成します。シークレットキーは、生成された
partnerApiTokenに関連付けられたシークレットです。 - UTF-8でエンコードされたプレーンテキスト属性のバイトを読み取ります。
- AESアルゴリズムと128ビットキーで属性を暗号化します。CBCモードとPKCS5パディングを必ず使用してください。
- 暗号化されたバイトを16進文字列に変換します。
- この16進文字列を
data-indeed-apply-{属性名}属性として使用します。 プレーンテキスト属性の代わりに暗号化データを使用します。Indeed Applyは、暗号化データが送信されていることを認識します。
- シークレットキーの最初の16バイトを使用して128ビットのシークレットキーを生成します。シークレットキーは、生成された
- データの暗号化・復号化については、次のサンプルをご覧ください。
import java.nio.charset.Charset;import java.lang.RuntimeException;import javax.crypto.Cipher;import javax.crypto.spec.*;import javax.crypto.spec.SecretKeySpec;
public class EncryptionTest {
public static void main(String[] args) {
String url = "YOUR_URL"; String apiSecret = "YOUR_API_SECRET"; String encrypted_url = encrypt(url, apiSecret); String decrypted_url = decrypt(encrypted_url, apiSecret);
System.out.println(encrypted_url); System.out.println(decrypted_url); }
static String encrypt(String message, String apiSecret) { try { byte[] keyBytes = apiSecret.getBytes(Charset.forName("UTF-8")); byte[] message_bytes = message.getBytes("UTF-8"); SecretKeySpec key = new SecretKeySpec(keyBytes, 0, 16, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ivspec = new IvParameterSpec(new byte[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }); cipher.init(Cipher.ENCRYPT_MODE, key, ivspec); byte[] email_encrypted = cipher.doFinal(message_bytes); return bytesToHexString(email_encrypted); } catch (Exception e) { System.out.println(e.getMessage()); throw new RuntimeException(e); } }
static String decrypt(String message, String apiSecret) { try { byte[] keyBytes = apiSecret.getBytes(Charset.forName("UTF-8")); byte[] message_bytes = message.getBytes(Charset.forName("UTF-8")); message_bytes = decodeHex(message_bytes); SecretKeySpec key = new SecretKeySpec(keyBytes, 0, 16, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ivspec = new IvParameterSpec(new byte[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }); cipher.init(Cipher.DECRYPT_MODE, key, ivspec); byte[] email_decrypted = cipher.doFinal(message_bytes); return new String(email_decrypted, "UTF-8"); } catch (Exception e) { System.out.println(e.getMessage()); throw new RuntimeException(e); } }
static String bytesToHexString(byte[] in) { final StringBuilder builder = new StringBuilder(); for (byte b: in) { builder.append(String.format("%02x", b)); } return builder.toString(); }
static byte[] decodeHex(byte[] data) throws Exception { String text = new String(data, "UTF-8"); char[] chars = text.toCharArray();
int len = chars.length; byte[] out = new byte[len >> 1]; int i = 0;
for (int j = 0; j < len; ++i) { int f = toDigit(chars[j], j) << 4; ++j; f |= toDigit(chars[j], j); ++j; out[i] = (byte)(f & 255); } return out; }
static int toDigit(char ch, int index) throws Exception { int digit = Character.digit(ch, 16); if (digit == -1) { throw new Exception("Illegal hexadecimal character " + ch + " at index " + index); } else { return digit; } }}Job Sync APIのサンプルデータ
<divdata-indeed-apply-widget-type="<WIDGET-TYPE>"data-indeed-apply-sourceJobPostingId="<JobId>"data-indeed-apply-partnerApiToken="<PartnerApiToken>"data-indeed-apply-encryptedJobUrl="b18d0be4c173dfa2b7cb7856e7c7b6f02a563867a9df67ca208c8b9654966299"data-indeed-apply-encryptedContinueUrl="417856e7c173dfa2b7cb7856e7c7b6f02a563867a9df67ca208c8b9654966299"data-indeed-apply-encryptedExitUrl="2b7cb78563dfa2b7cb7856e7c7b6f02a563867a9df67ca208c8b9654966299"></div>XMLフィードのサンプルデータ
<divdata-indeed-apply-widget-type="<WIDGET-TYPE>"data-indeed-apply-encryptedSourceName="1d76ab187297cf4c284e2621c2c7462fbfb216704ed0fdc325de0baf6dca5718"data-indeed-apply-encryptedFeedUrl="b18d0be4c173dfa2b7cb7856e7c7b6f02a563867a9df67ca208c8b9654966299"data-indeed-apply-encryptedReferenceId="<ReferenceId>"data-indeed-apply-partnerApiToken="<PartnerApiToken>"data-indeed-apply-encryptedJobUrl="b18d0be4c173dfa2b7cb7856e7c7b6f02a563867a9df67ca208c8b9654966299"data-indeed-apply-encryptedContinueUrl="417856e7c173dfa2b7cb7856e7c7b6f02a563867a9df67ca208c8b9654966299"data-indeed-apply-encryptedExitUrl="2b7cb78563dfa2b7cb7856e7c7b6f02a563867a9df67ca208c8b9654966299"></div>ボタン設定では、求人のいずれの属性フィールド(encryptedJobUrl、encryptedContinueUrl、encryptedExitUrl、encryptedFeedUrl)にも複数のURLを含めないでください。複数のURLを含めるとエラーが発生し、Apply with Indeedボタンがグレーの非アクティブ状態で表示されます。
ボタンのデザイン
次の画像は、正常に動作しているApply with Indeedボタンを示しています。
次の画像は、正常に動作していないApply with Indeedボタンを示しています。
問題が発生した場合は、AWI JavaScript固有のエラーとトラブルシューティングガイドをご覧ください。
生成されたApply With Indeedボタンは、他のApplyボタンのサイズと表示と一致する必要があります。
applyUrlForEmployersミューテーション
このミューテーションを使用して、Apply with Indeedボタンの読み込み時にIndeed Apply URLを作成します。Apply with Indeedボタンの読み込みごとに呼び出してください。
Indeed APIと連携する
Indeedパートナーになると、Indeedが連携用のアプリを作成します。Partner Consoleにログインして、アプリとOAuth認証情報(クライアントID、クライアントシークレット、および3-legged OAuthの場合は認可コード)を確認します。認証情報をアクセストークンと交換し、API呼び出しを認証します。
Apply with Indeed URLを作成する
Apply with Indeed URL(Indeed Apply URLとも呼ばれます)を作成するには、ApplyUrlMutations.applyUrlForEmployersミューテーションを呼び出します。Apply with Indeedボタンが必要な特定の求人を識別するため、ミューテーションへの入力を指定します。XMLフィードの入力はJob Sync APIの入力と異なります。
Job Sync APIの入力
sourcedPostingId*:Indeed雇用主の求人ID。求人投稿を作成する際にJob Sync APIが生成しますjobUrl*:Apply with Indeedボタンが読み込まれた公開求人説明ページのURLcontinueUrl:応募者が成功画面でContinueボタンをクリックした際にリダイレクトされる続行URLexitUrl:応募者がIndeed Applyフォームを終了する際にリダイレクトされる終了URL
* - 必須入力
XMLフィードの入力
sourceName*:役職を募集している親組織名(例:Test Company Name、Indeed Japan)feedUrl*:XML求人のフィードURLreferenceId*:XMLフィードの<referenceNumber>または<referenceId>jobUrl*:Apply with Indeedボタンが読み込まれた公開求人説明ページのURLcontinueUrl:応募者が成功画面でContinueボタンをクリックした際にリダイレクトされる続行URLexitUrl:応募者がIndeed Applyフォームを終了する際にリダイレクトされる終了URL
* - 必須入力
Apply with Indeed URLは、Apply with Indeedボタンが描画されるたびに生成する必要があります。URLは再利用できず、1回のみ有効です。
リクエスト
Job Sync APIリクエストのコードサンプル
mutation { applyUrl { createApplyUrlForEmployers( input: { jobId: { sourceJobPostingId: "jobId" } jobUrl: "http://example.com/careers/job1.html" continueUrl: "http://example.com/careers/indeedapply-continue.html" exitUrl: "http://example.com/careers" } ) { applyUrl } }}XMLフィードリクエストのコードサンプル
mutation { applyUrl { createApplyUrlForEmployers( input: { xmlFeedParams: { sourceName: "sourceName", feedUrl: "feedUrl", referenceId: "referenceNumber" } jobUrl: "http://example.com/careers/job1.html" continueUrl: "http://example.com/careers/indeedapply-continue.html" exitUrl: "http://example.com/careers" } ) { applyUrl } }}ミューテーションはapplyUrlを返します。これは、ATSの求人ページのApply with Indeedボタンで使用できます。
レスポンス
次はレスポンスのコードサンプルです。
{ applyUrl: "https://smartapply.indeed.com/beta/indeedapply/applybyapplyablejobid?indeedApplyableJobId=b957be31-16ed-4f65-9376-cf383594eee5-Y21ocWEx"}ヘッダー
| ヘッダー | 意味 | 必須/任意 | 詳細 | 例 |
|---|---|---|---|---|
authorization | アクセストークン | 必須 | ミューテーションへのアクセス認可を提供します。アクセストークンを取得する | Bearer eyJrEIOeWQiOiI5NzVkOWZkMC01NzE3LTQzMzQtOTM |
indeed-co | 国 | 任意 | このリクエストの国。[対応国] | US |
indeed-locale | ロケール | 任意 | リクエスト元のクライアントロケール | en-US(形式) |
indeed-user-agent | 応募者のユーザーエージェント文字列 | 任意 | リクエスト元のブラウザのユーザーエージェント | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 |
indeed-user-ip | 応募者のIP | 任意 | リクエスト元のブラウザのクライアントIP | 192.168.0.0 |
ボタンデザインをミューテーションと統合する
ミューテーションのクライアントは、次のスクリプトを使用して、Indeedが提供するボタンCSSを有効化できます。
<!DOCTYPE html><html><head> ... <!-- Step 1: Load the script --> <script src="https://apply.indeed.com/indeedapply/static/scripts/app/buttonStyles.js" ></script></head><body> ... <!-- Step 2: Specify data-style as indeed-apply-button for the button where you want to enable button style --> <button data-style="indeed-apply-button">Apply Now</button></body></html>次の画像は、前のスクリプトでCSSを適用した後のApply with Indeedボタンを示しています。
失敗時にボタンを無効化するには、ボタン要素にaria-disabled=true属性を追加できます。
<!-- Set aria-disabled attribute to true to disabled the button --><button data-style="indeed-apply-button" aria-disabled=true>Apply Now</button>次の画像は、前のスクリプトで属性を適用した後のApply with Indeedボタンを示しています。
ボタンの翻訳
Apply with Indeedボタンの言語を変更するには、スクリプトでクエリパラメーター(hl=jaやhl=esなど)を使用して言語を指定します。hlクエリパラメーターの値には、[対応言語]を使用します。
<!DOCTYPE html><html><head> ... <!-- Step 1: Specify query parameter --> <script src="https://apply.indeed.com/indeedapply/static/scripts/app/buttonStyles.js" ></script></head><body> ... <!-- Step 2: Specify data-style as indeed-apply-button for the button where you want to enable button style --> <button data-style="indeed-apply-button">Apply Now</button></body></html>次の画像は、前のスクリプトで属性を適用した後の日本語のApply with Indeedボタンを示しています。
エラーをトラブルシュートする
リクエストが失敗すると、dataフィールドはnullになり、errorsフィールドに失敗に関する情報が含まれます。一般的なエラーには、GRAPHQL_PARSE_FAILED、BAD_USER_INPUT(JOB_NOT_FOUNDやPARTNER_DATA_NOT_FOUNDなどのサブコードあり)、INTERNAL_SERVER_ERRORがあります。
リクエストが失敗してURLが返されない場合は、Apply with Indeedボタンを表示せずにリクエストをリトライしてください。URLが返されたら、ボタンを再度有効化します。
詳細なエラーの説明、サブコード、解決手順については、Indeed Applyエラーのトラブルシューティングをご覧ください。