{"id":18779426,"url":"https://github.com/zostay/raku-net-smtp-client-async","last_synced_at":"2025-12-18T00:30:19.348Z","repository":{"id":66558053,"uuid":"234687746","full_name":"zostay/raku-Net-SMTP-Client-Async","owner":"zostay","description":"Asynchronous SMTP client for Raku","archived":false,"fork":false,"pushed_at":"2020-06-10T23:22:02.000Z","size":51,"stargazers_count":2,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-29T10:29:20.485Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Raku","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"artistic-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zostay.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-18T05:40:59.000Z","updated_at":"2021-05-14T15:57:00.000Z","dependencies_parsed_at":"2023-04-06T08:06:13.309Z","dependency_job_id":null,"html_url":"https://github.com/zostay/raku-Net-SMTP-Client-Async","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zostay%2Fraku-Net-SMTP-Client-Async","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zostay%2Fraku-Net-SMTP-Client-Async/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zostay%2Fraku-Net-SMTP-Client-Async/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zostay%2Fraku-Net-SMTP-Client-Async/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zostay","download_url":"https://codeload.github.com/zostay/raku-Net-SMTP-Client-Async/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239690606,"owners_count":19681130,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T20:20:02.593Z","updated_at":"2025-12-18T00:30:19.288Z","avatar_url":"https://github.com/zostay.png","language":"Raku","funding_links":[],"categories":[],"sub_categories":[],"readme":"NAME\n====\n\nNet::SMTP::Client::Async - asynchronous communication client for SMTP\n\nSYNOPSIS\n========\n\n    use Net::SMTP::Client::Async;\n\n    with await Net::SMTP::Client::Async.connect(:host\u003csmtp.gmail.com\u003e, :port(465), :secure) -\u003e $smtp {\n        await $smtp.hello;\n\n        my $message = q:to/END_OF_MESSAGE/;\n        To: Sterling \u003chanenkamp@cpan.org\u003e\n        From: Sterling \u003chanenkamp@cpan.org\u003e\n        Subject: Hello World\n\n        Goodbye.\n        END_OF_MESSAGE\n\n        await $smtp.send-message(\n            from =\u003e \"hanenkamp@cpan.org\",\n            to   =\u003e [ \"hanenkamp@cpan.org\" ],\n            :$message,\n        );\n\n        $smtp.quit;\n\n        CATCH {\n            when X::Net::SMTP::Client::Async {\n                note \"Unable to send email message: $_\";\n                $smtp.quit\n            }\n        }\n    }\n\nDESCRIPTION\n===========\n\nThis is an SMTP client library written using asynchronous methods. This class provides two interfaces:\n\n  * **Simple Message Sending API**. A high-level interface is provided for doing the initial connection handshake, sending a message, and quitting. This is probably the usual use of this library where you just want to send an email message to an SMTP server.\n\n  * **Complete Low Level API**. A low-level interface is provided that gives you direct access to any command you want to send to an SMTP server. It also provides low-level access to the responses from the SMTP server.\n\nThese interfaces are completely interchangeable and can be interleaved.\n\nFor example, consider this program which will connect to an ESMTP server on port 587, upgrade a plaintext connection to TLS and then send a message:\n\n    use Net::SMTP::Client::Async;\n\n    my $smtp = Net::SMTP::Client::Async.connect(\n        :host\u003csmtp.gmail.com\u003e, :port(587),\n    );\n\n    await $smtp.hello;\n    await $smtp.start-tls(:host\u003csmtp.gmail.com\u003e);\n\n    # After TLS, you must say hello again.\n    await $smtp.hello;\n\n    await $smtp.send-message(\n        from    =\u003e \"hanenkamp@cpan.org\",\n        to      =\u003e [ \"hanenkamp@cpan.org\" ],\n        message =\u003e q:to/END_OF_MESSAGE/,\n            To: Sterling \u003chanenkamp@cpan.org\u003e\n            From: Sterling \u003chanenkamp@cpan.org\u003e\n            Subject: Hello World\n\n            Goodbye.\n            END_OF_MESSAGE\n    );\n\n    $smtp.quit;\n\n    CATCH {\n        when X::Net::SMTP::Client::Async {\n            note \"Unable to send email message: $_\";\n            .quit\n        }\n    }\n\nNow consider a similar program, but written solely using the low-level interface API:\n\n    use Net::SMTP::Client::Async;\n\n    my $smtp = Net::SMTP::Client::Async.connect(\n        :host\u003csmtp.gmail.com\u003e, :port(587),\n    );\n\n    my $ehlo = await $smtp.EHLO('localhost.localdomain');\n\n    die \"unable to perform SMTP handshake\" if $ehlo.is-error;\n\n    $smtp.populate-keywords($ehlo.text);\n\n    die \"STARTTLS is not supported by SMTP server\" unless $smtp.keywords\u003cSTARTTLS\u003e;\n\n    my $start-tls = await $smtp.STARTTLS;\n    die \"unable to perform upgrade to secure SMTP connection\" if $start-tls.is-error;\n\n    $smtp.clear-keywords;\n\n    my $upgrade = try {\n        await $smtp.upgrade-client(:host\u003csmtp.gmail.com\u003e);\n\n        CATCH {\n            default {\n                die \"unable to negotiate SSL upgrade with client\";\n            }\n        }\n    }\n\n    my $ehlo-again = await $smtp.EHLO('localhost.localdomain');\n    die \"unable to perform secure SMTP handshake\" if $ehlo-again.is-error;\n\n    $smtp.populate-keywords($ehlo-again.text);\n\n    my $mail = await $smtp.MAIL('hanenkamp@cpan.org');\n    die \"unable to send mail FROM hanenkamp@cpan.org\" if $mail.is-error;\n\n    my $rcpt = await $smtp.RCPT('hanenkamp@cpan.org');\n    die \"unable to send mail TO hanenkamp@cpan.org\" if $rcpt.is-error;\n\n    my $data = await $smtp.DATA;\n    die \"unable to initiate message send\" if $data.is-error;\n\n    # perform dot-stuffing of the message\n    my $message = $smtp.escape-message(q:to/END_OF_MESSAGE/);\n        To: Sterling \u003chanenkamp@cpan.org\u003e\n        From: Sterling \u003chanenkamp@cpan.org\u003e\n        Subject: Hello World\n\n        Goodbye.\n        END_OF_MESSAGE\n\n    my $message-response = await $smtp.send-raw-message($message);\n\n    $smtp.QUIT;\n    $smtp.disconnect;\n\nThese programs are not equivalent as the high-level methods perform additional error checking and such that is not being deon in the second program. However, the second program illustrates what is possible.\n\nAside from the change in interface, the greatest difference between the high-level and low-level APIs is that the high-level API provides errors through `X::Net::SMTP::Client::Async` exceptions. The low-level API, on the other hand does no error checking and leaves it to the developer to do the error checking. You can do that by looking at the returned `Net::SMTP::Client::Async::Response` and checking the details of that response, which includes the response code, the full text of the response (which may span multiple lines for some commands, but has the code parts at the start of every line removed), and some convenience methods for detecting success and errors.\n\nThe only exception to the no error checking rule is the [.upgrade-client](#method upgrade-client) method. This is due to the fact that this is a call-out to the method with the same name in [IO::Socket::Async::SSL](IO::Socket::Async::SSL), which passes SSL exception from failed SSL negotiation through to the caller.\n\nAnother difference between the high-level and low-level interfaces is that the high-level interface guarantees thread safety. The high-level interface works to keep the object and connection consistent and prevents the state from being corrupted across threads. The low-level interface provides fewer guarantees.\n\nFor example, consider the situation where you use [.STARTTLS](#method STARTTLS) to request SSL negotiation and receive a favorable 250 code response. However, you then call another method other than `.upgrade-client`. If you do that, your client will be in the wrong state compared to the server. On the other hand, this also means you can use features of SMTP that the high-level interface does not implement or permit, which is the primary purpose of the low-level interface.\n\nIf you have an SMTP server where you need to do something that takes you off the beaten path of sending a fairly simple email message, you should be able to do that with this library.\n\nCONCURRENCY\n===========\n\nThis class is intended to be thread safe. However, it is also fairly immature, so there might be some bugs with that.\n\nInternally, any command sent to the SMTP socket is queued up using a [Channel](Channel). This means all commands will be executed in the order they are received. Commands may be sent before the response has been received if you do not make sure to `await` on the previous method call before calling another, which could result in unrecoverable errors. For this reason, it is recommended that you perform an `await` prior to calling another method.\n\nInternal state within the object is protected by a [Lock](Lock) using a monitor pattern. The state of the object returned by the accessors will never be partially constructed. However, it is still possible to use the returned state in an unsafe way if a method, which changes state is called. This includes the following methods:\n\n  * [.hello](#method hello)\n\n  * [.start-tls](#method start-tls)\n\n  * [.upgrade-client](#method upgrade-client)\n\nOther methods may also change state. Those changes are clearly documented in each method's documentation.\n\nAdditional precautions should be taken around the calls of these methods or any state-changing methods to make sure that the operation is complete *before* accessing the attributes of the method. Otherwise, you *will* end up with thread safety problems.\n\nMETHODS\n=======\n\nmethod socket\n-------------\n\n    has $.socket\n\nThis will be either a [IO::Socket::Async](IO::Socket::Async) or a [IO::Socket::Async::SSL](IO::Socket::Async::SSL) object which represents the underlying connection to the SMTP server. As long as the object is defined, this will also be defined. After [.quit](#method quit) or [.disconnect](#method disconnect) has been called, though, the object will be in a disconnected state.\n\nmethod secure\n-------------\n\n    has Bool $.secure = False\n\nThis flag will be set to `False` if the connection to the SMTP server is a plain text connection or to `True` if the connection is currently secure. It will be set to `True` if the socket is upgraded to use SSL.\n\nmethod keywords\n---------------\n\n    has %.keywords\n\nThis hash will be populated after the client has successfully performed an ESMTP handshake during [.hello](#method hello) or by calling [.populate-keywords](#method populate-keywords). If the SMTP object is used to initiate a plaintext connection and then upgraded using [.start-tls](#method start-tls) or clared using [.clear-keywords](#method clear-keywords), these will be cleared again. This is because the ESMTP handshake must be performed again after upgrading the connection to a secure connection as the server may provide different keywords for secure connections than it provides for unsecure connections.\n\nThe keywords are typically the name of supported extended commands. The value of the keywords is set to `True` if no parameters are provided. If parameters are provided, then the value of that keyword will be set to the list of those parameters:\n\n    my $smtp = Net::SMTP::Client::Async.new;\n    await $smtp.hello;\n    say \"Supports STARTTLS\" if $smtp.keywords\u003cSTARTTLS\u003e;\n    say \"Supports these SASL plugins: $smtp.keywords\u003cAUTH\u003e.join(', ')\" if $smtp.keywords\u003cAUTH\u003e;\n\nmethod connect\n--------------\n\n    multi method connect(IO::Socket::Async $socket --\u003e Promise:D)\n    multi method connect(IO::Socket::Async::SSL $socket --\u003e Promise:D)\n    multi method connect(Str :$host, UInt :$port, Bool :$secure --\u003e Promise:D)\n\nThese are the constructors for [Net::SMTP::Client::Async](Net::SMTP::Client::Async). These establish a connection to the SMTP server or allow the object to adopt a previously established connection to an SMTP server. If an [IO::Socket::Async](IO::Socket::Async) object is given, the [.secure](#method secure) flag will be `False`. If an [IO::Socket::Async::SSL](IO::Socket::Async::SSL) object is given, the `.secure` flag will be `True`.\n\nIf called with no arguments or called with some combination of `$host`, `$port`, and `$secure`, the constructor will make the connection for you. The default `$host` is `\"localhost\"`. The default `$port` is 25 if `$secure` is not set or 465 if `$secure` is set. The default value for `$secure` is `False`.\n\nEach of these methods return a [Promise](Promise), which will be fulfilled once the connection has been established and the object constructed. The promise is kept with a [Net::SMTP::Client::Async](Net::SMTP::Client::Async) object.\n\nThat constructed object will not have performed the initial SMTP handshake. Therefore, you will need to immediately call [.hello](#method hello) or [.EHLO](#method EHLO) or [.HELO](#method HELO) to complete the connection process.\n\nmethod hello\n------------\n\n    method hello(Str:D $domain = \"localhost.localdomain\" --\u003e Promise:D)\n\nOn success, this method updates the state of this object by either setting or clearing the `keywords`.\n\nThis method will attempt to perform an ESMTP handshake (i.e., `EHLO`) with the SMTP server. If that handshake succeeds, it will parse the response and place all the announced keywords and paramters into the [.keywords attribute](#method keywords).\n\nIf the ESMTP handshake fails, this method will attempt to fallback on SMTP handshake (i.e., `HELO`). In this case, `.keywords` will remain empty.\n\nThe method returns a [Promise](Promise). On failure, the `Promise` will be broken with a [X::Net::SMTP::Client::Async::Handshake](X::Net::SMTP::Client::Async#class X::Net::SMTP::Client::Async::Handshake) exception. On success, the `Promise` is kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response) containing a successful response.\n\nmethod start-tls\n----------------\n\n    method start-tls(--\u003e Promise:D)\n\nOn success, this method updates the state of this object by clearing the `keywords` and setting the `secure` flag to `True`.\n\nThis method returns a [Promise](Promise), which will be kept if the operation completes successfully with the [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response) object showing the successful response from the server. If the operation fails to secure the connection by first sending the `STARTTLS` command and then performing a successful SSL negotiation, it will be broken with an exception.\n\nIf an ESMTP handshake has not completed or the ESMTP server does not list `STARTTLS` support, the returned `Promise` will be broken with an [X::Net::SMTP::Client::Async::Support](X::Net::SMTP::Client::Async#class X::Net::SMTP::Client::Async::Support) exception.\n\nIf the connection is already secure or if the `STARTTLS` command results in an error response, the returned `Promise` will be broken with an [X::Net::SMTP::Client::Async::Secure](x::SMTP::Client::Async#class X::Net::SMTP::Client::Async::Secure) exception.\n\nIf the SSL handshake fails, the returned `Promise` will be broken with an exception from OpenSSL.\n\nIf the returned `Promise` is broken fro any resonse, the connection to the SMTP server will also be disconnected and the [Net::SMTP::Client::Async](Net::SMTP::Client::Async) object is now no longer in a usable state and should be discarded.\n\nmethod send-message\n-------------------\n\n    method send-message(\n        Str:D :$from!,\n        Str:D :@to!,\n        Str:D :$message!,\n        --\u003e Promise:D\n    )\n\nThis method performs the work required for sending an SMTP message. This means sending the `MAIL` command with the given `$from` address, teh `RCPT` command for each given `@to` address, the `DATA` command to start sending data, and then the `$message` itself followed by a line containing only a \".\". The `$message` will have \"dot stuffing\" performed on it as well.\n\nThe method returns a [Promise](Promise) which will be kept with the final successful [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response) received after transmitting the message. If any step of the process fails, the returned `Promise` will be broken with the [X::Net::SMTP::Client::Async::Send](X::Net::SMTP::Client::Async#class X::Net::SMTP::Client::Async::Send) exception.\n\nmethod quit\n-----------\n\n    method quit(--\u003e Promise:D)\n\nAfter this method is called, no other method should be called on this object. The object should now be discarded and cannot be reused.\n\nThis sends a `QUIT` command to the SMTP serer and disconnects the socket.\n\nThe returned `Promise` will be kept with the result of the [Net::SMTP::Client::Async::Result](Net::SMTP::Client::Async::Result) returned by the server after sending teh `QUIT` command.\n\nmethod send-command\n-------------------\n\n    method send-command(Str:D $command, Str $argument? --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send any arbitrary command to the SMTP server with the given argument. Nothing special is done to escape or prepare the values sent other than having a space inserted between `$command` and `$argument` (assuming `$argument` is specified at all).\n\nThe returned [Promise](Promise) will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response) object containing the response from the server for that command. This class will not break the returned `Promies`, so if it is broken, something unexpected has gone wrong.\n\nmethod EHLO\n-----------\n\n    method EHLO(Str:D $domain --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `EHLO` command and return a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod populate-keywords\n------------------------\n\n    multi method populate-keywords(Net::SMTP::Client::Async::Response:D $text)\n    multi method populate-keywords(Str:D $text)\n\nThis is a low-level method.\n\nThis will set the [.keywords](#method keywords) attribute to the keywords found in the message. If passed as a string, it should be text the format returned by [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response) by the `.text` method.\n\nmethod clear-keywords\n---------------------\n\n    method clear-keywords()\n\nThis is a low-level method.\n\nThis will clear the [.keywords](#method keywords) attribute. This should be called when the capabilities of the SMTP server were previously known, but now are not. (I.e., after `STARTTLS`).\n\nmethod HELO\n-----------\n\n    method HELO(Str:D $domain --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `HELO` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod MAIL\n-----------\n\n    method MAIL(Str:D $from --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `MAIL` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nThe `$from` argument will have the \"FROM:\" prefix added to it automatically before being sent to the SMTP server.\n\nmethod RCPT\n-----------\n\n    method RCPT(Str:D $to --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `RCPT` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nThe `$to` argument will have the \"TO:\" prefix added to it automatically before being sent to the SMTP server.\n\nmethod DATA\n-----------\n\n    method DATA(--\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `DATA` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod escape-message\n---------------------\n\n    method escape-message(Str:D $message --\u003e Str:D)\n\nThis is a low-level method.\n\nYou only need this if you are using [.send-raw-message](#method send-raw-message). This performs \"dot stuffing\" on the given string. That is, SMTP uses a line containing a single period to mark the end of a message. In order to make sure that users never see this, the SMTP server will ignore the first period that starts any line that contains any text other than a single period. Therefore, dot stuffing is the process of escaping any line that starts with a period by adding an additional period to the start of those lines.\n\nThe string returned byt this method will have an extra period added to any line that starts with a period.\n\nmethod send-raw-message\n-----------------------\n\n    method send-raw-message(Str:D $raw-message --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send message content to the SMTP server followed by a \".\". This will not perform any \"dot stuffing\" on the message. See [.escape-message](#method escape-message).\n\nThis will return a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod RSET\n-----------\n\n    method RSET(--\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `RSET` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod SEND\n-----------\n\n    method SEND(Str:D $from --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `SEND` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod SOML\n-----------\n\n    method SOML(Str:D $from --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `SOML` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod SAML\n-----------\n\n    method SAML(Str:D $from --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `SAML` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod VRFY\n-----------\n\n    method VRFY(Str:D $string --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `VRFY` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod EXPN\n-----------\n\n    method EXPN(Str:D $string --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `EXPN` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod HELP\n-----------\n\n    method HELP(Str:D $string? --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `HELP` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod NOOP\n-----------\n\n    method NOOP(--\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `NOOP` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod QUIT\n-----------\n\n    method QUIT(--\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `QUIT` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod disconnect\n-----------------\n\n    method disconnect(--\u003e Promise:D)\n\nThis is a low-level method.\n\nNormally, to close your connection, you should issue a call to the [.quit](#method quit) method. This closes the connection to the SMTP server without issuing a `QUIT` command. It also makes sure any internally queued actions stop working.\n\nAfter this method has been called, the object is in an unusable state and should be discarded.\n\nmethod TURN\n-----------\n\n    method TURN(--\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `TURN` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod STARTTLS\n---------------\n\n    method STARTTLS(--\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `STARTTLS` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod upgrade-client\n---------------------\n\n    method upgrade-client(*%passthru --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis upgrades the current socket from [IO::Socket::Async](IO::Socket::Async) to [IO::Socket::Async::SSL](IO::Socket::Async::SSL). All arguments are passed through to the `.upgrade-client` method of [IO::Socket::Async::SSL](IO::Socket::Async::SSL).\n\nmethod ETRN\n-----------\n\n    method ETRN(Str:D $node-name --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `ETRN` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod AUTH\n-----------\n\n    method AUTH(Str:D $mechanism --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will send the `AUTH` command and returns a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response).\n\nmethod send-raw\n---------------\n\n    method send-raw(Str:D $string --\u003e Promise:D)\n\nThis is a low-level method.\n\nThis queues a data send of the given string. The string is passed through, as is. The method returns a [Promise](Promise) which will be kept with a `True`, but makes no guarantee that the send has actually occurred. If you need that, then you need to work directly with the [.socket](#method socket) itself.\n\nmethod receive-raw\n------------------\n\n    method receive-raw(--\u003e Promise:D)\n\nThis is a low-level method.\n\nThis will return a [Promise](Promise) that will be kept with a [Net::SMTP::Client::Async::Response](Net::SMTP::Client::Async::Response) containing the next response sent by the SMTP server.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzostay%2Fraku-net-smtp-client-async","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzostay%2Fraku-net-smtp-client-async","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzostay%2Fraku-net-smtp-client-async/lists"}