如果 imap 帐户上有未读邮件,如何在 powershell 中编写代码检查?
How to code in powershell a check if there are unread mails on an imap account?
看来我的问题在这里措辞不清楚改写后的版本:
如何在 powershell 中编写一个脚本来检查第三方 imap 帐户是否有未读邮件。
心目中的帐户使用具有 user/pwd 授权的 TSL。
IMAP 不是一个复杂的协议,它是基于行的,相关命令的数量是有限的,尤其是当您只想检查收件箱中的未读邮件时。
因此,在 System.Net.Sockets.TcpClient
之上构建 IMAP 客户端非常简单。 SSL/TLS 有点复杂,但还算不错。
与 IMAP 服务器的对话是这样的:
Client: A001 command argument argument
Server: * response line 1
* response line 2
A001 OK response line 3
其中A001
是命令标签,用来标识命令。它通常采用递增计数器的形式(a1
、a2
、a3
、...),但实际上它可以是任何东西。服务器在其响应的最后一行重复命令标记。
与 GMail IMAP 服务器的示例对话(显然身份验证失败):
* OK Gimap ready for requests from 213.61.242.253 g189mb36880374lfe
a1 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH
a1 OK Thats all she wrote! g189mb36880374lfe
a2 LOGIN test test
a2 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
a3 LOGOUT
* BYE Logout Requested g189mb36880374lfe
a3 OK Quoth the raven, nevermore... g189mb36880374lfe
执行此操作的 Powershell 代码并不太复杂:
using namespace System.IO;
using namespace System.Text;
using namespace System.Net.Sockets;
using namespace System.Net.Security;
using namespace System.Security.Cryptography.X509Certificates;
Set-StrictMode -Version 2.0
$DebugPreference = "Continue" # set to "SilentlyContinue" to hide Write-Debug output
$CRLF = "`r`n"
$server = "imap.gmail.com"
$port = 993
$username = "test"
$password = "test"
# connect to server
$client = [TcpClient]::new($server, $port)
$client.ReceiveTimeout = 2000 #milliseconds
# set up SSL stream, be lenient about the server's certificate
$acceptAnyCertificate = [RemoteCertificateValidationCallback] { $true }
$sslStream = [SslStream]::new($client.GetStream(), $false, $acceptAnyCertificate)
$sslStream.AuthenticateAsClient($server)
function StreamWrite {
param([Stream]$stream, [string]$command, [Encoding]$enc = [Encoding]::ASCII)
$data = $enc.GetBytes($command)
Write-Debug "> $($command.trim())"
$stream.Write($data, 0, $data.Length)
}
function StreamRead {
param([Stream]$stream, [int]$bufsize = 4*1KB, [Encoding]$enc = [Encoding]::ASCII)
$buffer = [byte[]]::new($bufsize)
$bytecount = $stream.Read($buffer, 0, $bufsize)
$response = $enc.GetString($buffer, 0, $bytecount)
Write-Debug "< $($response.trim())"
$response
}
# read server hello
$response = StreamRead $sslStream
StreamWrite $sslStream ("a1 CAPABILITY" + $CRLF)
$response = StreamRead $sslStream
# log in
StreamWrite $sslStream ("a2 LOGIN $username $password" + $CRLF)
$response = StreamRead $sslStream
# send mailbox commands...
# log out
StreamWrite $sslStream ("a3 LOGOUT" + $CRLF)
$response = StreamRead $sslStream
$sslStream.Close()
$client.Close()
您的邮箱命令可能是一个简单的 select inbox
,服务器会返回一堆信息,包括未看到的电子邮件数量 (an example can be seen on the Wikipedia):
C: a002 select inbox
S: * 18 EXISTS
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * 2 RECENT
S: * OK [UNSEEN 17] Message 17 is the first unseen message
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: a002 OK [READ-WRITE] SELECT completed
您可能需要对您的邮件服务器进行一些试验,但应该很容易找出必要的细节。
阅读 Connecting to smtp.live.com with the TcpClient class 了解如何使用 STARTTLS
而不是 SSL
,如果这是您的服务器所需要的。
看来我的问题在这里措辞不清楚改写后的版本:
如何在 powershell 中编写一个脚本来检查第三方 imap 帐户是否有未读邮件。 心目中的帐户使用具有 user/pwd 授权的 TSL。
IMAP 不是一个复杂的协议,它是基于行的,相关命令的数量是有限的,尤其是当您只想检查收件箱中的未读邮件时。
因此,在 System.Net.Sockets.TcpClient
之上构建 IMAP 客户端非常简单。 SSL/TLS 有点复杂,但还算不错。
与 IMAP 服务器的对话是这样的:
Client: A001 command argument argument Server: * response line 1 * response line 2 A001 OK response line 3
其中A001
是命令标签,用来标识命令。它通常采用递增计数器的形式(a1
、a2
、a3
、...),但实际上它可以是任何东西。服务器在其响应的最后一行重复命令标记。
与 GMail IMAP 服务器的示例对话(显然身份验证失败):
* OK Gimap ready for requests from 213.61.242.253 g189mb36880374lfe
a1 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH
a1 OK Thats all she wrote! g189mb36880374lfe
a2 LOGIN test test
a2 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
a3 LOGOUT
* BYE Logout Requested g189mb36880374lfe
a3 OK Quoth the raven, nevermore... g189mb36880374lfe
执行此操作的 Powershell 代码并不太复杂:
using namespace System.IO;
using namespace System.Text;
using namespace System.Net.Sockets;
using namespace System.Net.Security;
using namespace System.Security.Cryptography.X509Certificates;
Set-StrictMode -Version 2.0
$DebugPreference = "Continue" # set to "SilentlyContinue" to hide Write-Debug output
$CRLF = "`r`n"
$server = "imap.gmail.com"
$port = 993
$username = "test"
$password = "test"
# connect to server
$client = [TcpClient]::new($server, $port)
$client.ReceiveTimeout = 2000 #milliseconds
# set up SSL stream, be lenient about the server's certificate
$acceptAnyCertificate = [RemoteCertificateValidationCallback] { $true }
$sslStream = [SslStream]::new($client.GetStream(), $false, $acceptAnyCertificate)
$sslStream.AuthenticateAsClient($server)
function StreamWrite {
param([Stream]$stream, [string]$command, [Encoding]$enc = [Encoding]::ASCII)
$data = $enc.GetBytes($command)
Write-Debug "> $($command.trim())"
$stream.Write($data, 0, $data.Length)
}
function StreamRead {
param([Stream]$stream, [int]$bufsize = 4*1KB, [Encoding]$enc = [Encoding]::ASCII)
$buffer = [byte[]]::new($bufsize)
$bytecount = $stream.Read($buffer, 0, $bufsize)
$response = $enc.GetString($buffer, 0, $bytecount)
Write-Debug "< $($response.trim())"
$response
}
# read server hello
$response = StreamRead $sslStream
StreamWrite $sslStream ("a1 CAPABILITY" + $CRLF)
$response = StreamRead $sslStream
# log in
StreamWrite $sslStream ("a2 LOGIN $username $password" + $CRLF)
$response = StreamRead $sslStream
# send mailbox commands...
# log out
StreamWrite $sslStream ("a3 LOGOUT" + $CRLF)
$response = StreamRead $sslStream
$sslStream.Close()
$client.Close()
您的邮箱命令可能是一个简单的 select inbox
,服务器会返回一堆信息,包括未看到的电子邮件数量 (an example can be seen on the Wikipedia):
C: a002 select inbox S: * 18 EXISTS S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft) S: * 2 RECENT S: * OK [UNSEEN 17] Message 17 is the first unseen message S: * OK [UIDVALIDITY 3857529045] UIDs valid S: a002 OK [READ-WRITE] SELECT completed
您可能需要对您的邮件服务器进行一些试验,但应该很容易找出必要的细节。
阅读 Connecting to smtp.live.com with the TcpClient class 了解如何使用 STARTTLS
而不是 SSL
,如果这是您的服务器所需要的。