Skip to content

Instantly share code, notes, and snippets.

@ngshiheng
Last active January 13, 2022 14:08
Show Gist options
  • Save ngshiheng/cdeeda5eae219196d9014f46d688f34b to your computer and use it in GitHub Desktop.
Save ngshiheng/cdeeda5eae219196d9014f46d688f34b to your computer and use it in GitHub Desktop.
How I Sync Daily LeetCoding Challenge to Todoist for Free https://jerrynsh.com/how-i-sync-daily-leetcoding-challenge-to-todoist/
const TODOIST_API_ENDPOINT = 'https://api.todoist.com/rest/v1'
// Passing in the `question` object from fetchDailyCodingChallenge function
const createTodoistTask = async question => {
const questionInfo = question.data.activeDailyCodingChallengeQuestion
const questionTitle = questionInfo.question.title
const questionDifficulty = questionInfo.question.difficulty
const questionLink = `https://leetcode.com${questionInfo.link}`
console.log(`Creating Todoist task with title ${questionTitle}.`)
const body = {
content: `[${questionTitle}](${questionLink})`,
description: `Difficulty: ${questionDifficulty}`,
due_string: 'Today',
priority: 4,
}
const init = {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${TODOIST_API_TOKEN}`, // Set at environment variable
},
}
const response = await fetch(`${TODOIST_API_ENDPOINT}/tasks`, init)
return response.json()
}
// Just some constants
const LEETCODE_API_ENDPOINT = 'https://leetcode.com/graphql'
const DAILY_CODING_CHALLENGE_QUERY = `
query questionOfToday {
activeDailyCodingChallengeQuestion {
date
userStatus
link
question {
acRate
difficulty
freqBar
frontendQuestionId: questionFrontendId
isFavor
paidOnly: isPaidOnly
status
title
titleSlug
hasVideoSolution
hasSolution
topicTags {
name
id
slug
}
}
}
}`
// We can pass the JSON response as an object to our createTodoistTask later.
const fetchDailyCodingChallenge = async () => {
console.log(`Fetching daily coding challenge from LeetCode API.`)
const init = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: DAILY_CODING_CHALLENGE_QUERY }),
}
const response = await fetch(LEETCODE_API_ENDPOINT, init)
return response.json()
}
# HTTP POST to https://leetcode.com/graphql
query questionOfToday {
activeDailyCodingChallengeQuestion {
date
userStatus
link
question {
acRate
difficulty
freqBar
frontendQuestionId: questionFrontendId
isFavor
paidOnly: isPaidOnly
status
title
titleSlug
hasVideoSolution
hasSolution
topicTags {
name
id
slug
}
}
}
}
curl --request POST \
--url https://leetcode.com/graphql \
--header 'Content-Type: application/json' \
--data '{"query":"query questionOfToday {\n\tactiveDailyCodingChallengeQuestion {\n\t\tdate\n\t\tuserStatus\n\t\tlink\n\t\tquestion {\n\t\t\tacRate\n\t\t\tdifficulty\n\t\t\tfreqBar\n\t\t\tfrontendQuestionId: questionFrontendId\n\t\t\tisFavor\n\t\t\tpaidOnly: isPaidOnly\n\t\t\tstatus\n\t\t\ttitle\n\t\t\ttitleSlug\n\t\t\thasVideoSolution\n\t\t\thasSolution\n\t\t\ttopicTags {\n\t\t\t\tname\n\t\t\t\tid\n\t\t\t\tslug\n\t\t\t}\n\t\t}\n\t}\n}\n","operationName":"questionOfToday"}'
// Move the constants to const.js
const syncLeetCodeCodingChallenge = async event => {
const question = await fetchDailyCodingChallenge()
await createTodoistTask(question)
}
addEventListener('scheduled', event => {
// Change 'fetch' to 'scheduled'
event.waitUntil(syncLeetCodeCodingChallenge(event))
})
curl --request POST \
--url 'https://api.todoist.com/rest/v1/tasks?=' \
--header 'Authorization: Bearer xxx-your-todoist-api-token-xxx' \
--header 'Content-Type: application/json' \
--data '{
"content": "Buy a jar of peanut butter",
"due_string": "Today"
}'
name = "<your-project-name>"
type = "webpack"
...
[triggers]
crons = ["1 0 * * *"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment