2012-11-08 4 views
0

Я пытаюсь отправить текстовое сообщение с использованием Gmail и модуля smtplib в Python.Python: smtplib Добавляет новую строку в сообщение

Основная функциональность реализована, и, используя следующий код, я совершенно в состоянии получить эти текстовые сообщения на свой телефон:

server = smtplib.SMTP('smtp.gmail.com', 587) 
server.ehlo() 
server.starttls() 
server.login('email', 'password') 
server.sendmail('email', 'recipient', '\nhttp://apple.com') 

Теперь, это может быть какой-то полезности говоря я посылаю ссылка. Интересно, почему я вставил \n перед ссылкой на пример. очевидно, без него smtplib обрабатывает ссылку как заголовок, и поэтому отправляет пустое сообщение.

Однако символ новой строки добавляется к моему сообщению, например, так:

http://apple.com 
newline here 

Я не могу понять, почему это происходит:

  • является smtplib добавление новой строки, так как сообщение это ссылка?
  • Это потому, что я получаю сообщение в виде SMS-сообщения?
  • Gmail добавляет новую строку?
+1

Кстати, вы, вероятно, захотите использовать '['recipient']' там, а не только '' получатель''. Существует специальное исключение, чтобы рассматривать одну строку как одноэлементный список, но лучше не полагаться на это. (Если я правильно помню, была одна версия Python, где отправка одного 'unicode' вместо' str' означала, что вы получили список символов Unicode ...) – abarnert

+0

Спасибо, вы правы, это безопаснее. – elliottbolzan

ответ

2

Аргумент msg для sendmail не является телом сообщения, но все сообщение. Таким образом, это должно быть допустимое сообщение RFC (2) 822.

В примечании в конце the documentation говорит:

В общем, вы хотите использовать функции Свойства почтового пакета, чтобы построить сообщения электронной почты, который затем можно преобразовать в строку и отправить через Sendmail(); см. электронную почту: Примеры.

Однако пример непосредственно выше, который показывает, как создать простое сообщение самостоятельно:

# Add the From: and To: headers at the start! 
msg = ("From: %s\r\nTo: %s\r\n\r\n" 
     % (fromaddr, ", ".join(toaddrs))) 

Если вы хотите знать, что представляет собой действительное сообщение электронной почты, см RFC 2822 (и, возможно, RFC 822, что 2822 но с некоторыми полезными объяснениями и примерами). Но короткая версия такова: это последовательность строк заголовка, каждая заканчивается в \r\n, а затем пустая строка (то есть \r\n\r\n), а затем тело сообщения.

Так что, технически говоря, ваш код не должен даже работать, потому что он просто имеет \n вместо префикса \r\n.

Что еще более важно, вы отправляете сообщение без заголовков. Даже не From: и To:, что вы, вероятно, думаете, что входите. Как the documentation для sendmail говорит:

from_addr и to_addrs параметры используются для построения конверта сообщения, используемого транспортными средствами. SMTP не изменяет заголовки сообщений каким-либо образом.

Это может считаться недействительным (или спамом) на разных серверах.

Между тем, дополнительная строка в конце состоит в том, что все строки должны заканчиваться \r\n, а SMTP - это протокол, ориентированный на линию. Просто невозможно сообщить, что сообщение выполнено, если оно не заканчивается новой строкой.

Если вы хотите понять подробности, см. RFC2821, в котором объясняется протокол SMTP. В частности, посмотрите 2.3.1 Mail Objects, 2.3.7 Lines и 4.1.1.4 DATA (DATA). Но короткая версия заключается в том, что для отправки сообщения требуется команда DATA, которая должна заканчиваться \r\n.\r\n, а «первая из этой завершающей последовательности также заканчивается окончательной строкой данных (текст сообщения)». Это означает, что нет способа отправить сообщение, которое не заканчивается новой строкой.

Если вы действительно этого хотите, можно обойти это, инкапсулируя свое тело в сообщении MIME; само сообщение MIME, конечно, закончится новой строкой, но это не повлияет на ваш инкапсулированный объект. Есть несколько способов сделать это, но вам нужно, чтобы получатель мог обрабатывать все, что вы отправляете, и я предполагаю, что ни один из этих способов не будет работать с шлюзом электронной почты-SMS (тем более, что конечная точка приема SMS).

+0

Хотя я немного разочарован этим, ваш ответ невероятно детализирован. Спасибо огромное ! – elliottbolzan

+0

@boopyman: Да, вы можете сказать по двухсимвольной новой строке, дополнительным записям, повторяющимся заголовкам с повторной информацией в конверте и т. Д., Что письмо не было точно спроектировано вокруг идеи 140-байтовых сообщений ... – abarnert

+0

Да, Я определенно понимаю, что вы имеете в виду. Однако есть ли альтернатива Python для отправки SMS, может быть, не через электронную почту, которая не добавляет новую строку? Это просто для эстетики, но тем не менее это меня беспокоит;) – elliottbolzan

Смежные вопросы