Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Fank committed Aug 15, 2024
1 parent 8ba3e16 commit b622807
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 1 deletion.
15 changes: 15 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
reviewers:
- "Fank"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
reviewers:
- "Fank"
89 changes: 89 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Go

on:
push:
branches:
- main
- master
pull_request:

permissions:
contents: read
pull-requests: read

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod

- name: Set up Golang build cache
uses: actions/cache@v4
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-golang-golangci-lint-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-golang-
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latest

test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod

- name: Set up Golang build cache
uses: actions/cache@v4
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-golang-test-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-golang-
- name: Download go modules
run: go mod download

- name: Test
uses: robherley/go-test-action@v0
with:
testArguments: ./...

license-check:
runs-on: ubuntu-latest
name: License Check
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod

- name: Install go-licenses
run: go install github.com/google/go-licenses@latest
shell: bash

- name: Check licenses
run: go-licenses check ./...
shell: bash

- name: Get licenses list
run: go-licenses csv ./...
shell: bash
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ go.work.sum

# env file
.env

# IDE
.idea
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# epostbusiness
E-POSTBUSINESS Box golang SDK

[E-POSTBUSINESS Box](https://www.deutschepost.de/de/e/epost/geschaeftskunden/epost-business-box.html) golang SDK
38 changes: 38 additions & 0 deletions date.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package epostbusiness

import (
"errors"
"time"
)

const TimeFormat = "2006-01-02T15:04:05.999"

type Time struct {
time.Time
}

func (t Time) MarshalJSON() ([]byte, error) {
if y := t.Time.Year(); y < 0 || y >= 10000 {
// RFC 3339 is clear that years are 4 digits exactly.
// See golang.org/issue/4556#c15 for more discussion.
return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
}

b := make([]byte, 0, len(TimeFormat)+2)
b = append(b, '"')
b = t.Time.AppendFormat(b, TimeFormat)
b = append(b, '"')

return b, nil
}

func (t *Time) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
var err error
t.Time, err = time.ParseInLocation(`"`+TimeFormat+`"`, string(data), time.Local)
return err
}
17 changes: 17 additions & 0 deletions epostbusiness.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package epostbusiness

import "net/http"

const url = "https://api.epost.docuguide.com"

type API struct {
Client *http.Client

jwt string
}

func New() *API {
return &API{
Client: http.DefaultClient,
}
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/enthus-golang/epostbusiness

go 1.22.6
162 changes: 162 additions & 0 deletions letter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package epostbusiness

import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
)

type Letter struct {
FileName string `json:"fileName" validate:"min=5,max=200"`
Data string `json:"data"`
IsColor bool `json:"isColor"`
IsDuplex bool `json:"isDuplex"`
BatchID int `json:"batchID"`
TestFlag bool `json:"testFlag"`
TestShowRestrictedArea bool `json:"testShowRestrictedArea"`
TestEMail string `json:"testEMail"`
AddressLine1 string `json:"addressLine1"`
AddressLine2 string `json:"addressLine2"`
AddressLine3 string `json:"addressLine3"`
ZipCode string `json:"zipCode"`
City string `json:"city"`
Country string `json:"country"`
SenderAdressLine1 string `json:"senderAdressLine1"`
SenderStreet string `json:"senderStreet"`
SenderZipCode string `json:"senderZipCode"`
SenderCity string `json:"senderCity"`
Custom1 string `json:"custom1"`
Custom2 string `json:"custom2"`
}

type LetterIdentifier struct {
FileName string `json:"fileName"`
LetterID int `json:"letterID"`
}

func (a API) CreateLetters(ctx context.Context, letters []Letter) ([]LetterIdentifier, error) {
var letterIdentifiers []LetterIdentifier

body, err := json.Marshal(letters)
if err != nil {
return nil, err
}

req, err := http.NewRequestWithContext(ctx, http.MethodPost, url+"/api/Letter", bytes.NewReader(body))
if err != nil {
return nil, err
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+a.jwt)

res, err := a.Client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()

switch res.StatusCode {
case http.StatusOK:
err = json.NewDecoder(res.Body).Decode(&letterIdentifiers)
if err != nil {
return nil, err
}

return letterIdentifiers, nil

case http.StatusBadRequest:
fallthrough
case http.StatusUnauthorized:
fallthrough
case http.StatusTooManyRequests:
var loginErr loginError

err = json.NewDecoder(res.Body).Decode(&loginErr)
if err != nil {
return nil, err
}

return nil, fmt.Errorf("%s: %s", loginErr.Code, loginErr.Description)

default:
return nil, errors.New(res.Status)
}
}

type LetterStatus struct {
LetterID int `json:"letterID"`
FileName string `json:"fileName"`
StatusID int `json:"statusID"`
StatusDetails *string `json:"statusDetails"`
CreatedDate Time `json:"createdDate"`
ProcessedDate *Time `json:"processedDate"`
PrintUploadDate *Time `json:"printUploadDate"`
PrintFeedbackDate *Time `json:"printFeedbackDate"`
TestFlag *bool `json:"testFlag"`
TestEMail *string `json:"testEMail"`
TestShowRestrictedArea bool `json:"testShowRestrictedArea"`
RegisteredLetter *string `json:"registeredLetter"`
RegisteredLetterID *string `json:"registeredLetterID"`
BatchID int `json:"batchID"`
CoverLetter bool `json:"coverLetter"`
NoOfPages int `json:"noOfPages"`
SubVendorID *string `json:"subVendorID"`
Custom1 *string `json:"custom1"`
Custom2 *string `json:"custom2"`
Custom3 *string `json:"custom3"`
Custom4 *string `json:"custom4"`
Custom5 *string `json:"custom5"`
ZipCode *string `json:"zipCode"`
City *string `json:"city"`
Country *string `json:"country"`
IsColor bool `json:"isColor"`
IsDuplex bool `json:"isDuplex"`
RegisteredLetterStatus *string `json:"registeredLetterStatus"`
RegisteredLetterStatusDate *Time `json:"registeredLetterStatusDate"`
ErrorList []LetterError `json:"errorList"`
}

type LetterError struct {
Description string `json:"description"`
Level string `json:"level"`
Code string `json:"code"`
Date *Time `json:"date"`
}

func (a API) GetLettersStatusList(ctx context.Context, letterIDs []int) ([]LetterStatus, error) {
var statusList []LetterStatus

body, err := json.Marshal(letterIDs)
if err != nil {
return nil, err
}

req, err := http.NewRequestWithContext(ctx, http.MethodPost, url+"/api/Letter/StatusQuery", bytes.NewReader(body))
if err != nil {
return nil, err
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+a.jwt)

res, err := a.Client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()

if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%d: %s", res.StatusCode, res.Status)
}

err = json.NewDecoder(res.Body).Decode(&statusList)
if err != nil {
return nil, err
}

return statusList, nil
}
Loading

0 comments on commit b622807

Please sign in to comment.