Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add discourse service #217

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
more tests and bugfixes
  • Loading branch information
piksel committed Jul 27, 2021
commit b2f75bf0c91fe92210bbaaff162068d340bdbf2c
17 changes: 11 additions & 6 deletions pkg/common/webclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
type client struct {
headers http.Header
indent string
HttpClient http.Client
httpClient http.Client
parse ParserFunc
write WriterFunc
}
Expand All @@ -32,9 +32,14 @@ func (c *client) Headers() http.Header {
return c.headers
}

// HTTPClient returns the underlying http.WebClient used by the WebClient
func (c *client) HTTPClient() *http.Client {
return &c.httpClient
}

// Get fetches url using GET and unmarshals into the passed response
func (c *client) Get(url string, response interface{}) error {
return c.request(url, response, nil)
return c.request(http.MethodGet, url, response, nil)
}

// Post sends a serialized representation of request and deserializes the result into response
Expand All @@ -44,7 +49,7 @@ func (c *client) Post(url string, request interface{}, response interface{}) err
return fmt.Errorf("error creating payload: %v", err)
}

return c.request(url, response, bytes.NewReader(body))
return c.request(http.MethodPost, url, response, bytes.NewReader(body))
}

// ErrorResponse tries to deserialize any response body into the supplied struct, returning whether successful or not
Expand All @@ -57,8 +62,8 @@ func (c *client) ErrorResponse(err error, response interface{}) bool {
return c.parse([]byte(jerr.Body), response) == nil
}

func (c *client) request(url string, response interface{}, payload io.Reader) error {
req, err := http.NewRequest(http.MethodPost, url, payload)
func (c *client) request(method, url string, response interface{}, payload io.Reader) error {
req, err := http.NewRequest(method, url, payload)
if err != nil {
return err
}
Expand All @@ -67,7 +72,7 @@ func (c *client) request(url string, response interface{}, payload io.Reader) er
req.Header.Set(key, val[0])
}

res, err := c.HttpClient.Do(req)
res, err := c.httpClient.Do(req)
if err != nil {
return fmt.Errorf("error sending payload: %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/common/webclient/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ type WebClient interface {
ErrorResponse(err error, response interface{}) bool
SetParser(ParserFunc)
SetWriter(WriterFunc)
HTTPClient() *http.Client
}
6 changes: 3 additions & 3 deletions pkg/common/webclient/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type ClientService struct {
// HTTPClient returns the underlying http.WebClient used in the Service
func (s *ClientService) HTTPClient() *http.Client {
s.Initialize()
return &s.client.HttpClient
return s.client.HTTPClient()
}

// WebClient returns the WebClient instance, initializing it if necessary
Expand All @@ -42,7 +42,7 @@ func (s *ClientService) Initialize() {
}

s.client = &client{
HttpClient: http.Client{
httpClient: http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{},
},
Expand All @@ -66,7 +66,7 @@ func (s *ClientService) AddTrustedRootCertificate(caPEM []byte) bool {
certPool = x509.NewCertPool()
}
s.certPool = certPool
if tp, ok := s.client.HttpClient.Transport.(*http.Transport); ok {
if tp, ok := s.client.httpClient.Transport.(*http.Transport); ok {
tp.TLSClientConfig.RootCAs = s.certPool
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/services/telegram/telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (service *Service) Initialize(configURL *url.URL, logger types.StdLogger) e
}

func (service *Service) sendMessageForChatIDs(message string, config *Config) error {
client := &Client{token: config.Token, WebClient: service.WebClient()}
client := &Client{Token: config.Token, WebClient: service.WebClient()}
for _, chat := range service.config.Chats {
payload := createSendMessagePayload(message, chat, config)
if _, err := client.SendMessage(&payload); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions pkg/services/telegram/telegram_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
// Client for Telegram API
type Client struct {
WebClient webclient.WebClient
token string
Token string
}

func (c *Client) apiURL(endpoint string) string {
return fmt.Sprintf(apiFormat, c.token, endpoint)
return fmt.Sprintf(apiFormat, c.Token, endpoint)
}

// GetBotInfo returns the bot User info
Expand Down Expand Up @@ -61,7 +61,7 @@ func (c *Client) SendMessage(message *SendMessagePayload) (*Message, error) {

// GetErrorResponse retrieves the error message from a failed request
func (c *Client) getErrorResponse(err error) error {
var errResponse *errorResponse
errResponse := &ErrorResponse{}
if c.WebClient.ErrorResponse(err, errResponse) {
return errResponse
} else {
Expand Down
45 changes: 45 additions & 0 deletions pkg/services/telegram/telegram_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package telegram_test

import (
"github.com/containrrr/shoutrrr/pkg/common/webclient"
"github.com/containrrr/shoutrrr/pkg/services/telegram"
"github.com/jarcoal/httpmock"
"net/http"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var client *telegram.Client

var _ = Describe("the telegram client", func() {
BeforeEach(func() {
client = &telegram.Client{WebClient: webclient.NewJSONClient(), Token: `Test`}
httpmock.ActivateNonDefault(client.WebClient.HTTPClient())
})
AfterEach(func() {
httpmock.DeactivateAndReset()
})
When("an error is returned from the API", func() {
It("should return the error description", func() {

errRes := httpmock.NewJsonResponderOrPanic(http.StatusNotAcceptable, telegram.ErrorResponse{
OK: false,
Description: "no.",
})
httpmock.RegisterResponder("POST", `https://api.telegram.org/botTest/getUpdates`, errRes)
httpmock.RegisterResponder("GET", `https://api.telegram.org/botTest/getMe`, errRes)
httpmock.RegisterResponder("POST", `https://api.telegram.org/botTest/sendMessage`, errRes)

_, err := client.GetUpdates(0, 1, 10, []string{})
Expect(err).To(MatchError(`no.`))

_, err = client.GetBotInfo()
Expect(err).To(MatchError(`no.`))

_, err = client.SendMessage(&telegram.SendMessagePayload{})
Expect(err).To(MatchError(`no.`))
})
})

})
3 changes: 2 additions & 1 deletion pkg/services/telegram/telegram_generator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package telegram

import (
"github.com/containrrr/shoutrrr/pkg/common/webclient"
f "github.com/containrrr/shoutrrr/pkg/format"
"github.com/containrrr/shoutrrr/pkg/types"
"github.com/containrrr/shoutrrr/pkg/util/generator"
Expand Down Expand Up @@ -41,7 +42,7 @@ func (g *Generator) Generate(_ types.Service, props map[string]string, _ []strin
ud.Writeln("Fetching bot info...")
// ud.Writeln("Session token: %v", g.sessionToken)

g.client = &Client{token: token}
g.client = &Client{Token: token, WebClient: webclient.NewJSONClient()}
botInfo, err := g.client.GetBotInfo()
if err != nil {
return &Config{}, err
Expand Down
5 changes: 3 additions & 2 deletions pkg/services/telegram/telegram_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ func createSendMessagePayload(message string, channel string, config *Config) Se
return payload
}

type errorResponse struct {
// ErrorResponse is the generic response from the API when an error occurred
type ErrorResponse struct {
OK bool `json:"ok"`
ErrorCode int `json:"error_code"`
Description string `json:"description"`
}

func (e *errorResponse) Error() string {
func (e *ErrorResponse) Error() string {
return e.Description
}

Expand Down