From 2c0aa980e7d35cfc42519328fb971810a3ce1033 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Fri, 17 Apr 2026 01:00:16 +0000 Subject: [PATCH] Working creation of a letter I had to use an address ID for 'to' and 'from' and then did really weak-sauce inline HTML. --- lob/cmd/address-list/main.go | 2 +- lob/cmd/letter-create/main.go | 43 +++++++++++++++++++ lob/lob.go | 77 +++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 lob/cmd/letter-create/main.go diff --git a/lob/cmd/address-list/main.go b/lob/cmd/address-list/main.go index cc210c3a..4b9d4749 100644 --- a/lob/cmd/address-list/main.go +++ b/lob/cmd/address-list/main.go @@ -24,6 +24,6 @@ func main() { } for _, addr := range addresses { - log.Printf("%s %s %s: %s %s, %s, %s", addr.ID, addr.Name, addr.Company, addr.AddressLine1, addr.AddressCity, addr.AddressState, addr.AddressCountry, addr.AddressZip) + log.Printf("%s %s %s: %s %s, %s, %s, %s", addr.ID, addr.Name, addr.Company, addr.AddressLine1, addr.AddressCity, addr.AddressState, addr.AddressCountry, addr.AddressZip) } } diff --git a/lob/cmd/letter-create/main.go b/lob/cmd/letter-create/main.go new file mode 100644 index 00000000..b64a7846 --- /dev/null +++ b/lob/cmd/letter-create/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "context" + "flag" + "log" + "os" + + "github.com/Gleipnir-Technology/nidus-sync/lob" +) + +func main() { + to := flag.String("to", "", "") + from := flag.String("from", "", "") + file := flag.String("file", "", "") + color := flag.Bool("color", false, "") + use_type := flag.String("use_type", "operational", "") + + // Parse the flags + flag.Parse() + + key := os.Getenv("LOB_API_KEY") + if key == "" { + log.Println("LOB_API_KEY is empty") + os.Exit(1) + } + + client := lob.NewLob(key) + ctx := context.TODO() + req := lob.RequestLetterCreate{ + To: *to, + From: *from, + File: *file, + Color: *color, + UseType: *use_type, + } + letter, err := client.LetterCreate(ctx, req) + if err != nil { + log.Printf("err: %v", err) + os.Exit(2) + } + log.Printf("done. Letter: %s", letter.ID) +} diff --git a/lob/lob.go b/lob/lob.go index ea6e9f59..2f52e3ba 100644 --- a/lob/lob.go +++ b/lob/lob.go @@ -53,11 +53,46 @@ type Address struct { RecipientMoved bool `json:"recipient_moved"` Object string `json:"object"` } +type Letter struct { + ID string `json:"id"` + Description string `json:"description"` + Metadata map[string]interface{} `json:"metadata"` + To Address `json:"to"` + From Address `json:"from"` + Color bool `json:"color"` + DoubleSided bool `json:"double_sided"` + AddressPlacement string `json:"address_placement"` + ReturnEnvelope bool `json:"return_envelope"` + PerforatedPage *int `json:"perforated_page"` + ExtraService string `json:"extra_service"` + CustomEnvelope *string `json:"custom_envelope"` + TemplateID string `json:"template_id"` + TemplateVersionID string `json:"template_version_id"` + MailType string `json:"mail_type"` + URL string `json:"url"` + MergeVariables map[string]interface{} `json:"merge_variables"` + Carrier string `json:"carrier"` + TrackingNumber string `json:"tracking_number"` + TrackingEvents []interface{} `json:"tracking_events"` + Thumbnails []interface{} `json:"thumbnails"` + ExpectedDeliveryDate string `json:"expected_delivery_date"` + DateCreated string `json:"date_created"` + DateModified string `json:"date_modified"` + SendDate string `json:"send_date"` + UseType string `json:"use_type"` + FSC bool `json:"fsc"` + Object string `json:"object"` +} type ResponseAddressList struct { Addresses []Address `json:"data"` Count int `json:"count"` CountTotal int `json:"total_count"` } +type ResponseLetterList struct { + Letters []Letter `json:"data"` + Count int `json:"count"` + CountTotal int `json:"total_count"` +} type RequestAddressCreate struct { AddressLine1 string `json:"address_line1"` @@ -66,6 +101,13 @@ type RequestAddressCreate struct { AddressZip string `json:"address_zip"` Name string `json:"name"` } +type RequestLetterCreate struct { + Color bool `json:"color"` + From string `json:"from"` + File string `json:"file"` + To string `json:"to"` + UseType string `json:"use_type"` +} func (l *Lob) AddressCreate(ctx context.Context, req RequestAddressCreate) (Address, error) { var result Address @@ -101,3 +143,38 @@ func (l *Lob) AddressList(ctx context.Context) ([]Address, error) { } return result.Addresses, nil } + +func (l *Lob) LetterCreate(ctx context.Context, req RequestLetterCreate) (Letter, error) { + var result Letter + resp, err := l.client.R(). + SetBody(req). + SetContext(ctx). + SetContentType("application/json"). + SetResult(&result). + SetPathParam("urlBase", l.urlBaseApi). + Post("https://{urlBase}/v1/letters") + if err != nil { + return result, fmt.Errorf("letters list post: %w", err) + } + if !resp.IsSuccess() { + return result, fmt.Errorf("not successful") + } + return result, nil +} +func (l *Lob) LetterList(ctx context.Context) ([]Letter, error) { + var result ResponseLetterList + + resp, err := l.client.R(). + //SetQueryParamsFromValues(query). + SetContext(ctx). + SetResult(&result). + SetPathParam("urlBase", l.urlBaseApi). + Get("https://{urlBase}/v1/letters") + if err != nil { + return nil, fmt.Errorf("letter list get: %w", err) + } + if !resp.IsSuccess() { + return nil, fmt.Errorf("not successful") + } + return result.Letters, nil +}