feat: config

This commit is contained in:
2025-08-24 14:23:51 +02:00
parent 0f3da902dc
commit 958979c62b
9 changed files with 159 additions and 86 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
config.json

60
config.example.json Normal file
View File

@@ -0,0 +1,60 @@
{
"gitea_url": "https://git.schreifuchs.ch",
"gitea_token": "",
"repos": [
{
"owner": "lou-taylor",
"repo": "lou-taylor-web"
},
{
"owner": "lou-taylor",
"repo": "lou-taylor-api"
},
{
"owner": "lou-taylor",
"repo": "accounting"
}
],
"min_duration": "15m",
"hourly": 16,
"from_entity": {
"name": "schreifuchs.ch",
"iban": "",
"address": {
"street": "",
"number": "",
"zip_code": "",
"place": "",
"country": ""
},
"contact": ""
},
"to_entity": {
"name": "",
"address": {
"street": "",
"number": "",
"zip_code": "",
"place": "",
"country": ""
},
"contact": "Loana Groux"
},
"pdf_generator_url": "http://localhost:3030",
"mailer": {
"smtp": {
"host": "mail.your-server.de",
"port": "465",
"user": "",
"password": ""
},
"from": ""
},
"mail": {
"to": "",
"subject": "",
"body": ""
},
"mail_bcc": [""]
}

36
config.go Normal file
View File

@@ -0,0 +1,36 @@
package main
import (
"encoding/json"
"os"
"git.schreifuchs.ch/lou-taylor/accounting/mailer"
"git.schreifuchs.ch/lou-taylor/accounting/model"
)
type Config struct {
GiteaURL string `json:"gitea_url"`
GiteaToken string `json:"gitea_token"`
Repos []Repo `json:"repos"`
MinDuration Duration `json:"min_duration"`
Hourly float64 `json:"hourly"`
FromEntity model.Entity `json:"from_entity"`
ToEntity model.Entity `json:"to_entity"`
PdfGeneratorURL string `json:"pdf_generator_url"`
Mailer mailer.Config `json:"mailer"`
Mail mailer.Mail `json:"mail"`
MailBcc []string `json:"mail_bcc"`
}
func LoadConfig(path string) (Config, error) {
var cfg Config
file, err := os.Open(path)
if err != nil {
return cfg, err
}
defer file.Close()
decoder := json.NewDecoder(file)
err = decoder.Decode(&cfg)
return cfg, err
}

3
go.mod
View File

@@ -6,6 +6,7 @@ require (
code.gitea.io/sdk/gitea v0.21.0 code.gitea.io/sdk/gitea v0.21.0
github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a
github.com/jedib0t/go-pretty/v6 v6.6.8 github.com/jedib0t/go-pretty/v6 v6.6.8
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/starwalkn/gotenberg-go-client/v8 v8.11.0 github.com/starwalkn/gotenberg-go-client/v8 v8.11.0
) )
@@ -15,11 +16,9 @@ require (
github.com/davidmz/go-pageant v1.0.2 // indirect github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-fed/httpsig v1.1.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/crypto v0.41.0 // indirect golang.org/x/crypto v0.41.0 // indirect
golang.org/x/sys v0.35.0 // indirect golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect golang.org/x/text v0.28.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
) )

4
go.sum
View File

@@ -49,9 +49,5 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -216,7 +216,7 @@ article {
<h2>schreifuchs.ch</h2> <h2>schreifuchs.ch</h2>
<p> <p>
Kilchbergerweg 1 <br /> Kilchbergerweg 1 <br />
3052 Zollikofen <br /> Zollikofen <br />
Niklas Breitenstein Niklas Breitenstein
</p> </p>
@@ -224,7 +224,7 @@ article {
</div> </div>
<div class="invoice-info"> <div class="invoice-info">
<p> <p>
<strong>Rechnung:</strong> 20 25082 41057 10271 08692 82635 <br /> <strong>Rechnung:</strong> 20 25082 41117 00284 67114 43342 <br />
<strong>Datum:</strong> 24.08.2025 <br /> <strong>Datum:</strong> 24.08.2025 <br />
</p> </p>
</div> </div>
@@ -234,7 +234,7 @@ article {
<p> <p>
Lou Taylor <br /> Lou Taylor <br />
Alpenstrasse 22 <br /> Alpenstrasse 22 <br />
4950 Huttwil <br /> Huttwil <br />
Loana Groux Loana Groux
</p> </p>
</section> </section>
@@ -387,19 +387,19 @@ article {
CH06 0079 0042 5877 0443 7 <br /> CH06 0079 0042 5877 0443 7 <br />
schreifuchs.ch <br /> schreifuchs.ch <br />
Kilchbergerweg 1 <br /> Kilchbergerweg 1 <br />
3052 Zollikofen Zollikofen
</p> </p>
</div> </div>
<div> <div>
<h4>Referenz</h4> <h4>Referenz</h4>
<p>20 25082 41057 10271 08692 82635</p> <p>20 25082 41117 00284 67114 43342</p>
</div> </div>
<div> <div>
<h4>Zahlbar durch</h4> <h4>Zahlbar durch</h4>
<p> <p>
Lou Taylor <br /> Lou Taylor <br />
Alpenstrasse 22 <br /> Alpenstrasse 22 <br />
4950 Huttwil Huttwil
</p> </p>
</div> </div>
</div> </div>
@@ -481,7 +481,7 @@ article {
<div class="qr-code"> <div class="qr-code">
<div class="qr-section-img"> <div class="qr-section-img">
<image src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIAAQMAAADOtka5AAAABlBMVEX///8AAABVwtN&#43;AAAGaklEQVR42uydzbGkOgyF1cXCS0IgFEKD0AiFEFiyoNAr6xzJ7vsiaI96NXXLfLNx6fdIFsXvnC&#43;pv0lfUdFdVj1EZr3KXfSRj6qKbHqseopI0XvihwlIAAB7/W6pgKL1aAXItgNwiZRb7HsVke2oh&#43;erAh77DxMwDGBTPZZTZL7LMz0fHlU9ZLlkvqVU6gfX5ljPxf5x82QCEvANmK/5xlUk4FhVzUoVfSrALp6sei71ZAIGBcistwjsTDVJ9Xv/mZ3CSa2eqR5NwGgAeCYH0AltsB3mmSZ9K8Du0Z//KgEJcECEuvRMCHW3Y3UzVY1PtUi6b3v9Iy3S/2PlBPwwwH8z3NDUApT1ZKjLs7LtcbZepT&#43;/BPzbgOqwGM3UozXEoRc7ZHHf5pGuUZdLkDPVS6sJGANg7sacEAMXy50tSzYnZFfm012k6q5qPj2Zu0rASID61/mS8kzubDY3KMUAFqBs9c6JNM&#43;E/ysBCaDxOeBjCo2PiFpV9lyqoUJN9nWqFWXtbDVTTLoS8PsANcdkBqkwjanfix&#43;1WprnQXBXrNibE0tAAgBg/Drjzv3t51hRdnrl48ZrQUOoGq/307o8Cfh1QNwky3ge1mT3rlzi0cxuRdl6tKi1fl6voSTg9wE7Q11VK857k&#43;ZYD0H51e4Mbpt1&#43;xChMO9NQAIAsA6x6lmzo/JM4ZssqEUixZsom&#43;JozbK99ZOAQQBmkJDzqDf78P1aqRfj35dxiywo2RvV7lwCEmCAXXi9pNyTJc9sF0Jzop4726W1ygziXy/CJGAQABOZC4DX3A0KtWdfhY&#43;U55Q5tGp9ATcBvwxgVItqiTIYUd1X7/rGnZFt3471FFbYLA9KQAII0H07xOuvk/r3NT3CWfuhy7Mz1LXv6a4SMAhAva93lVAeWXKzKiNdaSV77/3cVlixkwlIgHyFumzooDOIpAmuDQ2dGgxt0Uq&#43;q&#43;nyYlwCBgDsG6KZmvI8wlDXAKaCrogJjb2NGjZeryjOJ2AMAFu5lvlO7PZ5UIvrZcJ3dn2t6ibl8TuXgAS0&#43;utyQpdmka4FM9bmmREAwyBZ6mzNZHZ5mr9KwM8DosFbww5F7hzu6kIA3EbzFN8XTNK8IglIgAM4beG9YLZueBM1lG2hnF8wtMPrmYAxAF1Uy4aO0iJh8JMZtSnnmfJ07koSMAjADIp5JstnqQ2JqV5IEVstzRVsMVaRgAR0AC&#43;7AdDiHtxEc0KqXw0hkd61JeDXAVacV7qmKYRpvkSCM54SMpLqmRD&#43;WkKtCRgDwMk8sx0SGncDLFZUNQladH3XU8h9Pm83opmABFBkZDUUlN3UK3QoxqH&#43;6uEQpUvdTUzAAAAan5rl2qBV/FVM4s7NEuKhLrLku19Vk4AEYOoGqfN8&#43;dGQUdvQeJMeWSZlurTSGa8EDAFAg/dE2cyvDEZpTkFRFomQz1qw66vPJ4ooCfh9gM9FXG00j9uJfAdadPs4zXnaurPIjhKQAOrSVoS6pjJ6ov5KTWuJygoy6lNgkaamOEnACAAGI9UiyRSTNBivubpVia4piKiYcqIEJEAYqR6ovyJnalMR3tjDKE5soaDIntuREjAKQJtS4HH9ANwV11whqg2xGnQkU1&#43;MS8DPA5D8xlLEyccqmliN9ddYrnnOFC2yQZyABFAo4AsjbMbzw7EK8et5o5fc7y3BUkVx&#43;UACBgCgQIax3q7Lw/GaOXYxU1RAiXzTGCUgARqbjL4WcYZrw&#43;6rTuhqDeZFfaMA19okYADAt2cKsVnLg7BZ4pVuxJPDFpKAgQA17ICZQKiLCQob0cTMt6sWXad6ej7MPZoJSADaxrJ65BLru1sw06mUoFg5fSMWa3EJGAJATQAFI1OnNcOGEZoejuZxKXjRu&#43;/2JSABX1tpeFh9eQDXXHkzOVb7xrxfAkYCcBmJNYj96QDx3VdRQvFuH2dufP93AsYAxOb/iwCN5e7cmOlCVzMoFstokxMlIAF/3iJpl86imVXpmbqcqc14xiNXkoBBAN3riZ7H9H&#43;UWJnJUKZNUHQ6lAQkIF5Lg0nyXXiY4ovX0rSf7dM246kJGAsQ&#43;kZYJI0XeKOz5w8W2Zqr8rQNzwkYDPDn5aolVIuYoNh8NK/N3HQGJQH/OsBl0FdplVa&#43;a2Z1lUKA7lzIOuNZXoirEzAI4Ov1xK&#43;3u7mySJ9Ol0YZSfl&#43;eyABvw74LwAA//9wYD7CB3CrcAAAAABJRU5ErkJggg=="></image> <image src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIAAQMAAADOtka5AAAABlBMVEX///8AAABVwtN&#43;AAAFNElEQVR42uydMZLySgyERREQcgSO4qPB0TgKRyDcwGW9stRqybsEL/2LdrRrzEeimpFbLY15Xpv5Y/H3ZT3l/z/nzcyWl13yo9fV15Ob2e19cXezBV8UQIAEPMzMzpu5P83iw7v72&#43;a1fxSA/Xqb7aTllR8JIAAAC&#43;LuHk/td5eMzYg7Owfydf2xHfDEHdtjcw9SAQQ4AmLd&#43;onHn5Z/5AIGdgB6bRNAgM&#43;AuOLx2BLXeBwb4IMhuS97AgjwCYC9MbfEJN08wu3uL6s7b3yvnvm7uQrw3YCRre9L2v/&#43;41O6L8D3AmZKfstM/P68Ie2KSMSSdom1LfZG&#43;3gJ8NWAlA3ybW9fpTKTssv&#43;1H1KC/yR4/4pgAABiLgrkcnxbleZVMtOe0rljocj/PLXTAABAjCFqCQFIK/aAONObIl72m7xs72kCSBArlupiD8iErnZlWxwzi0xVzv3/CiTrFUAAQoQkViFFKPsjWJLigSIu1Q083uZiLkLIAAAlaRnIaVkp1abVsQmhKjcP0NIQJYmgABZtL297Vwp&#43;dQGssZSO&#43;HFCchIxI8IIEAA4sptEiKBMyU3S9nJsX9mto4L738CCLAZXuBib3QfskG&#43;/0Wxd0Qrqnb42XhGAAEA2JOszJsq7p6VdlnGHWp0WMlAwjuiAAIQcKXrBN/LnZB/9N5orLHUwwII0PYBL7NAmk0Qm7hjWO18a4tcvgie3QUQgIDXWMCoDfTeePL2ymWStfX6ZwIIcK5sPfWDR9VYUj&#43;Ypbk7FKleyR60YQogQNrhIhJpfytnU6rmEKLcX1ZCwvWYdgkgQJZIxtseFrCyyEE2SGmhyy&#43;oFoMkgAApWtK1xCvyd6ZdtIGzjjeTLAEEMBTrKrjuE/JDQ9wKIaoUzfewqGwmgAAljbNGNwy5NpBDdjqsdrBBCSDAybklHnwEJU3VajcNKd7lFxpZBBAgrlmRqxrvevJulesFDB0q&#43;VHUWAQQoGwkXhU56AclZMbaVj1zXMmwbWIhFECA2c8UVzVW2s17AfOtbJgpNpSigMYCAQQAgAlUtzF1q1y9HHarU3VhdiQKIICj6fZgn2z7m9feyA6nqrHY0iNPBBAgCyn9uMPZdGUX7phCQWflMH27AAKc2bLdb3urDR9K&#43;ihzk6Qild&#43;jVVwAAQydtoiyMiv1OCUqCs4u3vbKVRuKAAJUjaWsAfAoZZTZQVGoOyj2JjKzLQEEmB6B1i&#43;NJLgG2lkQqtWhICOAAA0o2ZJzuZC298hAG9HaGf1JAAEIGDMnMDyAhhROyqme3fEMei4FEKB6vnMu4EigOFepxyqzi7f84FaDKgUQwH1avB/LHBXAQd3rYXgJ7rSfTgABMI2EXt058pbFuss6Ry6N2Se/2lAE&#43;HYAJaUx&#43;7ZkS/caFWD2IVv/NcZCgK8G9Hxuvv&#43;x2FKN3cOQYlOswtEBAgjQEyZYWqHa1BOX/9To0OpUPhQBBGCHZS9XxlMpesBbVYZbbLA&#43;zEQAAWowCRTNvydO0NkEH0GZvnlOhQACdESdObJ0zi717h6omQGYxsSzvFwAAQbArJsGGGVcyUar7mg1uA4figBfDzicQVHTTKuxEjthA9hqUGKDAAKMSV09hDJLK9XP3V7dXtJKR6&#43;MTAABTm6HkwN5vgTPUCqLANe29qFwHooAAkwAzzJlPxOHKDPJon0AVbtDJAogQI0D5OxkP7ztfThvuY/HEUCAbR5mMnp2235ysFiyn8l9VF0EEKAHdSO4euQkLp6lXMO8lzGFYihZAvzjgP8CAAD//4aIC6aSJNHQAAAAAElFTkSuQmCC"></image>
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
@@ -587,19 +587,19 @@ article {
CH06 0079 0042 5877 0443 7 <br /> CH06 0079 0042 5877 0443 7 <br />
schreifuchs.ch <br /> schreifuchs.ch <br />
Kilchbergerweg 1 <br /> Kilchbergerweg 1 <br />
3052 Zollikofen Zollikofen
</p> </p>
</div> </div>
<div> <div>
<h4>Referenz</h4> <h4>Referenz</h4>
<p>20 25082 41057 10271 08692 82635</p> <p>20 25082 41117 00284 67114 43342</p>
</div> </div>
<div> <div>
<h4>Zahlbar durch</h4> <h4>Zahlbar durch</h4>
<p> <p>
Lou Taylor <br /> Lou Taylor <br />
Alpenstrasse 22 <br /> Alpenstrasse 22 <br />
4950 Huttwil Huttwil
</p> </p>
</div> </div>
</div> </div>

View File

@@ -7,10 +7,10 @@ import (
"github.com/jordan-wright/email" "github.com/jordan-wright/email"
) )
func (s Service) Send(m Mail) (err error) { func (s Service) Send(m Mail, bcc ...string) (err error) {
e := email.NewEmail() e := email.NewEmail()
e.To = []string{m.TO} e.To = []string{m.TO}
e.Bcc = []string{"niklas@sunway.ch"} e.Bcc = bcc
e.From = s.from e.From = s.from
e.Subject = m.Subject e.Subject = m.Subject
e.Text = []byte(m.Body) e.Text = []byte(m.Body)

88
main.go
View File

@@ -1,40 +1,39 @@
package main package main
import ( import (
"os"
"time" "time"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"git.schreifuchs.ch/lou-taylor/accounting/issue" "git.schreifuchs.ch/lou-taylor/accounting/issue"
"git.schreifuchs.ch/lou-taylor/accounting/mailer" "git.schreifuchs.ch/lou-taylor/accounting/mailer"
"git.schreifuchs.ch/lou-taylor/accounting/model"
"git.schreifuchs.ch/lou-taylor/accounting/pdf" "git.schreifuchs.ch/lou-taylor/accounting/pdf"
"git.schreifuchs.ch/lou-taylor/accounting/report" "git.schreifuchs.ch/lou-taylor/accounting/report"
) )
type Repo struct { type Repo struct {
owner string Owner string `json:"owner"`
repo string Repo string `json:"repo"`
} }
func main() { func main() {
cfg, err := LoadConfig("config.json")
if err != nil {
panic(err)
}
client, err := gitea.NewClient( client, err := gitea.NewClient(
"https://git.schreifuchs.ch", cfg.GiteaURL,
gitea.SetToken("6a8ea8f9de039b0950c634bfea40c6f97f94b06b"), gitea.SetToken(cfg.GiteaToken),
) )
if err != nil { if err != nil {
panic(err) panic(err)
} }
var is []*gitea.Issue var is []*gitea.Issue
for _, repo := range []Repo{ for _, repo := range cfg.Repos {
{"lou-taylor", "lou-taylor-web"},
{"lou-taylor", "lou-taylor-api"},
{"lou-taylor", "accounting"},
} {
iss, _, err := client.ListRepoIssues( iss, _, err := client.ListRepoIssues(
repo.owner, repo.Owner,
repo.repo, repo.Repo,
gitea.ListIssueOption{ gitea.ListIssueOption{
ListOptions: gitea.ListOptions{Page: 0, PageSize: 99999}, ListOptions: gitea.ListOptions{Page: 0, PageSize: 99999},
Since: time.Now().AddDate(0, -1, 0), Since: time.Now().AddDate(0, -1, 0),
@@ -55,46 +54,16 @@ func main() {
return i.Closed != nil && i.Closed.After(time.Now().AddDate(0, -1, 0)) return i.Closed != nil && i.Closed.After(time.Now().AddDate(0, -1, 0))
}, },
) )
issues := issue.FromGiteas(is, time.Minute*15) issues := issue.FromGiteas(is, time.Duration(cfg.MinDuration))
r := report.New( r := report.New(
issues, issues,
model.Entity{ cfg.FromEntity,
Name: "schreifuchs.ch", cfg.ToEntity,
IBAN: "CH06 0079 0042 5877 0443 7", cfg.Hourly,
Address: model.Address{
Street: "Kilchbergerweg",
Number: "1",
ZIPCode: "3052",
Place: "Zollikofen",
Country: "Schweiz",
},
Contact: "Niklas Breitenstein",
},
model.Entity{
Name: "Lou Taylor",
Address: model.Address{
Street: "Alpenstrasse",
Number: "22",
ZIPCode: "4950",
Place: "Huttwil",
Country: "Schweiz",
},
Contact: "Loana Groux",
},
16,
) )
html := r.ToHTML() html := r.ToHTML()
file, err := os.Create("index.html") pdfs, err := pdf.New(cfg.PdfGeneratorURL)
if err != nil {
panic(err)
}
defer file.Close()
file.Write([]byte(html))
// fmt.Print(html)
pdfs, err := pdf.New("http://localhost:3030")
if err != nil { if err != nil {
panic(err) panic(err)
} }
@@ -104,30 +73,21 @@ func main() {
panic(err) panic(err)
} }
mlr, err := mailer.New(mailer.Config{ mlr, err := mailer.New(cfg.Mailer)
SMTP: mailer.SMTPConfig{
Host: "mail.your-server.de",
Port: "465",
User: "test@schreifuchs.ch",
Password: "xV27D1nj33dNz8B4",
},
From: "test@schreifuchs.ch",
})
if err != nil { if err != nil {
panic(err) panic(err)
} }
err = mlr.Send(mailer.Mail{
TO: "kontakt@schreifuchs.ch", mail := cfg.Mail
Subject: "test", mail.Attachments = []mailer.Attachment{
Body: "Hallo",
Attachments: []mailer.Attachment{
{ {
Name: "invoice.pdf", Name: "invoice.pdf",
MimeType: "pdf", MimeType: "pdf",
Content: document, Content: document,
}, },
}, }
})
err = mlr.Send(mail)
if err != nil { if err != nil {
panic(err) panic(err)
} }

21
types.go Normal file
View File

@@ -0,0 +1,21 @@
package main
import (
"encoding/json"
"time"
)
type Duration time.Duration
func (d *Duration) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
tmp, err := time.ParseDuration(s)
if err != nil {
return err
}
*d = Duration(tmp)
return nil
}