Skip to content

Commit

Permalink
feat(containrrr#404): Implement use of rooms query parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
surdaft committed Nov 7, 2023
1 parent c2cf3f2 commit 1aaf081
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 29 deletions.
12 changes: 8 additions & 4 deletions docs/services/webex.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ Adds Webex service functionality
!!! info "Your bot must be in the room"
Your bot must be invited to the room before a message can be sent by it.

## Examples
## URL Format

!!! example "General"
The URL format requires the `@webex?` to be present. This is to handle the URL
being parsed properly and is ignored.

!!! info ""
```uri
webex://your-bot-token@your-room-id
```
webex://__`token`__@webex?rooms=__`room-1`__[,__`room-2`__,...]

--8<-- "docs/services/webex/config.md"
34 changes: 21 additions & 13 deletions pkg/services/webex/webex.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,36 @@ func (service *Service) Initialize(configURL *url.URL, logger types.StdLogger) e
}

func doSend(message string, config *Config) error {
req, err := BuildRequestFromPayloadAndConfig(message, config)
if err != nil {
return err
}
var firstErr error

res, err := http.DefaultClient.Do(req)
for _, room := range config.Rooms {
req, firstErr := BuildRequestFromPayloadAndConfig(message, room, config)
if firstErr != nil {
return firstErr
}

if res == nil && err == nil {
err = fmt.Errorf("unknown error")
}
res, firstErr := http.DefaultClient.Do(req)

if res == nil && firstErr == nil {
firstErr = fmt.Errorf("unknown error")
}

if firstErr == nil && res.StatusCode != http.StatusOK {
firstErr = fmt.Errorf("response status code %s", res.Status)
}

if err == nil && res.StatusCode != http.StatusOK {
err = fmt.Errorf("response status code %s", res.Status)
if firstErr != nil {
return firstErr
}
}

return err
return firstErr
}

func BuildRequestFromPayloadAndConfig(message string, config *Config) (*http.Request, error) {
func BuildRequestFromPayloadAndConfig(message string, room string, config *Config) (*http.Request, error) {
var err error
payload := MessagePayload{
RoomID: config.RoomID,
RoomID: room,
Markdown: message,
}

Expand Down
20 changes: 12 additions & 8 deletions pkg/services/webex/webex_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
// Config is the configuration needed to send webex notifications
type Config struct {
standard.EnumlessConfig
RoomID string `url:"host"`
BotToken string `url:"user"`
BotToken string `url:"user"`
Rooms []string `key:"rooms"`
}

// GetURL returns a URL representation of it's current field values
Expand All @@ -31,19 +31,17 @@ func (config *Config) SetURL(url *url.URL) error {
func (config *Config) getURL(resolver types.ConfigQueryResolver) (u *url.URL) {
u = &url.URL{
User: url.User(config.BotToken),
Host: config.RoomID,
Host: Scheme,
Scheme: Scheme,
RawQuery: format.BuildQuery(resolver),
ForceQuery: false,
ForceQuery: true,
}

return u
}

// SetURL updates a ServiceConfig from a URL representation of it's field values
func (config *Config) setURL(resolver types.ConfigQueryResolver, url *url.URL) error {

config.RoomID = url.Host
config.BotToken = url.User.Username()

if len(url.Path) > 0 {
Expand All @@ -54,8 +52,14 @@ func (config *Config) setURL(resolver types.ConfigQueryResolver, url *url.URL) e
}
}

if config.RoomID == "" {
return errors.New("room ID missing from config URL")
for key, vals := range url.Query() {
if err := resolver.Set(key, vals[0]); err != nil {
return err
}
}

if len(config.Rooms) < 1 {
return errors.New("no rooms defined in config URL")
}

if len(config.BotToken) < 1 {
Expand Down
15 changes: 11 additions & 4 deletions pkg/services/webex/webex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ var _ = Describe("the webex service", func() {
})
When("parsing the configuration URL", func() {
It("should be identical after de-/serialization", func() {
testURL := "webex://token@room"
testURL := "webex://token@webex?rooms=room"

url, err := url.Parse(testURL)
Expect(err).NotTo(HaveOccurred(), "parsing")
Expand All @@ -97,9 +97,10 @@ var _ = Describe("the webex service", func() {

Describe("sending the payload", func() {
var dummyConfig = Config{
RoomID: "1",
BotToken: "dummyToken",
Rooms: []string{"1", "2"},
}

var service Service
BeforeEach(func() {
httpmock.Activate()
Expand All @@ -108,40 +109,46 @@ var _ = Describe("the webex service", func() {
panic(fmt.Errorf("service initialization failed: %w", err))
}
})

AfterEach(func() {
httpmock.DeactivateAndReset()
})

It("should not report an error if the server accepts the payload", func() {
setupResponder(&dummyConfig, 200, "")

Expect(service.Send("Message", nil)).To(Succeed())
})

It("should report an error if the server response is not OK", func() {
setupResponder(&dummyConfig, 400, "")
Expect(service.Initialize(dummyConfig.GetURL(), logger)).To(Succeed())
Expect(service.Send("Message", nil)).NotTo(Succeed())
})

It("should report an error if the message is empty", func() {
setupResponder(&dummyConfig, 400, "")
Expect(service.Initialize(dummyConfig.GetURL(), logger)).To(Succeed())
Expect(service.Send("", nil)).NotTo(Succeed())
})
})

Describe("doing request", func() {
dummyConfig := &Config{
BotToken: "dummyToken",
Rooms: []string{"1"},
}

It("should add authorization header", func() {
request, err := BuildRequestFromPayloadAndConfig("", dummyConfig)
request, err := BuildRequestFromPayloadAndConfig("", dummyConfig.Rooms[0], dummyConfig)

Expect(err).To(BeNil())
Expect(request.Header.Get("Authorization")).To(Equal("Bearer dummyToken"))
})

// webex API rejects messages which do not define Content-Type
It("should add content type header", func() {
request, err := BuildRequestFromPayloadAndConfig("", dummyConfig)
request, err := BuildRequestFromPayloadAndConfig("", dummyConfig.Rooms[0], dummyConfig)

Expect(err).To(BeNil())
Expect(request.Header.Get("Content-Type")).To(Equal("application/json"))
Expand Down

0 comments on commit 1aaf081

Please sign in to comment.