Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Perl SMTP - помогите поправить скрипт / 4 сообщений из 4, страница 1 из 1
15.08.2015, 11:45
    #39029928
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Perl SMTP - помогите поправить скрипт
Есть такой скрипт:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
use utf8;
use strict;
use warnings;
use boolean;
use Encode;
use Net::SMTPS;
use MIME::Base64;

my $from = 'Отправитель <auto@domain.ru>;';
my $rcpt = 'Получатель <info@domain.ru>;';
my $copy = 'Копия <support@domain.ru>;';
my $subj = 'Тестовый заголовок';
my $body = 'Тест тест' . "\n" . 'Строка2';
my @hdr = ();
push @hdr, 'From: '       . encode('MIME-Header', $from);
push @hdr, 'To: '         . encode('MIME-Header', $rcpt);
push @hdr, 'Reply-To: '   . encode('MIME-Header', $copy);
push @hdr, 'Subject: '    . encode('MIME-Header', $subj);
push @hdr, encode('MIME-Header', $subj);
push @hdr, 'MIME-Version: 1.0';
push @hdr, 'Content-type: text/plain; charset=UTF-8';
push @hdr, 'Content-Transfer-Encoding: base64';
my $smtp = Net::SMTPS->new('smtp.gmail.com', 'Port'=>587, 'doSSL'=>'starttls', 'Debug'=>1);
$smtp->auth('auto@domain.ru', 'password');
$smtp->mail($from);
$smtp->to($rcpt);
$smtp->cc($copy);
$smtp->data();
$smtp->datasend($_) foreach (@hdr);
$smtp->datasend("\n");
$smtp->datasend(encode_base64(encode('utf8',$body)));
$smtp->dataend();
$smtp->quit;



Скрипт должен отправлять почту с домена, обслуживаемого Gmail.
В принципе почта уходит, вот лог:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
Net::SMTPS=GLOB(0x10516c8)<<< 220 smtp.gmail.com ESMTP n10sm2076605lbc.37 - gsmtp
Net::SMTPS=GLOB(0x10516c8)>>> EHLO localhost.localdomain
Net::SMTPS=GLOB(0x10516c8)<<< 250-smtp.gmail.com at your service, [195.209.124.90]
Net::SMTPS=GLOB(0x10516c8)<<< 250-SIZE 35882577
Net::SMTPS=GLOB(0x10516c8)<<< 250-8BITMIME
Net::SMTPS=GLOB(0x10516c8)<<< 250-STARTTLS
Net::SMTPS=GLOB(0x10516c8)<<< 250-ENHANCEDSTATUSCODES
Net::SMTPS=GLOB(0x10516c8)<<< 250-PIPELINING
Net::SMTPS=GLOB(0x10516c8)<<< 250-CHUNKING
Net::SMTPS=GLOB(0x10516c8)<<< 250 SMTPUTF8
Net::SMTPS=GLOB(0x10516c8)>>> STARTTLS
Net::SMTPS=GLOB(0x10516c8)<<< 220 2.0.0 Ready to start TLS
Net::SMTPS=GLOB(0x10516c8)>>> EHLO localhost.localdomain
Net::SMTPS=GLOB(0x10516c8)<<< 250-smtp.gmail.com at your service, [195.209.124.90]
Net::SMTPS=GLOB(0x10516c8)<<< 250-SIZE 35882577
Net::SMTPS=GLOB(0x10516c8)<<< 250-8BITMIME
Net::SMTPS=GLOB(0x10516c8)<<< 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN XOAUTH
Net::SMTPS=GLOB(0x10516c8)<<< 250-ENHANCEDSTATUSCODES
Net::SMTPS=GLOB(0x10516c8)<<< 250-PIPELINING
Net::SMTPS=GLOB(0x10516c8)<<< 250-CHUNKING
Net::SMTPS=GLOB(0x10516c8)<<< 250 SMTPUTF8
Net::SMTPS=GLOB(0x10516c8)>>> AUTH LOGIN
Net::SMTPS=GLOB(0x10516c8)<<< 334 xxx
Net::SMTPS=GLOB(0x10516c8)>>> xxx
Net::SMTPS=GLOB(0x10516c8)<<< 334 xxx
Net::SMTPS=GLOB(0x10516c8)>>> xxx
Net::SMTPS=GLOB(0x10516c8)<<< 235 2.7.0 Accepted
Net::SMTPS=GLOB(0x10516c8)>>> MAIL FROM:<auto@domain.ru>;
Net::SMTPS=GLOB(0x10516c8)<<< 250 2.1.0 OK n10sm2076605lbc.37 - gsmtp
Net::SMTPS=GLOB(0x10516c8)>>> RCPT TO:<info@domain.ru>;
Net::SMTPS=GLOB(0x10516c8)<<< 250 2.1.5 OK n10sm2076605lbc.37 - gsmtp
Net::SMTPS=GLOB(0x10516c8)>>> RCPT TO:<support@domain.ru>;
Net::SMTPS=GLOB(0x10516c8)<<< 250 2.1.5 OK n10sm2076605lbc.37 - gsmtp
Net::SMTPS=GLOB(0x10516c8)>>> DATA
Net::SMTPS=GLOB(0x10516c8)<<< 354  Go ahead n10sm2076605lbc.37 - gsmtp
Net::SMTPS=GLOB(0x10516c8)>>> From: auto@domain.ru
Net::SMTPS=GLOB(0x10516c8)>>> To: info@domain.ru
Net::SMTPS=GLOB(0x10516c8)>>> Reply-To: support@domain.ru
Net::SMTPS=GLOB(0x10516c8)>>> Subject: =?UTF-8?B?0KLQtdGB0YLQvtCy0YvQuSDQt9Cw0LPQvtC70L7QstC+0Lo=?=
Net::SMTPS=GLOB(0x10516c8)>>> =?UTF-8?B?0KLQtdGB0YLQvtCy0YvQuSDQt9Cw0LPQvtC70L7QstC+0Lo=?=
Net::SMTPS=GLOB(0x10516c8)>>> MIME-Version: 1.0
Net::SMTPS=GLOB(0x10516c8)>>> Content-type: text/plain; charset=UTF-8
Net::SMTPS=GLOB(0x10516c8)>>> Content-Transfer-Encoding: base64
Net::SMTPS=GLOB(0x10516c8)>>> 0KLQtdGB0YIg0YLQtdGB0YIK0KHRgtGA0L7QutCwMg==
Net::SMTPS=GLOB(0x10516c8)>>> .
Net::SMTPS=GLOB(0x10516c8)<<< 250 2.0.0 OK 1439627958 n10sm2076605lbc.37 - gsmtp
Net::SMTPS=GLOB(0x10516c8)>>> QUIT
Net::SMTPS=GLOB(0x10516c8)<<< 221 2.0.0 closing connection n10sm2076605lbc.37 - gsmtp


Но как-то неправильно.
Во-первых, сообщение получается без темы.
Во-вторых, в письме не указаны адресаты; у получателей в поле "Кому" пусто, у отправителя адреса заданы как скрытая копия.
В-третьих, тело сообщение не раскодировано, оно отображается в закодированном виде.
Вот содержимое письма в ящике отправителя:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Bcc: info@domain.ru, support@domain.ru
Return-Path: <auto@domain.ru>;
Received: from localhost.localdomain (paygate.domain.ru. [195.209.124.90])
        by smtp.gmail.com with ESMTPSA id n10sm2076605lbc.37.2015.08.15.01.39.16
        (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);
        Sat, 15 Aug 2015 01:39:17 -0700 (PDT)
Message-ID: <55cefab5.4a0e700a.7313b.ffff92ac@mx.google.com>;
Date: Sat, 15 Aug 2015 01:39:17 -0700 (PDT)
From: auto@domain.ru
X-Google-Original-From: auto@domain.ruTo: info@domain.ruReply-To: support@domain.ruSubject: =?UTF-8?B?0KLQtdGB0YLQvtCy0YvQuSDQt9Cw0LPQvtC70L7QstC+0Lo=?==?UTF-8?B?0KLQtdGB0YLQvtCy0YvQuSDQt9Cw0LPQvtC70L7QstC+0Lo=?=MIME-Version: 1.0Content-type: text/plain; charset=UTF-8Content-Transfer-Encoding: base64
0KLQtdGB0YIg0YLQtdGB0YIK0KHRgtGA0L7QutCwMg==

То есть все указанные мною заголовки перенеслись в X-Google-Original-From.

Не подскажите, как это исправить?

________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
15.08.2015, 12:42
    #39029954
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Perl SMTP - помогите поправить скрипт
Content-type заменил на Content-Type, UTF-8 заменил на utf-8, base64 заменил на 8bit.
И заголовки типов (MIME-Version, Content-*) перенес в конец.
И в методе datasend добавил переводы строк — $smtp->datasend("$_\n").
Теперь почти все заработало, кроме тела сообщения — почему-то в письме остается только первая строка ("Тест тест").
Пробовал использовать \r\n вместо \n, но не помогло.
...
Рейтинг: 0 / 0
15.08.2015, 13:06
    #39029966
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Perl SMTP - помогите поправить скрипт
Так и не получилось обрабатывать многострочный текст.
Вернул Content-Transfer-Encoding в base64 и закодировал текст в base64, теперь в почтовом клиенте многострочный текст отображается нормально.
Но модуль Email::Send::SMTP::Gmail (а также PHPMailer) как-то умеют выводить многострочный текст с кодировкой 8bit.
...
Рейтинг: 0 / 0
18.09.2015, 17:21
    #39055482
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Perl SMTP - помогите поправить скрипт
Делюсь функцией:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
sub email($$;$)
{
	my $from = '...';
	my $rcpt = '...';
	my $copy = '...';
	my $subj = shift;
	my $body = shift;
	my $file = shift;
	if (defined($file))
	{
		$file = [$file] unless (ref($file) eq 'ARRAY');
		$file = [grep {exists($_->{'filename'}) && exists($_->{'data'})} grep {ref($_) eq 'HASH'} @$file];
		$file = undef unless (@$file);
	}
	my $boundary = 'BOUNDARY';
	$body = encode_base64(encode('UTF-8',$body));
	my @hdr = ();
	push @hdr, 'Date: '       . strftime("%a, %d %b %Y %H:%M:%S %z", localtime(time()));
	push @hdr, 'From: '       . encode('MIME-Header', $from) if (defined($from));
	push @hdr, 'To: '         . encode('MIME-Header', $rcpt) if (defined($rcpt));
	push @hdr, 'Cc: '         . encode('MIME-Header', $copy) if (defined($copy));
	push @hdr, 'Reply-To: '   . encode('MIME-Header', $copy) if (defined($copy));
	push @hdr, 'Subject: '    . encode('MIME-Header', $subj) if (defined($subj));
	push @hdr, 'MIME-Version: 1.0';
	if (@$file)
	{
		push @hdr, 'Content-Type: multipart/mixed; boundary='.$boundary;
	}
	else
	{
		push @hdr, 'Content-Type: text/plain; charset=utf-8';
		push @hdr, 'Content-Transfer-Encoding: base64';
	}
	my $smtp = Net::SMTPS->new('smtp.gmail.com', 'Port'=>587, 'doSSL'=>'starttls', 'Debug'=>0);
	$smtp->auth('...', '...');
	$smtp->mail($from);
	$smtp->to($rcpt) if (defined($rcpt));
	$smtp->cc($copy) if (defined($copy));
	$smtp->data();
	$smtp->datasend("$_\n") foreach (@hdr);
	$smtp->datasend("\n");
	if (@$file)
	{
		$smtp->datasend("--$boundary\n");
		$smtp->datasend("Content-Type: text/plain; charset=utf-8\n");
		$smtp->datasend("Content-Transfer-Encoding: base64\n");
		$smtp->datasend("\n");
		$smtp->datasend($_) foreach (unpack("(A4096)*", $body));
		$smtp->datasend("\n");
		foreach my $f (@$file)
		{
			$smtp->datasend("--$boundary\n");
			my ($data,$type);
			if (exists($f->{'mimetype'}))
			{
				$data = $f->{'data'};
				$type = $f->{'mimetype'};
			}
			else
			{
				$data = encode('UTF-8',$f->{'data'});
				$type = "application/text";
			}
			$smtp->datasend("Content-Type: " . encode('MIME-Header', "$type; name=$f->{'filename'}") . "\n");
			$smtp->datasend("Content-Transfer-Encoding: base64\n");
			$smtp->datasend("Content-Disposition: " . encode('MIME-Header', "attachment; filename=$f->{'filename'}") . "\n");
			$smtp->datasend("\n");
			$smtp->datasend($_) foreach (unpack("(A4096)*", encode_base64($data)));
			$smtp->datasend("\n\n");
		}
		$smtp->datasend("--$boundary--\n");
	}
	else
	{
		$smtp->datasend($_) foreach (unpack("(A4096)*", $body));
	}
	$smtp->datasend("\n");
	$smtp->dataend();
	$smtp->quit;
}




Работает с GMail, умеет отправлять простой текст (в UTF8), а также прикреплять к письмам файлы.
Единственная странность — с границей между частями письма.
По RFC содержимое нужно заключать в двойные кавычки, если оно содержит что-то отличное от букв и цифр.
Но если сделать $boundary = '"::::::::"', то веб-интерфейс gmail почему-то не показывает аттачи внутри письма.
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Perl SMTP - помогите поправить скрипт / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]