Skip to content

Commit

Permalink
Merge pull request #2 from sglkc/discord-integration
Browse files Browse the repository at this point in the history
add discord webhook integration
  • Loading branch information
sglkc authored Jul 3, 2024
2 parents 558daee + e29dbbd commit 483e26e
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 28 deletions.
1 change: 1 addition & 0 deletions .github/workflows/login.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ jobs:
run: node index.js ${{ vars.GAMES }}
env:
COOKIE: ${{ secrets.COOKIE }}
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Today's check in status:

- [Getting your cookie](#getting-your-cookie)
- [Usage](#usage)
- [Discord Webhook](#discord-webhook)
- [FAQ](#faq)

## Getting your cookie
Expand Down Expand Up @@ -82,7 +83,7 @@ You have to check in manually first to get your cookie, follow these steps (clic

8. <details>
<summary>
For the first day, you have to run this manually.
For the first day, you have to trigger this manually.
Simply go <a href="../../actions/workflows/login.yml">HERE</a> and click on Run workflow
</summary>
<img src="https://github.com/sglkc/hoyolab-auto-daily/assets/31957516/ea1e48d2-a069-4db6-bdcd-86eecae8d81d" />
Expand All @@ -95,6 +96,32 @@ You have to check in manually first to get your cookie, follow these steps (clic

10. You're set! Hop on your game the next day and see if you got the rewards

## Discord Webhook

You may use Discord webhook to send notifications to your channel!

1. <details>
<summary>Go to channel settings</summary>
<img src="https://github.com/sglkc/hoyolab-auto-daily/assets/31957516/80f3b2f1-cc55-4316-9153-3fc5026b7da8" />
</details>

2. <details>
<summary>Go to Integrations and click Create Webhook</summary>
<img src="https://github.com/sglkc/hoyolab-auto-daily/assets/31957516/b4d0c07d-35a5-4382-99de-584c70c4d730" />
</details>

3. <details>
<summary>You can edit the name and picture freely, then Copy Webhook URL</summary>
<img src="https://github.com/sglkc/hoyolab-auto-daily/assets/31957516/3df5b59c-edc9-4884-897c-9159e243598e" />
</details>

4. <details>
<summary>Create a new repository <em>variable</em> named <code>DISCORD_WEBHOOK</code> with value of the webhook URL</summary>
<img src="https://github.com/sglkc/hoyolab-auto-daily/assets/31957516/15b029ff-906d-472c-b356-ae9efed4477b" />
</details>

5. You may trigger the check in manually and see if the messages got sent

## FAQ

1. Privacy
Expand Down
108 changes: 81 additions & 27 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,43 @@
#!/usr/bin/env node

const args = process.argv.slice(2)
const cookie = process.env.COOKIE
const discordWebhook = process.env.DISCORD_WEBHOOK
const messages = []
const endpoints = {
gi: 'https://sg-hk4e-api.hoyolab.com/event/sol/sign?act_id=e202102251931481',
hsr: 'https://sg-public-api.hoyolab.com/event/luna/os/sign?act_id=e202303301540311',
hi3: 'https://sg-public-api.hoyolab.com/event/mani/sign?act_id=e202110291205111',
tot: 'https://sg-public-api.hoyolab.com/event/luna/os/sign?act_id=e202202281857121',
}

async function main() {

// check script execution
const args = process.argv.slice(2);
let hasErrors = false

async function main() {
if (!args.length) {
console.error('Argument is empty!')
console.info('Usage: node index.js [gi] [hsr] [hi3] [tot]')
console.info('Example: node index.js hsr')
console.info(' node index.js gi hsr hi3 tot')
log('error', 'Argument is empty!')
log('info', 'Usage: node index.js [gi] [hsr] [hi3] [tot]')
log('info', 'Example: node index.js hsr')
log('info', ' node index.js gi hsr hi3 tot')
throw new Error('No argument passed.')
}

// check cookie environment variable
const cookie = process.env.COOKIE

if (!cookie) {
throw new Error('COOKIE environment variable not set!')
}

// track if any of the game has errors
let hasErrors = false

// begin processing command arguments
for (const arg of args) {
const game = arg.toLowerCase()

console.debug(`\n----- CHECKING IN FOR ${game} -----`)
log('debug', `\n----- CHECKING IN FOR ${game} -----`)

if (!(game in endpoints)) {
console.error(`Game ${arg} is invalid. Available games are: gi, hsr, hi3, and tot`)
hasErrors = true
log('error', `Game ${arg} is invalid. Available games are: gi, hsr, hi3, and tot`)
continue
}

// url, parameters, and body from valid browser request
// begin check in
const endpoint = endpoints[game]
const url = new URL(endpoint)
const actId = url.searchParams.get('act_id')
Expand Down Expand Up @@ -82,30 +77,89 @@ async function main() {

// success responses
if (json.message === 'OK' || json.retcode === 0) {
console.info(`${game}: Successfully checked in!`)
log('info', `${game}: Successfully checked in!`)
continue
}

if (json.message.includes('already') || json.retcode === -5003) {
console.info(`${game}: Already checked in for today`)
log('info', `${game}: Already checked in for today`)
continue
}

// error responses
hasErrors = true

console.debug(`${game}: Headers`, Object.fromEntries(res.headers))
console.debug(`${game}: Response`, json)
log('debug', `${game}: Headers`, Object.fromEntries(res.headers))
log('debug', `${game}: Response`, json)

if (json.message === 'Not logged in' || json.retcode === -100) {
console.error(`${game}: Error not logged in`)
log('error', `${game}: Error not logged in`)
continue
}

console.error(`${game}: Error undocumented, check debug headers and response`)
log('error', `${game}: Error undocumented, check debug headers and response`)
}

// send to discord webhook if set and valid url
if (discordWebhook && URL.canParse(discordWebhook)) {
await discordWebhookSend()
}

if (hasErrors) {
console.log('')
throw new Error('Error(s) occured.')
}
}

// custom log function to store messages
function log(type, ...data) {

// log to real console
console[type](...data)

// ignore debug and toggle hasErrors
switch (type) {
case 'debug': return
case 'error': hasErrors = true
}

// serialize data and add to messages
const string = data
.map(value => {
if (typeof value === 'object') {
return JSON.stringify(value, null, 2).replace(/^"|"$/, '')
}

return value
})
.join(' ')

messages.push({ type, string })
}

// must be function to return early
async function discordWebhookSend() {
log('debug', '\n----- DISCORD WEBHOOK -----')

if (!discordWebhook.toLowerCase().trim().startsWith('https://discord.com/api/webhooks/')) {
log('error', 'DISCORD_WEBHOOK is not a Discord webhook URL. Must start with `https://discord.com/api/webhooks/`')
return
}

const res = await fetch(discordWebhook, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
content: messages.map(msg => `(${msg.type.toUpperCase()}) ${msg.string}`).join('\n')
})
})

if (res.status === 204) {
log('info', 'Successfully sent message to Discord webhook!')
return
}

if (hasErrors) throw new Error('Error(s) occured.')
log('error', 'Error sending message to Discord webhook, please check URL and permissions')
}

await main()

0 comments on commit 483e26e

Please sign in to comment.