visit
As a lazy person, having to check every time I want to practice is too much of a hassle. So then I thought, why not just sync the Daily LeetCoding Challenge to my Todoist every day?
Here’s the GraphQL request body:
# HTTP POST to //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
}
}
}
}
You can use the curl
command below to try it out yourself:
curl --request POST \
--url //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"}'
Enough talking, let’s start to write some code that does exactly what we went through:
// Just some constants
const LEETCODE_API_ENDPOINT = '//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()
}
Task “Get Daily LeetCoding Challenge question” — checked.
Authorization: Bearer xxx-your-todoist-api-token-xxx
to your HTTP request headercurl --request POST \
--url '//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"
}'
const TODOIST_API_ENDPOINT = "//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 = `//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();
};
Task “Create a new task on my Todoist account” — done.
This is probably one of the most common misconceptions . As the worker’s environment is not in Node.js, a lot of packages (e.g. npm install some-node-package
) that are running on Node.js would simply not work.
Tip: Check out the supported packages and libraries .
Lucky for us, we only need to use the JavaScript built-in fetch
API.
npm install -g @cloudflare/wrangler
addEventListener
function. For our use case, we will be using the API where we simply have to change our event from "fetch"
to "scheduled"
// 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));
});
Next, we would simply need to modify the wrangler.toml as below:
name = "<your-project-name>"
type = "webpack"
...
[triggers]
crons = ["1 0 * * *"]
With the setting above, the worker will run every day at and sync the Daily LeetCoding Challenge to your Todoist.
That’s all! Moving on to testing.
# At terminal 1
miniflare
# At terminal 2
curl "//localhost:8787/.mf/scheduled"
If you see a new task is created on your Todoist, you have made it!
TODOIST_API_TOKEN
using wrangler secret put TODOIST_API_TOKEN
. You may find the newly added secret under 'Cloudflare Worker' → 'Settings' → 'Variables'. You can get your Todoist API token .CF_API_TOKEN
into your GitHub repository secrets. You can create your API token from using the Edit Cloudflare Workers
template.wrangler publish