Skip to content

Commit a9308ba

Browse files
committed
adding new files
1 parent 867760a commit a9308ba

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

.github/workflows/daily.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: LeetCode Daily Mailer
2+
3+
on:
4+
schedule:
5+
- cron: '30 2 * * *' # Runs daily at 8:00 AM IST (2:30 AM UTC)
6+
workflow_dispatch: # Allow manual trigger from GitHub UI
7+
8+
jobs:
9+
send-mail:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v3
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: '3.x'
20+
21+
- name: Install dependencies
22+
run: pip install requests
23+
24+
- name: Run script
25+
env:
26+
SENDER_EMAIL: ${{ secrets.SENDER_EMAIL }}
27+
RECEIVER_EMAIL: ${{ secrets.RECEIVER_EMAIL }}
28+
EMAIL_PASSWORD: ${{ secrets.EMAIL_PASSWORD }}
29+
run: python daily_leetcode.py

leetcode_daily_mailer.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import requests
2+
import smtplib
3+
from email.mime.multipart import MIMEMultipart
4+
from email.mime.text import MIMEText
5+
import os
6+
7+
def get_title_slug():
8+
query = {
9+
"query": """
10+
query questionOfToday {
11+
activeDailyCodingChallengeQuestion {
12+
date
13+
link
14+
question {
15+
title
16+
titleSlug
17+
difficulty
18+
topicTags {
19+
name
20+
}
21+
}
22+
}
23+
}
24+
"""
25+
}
26+
27+
headers = {"Content-Type": "application/json"}
28+
response = requests.post("https://leetcode.com/graphql", json=query, headers=headers)
29+
if response.status_code != 200:
30+
raise Exception("Failed to fetch daily question")
31+
32+
data = response.json()['data']['activeDailyCodingChallengeQuestion']
33+
question = data['question']
34+
return {
35+
"title": question['title'],
36+
"titleSlug": question['titleSlug'],
37+
"difficulty": question['difficulty'],
38+
"tags": [tag['name'] for tag in question['topicTags']],
39+
"link": "https://leetcode.com" + data['link']
40+
}
41+
42+
def get_full_question_data(title_slug):
43+
query = {
44+
"query": """
45+
query getQuestionDetail($titleSlug: String!) {
46+
question(titleSlug: $titleSlug) {
47+
title
48+
content
49+
difficulty
50+
exampleTestcases
51+
}
52+
}
53+
""",
54+
"variables": {
55+
"titleSlug": title_slug
56+
}
57+
}
58+
59+
headers = {"Content-Type": "application/json"}
60+
response = requests.post("https://leetcode.com/graphql", json=query, headers=headers)
61+
if response.status_code != 200:
62+
raise Exception("Failed to fetch question details")
63+
64+
return response.json()['data']['question']
65+
66+
def send_email(subject, body_html):
67+
sender_email = os.environ['SENDER_EMAIL']
68+
receiver_email = os.environ['RECEIVER_EMAIL']
69+
70+
password = os.environ['EMAIL_PASSWORD']
71+
72+
msg = MIMEMultipart("alternative")
73+
msg['Subject'] = subject
74+
msg['From'] = sender_email
75+
msg['To'] = receiver_email
76+
77+
part = MIMEText(body_html, "html")
78+
msg.attach(part)
79+
80+
with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
81+
server.login(sender_email, password)
82+
server.sendmail(sender_email, receiver_email, msg.as_string())
83+
84+
def main():
85+
print("Fetching daily LeetCode problem...")
86+
basic_info = get_title_slug()
87+
full_question = get_full_question_data(basic_info["titleSlug"])
88+
89+
html_body = f"""
90+
<h2>🧠 LeetCode Daily Challenge: {full_question['title']}</h2>
91+
<p><b>Difficulty:</b> {full_question['difficulty']}</p>
92+
<p><b>Tags:</b> {', '.join(basic_info['tags'])}</p>
93+
<p><a href="{basic_info['link']}">🔗 View Problem on LeetCode</a></p>
94+
<hr>
95+
{full_question['content']}
96+
<hr>
97+
<h4>Example Testcases:</h4>
98+
<pre>{full_question['exampleTestcases']}</pre>
99+
"""
100+
101+
send_email(f"📌 LeetCode Daily Challenge: {full_question['title']}", html_body)
102+
print("✅ Email sent successfully!")
103+
104+
if __name__ == "__main__":
105+
main()

0 commit comments

Comments
 (0)