کتابخانه‌ی استاندارد · شبکه

پست الکترونیک net/email

فرستادن ایمیل با SMTP و خواندن آن با IMAP و POP3.

واردسازی شبکه.پست الکترونیک

این بسته سه پروتکل پست الکترونیک را مستقیم روی تی سی پی و تی ال اس پیاده می‌کند: SMTP برای فرستادن، و POP3 و IMAP برای خواندن. برای ایمیل بازیابی گذرواژه، هشدار و گزارش از سمت کارگزار، یا اسکریپتی که صندوق پشتیبانی را می‌خواند به کار می‌آید. این بسته کارخواه پروتکل است، نه کتابخانه‌ی کامل پست: پیام ساده‌ی متنی و HTML می‌سازد، ولی پیوست و تجزیه‌گر MIME ندارد و پیام دریافتی به شکل سطرهای خام برمی‌گردد.

بخش‌های بسته:

  • ساخت پیام متن پیام را می‌نویسد: سرآیندها به‌همراه بدنه‌ی متنی، بدنه‌ی HTML، یا هر دو به شکل multipart/alternative.
  • ارسال کل تحویل SMTP را برای یک گیرنده در یک فراخوانی انجام می‌دهد. برای چند گیرنده، رونوشت پنهان یا پیام خطای روشن، کارخواه اس‌ام‌تی‌پی را گام‌به‌گام به کار ببرید؛ هر گام درست یا نادرست برمی‌گرداند و پاسخ کارگزار را در last_reply می‌گذارد.
  • POP3 (کارخواه پاپ۳) پیام‌ها را بارگیری می‌کند و می‌تواند پاکشان کند؛ IMAP (کارخواه آی‌مپ) آن‌ها را روی کارگزار نگه می‌دارد و جستجو را ممکن می‌کند، پس برای صندوق مشترک همین را به کار ببرید.

اشتباه‌های رایج:

  • ارسال همیشه رمزگذاری می‌کند. با use_tls درست از نخستین بایت TLS است (درگاه ۴۶۵)؛ با نادرست با STARTTLS ارتقا می‌دهد (درگاه ۵۸۷) و اگر کارگزار نتواند، شکست می‌خورد. اگر نام کاربری داده شود با AUTH PLAIN وارد می‌شود.
  • ساخت پیام فقط From، To، Subject و سرآیندهای محتوا را می‌نویسد. Date و Message-ID نمی‌گذارد و موضوع غیرانگلیسی را کدگذاری نمی‌کند؛ راهنمای نخست را ببینید. شکستن سطر در بدنه را \r\n بنویسید: \n تنها همان‌طور فرستاده می‌شود و برخی کارگزارها آن را نمی‌پذیرند.
  • ورود در IMAP نام کاربری و گذرواژه را بدون گریزاندن در گیومه‌ی دوتایی می‌گذارد. گذرواژه‌ای که " یا \ دارد شکست می‌خورد؛ برای آن دستور را با لیترال IMAP یا ورود ایکس‌اواث۲ به کار ببرید.
  • دریافت پیام‌ها فقط سطرهای پاسخ را برمی‌گرداند، نه این‌که دستور موفق بود یا نه؛ اگر وضعیت را لازم دارید دستور را صدا بزنید.

نمونه‌های پروتکل با یک کارگزار ساختگی کوچک در نخی از همان برنامه حرف می‌زنند؛ پس بدون شبکه اجرا می‌شوند و هر فرمانی را که روی سیم می‌رود می‌بینید.

ساخت پیام چه می‌نویسد

ساخت پیام(فرستنده، گیرنده، موضوع، متن، اچ‌تی‌ام‌ال) متن کامل پیامی را که SMTP می‌فرستد برمی‌گرداند. اگر فقط بدنه‌ی متنی باشد پیام ساده‌ی text/plain است، اگر فقط HTML باشد text/html، و اگر هر دو باشند multipart/alternative می‌شود تا هر برنامه‌ی پست نسخه‌ای را که ترجیح می‌دهد نشان دهد. بدنه‌ها UTF-8 هستند، پس متن فارسی در بدنه بی‌مشکل است.

net-email-plain-message.salam
واردسازی شبکه.پست الکترونیک
واردسازی رشته
واردسازی کدگذاری

تابع نمایش(پیام: رشته):
    هر سطر در رشته.تفکیک کردن(پیام، "\r\n"):
        سرچاپ سطر
    پایان
    سرچاپ "-----"
پایان

تابع ریشه:
    متنی := پست الکترونیک.ساخت پیام("[email protected]"، "[email protected]"، "Your code"، "کد ورود شما ۴۸۲۱ است."، "")
    نمایش(متنی)
    اچ‌تی‌ام‌ال := پست الکترونیک.ساخت پیام("[email protected]"، "[email protected]"، "Welcome"، ""، "<h1>سارا، خوش آمدید</h1>")
    نمایش(اچ‌تی‌ام‌ال)
    پیام دوگانه := پست الکترونیک.ساخت پیام("[email protected]"، "[email protected]"، "News"، "نسخه‌ی ساده"، "<p>نسخه‌ی HTML</p>")
    تکه‌ها := رشته.تفکیک کردن(پیام دوگانه، "Content-Type: ")
    هر ی، تکه در تکه‌ها:
        اگر ی بزرگتر ۰: سرچاپ "Content-Type"، ی، "برابر"، رشته.تفکیک کردن(تکه، ";")[۰] پایان
    پایان
    موضوع := "=?UTF-8?B?" + کدگذاری.کدگذاری پایه۶۴("سفارش شما رسید") + "?="
    سرچاپ "موضوع کدگذاری‌شده:"، موضوع
پایان
خروجیFrom: [email protected] To: [email protected] Subject: Your code MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 کد ورود شما ۴۸۲۱ است. ----- From: [email protected] To: [email protected] Subject: Welcome MIME-Version: 1.0 Content-Type: text/html; charset=utf-8 <h1>سارا، خوش آمدید</h1> ----- Content-Type 1 برابر multipart/alternative Content-Type 2 برابر text/plain Content-Type 3 برابر text/html موضوع کدگذاری‌شده: =?UTF-8?B?2LPZgdin2LHYtCDYtNmF2Kcg2LHYs9uM2K8=?=

موضوع همان‌طور که هست نوشته می‌شود. موضوع انگلیسی ساده همیشه بی‌خطر است؛ برای موضوع فارسی آن را به شکلی که سرآیندهای پست انتظار دارند کدگذاری کنید، یعنی =?UTF-8?B? و پس از آن پایه۶۴ متن و سپس ?=، همان‌طور که سطرهای آخر برنامه نشان می‌دهند، و این رشته را به عنوان موضوع بدهید. برای افزودن سرآیند Date یا Message-ID سطرش را جلوی خروجی ساخت پیام بگذارید، مثلاً "Date: " + زمان.قالب تاریخ اچ‌تی‌تی‌پی(زمان.اکنون()) + "\r\n" + پیام؛ پیام بی‌تاریخ بیشتر به هرزنامه می‌افتد.

یک نشست SMTP گام‌به‌گام

ارسال همه‌ی کار را با یک فراخوانی انجام می‌دهد، اما راندن کارخواه با دست اجازه می‌دهد چند گیرنده بیفزایید، روش ورود دیگری به کار ببرید یا ببینید سرور کجا نه می‌گوید. گام‌ها همیشه یکسان‌اند: اتصال اس‌ام‌تی‌پی (یا اتصال امن اس‌ام‌تی‌پی)، سلام، روی سرور واقعی یکی از فراخوانی‌های ورود، فرستنده، برای هر گیرنده یک گیرنده، داده با پیام و خروج اس‌ام‌تی‌پی. هر گام درست یا نادرست برمی‌گرداند و پاسخ سرور را در last_reply می‌گذارد.

net-email-smtp-session.salam
واردسازی شبکه.پست الکترونیک
واردسازی شبکه.تی سی پی

ناپایا سرور := تی سی پی.سرور {}
ناپایا دیده‌ها := وکتور {} برگردان وکتور<رشته>

تابع سطر بعدی(ا: تی سی پی.اتصال شبکه، انباشته &: رشته): رشته:
    تا انباشته.بیاب("\r\n") کوچکتر ۰:
        انباشته += تی سی پی.خواندن(ا، ۴۰۹۶)
    پایان
    جا := انباشته.بیاب("\r\n")
    سطر := انباشته.زیررشته(۰، جا)
    انباشته = انباشته.زیررشته(جا + ۲، انباشته.طول() - جا - ۲)
    برگشت سطر
پایان

تابع سرور نامه():
    ا := تی سی پی.پذیرش(سرور)
    ناپایا انباشته := ""
    _ := تی سی پی.نوشتن(ا، "220 mail.test ready\r\n")
    ناپایا باز := درست
    تا باز:
        سطر := سطر بعدی(ا، انباشته)
        دیده‌ها.بیفزا(سطر)
        اگر سطر برابر "DATA":
            _ := تی سی پی.نوشتن(ا، "354 end with a dot\r\n")
            ناپایا متن := سطر بعدی(ا، انباشته)
            تا متن نابرابر ".":
                متن = سطر بعدی(ا، انباشته)
            پایان
            _ := تی سی پی.نوشتن(ا، "250 queued as 1001\r\n")
        وگرنه سطر برابر "QUIT":
            _ := تی سی پی.نوشتن(ا، "221 bye\r\n")
            باز = نادرست
        وگرنه:
            _ := تی سی پی.نوشتن(ا، "250 ok\r\n")
        پایان
    پایان
    تی سی پی.بستن(ا)
پایان

تابع ریشه:
    سرور = تی سی پی.پیوند(۰)
    نخ := نخ‌ساز(سرور نامه)
    ناپایا ک := پست الکترونیک.اتصال اس‌ام‌تی‌پی("127.0.0.1"، تی سی پی.درگاه(سرور))
    سرچاپ "وصل شد:"، ک.سالم
    _ := پست الکترونیک.سلام(ک، "shop.test")
    _ := پست الکترونیک.فرستنده(ک، "[email protected]")
    هر گیرنده در ["[email protected]"، "[email protected]"]:
        _ := پست الکترونیک.گیرنده(ک، گیرنده)
    پایان
    پیام := پست الکترونیک.ساخت پیام("[email protected]"، "[email protected], [email protected]"، "Order 1001"، "سفارش شما فرستاده شد."، "")
    سرچاپ "پذیرفته شد:"، پست الکترونیک.داده(ک، پیام)، ک.آخرین پاسخ.پیراست()
    پست الکترونیک.خروج اس‌ام‌تی‌پی(ک)
    نخ‌پیوند(نخ)
    تی سی پی.بستن سرور(سرور)
    سرچاپ "آنچه سرور دید:"
    هر سطر در دیده‌ها:
        سرچاپ " "، سطر
    پایان
پایان
خروجیوصل شد: true پذیرفته شد: true 250 queued as 1001 آنچه سرور دید: EHLO shop.test MAIL FROM:<[email protected]> RCPT TO:<[email protected]> RCPT TO:<[email protected]> DATA QUIT

سرآیند To در پیام و فراخوانی‌های گیرنده دو چیز جدا هستند: سرآیند چیزی است که آدم‌ها می‌بینند و فهرست گیرنده جایی است که نامه تحویل داده می‌شود. گیرنده‌ی مخفی (Bcc) کسی است که گیرنده برایش صدا زده شده ولی در سرآیند نیست.

ارسال حتی وقتی آرگومان TLS نادرست باشد پیش از ورود با STARTTLS به TLS می‌رود، پس با سرور آزمایشی محلی بدون TLS مثل MailHog کار نمی‌کند. برای آن‌ها گام‌های بالا را بدون شروع تی‌ال‌اس به کار ببرید.

خواندن صندوق با POP3

POP3 راه ساده‌ی گرفتن نامه است: با کاربر و گذرواژه وارد شوید، شمار و اندازه را با وضعیت بپرسید، نامه‌ها را با فهرست پیام‌های پاپ۳ فهرست کنید، یکی را با دریافت پیام پاپ۳ بگیرید و با حذف برای پاک شدن نشانه بگذارید. پاک شدن وقتی انجام می‌شود که خروج پاپ۳ نشست را تمام کند.

net-email-pop3-inbox.salam
واردسازی شبکه.پست الکترونیک
واردسازی شبکه.تی سی پی
واردسازی رشته

ناپایا سرور := تی سی پی.سرور {}

تابع سطر بعدی(ا: تی سی پی.اتصال شبکه، انباشته &: رشته): رشته:
    تا انباشته.بیاب("\r\n") کوچکتر ۰:
        انباشته += تی سی پی.خواندن(ا، ۴۰۹۶)
    پایان
    جا := انباشته.بیاب("\r\n")
    سطر := انباشته.زیررشته(۰، جا)
    انباشته = انباشته.زیررشته(جا + ۲، انباشته.طول() - جا - ۲)
    برگشت سطر
پایان

تابع سرور پاپ():
    نامه‌ها := ["Subject: Welcome\r\n\r\nسلام سارا."، "Subject: Invoice 12\r\n\r\nجمع: ۴۰ دلار\r\n..پایان صورت‌حساب"]
    ا := تی سی پی.پذیرش(سرور)
    ناپایا انباشته := ""
    _ := تی سی پی.نوشتن(ا، "+OK ready\r\n")
    ناپایا سطر := سطر بعدی(ا، انباشته)
    تا سطر نابرابر "QUIT":
        اگر سطر برابر "STAT":
            _ := تی سی پی.نوشتن(ا، "+OK 2 " + (نامه‌ها[۰].طول() + نامه‌ها[۱].طول()) + "\r\n")
        وگرنه سطر برابر "LIST":
            _ := تی سی پی.نوشتن(ا، "+OK\r\n1 " + نامه‌ها[۰].طول() + "\r\n2 " + نامه‌ها[۱].طول() + "\r\n.\r\n")
        وگرنه رشته.شروع با(سطر، "RETR "):
            شماره := سطر.زیررشته(۵، سطر.طول() - ۵).به صحیح()
            _ := تی سی پی.نوشتن(ا، "+OK\r\n" + نامه‌ها[شماره - ۱] + "\r\n.\r\n")
        وگرنه:
            _ := تی سی پی.نوشتن(ا، "+OK\r\n")
        پایان
        سطر = سطر بعدی(ا، انباشته)
    پایان
    _ := تی سی پی.نوشتن(ا، "+OK bye\r\n")
    تی سی پی.بستن(ا)
پایان

تابع ریشه:
    سرور = تی سی پی.پیوند(۰)
    نخ := نخ‌ساز(سرور پاپ)
    ناپایا ک := پست الکترونیک.اتصال پاپ۳("127.0.0.1"، تی سی پی.درگاه(سرور))
    اگر وارونه (ک.سالم و پست الکترونیک.کاربر(ک، "sara") و پست الکترونیک.گذرواژه(ک، "secret")):
        سرچاپ "ورود شکست خورد"
        برگشت ۱
    پایان
    سرچاپ "وضعیت:"، پست الکترونیک.وضعیت(ک)
    هر مورد در پست الکترونیک.فهرست پیام‌های پاپ۳(ک):
        تکه‌ها := رشته.تفکیک کردن(مورد، " ")
        شماره := تکه‌ها[۰].به صحیح()
        متن := پست الکترونیک.دریافت پیام پاپ۳(ک، شماره)
        موضوع := رشته.تفکیک کردن(متن، "\r\n")[۰]
        سرچاپ "نامه"، شماره، "(" + تکه‌ها[۱] + " بایت):"، موضوع
    پایان
    سرچاپ "سطر آخر نامه‌ی ۲:"، رشته.تفکیک کردن(پست الکترونیک.دریافت پیام پاپ۳(ک، ۲)، "\r\n")[۳]
    سرچاپ "حذف ۱:"، پست الکترونیک.حذف(ک، ۱)
    پست الکترونیک.خروج پاپ۳(ک)
    نخ‌پیوند(نخ)
    تی سی پی.بستن سرور(سرور)
    برگشت ۰
پایان
خروجیوضعیت: +OK 2 116 نامه 1 (38 بایت): Subject: Welcome نامه 2 (78 بایت): Subject: Invoice 12 سطر آخر نامه‌ی ۲: .پایان صورت‌حساب حذف ۱: true

در POP3 سطری از نامه که با نقطه شروع شود با یک نقطه‌ی اضافه فرستاده می‌شود. دریافت پیام پاپ۳ آن را دوباره برمی‌دارد؛ برای همین ..پایان صورت‌حساب ذخیره‌شده به شکل .پایان صورت‌حساب برمی‌گردد. اندازه‌ها به بایت‌اند و هر حرف فارسی دو بایت می‌شود.

پیدا کردن نامه‌های نخوانده با IMAP

IMAP نامه‌ها را روی سرور نگه می‌دارد و اجازه‌ی جستجو در آن‌ها را می‌دهد. پس از ورود، دستور هر فرمان IMAP را می‌فرستد و سطرها و وضعیت پایانی‌اش را برمی‌گرداند و دریافت پیام‌ها بخش‌هایی از نامه‌های انتخاب‌شده را می‌خواهد. الگوی معمول برای نامه‌ی تازه این است: SELECT یک صندوق، SEARCH UNSEEN برای شماره‌ی نامه‌های نخوانده و سپس دریافت پیام‌ها برای آنچه از آن‌ها لازم دارید.

net-email-imap-unread.salam
واردسازی شبکه.پست الکترونیک
واردسازی شبکه.تی سی پی
واردسازی رشته

ناپایا سرور := تی سی پی.سرور {}

تابع سطر بعدی(ا: تی سی پی.اتصال شبکه، انباشته &: رشته): رشته:
    تا انباشته.بیاب("\r\n") کوچکتر ۰:
        انباشته += تی سی پی.خواندن(ا، ۴۰۹۶)
    پایان
    جا := انباشته.بیاب("\r\n")
    سطر := انباشته.زیررشته(۰، جا)
    انباشته = انباشته.زیررشته(جا + ۲، انباشته.طول() - جا - ۲)
    برگشت سطر
پایان

تابع سرور آی‌مپ():
    ا := تی سی پی.پذیرش(سرور)
    ناپایا انباشته := ""
    _ := تی سی پی.نوشتن(ا، "* OK IMAP ready\r\n")
    ناپایا تمام := نادرست
    تا وارونه تمام:
        سطر := سطر بعدی(ا، انباشته)
        برچسب := رشته.تفکیک کردن(سطر، " ")[۰]
        اگر رشته.شامل است(سطر، " SELECT "):
            _ := تی سی پی.نوشتن(ا، "* 3 EXISTS\r\n* 2 RECENT\r\n")
        وگرنه رشته.شامل است(سطر، " SEARCH "):
            _ := تی سی پی.نوشتن(ا، "* SEARCH 2 3\r\n")
        وگرنه رشته.شامل است(سطر، " FETCH "):
            _ := تی سی پی.نوشتن(ا، "* 2 FETCH (FLAGS (\\Recent))\r\n* 3 FETCH (FLAGS (\\Recent \\Flagged))\r\n")
        وگرنه رشته.شامل است(سطر، " LOGOUT"):
            _ := تی سی پی.نوشتن(ا، "* BYE\r\n")
            تمام = درست
        پایان
        _ := تی سی پی.نوشتن(ا، برچسب + " OK done\r\n")
    پایان
    تی سی پی.بستن(ا)
پایان

تابع ریشه:
    سرور = تی سی پی.پیوند(۰)
    نخ := نخ‌ساز(سرور آی‌مپ)
    ناپایا ک := پست الکترونیک.اتصال آی‌مپ("127.0.0.1"، تی سی پی.درگاه(سرور))
    سرچاپ "وارد شد:"، ک.سالم و پست الکترونیک.ورود(ک، "sara"، "secret")
    انتخاب := پست الکترونیک.دستور(ک، "SELECT \"INBOX\"")
    هر سطر در انتخاب.خطوط:
        اگر رشته.پایان با(سطر، " EXISTS"): سرچاپ "صندوق:"، سطر پایان
    پایان
    نخوانده := پست الکترونیک.دستور(ک، "SEARCH UNSEEN")
    سرچاپ "نخوانده:"، نخوانده.خطوط[۰]، "وضعیت:"، نخوانده.وضعیت
    هر سطر در پست الکترونیک.دریافت پیام‌ها(ک، "2:3"، "FLAGS"):
        سرچاپ " "، سطر
    پایان
    پست الکترونیک.خروج آی‌مپ(ک)
    نخ‌پیوند(نخ)
    تی سی پی.بستن سرور(سرور)
پایان
خروجیوارد شد: true صندوق: * 3 EXISTS نخوانده: * SEARCH 2 3 وضعیت: A3 OK done * 2 FETCH (FLAGS (\Recent)) * 3 FETCH (FLAGS (\Recent \Flagged))

دریافت پیام‌ها پرانتزهای دور فهرست موارد را خودش می‌گذارد، پس FLAGS یا BODY[HEADER] بدهید، نه (FLAGS).

خواندن موضوع و فرستنده با IMAP

برای فهرست کردن صندوق بدون بارگیری کل پیام‌ها، فقط فیلدهای سرآیندی را که لازم دارید با BODY.PEEK[HEADER.FIELDS (SUBJECT FROM)] بگیرید؛ PEEK پیام‌ها را نخوانده نگه می‌دارد. کارگزار هر بخش سرآیند را به شکل لیترال IMAP می‌فرستد ({57} و پس از آن همان تعداد بایت) و دریافت پیام‌ها آن را سطر به سطر برمی‌گرداند: سطر * 2 FETCH، سطرهای سرآیند، سطر خالی پایان سرآیندها و یک ) پایانی. برنامه این سطرها را می‌پیماید و برای هر پیام یک سطر چاپ می‌کند.

net-email-imap-headers.salam
واردسازی شبکه.پست الکترونیک
واردسازی شبکه.تی سی پی
واردسازی رشته

ناپایا سرور := تی سی پی.سرور {}

تابع سطر بعدی(ا: تی سی پی.اتصال شبکه، انباشته &: رشته): رشته:
    تا انباشته.بیاب("\r\n") کوچکتر ۰:
        انباشته += تی سی پی.خواندن(ا، ۴۰۹۶)
    پایان
    جا := انباشته.بیاب("\r\n")
    سطر := انباشته.زیررشته(۰، جا)
    انباشته = انباشته.زیررشته(جا + ۲، انباشته.طول() - جا - ۲)
    برگشت سطر
پایان

تابع سرور آی‌مپ():
    ا := تی سی پی.پذیرش(سرور)
    ناپایا انباشته := ""
    _ := تی سی پی.نوشتن(ا، "* OK IMAP ready\r\n")
    ناپایا تمام := نادرست
    تا وارونه تمام:
        سطر := سطر بعدی(ا، انباشته)
        برچسب := رشته.تفکیک کردن(سطر، " ")[۰]
        اگر رشته.شامل است(سطر، " FETCH "):
            اولی := "Subject: Invoice 12\r\nFrom: [email protected]\r\n\r\n"
            دومی := "Subject: Lunch?\r\nFrom: [email protected]\r\n\r\n"
            _ := تی سی پی.نوشتن(ا، "* 2 FETCH (BODY[HEADER.FIELDS (SUBJECT FROM)] {" + اولی.طول() + "}\r\n" + اولی + ")\r\n")
            _ := تی سی پی.نوشتن(ا، "* 3 FETCH (BODY[HEADER.FIELDS (SUBJECT FROM)] {" + دومی.طول() + "}\r\n" + دومی + ")\r\n")
        وگرنه رشته.شامل است(سطر، " LOGOUT"):
            _ := تی سی پی.نوشتن(ا، "* BYE\r\n")
            تمام = درست
        پایان
        _ := تی سی پی.نوشتن(ا، برچسب + " OK done\r\n")
    پایان
    تی سی پی.بستن(ا)
پایان

تابع ریشه:
    سرور = تی سی پی.پیوند(۰)
    نخ := نخ‌ساز(سرور آی‌مپ)
    ناپایا ک := پست الکترونیک.اتصال آی‌مپ("127.0.0.1"، تی سی پی.درگاه(سرور))
    _ := پست الکترونیک.ورود(ک، "sara"، "secret") و پست الکترونیک.انتخاب(ک، "INBOX")
    سطرها := پست الکترونیک.دریافت پیام‌ها(ک، "2:3"، "BODY.PEEK[HEADER.FIELDS (SUBJECT FROM)]")
    سرچاپ "سطرهای رسیده:"، سطرها.طول()
    ناپایا موضوع := ""
    ناپایا فرستنده := ""
    هر سطر در سطرها:
        اگر رشته.شروع با(سطر، "Subject: "):
            موضوع = سطر.زیررشته(۹، سطر.طول() - ۹)
        وگرنه رشته.شروع با(سطر، "From: "):
            فرستنده = سطر.زیررشته(۶، سطر.طول() - ۶)
        وگرنه سطر == ")":
            سرچاپ فرستنده، "نوشته:"، موضوع
        پایان
    پایان
    پست الکترونیک.خروج آی‌مپ(ک)
    نخ‌پیوند(نخ)
    تی سی پی.بستن سرور(سرور)
پایان
خروجیسطرهای رسیده: 10 [email protected] نوشته: Invoice 12 [email protected] نوشته: Lunch?

مقدار سرآیند ممکن است در چند سطر شکسته شده یا به شکل =?UTF-8?B?...?= کدگذاری شده باشد؛ سطرها دقیقاً همان‌طور که کارگزار فرستاده برمی‌گردند، پس اگر پیام‌ها انگلیسی ساده نیستند خودتان رمزگشایی‌شان کنید.

فرستادن از راه جیمیل

جیمیل هم مثل بیشتر سرویس‌ها فقط اتصال رمزشده را می‌پذیرد و گذرواژه‌ی معمولی شما را قبول نمی‌کند. تأیید دومرحله‌ای را روشن کنید و یک گذرواژه‌ی برنامه بسازید، یا با احراز هویت ایکس‌اواث۲ از توکن OAuth استفاده کنید. درگاه ۴۶۵ با TLS روشن از همان آغاز با TLS وصل می‌شود. برنامه نشانی و رمزها را از متغیرهای محیطی می‌خواند تا در کد نمانند:

[email protected] MAIL_APP_PASSWORD='abcd efgh ijkl mnop' salam run net-email-gmail.salam
net-email-gmail.salam
واردسازی شبکه.پست الکترونیک
واردسازی سیستم عامل

تابع ریشه:
    کاربر := سیستم عامل.متغیر محیطی("MAIL_USER")
    گذرواژه := سیستم عامل.متغیر محیطی("MAIL_APP_PASSWORD")
    فرستاده := پست الکترونیک.ارسال("smtp.gmail.com"، ۴۶۵، درست، کاربر، گذرواژه، کاربر، "[email protected]"، "گزارش هفتگی"، "گزارش آماده است."، "<p><b>گزارش</b> آماده است.</p>")
    سرچاپ "با گذرواژه فرستاده شد:"، فرستاده
    ناپایا ک := پست الکترونیک.اتصال امن اس‌ام‌تی‌پی("smtp.gmail.com"، ۴۶۵)
    اگر وارونه (ک.سالم و پست الکترونیک.سلام(ک، "example.com")):
        سرچاپ "اتصال برقرار نشد:"، ک.آخرین پاسخ
        برگشت ۱
    پایان
    اگر وارونه پست الکترونیک.احراز هویت ایکس‌اواث۲(ک، کاربر، سیستم عامل.متغیر محیطی("MAIL_OAUTH_TOKEN")):
        سرچاپ "ورود پذیرفته نشد:"، ک.آخرین پاسخ
        پست الکترونیک.خروج اس‌ام‌تی‌پی(ک)
        برگشت ۱
    پایان
    خوب := پست الکترونیک.فرستنده(ک، کاربر) و پست الکترونیک.گیرنده(ک، "[email protected]") و پست الکترونیک.داده(ک، پست الکترونیک.ساخت پیام(کاربر، "[email protected]"، "سلام"، "با توکن OAuth فرستاده شد."، ""))
    سرچاپ "با توکن فرستاده شد:"، خوب
    پست الکترونیک.خروج اس‌ام‌تی‌پی(ک)
    برگشت ۰
پایان

گونه‌ها

کارخواه پاپ۳ POP3Client

ساختار کارخواه پاپ۳
کارخواه POP3 برای برداشتن ایمیل.
نامانگلیسیگونهتوضیح
اتصالconntcp.Connاتصال.
امنsecureمنطقی = نادرسترمزشده است.
شناسه درونی تی‌ال‌اسtls_idxصحیح = -1شناسه‌ی درونی TLS.
سالمokمنطقی = نادرستاتصال برقرار است.
بافر دریافتrxbufرشته = ""داده‌ی خوانده‌نشده.
net-email-Clients.salam
واردسازی شبکه.پست الکترونیک

تابع ریشه:
    ناپایا س := پست الکترونیک.اتصال امن اس‌ام‌تی‌پی("smtp.example.com"، ۴۶۵)
    اگر س.سالم و پست الکترونیک.سلام(س، "example.com") و پست الکترونیک.ورود با احراز هویت(س، "ali"، "رمز"):
        _ := پست الکترونیک.فرستنده(س، "[email protected]")
        _ := پست الکترونیک.گیرنده(س، "[email protected]")
        _ := پست الکترونیک.داده(س، پست الکترونیک.ساخت پیام("[email protected]"، "[email protected]"، "سلام"، "متن"، ""))
    پایان
    پست الکترونیک.خروج اس‌ام‌تی‌پی(س)
    ناپایا س۲ := پست الکترونیک.اتصال اس‌ام‌تی‌پی("smtp.example.com"، ۵۸۷)
    _ := پست الکترونیک.شروع تی‌ال‌اس(س۲، "smtp.example.com")
    _ := پست الکترونیک.ورود ساده(س۲، "ali"، "رمز")
    _ := پست الکترونیک.احراز هویت ایکس‌اواث۲(س۲، "ali"، "token")
    سرچاپ س۲.آخرین پاسخ
    _ := پست الکترونیک.ارسال("smtp.example.com"، ۴۶۵، درست، "ali"، "رمز"، "[email protected]"، "[email protected]"، "سلام"، "متن"، "")
    ناپایا ی := پست الکترونیک.اتصال امن آی‌مپ("imap.example.com"، ۹۹۳)
    _ := پست الکترونیک.ورود(ی، "ali"، "رمز")
    _ := پست الکترونیک.ورود ایکس‌اواث۲(ی، "ali"، "token")
    سرچاپ پست الکترونیک.فهرست صندوق‌ها(ی، ""، "*")
    _ := پست الکترونیک.انتخاب(ی، "INBOX")
    سرچاپ پست الکترونیک.دریافت پیام‌ها(ی، "1:5"، "(FLAGS BODY[HEADER.FIELDS (SUBJECT)])")
    پ := پست الکترونیک.دستور(ی، "NOOP")
    سرچاپ پ.موفق، پ.وضعیت، پ.خطوط.طول()
    پست الکترونیک.خروج آی‌مپ(ی)
    _ := پست الکترونیک.اتصال آی‌مپ("imap.example.com"، ۱۴۳)
    ناپایا پاپ := پست الکترونیک.اتصال امن پاپ۳("pop.example.com"، ۹۹۵)
    _ := پست الکترونیک.کاربر(پاپ، "ali")
    _ := پست الکترونیک.گذرواژه(پاپ، "رمز")
    سرچاپ پست الکترونیک.وضعیت(پاپ)، پست الکترونیک.فهرست پیام‌های پاپ۳(پاپ)
    سرچاپ پست الکترونیک.دریافت پیام پاپ۳(پاپ، ۱)
    _ := پست الکترونیک.حذف(پاپ، ۱)
    پست الکترونیک.خروج پاپ۳(پاپ)
    _ := پست الکترونیک.اتصال پاپ۳("pop.example.com"، ۱۱۰)
پایان

کارخواه اس‌ام‌تی‌پی SMTPClient

ساختار کارخواه اس‌ام‌تی‌پی
کارخواه SMTP برای فرستادن ایمیل.
نامانگلیسیگونهتوضیح
اتصالconntcp.Connاتصال.
امنsecureمنطقی = نادرسترمزشده است.
شناسه درونی تی‌ال‌اسtls_idxصحیح = -1شناسه‌ی درونی TLS.
سالمokمنطقی = نادرستاتصال برقرار است.
بافر دریافتrxbufرشته = ""داده‌ی خوانده‌نشده.
آخرین پاسخlast_replyرشته = ""آخرین پاسخ کارگزار؛ برای خطایابی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

کارخواه آی‌مپ IMAPClient

ساختار کارخواه آی‌مپ
کارخواه IMAP برای خواندن صندوق پستی.
نامانگلیسیگونهتوضیح
اتصالconntcp.Connاتصال.
امنsecureمنطقی = نادرسترمزشده است.
شناسه درونی تی‌ال‌اسtls_idxصحیح = -1شناسه‌ی درونی TLS.
سالمokمنطقی = نادرستاتصال برقرار است.
بافر دریافتrxbufرشته = ""داده‌ی خوانده‌نشده.
شمارنده برچسبtag_counterصحیح = 0شمارنده‌ی برچسب دستورها.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

پاسخ آی‌مپ IMAPReply

ساختار پاسخ آی‌مپ
پاسخ یک دستور IMAP.
نامانگلیسیگونهتوضیح
موفقokمنطقی = نادرستپاسخ OK بود.
وضعیتstatusرشته = ""خط وضعیت پایانی.
خطوطlinesوکتور<رشته>خط‌های پاسخ.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

تابع‌ها

اتصال پاپ۳ DialPOP3

تابع اتصال پاپ۳(host: رشته، port: صحیح): کارخواه پاپ۳
به کارگزار POP3 وصل می‌شود، معمولاً درگاه ۱۱۰.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

اتصال امن پاپ۳ DialPOP3TLS

تابع اتصال امن پاپ۳(host: رشته، port: صحیح): کارخواه پاپ۳
رمزشده وصل می‌شود، معمولاً درگاه ۹۹۵.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

کاربر User

تابع کاربر(c &: کارخواه پاپ۳، username: رشته): منطقی
نام کاربری را می‌فرستد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

گذرواژه Pass

تابع گذرواژه(c &: کارخواه پاپ۳، password: رشته): منطقی
گذرواژه را می‌فرستد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

وضعیت Stat

تابع وضعیت(c &: کارخواه پاپ۳): رشته
پاسخ خام +OK با تعداد پیام‌ها و اندازه‌ی کل آن‌ها به بایت.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

فهرست پیام‌های پاپ۳ POP3List

تابع فهرست پیام‌های پاپ۳(c &: کارخواه پاپ۳): وکتور<رشته>
برای هر پیام یک سطر: شماره و اندازه‌اش به بایت.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

دریافت پیام پاپ۳ Retr

تابع دریافت پیام پاپ۳(c &: کارخواه پاپ۳، msgnum: صحیح): رشته
متن کامل یک پیام، با نقطه‌های اضافه‌ی POP3 برداشته‌شده.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

حذف Dele

تابع حذف(c &: کارخواه پاپ۳، msgnum: صحیح): منطقی
پیام را برای حذف علامت می‌زند؛ با خروج حذف می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

خروج پاپ۳ POP3Quit

تابع خروج پاپ۳(c &: کارخواه پاپ۳)
خارج می‌شود و حذف‌ها را قطعی می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

اتصال اس‌ام‌تی‌پی DialSMTP

تابع اتصال اس‌ام‌تی‌پی(host: رشته، port: صحیح): کارخواه اس‌ام‌تی‌پی
بدون رمزگذاری به کارگزار SMTP وصل می‌شود، معمولاً درگاه ۵۸۷ یا ۲۵؛ اگر کارگزار با ۲۲۰ خوشامد بگوید ok درست است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

اتصال امن اس‌ام‌تی‌پی DialSMTPTLS

تابع اتصال امن اس‌ام‌تی‌پی(host: رشته، port: صحیح): کارخواه اس‌ام‌تی‌پی
از ابتدا رمزشده وصل می‌شود، معمولاً درگاه ۴۶۵.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

سلام Hello

تابع سلام(c &: کارخواه اس‌ام‌تی‌پی، domain: رشته): منطقی
سلام EHLO را با نام دامنه‌ی فرستنده می‌فرستد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

شروع تی‌ال‌اس StartTLS

تابع شروع تی‌ال‌اس(c &: کارخواه اس‌ام‌تی‌پی، host: رشته): منطقی
اتصال ساده را با STARTTLS رمزشده می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

ورود با احراز هویت AuthLogin

تابع ورود با احراز هویت(c &: کارخواه اس‌ام‌تی‌پی، username: رشته، password: رشته): منطقی
با روش LOGIN وارد می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

ورود ساده AuthPlain

تابع ورود ساده(c &: کارخواه اس‌ام‌تی‌پی، username: رشته، password: رشته): منطقی
با روش PLAIN وارد می‌شود و نام کاربری و گذرواژه را در یک سطر پایه۶۴ می‌فرستد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

احراز هویت ایکس‌اواث۲ AuthXOAuth2

تابع احراز هویت ایکس‌اواث۲(c &: کارخواه اس‌ام‌تی‌پی، username: رشته، access_token: رشته): منطقی
با توکن OAuth وارد می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

فرستنده MailFrom

تابع فرستنده(c &: کارخواه اس‌ام‌تی‌پی، addr: رشته): منطقی
نشانی فرستنده‌ی پاکت را، بدون علامت‌های زاویه‌ای، اعلام می‌کند؛ پیام‌های برگشتی به آن‌جا می‌روند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

گیرنده RcptTo

تابع گیرنده(c &: کارخواه اس‌ام‌تی‌پی، addr: رشته): منطقی
یک گیرنده‌ی پاکت اضافه می‌کند؛ برای هر گیرنده‌ی دیگر دوباره صدا بزنید. همین، نه سرآیند To، تعیین می‌کند پیام به دست چه کسی برسد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

داده Data

تابع داده(c &: کارخواه اس‌ام‌تی‌پی، raw_message: رشته): منطقی
متن کامل پیام را می‌فرستد و نقطه‌ی آغاز هر سطر را دوتایی می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

خروج اس‌ام‌تی‌پی Quit

تابع خروج اس‌ام‌تی‌پی(c &: کارخواه اس‌ام‌تی‌پی)
جلسه را تمام می‌کند و اتصال را می‌بندد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

ساخت پیام BuildMessage

تابع ساخت پیام(from: رشته، to_addr: رشته، subject: رشته، text_body: رشته، html_body: رشته): رشته
یک پیام ایمیل کامل با سرآیندهای From، To و Subject می‌سازد. اگر هم متن ساده و هم HTML بدهید، پیام multipart/alternative می‌شود تا هر برنامه‌ی ایمیل نسخه‌ی مناسب خودش را نشان دهد.
net-email-Message.salam
واردسازی شبکه.پست الکترونیک
واردسازی رشته

تابع ریشه:
    پیام := پست الکترونیک.ساخت پیام("[email protected]"، "[email protected]"، "سلام"، "متن ساده"، "<p>متن <b>زیبا</b></p>")
    هر خط در رشته.تفکیک کردن(پیام، "\r\n"):
        اگر رشته.شروع با(خط، "From:") یا رشته.شروع با(خط، "To:") یا رشته.شروع با(خط، "MIME-Version:") یا رشته.شروع با(خط، "Subject:"):
            سرچاپ خط
        پایان
    پایان
    سرچاپ رشته.شامل است(پیام، "multipart/alternative")
    سرچاپ پست الکترونیک.ساخت ایکس‌اواث۲("[email protected]"، "ya29.token")
پایان
خروجیFrom: [email protected] To: [email protected] Subject: سلام MIME-Version: 1.0 true dXNlcj1hbGlAZXhhbXBsZS5jb20BYXV0aD1CZWFyZXIgeWEyOS50b2tlbgEB

ارسال Send

تابع ارسال(host: رشته، port: صحیح، use_tls: منطقی، username: رشته، password: رشته، from: رشته، to_addr: رشته، subject: رشته، text_body: رشته، html_body: رشته): منطقی
ایمیل را در یک گام برای یک گیرنده می‌فرستد: وصل می‌شود، با AUTH PLAIN وارد می‌شود (اگر نام کاربری داده شود) و خروجی ساخت پیام را می‌فرستد. اگر use_tls درست باشد از ابتدا رمزشده وصل می‌شود، وگرنه باید بتواند با STARTTLS ارتقا دهد. فقط درست یا نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

ساخت ایکس‌اواث۲ BuildXOAuth2

تابع ساخت ایکس‌اواث۲(username: رشته، access_token: رشته): رشته
رشته‌ی ورود XOAUTH2 را برای ورود با توکن OAuth، مثل جیمیل، به پایه‌۶۴ می‌سازد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Message.salam

اتصال آی‌مپ DialIMAP

تابع اتصال آی‌مپ(host: رشته، port: صحیح): کارخواه آی‌مپ
به کارگزار IMAP وصل می‌شود، معمولاً درگاه ۱۴۳.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

اتصال امن آی‌مپ DialIMAPTLS

تابع اتصال امن آی‌مپ(host: رشته، port: صحیح): کارخواه آی‌مپ
رمزشده وصل می‌شود، معمولاً درگاه ۹۹۳.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

دستور Command

تابع دستور(c &: کارخواه آی‌مپ، cmd: رشته): پاسخ آی‌مپ
یک دستور IMAP دلخواه را با برچسب بعدی می‌فرستد و سطرهای بی‌برچسب و سطر وضعیت برچسب‌دار را برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

ورود Login

تابع ورود(c &: کارخواه آی‌مپ، username: رشته، password: رشته): منطقی
با نام کاربری و گذرواژه وارد می‌شود؛ هر دو بدون گریزاندن در گیومه‌ی دوتایی گذاشته می‌شوند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

ورود ایکس‌اواث۲ LoginXOAuth2

تابع ورود ایکس‌اواث۲(c &: کارخواه آی‌مپ، username: رشته، access_token: رشته): منطقی
با توکن OAuth وارد می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

انتخاب Select

تابع انتخاب(c &: کارخواه آی‌مپ، mailbox: رشته): منطقی
یک صندوق، مثل INBOX، را برای کار انتخاب می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

فهرست صندوق‌ها List

تابع فهرست صندوق‌ها(c &: کارخواه آی‌مپ، reference: رشته، pattern: رشته): وکتور<رشته>
سطرهای خام * LIST صندوق‌هایی که با یک مرجع و یک الگو، مثل "" و "*"، جور می‌شوند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

دریافت پیام‌ها Fetch

تابع دریافت پیام‌ها(c &: کارخواه آی‌مپ، seq: رشته، items: رشته): وکتور<رشته>
بخش‌هایی از پیام‌ها را می‌گیرد: یک مجموعه‌ی شماره مثل 2:3 و فهرست اقلام بدون پرانتز. سطرهای پاسخ را بدون وضعیت برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam

خروج آی‌مپ Logout

تابع خروج آی‌مپ(c &: کارخواه آی‌مپ)
خارج می‌شود و اتصال را می‌بندد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-email-Clients.salam