imap-json-fetcher
This commit is contained in:
commit
19e22df93f
|
@ -0,0 +1,31 @@
|
|||
# IMAP JSON Fetcher
|
||||
|
||||
## Setup
|
||||
|
||||
Before running the `imap-json-fetcher`, ensure that the following environment variables are set:
|
||||
|
||||
- `IMAP_HOST`: Your IMAP server address (e.g., `imap.example.com:993`).
|
||||
- `IMAP_USERNAME`: Your email username.
|
||||
- `IMAP_PASSWORD`: Your email password.
|
||||
|
||||
You can set these environment variables in a Unix-like terminal as follows:
|
||||
|
||||
```bash
|
||||
export IMAP_HOST="your_imap_server_address"
|
||||
export IMAP_USERNAME="your_username"
|
||||
export IMAP_PASSWORD="your_password"
|
||||
```
|
||||
|
||||
## Running the Script
|
||||
|
||||
To run the `imap-json-fetcher`, navigate to the `dist` directory where the binary is located, and use the following command:
|
||||
|
||||
```bash
|
||||
./imap-json-fetcher
|
||||
```
|
||||
|
||||
This assumes that you have already compiled the binary and placed it in the `dist` directory.
|
||||
|
||||
## Output
|
||||
|
||||
The `imap-json-fetcher` will listen for new emails and output the extracted email addresses in separate JSON files, one per email, named in the format `email-seqNum.json`.
|
|
@ -0,0 +1,70 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Default architecture
|
||||
DEFAULT_ARCH="linux/amd64"
|
||||
|
||||
# Supported architectures (adjust as needed)
|
||||
ARCHITECTURES=("linux/amd64" "linux/arm64" "linux/arm/v7" "darwin/amd64" "darwin/arm64")
|
||||
|
||||
# Ensure all necessary directories exist and go modules are ready
|
||||
prepare_build() {
|
||||
# Create necessary directories if they don't exist
|
||||
mkdir -p dist
|
||||
mkdir -p build_logs
|
||||
|
||||
# Initialize go modules if go.mod does not exist
|
||||
if [ ! -f go.mod ]; then
|
||||
echo "Initializing Go modules"
|
||||
go mod init imap-json-fetcher # Replace 'yourmodule' with your actual module name or path
|
||||
fi
|
||||
|
||||
# Fetch and ensure all dependencies are up to date
|
||||
echo "Checking dependencies..."
|
||||
go mod tidy
|
||||
}
|
||||
|
||||
# Build function
|
||||
build_binary() {
|
||||
os=$1
|
||||
arch=$2
|
||||
output_name="imap-json-fetcher"
|
||||
|
||||
if [[ "$os/$arch" != "$DEFAULT_ARCH" ]]; then
|
||||
output_name="${output_name}_${os}_${arch}"
|
||||
fi
|
||||
|
||||
output_name="dist/${output_name}"
|
||||
|
||||
# Dynamic Linking
|
||||
echo "Building dynamically linked for ${os}/${arch} -> ${output_name}"
|
||||
GOOS=${os} GOARCH=${arch} go build -o ${output_name} main.go 2>build_logs/${os}_${arch}_build.log
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Successfully built ${output_name}"
|
||||
else
|
||||
echo "Failed to build ${output_name}. Check build_logs/${os}_${arch}_build.log for errors."
|
||||
fi
|
||||
|
||||
# Static Linking
|
||||
if [[ "$os" == "linux" ]]; then # Typically, static linking is most relevant for Linux environments
|
||||
static_output_name="${output_name}_static"
|
||||
echo "Building statically linked for ${os}/${arch} -> ${static_output_name}"
|
||||
CGO_ENABLED=0 GOOS=${os} GOARCH=${arch} go build -a -ldflags '-extldflags "-static"' -o ${static_output_name} main.go 2>build_logs/${os}_${arch}_static_build.log
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Successfully built ${static_output_name}"
|
||||
else
|
||||
echo "Failed to build ${static_output_name}. Check build_logs/${os}_${arch}_static_build.log for errors."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Main Build Process
|
||||
prepare_build
|
||||
for arch in "${ARCHITECTURES[@]}"; do
|
||||
IFS='/' read -r -a parts <<< "$arch" # Split architecture string
|
||||
os=${parts[0]}
|
||||
arch=${parts[1]}
|
||||
build_binary $os $arch
|
||||
done
|
||||
|
||||
echo "Build process completed."
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
module imap-json-fetcher
|
||||
|
||||
go 1.21.1
|
||||
|
||||
require github.com/emersion/go-imap v1.2.1
|
||||
|
||||
require (
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
)
|
|
@ -0,0 +1,10 @@
|
|||
github.com/emersion/go-imap v1.2.1 h1:+s9ZjMEjOB8NzZMVTM3cCenz2JrQIGGo5j1df19WjTA=
|
||||
github.com/emersion/go-imap v1.2.1/go.mod h1:Qlx1FSx2FTxjnjWpIlVNEuX+ylerZQNFE5NsmKFSejY=
|
||||
github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4=
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||
github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
@ -0,0 +1,108 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/client"
|
||||
"github.com/emersion/go-message/mail"
|
||||
)
|
||||
|
||||
func main() {
|
||||
host := os.Getenv("IMAP_HOST")
|
||||
username := os.Getenv("IMAP_USERNAME")
|
||||
password := os.Getenv("IMAP_PASSWORD")
|
||||
|
||||
if host == "" || username == "" || password == "" {
|
||||
log.Fatal("Environment variables IMAP_HOST, IMAP_USERNAME, and IMAP_PASSWORD must be set")
|
||||
}
|
||||
|
||||
log.Println("Connecting to server...")
|
||||
|
||||
// Connect to the IMAP server
|
||||
c, err := client.DialTLS(host, nil)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to IMAP server: %v", err)
|
||||
}
|
||||
log.Println("Connected")
|
||||
defer c.Logout()
|
||||
|
||||
// Login
|
||||
if err := c.Login(username, password); err != nil {
|
||||
log.Fatalf("Failed to log in: %v", err)
|
||||
}
|
||||
log.Println("Logged in")
|
||||
|
||||
// Select INBOX
|
||||
_, err = c.Select("INBOX", false)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to select INBOX: %v", err)
|
||||
}
|
||||
|
||||
// Set up criteria to search for new unseen emails
|
||||
criteria := imap.NewSearchCriteria()
|
||||
criteria.WithoutFlags = []string{imap.SeenFlag}
|
||||
ids, err := c.Search(criteria)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to search emails: %v", err)
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
log.Println("No new emails")
|
||||
return
|
||||
}
|
||||
|
||||
seqset := new(imap.SeqSet)
|
||||
seqset.AddNum(ids...)
|
||||
|
||||
section := &imap.BodySectionName{}
|
||||
items := []imap.FetchItem{section.FetchItem(), imap.FetchEnvelope}
|
||||
messages := make(chan *imap.Message)
|
||||
go func() {
|
||||
if err := c.Fetch(seqset, items, messages); err != nil {
|
||||
log.Fatalf("Failed to fetch emails: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
for msg := range messages {
|
||||
if msg == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
r := mail.NewReader(msg.GetBody(section))
|
||||
email, err := r.NextPart()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read message body: %v", err)
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(email)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read body content: %v", err)
|
||||
}
|
||||
|
||||
emailData := map[string]interface{}{
|
||||
"subject": msg.Envelope.Subject,
|
||||
"from": msg.Envelope.From,
|
||||
"to": msg.Envelope.To,
|
||||
"date": msg.Envelope.Date,
|
||||
"body": string(body),
|
||||
}
|
||||
|
||||
emailJSON, err := json.MarshalIndent(emailData, "", " ")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to marshal JSON: %v", err)
|
||||
}
|
||||
|
||||
timestamp := time.Now().Format("20060102-150405")
|
||||
fileName := fmt.Sprintf("email-%s.json", timestamp)
|
||||
err = os.WriteFile(fileName, emailJSON, 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to write file %s: %v", fileName, err)
|
||||
}
|
||||
log.Printf("Saved %s", fileName)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue