Skip to content

Instantly share code, notes, and snippets.

@akemin-dayo
Last active March 6, 2026 23:37
Show Gist options
  • Select an option

  • Save akemin-dayo/158bca74e0eac967166c51cdc3958b16 to your computer and use it in GitHub Desktop.

Select an option

Save akemin-dayo/158bca74e0eac967166c51cdc3958b16 to your computer and use it in GitHub Desktop.
Provides an easy way to extract your account token for use in scouting / headhunting tracking tools such as EndfieldTools.DEV without needing the Windows version of the game. Windows版のゲームを使わなくても「EndfieldTools.DEV」などのスカウト履歴ツールで利用できるアカウントトークンを簡単に抽出できます。

Arknights: Endfield Token Extractor / 『アークナイツ:エンドフィールド』アカウントトークン抽出ツール

Provides an easy way to extract your account token for use in scouting / headhunting tracking tools such as EndfieldTools.DEV without needing the Windows version of the game.

Mostly useful for those playing on PS5, iOS, and Android.

Supports Asia, NA/EU, and China servers. (※ China is untested.)

Windows版のゲームを使わなくても「EndfieldTools.DEV」などのスカウト履歴ツールで利用できるアカウントトークンを簡単に抽出できます。

主にPS5、iOS、Androidでプレイしている方に便利です。

アジア、北米・ヨーロッパ、中国の各サーバーに対応しています。(※中国サーバーでの動作は未検証。)

Instructions (EN)

  1. Install an userscript browser extension.
    • For browsers with Manifest V2 support (Firefox, Edge, Vivaldi, Brave, Opera, Helium, Ungoogled Chromium, etc.), I recommend Violentmonkey (※ open-source).
    • For browsers without Manifest V2 support (Chrome, Arc, etc.), Tampermonkey is your only choice.
    • For Safari (macOS, iOS), I recommend the open-source Userscripts (※ open-source).
    • For Android, you'll need to install Firefox and Tampermonkey.
    • That being said, just about any userscript engine should work.
  2. Click here to open the akemi-arknights-endfield-token-extractor.user.js userscript. This should prompt you to install it.
  3. Open the "Daily Sign-in Tool (Stamp Rally)" page and the buttons should appear on the upper left corner of the screen.
  4. To use this with EndfieldTools.DEV's Headhunting / Scout tracker, click on the "Copy URL" button corresponding to the server you're on and paste it into the URL box to import your headhunting / scout history. (※ It doesn't matter which platform you choose.)

使い方 (JP)

  1. ユーザースクリプト(Userscript)対応のブラウザ拡張機能をインストールします。
    • Manifest V2に対応しているブラウザ(Firefox、Edge、Vivaldi、Brave、Opera、Helium、Ungoogled Chromiumなど)の場合は、オープンソースのViolentmonkey をおすすめします。
    • Manifest V2に対応していないブラウザ(Chrome、Arcなど)の場合は、Tampermonkeyが唯一の選択肢です。
    • Safari(macOS・iOS)の場合は、オープンソースのUserscriptsをおすすめします。
    • Androidの場合は、FirefoxTampermonkeyをインストールする必要があります。
    • 基本的には、ほとんどのユーザースクリプトエンジンで動作するはずです。
  2. こちらをクリックしてakemi-arknights-endfield-token-extractor.user.jsユーザースクリプトを開いてください。インストール画面が表示されます。
  3. 「スタンプラリー」を開くと、画面左上にボタンが表示されます。
  4. 「EndfieldTools.DEV」のスカウト履歴ツールで使用する場合は、自分が所属しているサーバー(多分「アジア」)に対応した「URLをコピー」ボタンをクリックし、URL欄に貼り付けて履歴をインポートしてください(※どのプラットフォームを選んでも大丈夫です。)

⚠️ DISCLAIMER

Please use this tool at your own risk. I am not responsible for anything that may happen as a result of using it.

While all this code really does is read your account token from your browser's session storage and encode its value (something you can do manually via the Developer Console should you so wish), it is technically still executing code within the context of a Hypergryph-controlled webpage, which they may theoretically be able to detect if they wanted to do so.

Furthermore, the use of scout / headhunting tracking services such as EndfieldTools.DEV also carries with it a greater risk, as you are both trusting a third party with your account token (which is able to access data from your account), as well as authorising a remote service to send API requests to Hypergryph's servers directly on your behalf.

※ This is not unique to EndfieldTools.DEV. The same warning generally applies to most other third-party gacha pull tracking services for other games as well.

⚠️ 警告

このツールの使用は自己責任でお願いします。これを使ったことによって起こったいかなる問題についても私は責任を負いません。

このコードが実際にやっていることは、ブラウザのセッションストレージからアカウントトークンを読み取り、その値をエンコードするだけです(開発者コンソールを使って手動でもできます)。でも、Hypergryph社が管理しているウェブページのコンテキスト内でコードを実行していることになります。そのため、理論的にはもしHypergryph社がその気になれば検知できる可能性があります。

また、「EndfieldTools.DEV」のようなスカウト履歴ツールを使うことには、さらに高いリスクがあります。これらのサービスを利用する場合、アカウント内のデータにアクセス可能なアカウントトークンを第三者に渡すことになるうえに、外部サービスがあなたの代わりにHypergryph社のサーバーへ直接APIリクエストを送信することを許可することにもなります。

※これは「EndfieldTools.DEV」だけの話ではなく、他のゲーム向けのガチャ履歴サードパーティ製ツールでもだいたい同じです。

// ==UserScript==
// @name Arknights: Endfield Token Extractor / 『アークナイツ:エンドフィールド』アカウントトークン抽出ツール
// @namespace https://akemi.ai/
// @match https://game.skport.com/*
// @match https://game.skland.com/*
// @grant none
// @version 1.0
// @author Karen/あけみ (akemin_dayo)
// @description Provides an easy way to extract your account token for use in scouting / headhunting tracking tools such as EndfieldTools.DEV without needing the Windows version of the game. Mostly useful for those playing on PS5, iOS, and Android. Supports Asia, NA/EU, and China servers. (※ China is untested.) / Windows版のゲームを使わなくても「EndfieldTools.DEV」などのスカウト履歴ツールで利用できるアカウントトークンを簡単に抽出できます。主にPS5、iOS、Androidでプレイしている方に便利です。アジア、北米・ヨーロッパ、中国の各サーバーに対応しています。(※中国サーバーでの動作は未検証。)
// @icon https://web-static.hg-cdn.com/endfield/official-v4/_next/static/media/share-oversea.6f430b84.jpg
// @run-at document-idle
// @homepageURL https://gist.github.com/akemin-dayo/158bca74e0eac967166c51cdc3958b16.git
// @updateURL https://gist.github.com/akemin-dayo/158bca74e0eac967166c51cdc3958b16/raw/akemi-arknights-endfield-token-extractor.user.js
// @downloadURL https://gist.github.com/akemin-dayo/158bca74e0eac967166c51cdc3958b16/raw/akemi-arknights-endfield-token-extractor.user.js
// ==/UserScript==
"use strict";
let pasteboardButtonCount = 0;
function injectPasteboardButton(buttonLabel, pasteboardContents) {
console.log("[akemi-arknights-endfield-token-extractor] [injectPasteboardButton] Injecting pasteboard button… → %s", buttonLabel);
let baseYPos = 86;
let buttonYOffset = 72;
let pasteboardSuccessString = "✅️ Successfully copied to pasteboard!\n✅️ ペーストボードにコピーしました!";
let pasteboardFailureString = "❌️ Failed to copy to pasteboard!\n❌️ ペーストボードにコピーできませんでした!";
let buttonTransitionDelayMs = 2000;
let buttonColour = "#00c4ea";
let pasteboardSuccessColour = "#41c818";
let pasteboardFailureColour = "#6dea00";
let buttonObject = document.createElement("button");
buttonObject.textContent = buttonLabel;
buttonObject.style.backgroundColor = buttonColour;
buttonObject.style.border = "none";
buttonObject.style.borderRadius = "64px";
buttonObject.style.boxShadow = "0px 0px 8px 2px rgba(0, 0, 0, 0.2)";
buttonObject.style.color = "#ffffff";
buttonObject.style.cursor = "pointer";
buttonObject.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, 'MS Gothic', Arial, sans-serif";
buttonObject.style.fontSize = "16px";
buttonObject.style.fontStyle = "normal";
buttonObject.style.fontWeight = "bold";
buttonObject.style.left = "24px";
buttonObject.style.padding = "8px 16px";
buttonObject.style.position = "fixed";
buttonObject.style.textAlign = "left";
buttonObject.style.top = `${baseYPos + (pasteboardButtonCount * buttonYOffset)}px`;
buttonObject.style.transition = "all 0.2s ease";
buttonObject.style.whiteSpace = "pre-line";
buttonObject.style.zIndex = "7373";
buttonObject.addEventListener("click", async () => {
try {
console.log("[akemi-arknights-endfield-token-extractor] [pasteboardButton] Writing contents to pasteboard… → %s", pasteboardContents);
await navigator.clipboard.writeText(pasteboardContents);
buttonObject.textContent = pasteboardSuccessString;
console.log("[akemi-arknights-endfield-token-extractor] [pasteboardButton] Pasteboard write succeeded!");
buttonObject.style.backgroundColor = pasteboardSuccessColour;
setTimeout(() => {
buttonObject.textContent = buttonLabel;
buttonObject.style.backgroundColor = buttonColour;
}, buttonTransitionDelayMs);
} catch (error) {
console.error("[akemi-arknights-endfield-token-extractor] [pasteboardButton] Failed to write to pasteboard! Error info → %s", error);
buttonObject.textContent = pasteboardFailureString;
buttonObject.style.backgroundColor = pasteboardFailureColour;
setTimeout(() => {
buttonObject.textContent = buttonLabel;
buttonObject.style.backgroundColor = buttonColour;
}, buttonTransitionDelayMs);
}
});
document.body.appendChild(buttonObject);
pasteboardButtonCount++;
console.log("[akemi-arknights-endfield-token-extractor] [injectPasteboardButton] Pasteboard button injection complete!");
return;
}
function dumpU8Token() {
console.log("[akemi-arknights-endfield-token-extractor] [dumpU8Token] Dumping u8_token from APP_ROLE_U8_TOKEN in session storage…");
for (let i = 0; i < sessionStorage.length; i++) {
let iteratedKey = sessionStorage.key(i);
if (iteratedKey && iteratedKey.startsWith("APP_ROLE_U8_TOKEN:")) {
console.log("[akemi-arknights-endfield-token-extractor] [dumpU8Token] Found APP_ROLE_U8_TOKEN!");
let appRoleU8TokenValue = sessionStorage.getItem(iteratedKey);
if (appRoleU8TokenValue) {
console.log("[akemi-arknights-endfield-token-extractor] [dumpU8Token] Raw value for key → %s", appRoleU8TokenValue);
return appRoleU8TokenValue.split(":")[0];
console.log("[akemi-arknights-endfield-token-extractor] [dumpU8Token] Extracted u8_token → %s", appRoleU8TokenValue);
} else {
console.error("[akemi-arknights-endfield-token-extractor] [dumpU8Token] [ERROR] Raw value for key was nil!");
}
}
}
console.error("[akemi-arknights-endfield-token-extractor] [dumpU8Token] [ERROR] Failed to dump u8_token from APP_ROLE_U8_TOKEN in session storage!");
return null;
}
function generateScoutURLForU8TokenWithRegionID(uriEncodedU8Token, region) {
let domain = "ef-webview.gryphline.com"; // Global
let regionID = 2; // Asia
if (region == "NA/EU") {
regionID = 3;
} else if (region == "China") {
domain = "ef.webview.hypergryph.com";
regionID = 1;
}
let generatedScoutURL = `https://${domain}/page/gacha_char?server=${regionID}&u8_token=${uriEncodedU8Token}`;
console.log("[akemi-arknights-endfield-token-extractor] [generateScoutURLForU8TokenWithRegionID] Generated scout URL for region %s (※ ID %d, domain %s) → %s", region, regionID, domain, generatedScoutURL);
return generatedScoutURL;
}
function main() {
console.log("[akemi-arknights-endfield-token-extractor] [main] Initialised akemi-arknights-endfield-token-extractor! Calling method selectors…");
let dumpedU8Token = dumpU8Token();
if (!dumpedU8Token) {
console.error("[akemi-arknights-endfield-token-extractor] [main] [ERROR] u8_token is nil!");
alert("[akemi-arknights-endfield-token-extractor]\n\nFailed to extract token! (※ u8_token is nil)\n\nPlease let the page finish loading, then refresh it. If the issue persists. make sure you're logged into your account, and that you're using the latest version of this script.\n\nトークンの抽出に失敗しました!(※u8_tokenがnil)\n\nページの読み込みが完了するまでお待ちください。その後、ページを再読み込みしてください。問題が解決しない場合は、アカウントにログインしていることと、このスクリプトの最新バージョンを使用していることをご確認ください。");
return;
}
let uriEncodedU8Token = encodeURIComponent(dumpedU8Token);
console.log("[akemi-arknights-endfield-token-extractor] [main] URI encoded u8_token → %s", uriEncodedU8Token);
injectPasteboardButton("Copy URL (Asia)\nURLをコピー (アジア)", generateScoutURLForU8TokenWithRegionID(uriEncodedU8Token, "Asia"));
injectPasteboardButton("Copy URL (NA/EU)\nURLをコピー (北米・ヨーロッパ)", generateScoutURLForU8TokenWithRegionID(uriEncodedU8Token, "NA/EU"));
injectPasteboardButton("Copy URL (China)\nURLをコピー (中国)", generateScoutURLForU8TokenWithRegionID(uriEncodedU8Token, "China"));
injectPasteboardButton("Copy Token\nトークンをコピー", uriEncodedU8Token);
injectPasteboardButton("Copy Token (Raw)\nトークンをコピー (Raw)", dumpedU8Token);
console.log("[akemi-arknights-endfield-token-extractor] [main] All operations complete!");
return;
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment