feat: add umamiTeamId to organize websites
This commit is contained in:
parent
3ca46c9ea2
commit
3e5c982284
5 changed files with 25 additions and 8 deletions
|
|
@ -11,6 +11,7 @@ testData:
|
||||||
umamiToken: ""
|
umamiToken: ""
|
||||||
umamiUsername: ""
|
umamiUsername: ""
|
||||||
umamiPassword: ""
|
umamiPassword: ""
|
||||||
|
umamiTeamId: ""
|
||||||
websites:
|
websites:
|
||||||
domain: websiteId
|
domain: websiteId
|
||||||
createNewWebsites: false
|
createNewWebsites: false
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ http:
|
||||||
umamiHost: http://umami:3000
|
umamiHost: http://umami:3000
|
||||||
umamiUsername: "admin"
|
umamiUsername: "admin"
|
||||||
umamiPassword: "umami"
|
umamiPassword: "umami"
|
||||||
|
umamiTeamId: "8e39c6ad-e44a-4d3e-be98-015db2d62d40"
|
||||||
createNewWebsites: true
|
createNewWebsites: true
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,8 @@ http:
|
||||||
```
|
```
|
||||||
|
|
||||||
You have an option to give a list of domains to track (and their website IDs on Umami). \
|
You have an option to give a list of domains to track (and their website IDs on Umami). \
|
||||||
Or, you can give a token and the list will be fetched from Umami. For this, you need either [retrieve the token yourself](https://umami.is/docs/api/authentication), or use
|
Or, you can give a token and the list will be fetched from Umami. For this, you need
|
||||||
|
either [retrieve the token yourself](https://umami.is/docs/api/authentication), or use
|
||||||
username/password instead.
|
username/password instead.
|
||||||
|
|
||||||
After that, you need to add the middleware to a [router](https://doc.traefik.io/traefik/routing/routers/#middlewares_1).
|
After that, you need to add the middleware to a [router](https://doc.traefik.io/traefik/routing/routers/#middlewares_1).
|
||||||
|
|
@ -64,11 +65,13 @@ Remember to reference the
|
||||||
correct [provider namespace](https://doc.traefik.io/traefik/providers/overview/#provider-namespace).
|
correct [provider namespace](https://doc.traefik.io/traefik/providers/overview/#provider-namespace).
|
||||||
|
|
||||||
E.g. as Docker labels:
|
E.g. as Docker labels:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- "traefik.http.routers.whoami.middlewares=my-umami-middleware@file"
|
- "traefik.http.routers.whoami.middlewares=my-umami-middleware@file"
|
||||||
```
|
```
|
||||||
|
|
||||||
Or, for all routers in a static configuration:
|
Or, for all routers in a static configuration:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
entryPoints:
|
entryPoints:
|
||||||
web:
|
web:
|
||||||
|
|
@ -85,6 +88,7 @@ entryPoints:
|
||||||
| `umamiToken` | - | `string` | An API Token, used to automatize work with websites, not needed if you provide `websites` |
|
| `umamiToken` | - | `string` | An API Token, used to automatize work with websites, not needed if you provide `websites` |
|
||||||
| `umamiUsername` | - | `string` | An alternative to `umamiToken`, you can provide an username and password |
|
| `umamiUsername` | - | `string` | An alternative to `umamiToken`, you can provide an username and password |
|
||||||
| `umamiPassword` | - | `string` | Only in combination with `umamiUsername` |
|
| `umamiPassword` | - | `string` | Only in combination with `umamiUsername` |
|
||||||
|
| `umamiTeamId` | - | `string` | In order to organize websites, you can use Umami Teams |
|
||||||
| `websites` | - | `map` | A map of hostnames and their associated Umami IDs. Can also be used to override or extend fetched websites |
|
| `websites` | - | `map` | A map of hostnames and their associated Umami IDs. Can also be used to override or extend fetched websites |
|
||||||
| `createNewWebsites` | false | `bool` | If set to `true`, will try to create a new website on Umami, if domain not found there |
|
| `createNewWebsites` | false | `bool` | If set to `true`, will try to create a new website on Umami, if domain not found there |
|
||||||
| `debug` | false | `bool` | Something doesn't work? Set to `true` to see more logs (plugins doesn't have access to Traefik's log level) |
|
| `debug` | false | `bool` | Something doesn't work? Set to `true` to see more logs (plugins doesn't have access to Traefik's log level) |
|
||||||
|
|
|
||||||
8
umami.go
8
umami.go
|
|
@ -17,6 +17,7 @@ type Config struct {
|
||||||
// as an alternative to UmamiToken, you can set UmamiUsername and UmamiPassword to authenticate
|
// as an alternative to UmamiToken, you can set UmamiUsername and UmamiPassword to authenticate
|
||||||
UmamiUsername string `json:"umamiUsername"`
|
UmamiUsername string `json:"umamiUsername"`
|
||||||
UmamiPassword string `json:"umamiPassword"`
|
UmamiPassword string `json:"umamiPassword"`
|
||||||
|
UmamiTeamId string `json:"umamiTeamId"`
|
||||||
// if both UmamiToken and Websites are set, Websites will be used to override the websites in the API
|
// if both UmamiToken and Websites are set, Websites will be used to override the websites in the API
|
||||||
Websites map[string]string `json:"websites"`
|
Websites map[string]string `json:"websites"`
|
||||||
// if createNewWebsites is set to true, the plugin will create new websites in the API, UmamiToken is required
|
// if createNewWebsites is set to true, the plugin will create new websites in the API, UmamiToken is required
|
||||||
|
|
@ -31,6 +32,7 @@ func CreateConfig() *Config {
|
||||||
UmamiToken: "",
|
UmamiToken: "",
|
||||||
UmamiUsername: "",
|
UmamiUsername: "",
|
||||||
UmamiPassword: "",
|
UmamiPassword: "",
|
||||||
|
UmamiTeamId: "",
|
||||||
Websites: map[string]string{},
|
Websites: map[string]string{},
|
||||||
CreateNewWebsites: false,
|
CreateNewWebsites: false,
|
||||||
Debug: false,
|
Debug: false,
|
||||||
|
|
@ -46,6 +48,7 @@ type UmamiFeeder struct {
|
||||||
|
|
||||||
UmamiHost string
|
UmamiHost string
|
||||||
UmamiToken string
|
UmamiToken string
|
||||||
|
UmamiTeamId string
|
||||||
Websites map[string]string
|
Websites map[string]string
|
||||||
CreateNewWebsites bool
|
CreateNewWebsites bool
|
||||||
}
|
}
|
||||||
|
|
@ -61,6 +64,7 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
|
||||||
|
|
||||||
UmamiHost: config.UmamiHost,
|
UmamiHost: config.UmamiHost,
|
||||||
UmamiToken: config.UmamiToken,
|
UmamiToken: config.UmamiToken,
|
||||||
|
UmamiTeamId: config.UmamiTeamId,
|
||||||
Websites: config.Websites,
|
Websites: config.Websites,
|
||||||
CreateNewWebsites: config.CreateNewWebsites,
|
CreateNewWebsites: config.CreateNewWebsites,
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +92,7 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.UmamiToken != "" {
|
if h.UmamiToken != "" {
|
||||||
websites, err := fetchWebsites(h.UmamiHost, h.UmamiToken)
|
websites, err := fetchWebsites(h.UmamiHost, h.UmamiToken, h.UmamiTeamId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to fetch websites: %w", err)
|
return nil, fmt.Errorf("failed to fetch websites: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +138,7 @@ func (h *UmamiFeeder) trackRequest(req *http.Request) {
|
||||||
hostname := parseDomainFromHost(req.Host)
|
hostname := parseDomainFromHost(req.Host)
|
||||||
websiteId, ok := h.Websites[hostname]
|
websiteId, ok := h.Websites[hostname]
|
||||||
if !ok {
|
if !ok {
|
||||||
website, err := createWebsite(h.UmamiHost, h.UmamiToken, hostname)
|
website, err := createWebsite(h.UmamiHost, h.UmamiToken, h.UmamiTeamId, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.log("failed to create website: " + err.Error())
|
h.log("failed to create website: " + err.Error())
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,13 @@ type WebsitesResponse struct {
|
||||||
|
|
||||||
type Website struct {
|
type Website struct {
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name,omitempty"`
|
||||||
Domain string `json:"domain"`
|
TeamId string `json:"teamId,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
CreatedAt time.Time `json:"createdAt,omitempty"`
|
CreatedAt time.Time `json:"createdAt,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createWebsite(umamiHost string, umamiToken string, websiteDomain string) (*Website, error) {
|
func createWebsite(umamiHost string, umamiToken string, teamId string, websiteDomain string) (*Website, error) {
|
||||||
var headers = make(http.Header)
|
var headers = make(http.Header)
|
||||||
headers.Set("Authorization", "Bearer "+umamiToken)
|
headers.Set("Authorization", "Bearer "+umamiToken)
|
||||||
|
|
||||||
|
|
@ -28,6 +29,7 @@ func createWebsite(umamiHost string, umamiToken string, websiteDomain string) (*
|
||||||
err := sendRequestAndParse(umamiHost+"/api/websites", Website{
|
err := sendRequestAndParse(umamiHost+"/api/websites", Website{
|
||||||
Name: websiteDomain,
|
Name: websiteDomain,
|
||||||
Domain: websiteDomain,
|
Domain: websiteDomain,
|
||||||
|
TeamId: teamId,
|
||||||
}, headers, &result)
|
}, headers, &result)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -37,12 +39,17 @@ func createWebsite(umamiHost string, umamiToken string, websiteDomain string) (*
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchWebsites(umamiHost string, umamiToken string) (*[]Website, error) {
|
func fetchWebsites(umamiHost string, umamiToken string, teamId string) (*[]Website, error) {
|
||||||
var headers = make(http.Header)
|
var headers = make(http.Header)
|
||||||
headers.Set("Authorization", "Bearer "+umamiToken)
|
headers.Set("Authorization", "Bearer "+umamiToken)
|
||||||
|
|
||||||
|
url := umamiHost + "/api/websites?pageSize=200"
|
||||||
|
if len(teamId) != 0 {
|
||||||
|
url = umamiHost + "/api/teams/" + teamId + "/websites?pageSize=200"
|
||||||
|
}
|
||||||
|
|
||||||
var result WebsitesResponse
|
var result WebsitesResponse
|
||||||
err := sendRequestAndParse(umamiHost+"/api/websites?pageSize=200", nil, headers, &result)
|
err := sendRequestAndParse(url, nil, headers, &result)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue