Compare commits

...

3 Commits

Author SHA1 Message Date
4c74ebc1c7 Improve [Imap] [Client] Error Handling (#16)
- [+] feat(config.go): add error variables for client connection and body reading failures
- [+] refactor(export_messages.go, list_mailboxes.go, list_messages.go): replace error messages with new error variables

Reviewed-on: #16
Co-authored-by: H0llyW00dzZ <h0llyw00dzz@pm.me>
Co-committed-by: H0llyW00dzZ <h0llyw00dzz@pm.me>
2025-01-25 06:40:23 +00:00
7a43b90f67 Chore [Client] [ListMailboxes] copyright notice and license agreement (#15)
- [+] chore(list_mailboxes.go): add copyright notice and license agreement information

Reviewed-on: #15
Co-authored-by: H0llyW00dzZ <h0llyw00dzz@pm.me>
Co-committed-by: H0llyW00dzZ <h0llyw00dzz@pm.me>
2025-01-24 12:36:12 +00:00
5cab29c344 Implement [Client] "ListMailboxes" (#14)
- [+] feat(README.md): add functionality to list available mailboxes in the package description and usage examples
- [+] feat(client): implement ListMailboxes method to retrieve all available mailboxes for the connected user
- [+] test(client): add unit test for ListMailboxes method to validate mailbox retrieval functionality

Reviewed-on: #14
Co-authored-by: H0llyW00dzZ <h0llyw00dzz@pm.me>
Co-committed-by: H0llyW00dzZ <h0llyw00dzz@pm.me>
2025-01-24 12:34:51 +00:00
7 changed files with 176 additions and 6 deletions

View File

@ -2,7 +2,7 @@
[![Go Reference](https://pkg.go.dev/badge/git.b0zal.io/H0llyW00dzZ/imap.svg)](https://pkg.go.dev/git.b0zal.io/H0llyW00dzZ/imap) [![Go Report Card](https://goreportcard.com/badge/git.b0zal.io/H0llyW00dzZ/imap)](https://goreportcard.com/report/git.b0zal.io/H0llyW00dzZ/imap)
This package provides a simple interface to manage IMAP connections for single or multiple users. It allows you to connect to an IMAP server, list messages, export messages, and manage multiple user accounts.
This package provides a simple interface to manage IMAP connections for single or multiple users. It allows you to connect to an IMAP server, list messages, export messages, manage multiple user accounts, and list available mailboxes.
## Features
@ -10,6 +10,7 @@ This package provides a simple interface to manage IMAP connections for single o
- List messages in a specified mailbox
- Export messages to various formats
- Manage multiple users with separate IMAP clients
- **New**: List all available mailboxes
## Installation
@ -51,6 +52,13 @@ func main() {
}
defer imapClient.Disconnect()
// New: List all available mailboxes
mailboxes, err := imapClient.ListMailboxes()
if err != nil {
log.Fatalf("Failed to list mailboxes: %v", err)
}
fmt.Println("Mailboxes:", mailboxes)
messageConfig := client.MessageConfig{
GrabID: true,
GrabFrom: true,
@ -93,6 +101,17 @@ func main() {
}
defer multiUserIMAP.DisconnectUser("user1@example.com")
// New: List all available mailboxes for user1
client, err := multiUserIMAP.GetClient("user1@example.com")
if err != nil {
log.Fatalf("Failed to get client for user1: %v", err)
}
mailboxes, err := client.ListMailboxes()
if err != nil {
log.Fatalf("Failed to list mailboxes for user1: %v", err)
}
fmt.Println("User1 Mailboxes:", mailboxes)
messageConfig := client.MessageConfig{
GrabID: true,
GrabFrom: true,
@ -161,6 +180,43 @@ func main() {
}
```
### List All Available Mailboxes
```go
package main
import (
"fmt"
"log"
"git.b0zal.io/H0llyW00dzZ/imap/client"
)
func main() {
config := &client.Config{
Username: "user@example.com",
Password: "password",
Server: "imap.example.com:993",
InsecureSkipVerify: true,
}
imapClient := client.NewIMAP(config)
err := imapClient.Connect()
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer imapClient.Disconnect()
// List all available mailboxes
mailboxes, err := imapClient.ListMailboxes()
if err != nil {
log.Fatalf("Failed to list mailboxes: %v", err)
}
fmt.Println("Mailboxes:", mailboxes)
}
```
## TODO
- Implement functionality to send emails.

View File

@ -5,7 +5,11 @@
package client
import "github.com/emersion/go-imap/client"
import (
"errors"
"github.com/emersion/go-imap/client"
)
// Config holds the configuration for the IMAP client
type Config struct {
@ -35,3 +39,11 @@ type IMAPClient struct {
config *Config
client *client.Client
}
var (
// ErrorsClientIsNotConnected is returned when an operation is attempted on a client that is not connected.
ErrorsClientIsNotConnected = errors.New("client is not connected")
// ErrorsFailedToReadBody is returned when there is a failure in reading the body of a message.
ErrorsFailedToReadBody = errors.New("failed to read body")
)

View File

@ -5,13 +5,14 @@
// Package client provides a simple interface to manage IMAP connections
// for single or multiple users. It allows you to connect to an IMAP server,
// list messages, export messages, and manage multiple user accounts.
// list messages, export messages, manage multiple user accounts, and list available mailboxes.
//
// # Features
// - Connect and disconnect from an IMAP server
// - List messages in a specified mailbox
// - Export messages to various formats
// - Manage multiple users with separate IMAP clients
// - List all available mailboxes
//
// # Usage
//
@ -59,6 +60,40 @@
// }
// }
//
// List All Available Mailboxes Example:
//
// package main
//
// import (
// "fmt"
// "log"
//
// "git.b0zal.io/H0llyW00dzZ/imap/client"
// )
//
// func main() {
// config := &client.Config{
// Username: "user@example.com",
// Password: "password",
// Server: "imap.example.com:993",
// InsecureSkipVerify: true,
// }
//
// imapClient := client.NewIMAP(config)
//
// err := imapClient.Connect()
// if err != nil {
// log.Fatalf("Failed to connect: %v", err)
// }
// defer imapClient.Disconnect()
//
// mailboxes, err := imapClient.ListMailboxes()
// if err != nil {
// log.Fatalf("Failed to list mailboxes: %v", err)
// }
// fmt.Println("Mailboxes:", mailboxes)
// }
//
// Multiple Users Example:
//
// package main

View File

@ -15,7 +15,7 @@ import (
// ExportMessagesTo uses the provided exporter to write messages to the writer
func (c *IMAPClient) ExportMessagesTo(writer io.Writer, exporter export.Exporter, mailbox string, numMessages uint32, config MessageConfig) error {
if c.client == nil {
return fmt.Errorf("client is not connected")
return ErrorsClientIsNotConnected
}
// Fetch messages based on the provided MessageConfig and number of messages

View File

@ -123,3 +123,32 @@ func TestListMessages(t *testing.T) {
assert.Equal(t, expectedBody, messages[0][client.KeyBody], "Unexpected body content")
}
func TestListMailboxes(t *testing.T) {
listener, srv := setupTestServer()
defer listener.Close()
defer srv.Close() // Ensure the server is closed properly
// Use the existing user in the memory backend
config := &client.Config{
Username: "username",
Password: "password",
Server: listener.Addr().String(),
InsecureSkipVerify: true,
}
imapClient := client.NewIMAP(config)
// Connect to the server
err := imapClient.Connect()
assert.NoError(t, err, "Failed to connect")
defer imapClient.Disconnect()
// List mailboxes
mailboxes, err := imapClient.ListMailboxes()
assert.NoError(t, err, "Failed to list mailboxes")
// Validate the mailboxes
expectedMailboxes := []string{"INBOX"}
assert.ElementsMatch(t, expectedMailboxes, mailboxes, "Unexpected mailboxes")
}

38
client/list_mailboxes.go Normal file
View File

@ -0,0 +1,38 @@
// Copyright (c) 2025 H0llyW00dzZ All rights reserved.
//
// By accessing or using this software, you agree to be bound by the terms
// of the License Agreement, which you can find at LICENSE files.
package client
import (
"fmt"
"github.com/emersion/go-imap"
)
// ListMailboxes retrieves all available mailboxes for the connected user
func (c *IMAPClient) ListMailboxes() ([]string, error) {
if c.client == nil {
return nil, ErrorsClientIsNotConnected
}
mailboxes := make(chan *imap.MailboxInfo, 10)
done := make(chan error, 1)
// Start listing mailboxes
go func() {
done <- c.client.List("", "*", mailboxes)
}()
var mailboxNames []string
for m := range mailboxes {
mailboxNames = append(mailboxNames, m.Name)
}
if err := <-done; err != nil {
return nil, fmt.Errorf("failed to list mailboxes: %v", err)
}
return mailboxNames, nil
}

View File

@ -41,7 +41,7 @@ const (
// ListMessages lists the messages in the specified mailbox based on the MessageConfig
func (c *IMAPClient) ListMessages(mailbox string, numMessages uint32, config MessageConfig) ([]map[string]any, error) {
if c.client == nil {
return nil, fmt.Errorf("client is not connected")
return nil, ErrorsClientIsNotConnected
}
mbox, err := c.selectMailbox(mailbox)
@ -194,7 +194,7 @@ func (c *IMAPClient) extractBody(body map[*imap.BodySectionName]imap.Literal) (s
return result, nil
}
bytebufferpool.Put(buf)
return "", fmt.Errorf("failed to read body")
return "", ErrorsFailedToReadBody
}
return "", nil
}