Как я могу часто отправлять электронные письма через python django с помощью cronjob?

Я пытаюсь запускать функцию в django каждые 5 минут. Для этого я использую пакет django-crontab. Функция, которая должна запускаться, проверяет некоторые условия в базе данных и, если они выполнены, отправляет электронное письмо пользователю приложения.

На моем сервере linux ubuntu 20.04 запущен django 4. Я добавил cronjob через python3 manage.py crontab add (в активированной виртуальной среде). Но потом я задался вопросом, почему cronjob не запускается. Я попытался выполнить задание вручную, и оно сработало.

Я думаю, что проблема сводится к следующему: Когда я нахожусь в активированной виртуальной среде и запускаю кронтаб с помощью "python3 manage.py crontab run ", он работает. Но когда я запускаю его вне виртуальной среды, я получаю следующую ошибку:

Failed to complete cronjob at ('*/5 * * * *', 'evaluation_tool.scripts.cron.send_mail_if_classeval_ended')
Traceback (most recent call last):
  File "/var/www/amadeus/lib/python3.10/site-packages/django_crontab/crontab.py", line 145, in run_job
    func(*job_args, **job_kwargs)
  File "/var/www/amadeus/evaluation_tool/scripts/cron.py", line 12, in send_mail_if_classeval_ended
    send_mail_time_over_class_evaluation(class_evaluation=class_evaluation.pk,
  File "/var/www/amadeus/evaluation_tool/scripts/email_handler.py", line 122, in send_mail_time_over_class_evaluation
    send_falko_mail("AMADEUS Evaluation abgeschlossen", message, to_email_address)
  File "/var/www/amadeus/evaluation_tool/scripts/email_handler.py", line 34, in send_falko_mail
    msg.send(fail_silently=False)
  File "/var/www/amadeus/lib/python3.10/site-packages/django/core/mail/message.py", line 298, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/var/www/amadeus/lib/python3.10/site-packages/django/core/mail/backends/smtp.py", line 124, in send_messages
    new_conn_created = self.open()
  File "/var/www/amadeus/lib/python3.10/site-packages/django/core/mail/backends/smtp.py", line 87, in open
    self.connection.starttls(
  File "/usr/lib/python3.10/smtplib.py", line 769, in starttls
    self.ehlo_or_helo_if_needed()
  File "/usr/lib/python3.10/smtplib.py", line 611, in ehlo_or_helo_if_needed
    if not (200 <= self.ehlo()[0] <= 299):
  File "/usr/lib/python3.10/smtplib.py", line 451, in ehlo
    self.putcmd(self.ehlo_msg, name or self.local_hostname)
  File "/usr/lib/python3.10/smtplib.py", line 378, in putcmd
    self.send(f'{s}{CRLF}')
  File "/usr/lib/python3.10/smtplib.py", line 365, in send
    raise SMTPServerDisconnected('please run connect() first')
smtplib.SMTPServerDisconnected: please run connect() first

Почему соединение с SMTP-сервером работает в активированной виртуальной среде, но не работает вне ее, что является желаемым способом при использовании cronjob?

Чтобы часто отправлять электронные письма через Python Django с помощью cronjob, вы можете сделать следующее:

  1. Создайте команду управления Django: В вашем проекте Django создайте команду управления, которая отправляет электронные письма, которые вы хотите отправить. Вы можете сделать это, создав команду управления, используя класс Command from django.core.management.base.
  2. Запланируйте команду управления: После создания управляющую команду, вы можете запланировать ее выполнение через регулярные промежутки времени используя задание cron. Для этого вам нужно отредактировать файл crontab на вашем сервере и добавить запись для команды управления. В crontab должна быть указана частота, с которой вы хотите, чтобы команда и путь к управляющей команде.

Вот пример записи в crontab, которая запускает команду управления с именем send_emails каждый час:

0 * * * * /path/to/project/manage.py send_emails
  • Протестируйте задание cron: После добавления записи в crontab вам следует проверить правильность работы задания cron, запустив вручную команду команду управления и проверить, что электронные письма отправляются, как как ожидалось.

Важно отметить, что вам необходимо убедиться, что ваш проект Django правильно настроен для отправки электронной почты. Это может потребовать настройки почтового сервера или использования сторонних почтовых сервисов, таких как Gmail или Sendgrid.

Я нашел проблему.

Я установил определенные переменные среды для SMTP Host, User и Password. Но crontab не может получить к ним доступ. Поэтому есть две возможности:

  1. Добавьте их непосредственно в голову файла cron через crontab -e
  2. .
EMAIL_HOST=XXX
EMAIL_HOST_USER=XXX
EMAIL_PASS=XXX
  1. Добавьте их через аргумент django-crontab в settings.py:
CRONTAB_COMMAND_PREFIX = 'EMAIL_HOST=XXX\nEMAIL_HOST_USER=XXX\nEMAIL_PASS=XXX'
Вернуться на верх