danzuep / MailKitSimplified

Send and receive emails easily, fluently, with one line of code for each operation.
MIT License
79 stars 10 forks source link

Folders (or Labels) in Google mail #68

Closed alasdair-richardson closed 3 months ago

alasdair-richardson commented 3 months ago

I raised an issue previously about trying to move emails from INBOX to a Processed folder. The suggestions all worked fine when I was trying it out on my own mail server. However the charity i am doing the work for use google mail. From all I have read online google do not really have folders, they have labels. On the web I created a Processed label and moved some emails into it and that all seemed to work. Apparently google use imap calls for folders to control labels. But I can;t seem to make it work. First I am getting a list of all the folders, Processed does not appear.

2024-06-21 14:09:30.3663 [DEBUG] MailKitSimplified.Receive: 0 Inbox folders: . 
2024-06-21 14:09:31.3216 [DEBUG] MailKitSimplified.Receive: 7 personal folders: All Mail, Bin, Drafts, Important, Sent Mail, Spam, Starred.

I am trying to get hold of the folder using

            var destination = await summary.Folder.GetSubfolderAsync("Processed", ct);

and getting an exception as folder not found. The same happens if I try Spam. So really the question is how do I do this with Google?

alasdair-richardson commented 3 months ago

Sorry trying to work out how to label as a question

alasdair-richardson commented 3 months ago

Actually just saw the wiji section on folders, looks like maybe this would work - If I update to a later version than 2.10.0. Would that be correct?

var mailFolder = await _imapReceiver.MailFolderClient.GetFolderAsync([mailFolderName], cancellationToken);
danzuep commented 3 months ago

Yes, try the second method and let me know how it goes 🙂

alasdair-richardson commented 3 months ago

Will do. I just tried the method suggested on that wiki page for 2.10.0 (Option 5, GetOrCreateFolderAsync) and it did not work. Had to fix the example code - do you want me to do that on the wiki? (missing var, no return)

danzuep commented 3 months ago

If you can edit it, please do! If not then post it here and I'll update it.

alasdair-richardson commented 3 months ago

Oh ok i don't think I can edit so here

public async Task<IMailFolder> GetOrCreateFolderAsync(string mailFolderName, CancellationToken cancellationToken = default)
{
    var client = _imapReceiver.ImapClient;
    var baseFolder = client.GetFolder(client.PersonalNamespaces[0]);
    var folder = baseFolder.GetSubfolders(false, CancellationToken.None).FirstOrDefault(x =>
        mailFolderName.Equals(x.Name, StringComparison.OrdinalIgnoreCase));
    try
    {
        folder ??= await client.GetFolderAsync(mailFolderName, cancellationToken).ConfigureAwait(false);
    }
    catch (FolderNotFoundException)
    {
        folder = await baseFolder.CreateAsync(mailFolderName, isMessageFolder: true, cancellationToken);
    }
    return folder;
}

-- added var before folder and a return at the bottom

danzuep commented 3 months ago

Thanks! I actually made multiple mistakes with that one as I didn't test it properly, I'll add a tested method here as that folder still won't be open sorry.

danzuep commented 3 months ago

If you download the pre-release from NuGet you can use this: var folder = await mailFolderClient.GetOrCreateFolderAsync(destinationFolderFullName, cancellationToken); https://github.com/danzuep/MailKitSimplified/blob/9b2ad4eff29e3e65c7612b1a01bd62cfc2bad774/source/MailKitSimplified.Receiver/Services/MailFolderClient.cs#L189

alasdair-richardson commented 3 months ago

And as regards moving to a different folder in Google. no joy so far. My Processed label does not appear in the list obtained from await imapReceiver.GetMailFolderNamesAsync(ct); but Spam does, so I have been trying to get hold of that using await imapReceiver.MailFolderClient.GetFolderAsync([folder], ct);. this does not work (I just get null) for Processed, Spam and [Gmail]/Spam. (this link seemed to suggest that [Gmail]/Spam might be recognised). No idea what to do next. Why does Gmail have to be different?

danzuep commented 3 months ago

Maybe create the new folder manually in Gmail, then use await mailFolderClient.MoveToAsync(messageSummary, destinationMailFolderFullName);

danzuep commented 3 months ago

It's for a charity right? I should have some time to look at it tomorrow 🙂

alasdair-richardson commented 3 months ago

Yes I can try a couple of things tomorrow. Have to go out and play some music now. And yes I am doing the work for a charity - Campaign against Antisemitism. An online system for onboarding volunteers and then managing them. I am retired but still seem to keep pretty busy, and this is a lot more interesting than WordPress!

danzuep commented 3 months ago

Seems there is no easy way to get all Gmail labels. The good news though is that you don't need to! Download the latest pre-release version, then use this to create a "Processed" label in Gmail: var mailFolder = await mailFolderClient.GetOrCreateFolderAsync(mailFolderFullName, cancellationToken); Once you've made the label you just move it like this: var uniqueId = await mailFolderClient.MoveToAsync(messageSummary, destinationFolderFullName, cancellationToken);

alasdair-richardson commented 3 months ago

Wow that's great thanks a lot. I just have a meeting with the guy from CAA but I will try this out afterwards.

alasdair-richardson commented 3 months ago

Yes I can confirm this is working. Thanks again.