새 댓글 이메일 알림, 꽤 삽질 많이함 🥲
dboard 만지면서 AWS SES 뚫은김에 블로그에도 새 댓글이 달리면 이메일로 알림을 보내도록 설정했다.
django-crontab 을 사용.
1. pip install django-crontab
2. INSTALLED_APPS 에 django_crontab 추가 (언더바 주의!)
3. 설정 파일에 CRONJOBS 추가. 나는 core/cron.py 안에 def notify_new_comments() ... 라는 함수를 만들었다.
CRONJOBS = [
('*/10 * * * *', 'core.cron.notify_new_comments', '>> '+os.path.join(BASE_DIR, 'log/cron.log') + ' 2>&1'),
]
4. notify_new_comments 는 지난 10분간(cronjob 텀이 10분이니까) 새 댓글이 있다면 모아서 이메일로 쏴준다. 대충 아래같은 모양.
from datetime import timedelta
from django.utils import timezone
from django.core.mail import send_mail
from .models import Comment
def notify_new_comments():
now = timezone.now()
now_str = now.strftime('%Y-%m-%d %H:%M:%S')
print(f'run notify_new_comments @ {now_str}')
ten_minutes_ago = timezone.now() - timedelta(seconds=600)
recent_comments = Comment.objects.filter(created_at__gte=ten_minutes_ago)
if recent_comments.count() == 0:
return
comments_info = []
for idx, comment in enumerate(recent_comments):
comments_info.append(f'[{idx+1}] {comment.author} 님이 <{comment.post.title}>에 새 댓글을 달았습니다.')
new_comment_info_str = '\n'.join(comments_info)
print(new_comment_info_str)
send_mail(
"새 댓글이 달렸습니다.",
new_comment_info_str,
"FROM_EMAIL",
['TO_EMAIL'],
fail_silently=False)
5. BASE_DIR/log/cron.log 에 로그남기도록 했으니 log 디렉토리를 만들고 저장소에 반영.
6. python manage.py crontab add 를 해주면 crontab 에 등록된다. add 대신 remove 하면 제거됨.
7. 댓글달고 잠시 기다리면 10분에 한번씩 돌면서 알려준다.
... 일 줄 알았으나 문제 발생.
RuntimeError: No job with hash 09c5dbe2dcf1cc4af94d29548cd751ba found. It seems the crontab is out of sync with your settings.CRONJOBS. Run "python manage.py crontab add" again to resolve this issue!
이런 에러가 로그에 남아있다.
원인: 나는 설정파일을 development.py, production.py 두개로 나누어서 쓰고 있다. settings.py 는 development.py 를 가리키는 심볼릭 링크인 상태. 등록할때에는 --settings=production.py 를 주었는데, crontab 에는 세팅파일 지정이 없는 상태라서 환경이 달라서 못찾는 것. 여기를 참고해서, production.py 에 CRONTAB_DJANGO_SETTINGS_MODULE 를 설정해 주었다.
CRONTAB_DJANGO_SETTINGS_MODULE = 'dblog.production'
pip list --format=freeze > env1.txt
conda create -n env2 python=3.11.5
conda activate env2
pip install -r env1.txt