Skip to content

Instantly share code, notes, and snippets.

@cptmacp
Last active March 5, 2026 05:28
Show Gist options
  • Select an option

  • Save cptmacp/70f66f2a4fb9d5fa708d33fbcc8e265a to your computer and use it in GitHub Desktop.

Select an option

Save cptmacp/70f66f2a4fb9d5fa708d33fbcc8e265a to your computer and use it in GitHub Desktop.
automate for skport endfield daily login claim via js script and send notification to telegram
/** Config Starts. **/
const profiles = [
{
cred: "xxxxxxxxxxxxxxxxxxxxxx", // Replace with your Endfield cred cookie value ( get from cookie )
skGameRole: "xxxxxxxxxxxx", // Replace with your Endfield skGameRole cookie value ( get from cookie )
platform: "3",
vName: "1.0.0",
accountName: "acc_name" // Replace with a name to identify this account( a simple identifier )
}
// Add more profiles if needed
];
const telegram_notify = true;
const myTelegramID = "xxxxx"; // Replace with your Telegram ID
const telegramBotToken = "xxxxxx:xxxxxxxx"; // Replace with your bot token
/** Config ends. **/
const attendanceUrl = 'https://zonai.skport.com/web/v1/game/endfield/attendance';
async function main() {
const messages = await Promise.all(profiles.map(autoClaimFunction));
const endfieldResp = `${messages.join('\n\n')}`;
if (telegram_notify && telegramBotToken && myTelegramID) {
postWebhook(endfieldResp);
}
}
function autoClaimFunction({ cred, skGameRole, platform, vName, accountName }) {
console.log(`[${accountName}] Checking credentials and performing check-in...`);
const timestamp = Math.floor(Date.now() / 1000).toString();
// Try to refresh token for signing (best-effort)
let token = "";
try {
token = refreshToken(cred, platform, vName);
console.log(`[${accountName}] Token refreshed successfully.`);
} catch (e) {
console.error(`[${accountName}] Token refresh failed: ${e.message}`);
// continue with empty token; request may fail if token required
}
const sign = generateSign('/web/v1/game/endfield/attendance', '', timestamp, token, platform, vName);
const header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:147.0) Gecko/20100101 Firefox/147.0',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Referer': 'https://game.skport.com/',
'Content-Type': 'application/json',
'sk-language': 'en',
'sk-game-role': skGameRole,
'cred': cred,
'platform': platform,
'vName': vName,
'timestamp': timestamp,
'sign': sign,
'Origin': 'https://game.skport.com',
'Connection': 'keep-alive',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-site'
};
const options = {
method: 'POST',
headers: header,
muteHttpExceptions: true,
};
let response = `Daily reward claim for ${accountName}`;
try {
const endfieldResponse = UrlFetchApp.fetch(attendanceUrl, options);
const responseJson = JSON.parse(endfieldResponse.getContentText());
console.log(`[${accountName}] API Response Code: ${responseJson.code}`);
if (responseJson.code === 0) {
response += '\nClaim successful!';
const awards = responseJson.data.awardIds.map(award => {
const resource = responseJson.data.resourceInfoMap[award.id];
return `${resource.name}: ${resource.count}`;
}).join(', ');
response += `\nAwards: ${awards}`;
} else if (responseJson.code === 10001) {
response += '\nAlready claimed today.';
} else {
response += `\nError: ${responseJson.message}`;
}
} catch (error) {
console.error(`[${accountName}] Exception: ${error.message}`);
response += `\nFailed to claim: ${error.message}`;
}
return response;
}
function postWebhook(data) {
console.log('Posting to Telegram...');
let payload = JSON.stringify({
'chat_id': myTelegramID,
'text': data,
'parse_mode': 'HTML'
});
const options = {
method: 'POST',
contentType: 'application/json',
payload: payload,
muteHttpExceptions: true
};
UrlFetchApp.fetch('https://api.telegram.org/bot' + telegramBotToken + '/sendMessage', options);
}
/** Helper: Refresh token used for signing **/
function refreshToken(cred, platform, vName) {
const refreshUrl = 'https://zonai.skport.com/web/v1/auth/refresh';
const header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'application/json, text/plain, */*',
'cred': cred,
'platform': platform,
'vName': vName,
'Origin': 'https://game.skport.com',
'Referer': 'https://game.skport.com/'
};
const options = {
method: 'GET',
headers: header,
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(refreshUrl, options);
const json = JSON.parse(response.getContentText());
if (json.code === 0 && json.data && json.data.token) {
return json.data.token;
} else {
throw new Error(`Refresh Failed (Code: ${json.code}, Msg: ${json.message})`);
}
}
/** Signature generation (HMAC-SHA256 -> MD5) **/
function generateSign(path, body, timestamp, token, platform, vName) {
let str = path + body + timestamp;
const headerJson = `{"platform":"${platform}","timestamp":"${timestamp}","dId":"","vName":"${vName}"}`;
str += headerJson;
const hmacBytes = Utilities.computeHmacSha256Signature(str, token || '');
const hmacHex = bytesToHex(hmacBytes);
const md5Bytes = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, hmacHex);
return bytesToHex(md5Bytes);
}
function bytesToHex(bytes) {
return bytes.map(function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('');
}
@GOJiong
Copy link

GOJiong commented Jan 29, 2026

Thanks for sharing, was always using the Hoyolab auto sign-in via Github action, this is also useful!

@Renari
Copy link

Renari commented Feb 2, 2026

My daily sign in is completely broken I get a 10000 Request exception response. I also cannot manually do it on the website.

@OPdJ
Copy link

OPdJ commented Feb 2, 2026

Receiving the same error as @Renari
image

@cptmacp
Copy link
Author

cptmacp commented Feb 2, 2026

@cptmacp
Copy link
Author

cptmacp commented Feb 3, 2026

@OPdJ
Copy link

OPdJ commented Feb 3, 2026

Working great here, thank you for your work.

@magnade
Copy link

magnade commented Feb 25, 2026

I had deepseek redo this as python so it could be run on either other cloud services or just locally as a cronjob it can be found here: https://gist.github.com/magnade/8711a64f415a908fca882682c68d0582

@Nyaruko166
Copy link

does cred have expire time like ACCOUNT_TOKEN or i can just infinite refesh if im still logged in?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment