Last active
February 6, 2026 17:47
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** 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(''); | |
| } |
My daily sign in is completely broken I get a 10000 Request exception response. I also cannot manually do it on the website.
Receiving the same error as @Renari

Author
Hi please refer to my comment here
Author
Update 03 Feb 2025
The script are fixed now
Working great here, thank you for your work.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for sharing, was always using the Hoyolab auto sign-in via Github action, this is also useful!