Skip to content

Commit 5621ec6

Browse files
authored
implement webhook feature (#165)
* move lib * add webhook lib * add webhook setting * add webhook test case * add webhook test case * implement the webhook execute function * update test case * update webhook * update test case * update README * update README * update README * update settings
1 parent 8eb7c70 commit 5621ec6

File tree

22 files changed

+279
-16
lines changed

22 files changed

+279
-16
lines changed

README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Currently supports updating A records for subdomains. Doesn't support updating o
5353
- [Slack](#slack)
5454
- [Discord](#discord)
5555
- [Pushover](#pushover)
56+
- [Webhook](#webhook)
5657
- [Miscellaneous topics](#miscellaneous-topics)
5758
- [IPv6 support](#ipv6-support)
5859
- [Network interface IP address](#network-interface-ip-address)
@@ -645,6 +646,51 @@ The `message_template` property supports [html](https://pushover.net/api#html) i
645646
If the `device` and `title` parameters are left empty, Pushover will choose defaults [see](https://pushover.net/api#messages). More details on the priority parameter
646647
can be found on the Pushover [API description](https://pushover.net/api#priority).
647648

649+
### Webhook
650+
651+
Webhook is another feature that GoDNS provides to deliver notifications to the other applications while the IP is changed. GoDNS delivers a notification to the target URL via an HTTP `GET` or `POST` request.
652+
653+
The configuration section `webhook` is used for customizing the webhook request. In general, there are 2 fields used for the webhook request:
654+
655+
>* `url`: The target URL for sending webhook request.
656+
>* `request_body`: The content for sending `POST` request, if this field is empty, a HTTP GET request will be sent instead of the HTTP POST request.
657+
658+
Available variables:
659+
>* `Domain`: The current domain.
660+
>* `IP`: The new IP address.
661+
>* `IPType`: The type of the IP: `IPV4` or `IPV6`.
662+
663+
#### Webhook with HTTP GET reqeust
664+
665+
```json
666+
"webhook": {
667+
"enabled": true,
668+
"url": "http://localhost:5000/api/v1/send?domain={{.Domain}}&ip={{.CurrentIP}}&ip_type={{.IPType}}",
669+
"request_body": ""
670+
}
671+
```
672+
673+
For this example, a webhook with query string parameters will be sent to the target URL:
674+
```
675+
http://localhost:5000/api/v1/send?domain=ddns.example.com&ip=192.168.1.1&ip_type=IPV4
676+
```
677+
678+
#### Webhook with HTTP POST request
679+
680+
```json
681+
"webhook": {
682+
"enabled": true,
683+
"url": "http://localhost:5000/api/v1/send",
684+
"request_body": "{ \"domain\": \"{{.Domain}}\", \"ip\": \"{{.CurrentIP}}\", \"ip_type\": \"{{.IPType}}\" }"
685+
}
686+
```
687+
688+
For this example, a webhook will be triggered when the IP changes, the target URL `http://localhost:5000/api/v1/send` will receive an `HTTP POST` request with request body:
689+
690+
```json
691+
{ "domain": "ddns.example.com", "ip": "192.168.1.1", "ip_type": "IPV4" }
692+
```
693+
648694
### Miscellaneous topics
649695

650696
#### IPv6 support

configs/config_sample.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,10 @@
4444
"smtp_port": 25,
4545
"send_to": ""
4646
}
47+
},
48+
"webhook": {
49+
"enabled": false,
50+
"url": "http://localhost:5000/api/v1/send",
51+
"request_body": "{ \"domain\": \"{{.Domain}}\", \"ip\": \"{{.CurrentIP}}\", \"ip_type\": \"{{.IPType}}\" }"
4752
}
4853
}

configs/config_sample.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ notify:
3030
smtp_password:
3131
smtp_port: 25
3232
send_to:
33-
33+
webhook:
34+
enabled: false
35+
url: "http://localhost:5000/api/v1/send"
36+
request_body: "{ \"domain\": \"{{.Domain}}\", \"ip\": \"{{.CurrentIP}}\", \"ip_type\": \"{{.IPType}}\" }"

internal/handler/handler.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/TimothyYe/godns/internal/settings"
1313
"github.com/TimothyYe/godns/internal/utils"
14+
"github.com/TimothyYe/godns/pkg/lib"
1415
"github.com/TimothyYe/godns/pkg/notification"
1516
)
1617

@@ -90,6 +91,13 @@ func (handler *Handler) updateDNS(domain *settings.Domain, ip string) error {
9091

9192
successMessage := fmt.Sprintf("%s.%s", subdomainName, domain.DomainName)
9293
handler.notificationManager.Send(successMessage, ip)
94+
95+
// execute webhook when it is enabled
96+
if handler.Configuration.Webhook.Enabled {
97+
if err := lib.GetWebhook(handler.Configuration).Execute(hostname, ip); err != nil {
98+
return err
99+
}
100+
}
93101
}
94102
}
95103

internal/provider/cloudflare/cloudflare_handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func recordTracked(domain *settings.Domain, record *DNSRecord) bool {
124124

125125
// Create a new request with auth in place and optional proxy.
126126
func (provider *DNSProvider) newRequest(method, url string, body io.Reader) (*http.Request, *http.Client) {
127-
client := utils.GetHTTPClient(provider.configuration, provider.configuration.UseProxy)
127+
client := utils.GetHTTPClient(provider.configuration)
128128
if client == nil {
129129
log.Info("cannot create HTTP client")
130130
}

internal/provider/dnspod/dnspod_provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func (provider *DNSProvider) updateIP(domainID int64, subDomainID string, subDom
213213

214214
// postData post data and invoke DNSPod API.
215215
func (provider *DNSProvider) postData(url string, content url.Values) (string, error) {
216-
client := utils.GetHTTPClient(provider.configuration, provider.configuration.UseProxy)
216+
client := utils.GetHTTPClient(provider.configuration)
217217

218218
if client == nil {
219219
return "", errors.New("failed to create HTTP client")

internal/provider/dreamhost/dreamhost_handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (provider *DNSProvider) updateDNS(dns, ip, hostname, action string) error {
8585
return fmt.Errorf("unknown action: %s", action)
8686
}
8787

88-
client := utils.GetHTTPClient(provider.configuration, provider.configuration.UseProxy)
88+
client := utils.GetHTTPClient(provider.configuration)
8989
req, _ := http.NewRequest("POST", URL, strings.NewReader(values.Encode()))
9090
req.SetBasicAuth(provider.configuration.Email, provider.configuration.Password)
9191

internal/provider/duck/duck_handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func (provider *DNSProvider) updateIP(domainName, subdomainName, currentIP strin
3939
ip = fmt.Sprintf("ipv6=%s", currentIP)
4040
}
4141

42-
client := utils.GetHTTPClient(provider.configuration, provider.configuration.UseProxy)
42+
client := utils.GetHTTPClient(provider.configuration)
4343

4444
// update IP with HTTP GET request
4545
resp, err := client.Get(fmt.Sprintf(URL, subdomainName, provider.configuration.LoginToken, ip))

internal/provider/dynv6/dynv6_handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (provider *DNSProvider) Init(conf *settings.Settings) {
2929

3030
func (provider *DNSProvider) UpdateIP(domainName, subdomainName, ip string) error {
3131
hostname := subdomainName + "." + domainName
32-
client := utils.GetHTTPClient(provider.configuration, provider.configuration.UseProxy)
32+
client := utils.GetHTTPClient(provider.configuration)
3333
return provider.update(client, hostname, ip)
3434
}
3535

internal/provider/google/google_handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (provider *DNSProvider) UpdateIP(domainName, subdomainName, ip string) erro
3333

3434
// updateIP update subdomain with current IP.
3535
func (provider *DNSProvider) updateIP(domain, subDomain, currentIP string) error {
36-
client := utils.GetHTTPClient(provider.configuration, provider.configuration.UseProxy)
36+
client := utils.GetHTTPClient(provider.configuration)
3737
resp, err := client.Get(fmt.Sprintf(URL,
3838
provider.configuration.Email,
3939
provider.configuration.Password,

0 commit comments

Comments
 (0)