ks.dgoon.lee log

새 댓글 이메일 알림, 꽤 삽질 많이함 🥲


2024/01/06 00:38:50 #django #dev #comment #virtualenv #django-crontab #email #aws #smtp
Attachments:

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'

Done!

... 인줄 알았으나, 이번엔 이상하게도 블로그를 띄운 environment 에서만 아래 에러가 발생하며 이메일 발송이 실패한다!

[SSL: CERTIFICATE_VERIFY_FAILED]


여러가지 확인해본 결과, 같은 머신의 같은 계정의 다른 env 에서는 발송이 되는데 얘만 안됨. 삽질을 좀 해보다가 너무 이상해서

pip list --format=freeze > env1.txt
conda create -n env2 python=3.11.5
conda activate env2
pip install -r env1.txt

환경을 새로 하나 만들고 해보니까 이번에는 된다!? env1 이 다른 머신에서 conda-pack 으로 가져왔던 녀석인데 뭔가 오염된게 섞여있었나... ㅠㅠ 이건 원인 까보기에는 너무 오래 걸릴 것 같고, 환경 새로 만드는 것으로 우회했다.

확실친 않지만, 혹시 모르니 앞으로 conda-pack 안쓰고 그냥 requirements.txt 뽑아서 환경 다시 빌드해야겠다.




확인완료!



댓글 5개

2024/01/06 00:39:05 dgoon
테스트 댓글 한번 달아보자 ㅋ
⤷ 댓글을 작성해 주세요. 비밀번호는 나중에 댓글을 수정하거나 삭제할 때 필요합니다.
⤷ 댓글을 작성해 주세요. 비밀번호는 나중에 댓글을 수정하거나 삭제할 때 필요합니다.

2024/01/06 02:15:05 dgoon
이것이 환경까지 새로 만들고 나서 달아본 댓글이다.
⤷ 댓글을 작성해 주세요. 비밀번호는 나중에 댓글을 수정하거나 삭제할 때 필요합니다.

2024/04/12 10:54:38 지나가다가
와..이건 신의한수...감사합니다.
⤷ 댓글을 작성해 주세요. 비밀번호는 나중에 댓글을 수정하거나 삭제할 때 필요합니다.

2024/04/12 11:10:35 dgoon
도움이 되었다니 다행입니다. 댓글 알림이 잘 돌고 있군요. ㅎㅎ
⤷ 댓글을 작성해 주세요. 비밀번호는 나중에 댓글을 수정하거나 삭제할 때 필요합니다.