使用 Mailkit 创建 GMail 文件夹
Creating GMail folders with Mailkit
我有一个使用 Mailkit 的 SMTP 和 IMAP 的电子邮件提供商。我目前使用的主要功能是从收件箱中读取邮件,根据邮件的内容,它们将进入 'Processed' 或 'Ignored' 文件夹。在我们使用 Exchange 的现有系统中,这些文件夹作为收件箱的子文件夹存在。如果文件夹不存在,则会创建它们。示例代码片段如下:
var _inboxFolder = _provider.GetInboxFolder();
var folder = _inboxFolder.GetChildFolder(folderName);
if (folder == null)
{
// If Gmail, Inbox does not allow children. Check for folder in root.
folder = _provider.GetFolder(folderName);
}
if (folder == null)
{
// Create new folder under Inbox
folder = _inboxFolder.CreateChildFolder(folderName);
if (folder == null)
{
// Cannot create under Inbox, create on root
folder = _provider.CreateFolderOnRoot(folderName);
}
}
这些都使用我自己的提供者,该提供者基于我们用于其他提供者的接口,因此那里有一些 'strange' 逻辑对其他提供者有意义。 GetInboxFolder 和 GetFolder returns 一个文件夹,但如果找不到则 returns null。这在所有提供程序中都可以正常工作 - 如果文件夹不存在,可以创建它们。
创建文件夹时出现问题。如果找不到文件夹,则应在收件箱文件夹下创建它们。如果这不可能发生(如在 Gmail 中),则应在根文件夹中创建它们。但是,尝试在收件箱文件夹下创建文件夹并没有失败,它只是创建了一个名为 "INBOX/FolderName" 的标签。理想情况下,我希望创建此文件夹的任何尝试都失败,以便可以简单地在根目录上创建它。我想这是从 IMAP 到 GMail 标签系统的转换中的一个问题。
有什么方法可以防止 "INBOX/FolderName" 标签,或者在创建它之前识别这个问题?或者有没有办法识别这是一个 gmail 服务器并为它实施一个特殊的条款?
有关一些额外信息,下面是 CreateChildFolder 和 CreateFolderOnRoot 代码。
IMAP文件夹Class
public IEmailFolder CreateChildFolder(string displayName)
{
if (_imapClient == null || !_imapClient.IsConnected)
{
throw new NotLoggedInException();
}
return new ImapFolder(_folder.Create(displayName, true), _imapClient);
}
IMAPClient Class
public IEmailFolder CreateFolderOnRoot(string displayName)
{
if (_client == null)
{
throw new NotLoggedInException();
}
try
{
var toplevel = _client.GetFolder(_client.PersonalNamespaces[0]);
var mailkit = toplevel.Create(displayName, true);
return new ImapFolder(mailkit, _client);
}
catch (Exception exception)
{
throw new LoadFolderFailedException(exception);
}
}
GMail "Label System" 是 GMail 实现文件夹的方式。他们没有实现物理文件夹,他们所做的是 "virtual" 文件夹,这些文件夹只是用户定义的任何标签,文件夹只是对所有应用了该标签的邮件的查询。
也就是说,GMail 根命名空间是 string.Empty
。某些 IMAP 服务器的根命名空间为 "INBOX"
(我认为是 Courier IMAP)。
你的CreateFolderOnRoot
方法应该是在GMail的根目录下创建一个文件夹,不会在INBOX下创建,所以你的问题很混乱。
如果要在收件箱下添加文件夹,只需使用client.Inbox.Create (displayName, true);
The issue arrives when creating the folders. If the folders cannot be found, they should be created under the Inbox folder.
这让我觉得你真正想做的是:
try {
var toplevel = _client.GetFolder(_client.PersonalNamespaces[0]);
var mailkit = folder.GetSubfolder(displayName);
return new ImapFolder(mailkit, _client);
} catch (Exception ex) {
throw new LoadFolderFailedException(ex);
}
请注意使用 GetSubfolder
而不是 Create
。 Create
将始终创建文件夹。 GetSubfolder
只有存在才会获取
我有一个使用 Mailkit 的 SMTP 和 IMAP 的电子邮件提供商。我目前使用的主要功能是从收件箱中读取邮件,根据邮件的内容,它们将进入 'Processed' 或 'Ignored' 文件夹。在我们使用 Exchange 的现有系统中,这些文件夹作为收件箱的子文件夹存在。如果文件夹不存在,则会创建它们。示例代码片段如下:
var _inboxFolder = _provider.GetInboxFolder();
var folder = _inboxFolder.GetChildFolder(folderName);
if (folder == null)
{
// If Gmail, Inbox does not allow children. Check for folder in root.
folder = _provider.GetFolder(folderName);
}
if (folder == null)
{
// Create new folder under Inbox
folder = _inboxFolder.CreateChildFolder(folderName);
if (folder == null)
{
// Cannot create under Inbox, create on root
folder = _provider.CreateFolderOnRoot(folderName);
}
}
这些都使用我自己的提供者,该提供者基于我们用于其他提供者的接口,因此那里有一些 'strange' 逻辑对其他提供者有意义。 GetInboxFolder 和 GetFolder returns 一个文件夹,但如果找不到则 returns null。这在所有提供程序中都可以正常工作 - 如果文件夹不存在,可以创建它们。
创建文件夹时出现问题。如果找不到文件夹,则应在收件箱文件夹下创建它们。如果这不可能发生(如在 Gmail 中),则应在根文件夹中创建它们。但是,尝试在收件箱文件夹下创建文件夹并没有失败,它只是创建了一个名为 "INBOX/FolderName" 的标签。理想情况下,我希望创建此文件夹的任何尝试都失败,以便可以简单地在根目录上创建它。我想这是从 IMAP 到 GMail 标签系统的转换中的一个问题。
有什么方法可以防止 "INBOX/FolderName" 标签,或者在创建它之前识别这个问题?或者有没有办法识别这是一个 gmail 服务器并为它实施一个特殊的条款?
有关一些额外信息,下面是 CreateChildFolder 和 CreateFolderOnRoot 代码。
IMAP文件夹Class
public IEmailFolder CreateChildFolder(string displayName)
{
if (_imapClient == null || !_imapClient.IsConnected)
{
throw new NotLoggedInException();
}
return new ImapFolder(_folder.Create(displayName, true), _imapClient);
}
IMAPClient Class
public IEmailFolder CreateFolderOnRoot(string displayName)
{
if (_client == null)
{
throw new NotLoggedInException();
}
try
{
var toplevel = _client.GetFolder(_client.PersonalNamespaces[0]);
var mailkit = toplevel.Create(displayName, true);
return new ImapFolder(mailkit, _client);
}
catch (Exception exception)
{
throw new LoadFolderFailedException(exception);
}
}
GMail "Label System" 是 GMail 实现文件夹的方式。他们没有实现物理文件夹,他们所做的是 "virtual" 文件夹,这些文件夹只是用户定义的任何标签,文件夹只是对所有应用了该标签的邮件的查询。
也就是说,GMail 根命名空间是 string.Empty
。某些 IMAP 服务器的根命名空间为 "INBOX"
(我认为是 Courier IMAP)。
你的CreateFolderOnRoot
方法应该是在GMail的根目录下创建一个文件夹,不会在INBOX下创建,所以你的问题很混乱。
如果要在收件箱下添加文件夹,只需使用client.Inbox.Create (displayName, true);
The issue arrives when creating the folders. If the folders cannot be found, they should be created under the Inbox folder.
这让我觉得你真正想做的是:
try {
var toplevel = _client.GetFolder(_client.PersonalNamespaces[0]);
var mailkit = folder.GetSubfolder(displayName);
return new ImapFolder(mailkit, _client);
} catch (Exception ex) {
throw new LoadFolderFailedException(ex);
}
请注意使用 GetSubfolder
而不是 Create
。 Create
将始终创建文件夹。 GetSubfolder
只有存在才会获取