mirror of
https://github.com/hanzoai/notify.git
synced 2026-10-30 15:04:32 +00:00
111 lines
3.3 KiB
Go
111 lines
3.3 KiB
Go
// Package googlechat provides message notification integration sent to multiple
|
|
// spaces within a Google Chat Application.
|
|
package googlechat
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"google.golang.org/api/chat/v1"
|
|
"google.golang.org/api/googleapi"
|
|
"google.golang.org/api/option"
|
|
)
|
|
|
|
type spacesMessageCreator interface {
|
|
Create(string, *chat.Message) callCreator
|
|
}
|
|
|
|
type callCreator interface {
|
|
Do(...googleapi.CallOption) (*chat.Message, error)
|
|
}
|
|
|
|
var (
|
|
// Compile-time check to ensure that client implements the spaces message service
|
|
// interface.
|
|
_ spacesMessageCreator = new(messageCreator)
|
|
// Compile-time check to ensure that client implements the create call interface.
|
|
_ callCreator = new(chat.SpacesMessagesCreateCall)
|
|
)
|
|
|
|
// messageCreator is wrapper struct for the native chat.SpacesMessagesService struct.
|
|
// This exists so that we can mock the chat.SpacesMessagesCreateCall with the common
|
|
// interface "createCall".
|
|
type messageCreator struct {
|
|
*chat.SpacesMessagesService
|
|
}
|
|
|
|
func newMessageCreator(ctx context.Context, options ...option.ClientOption) (spacesMessageCreator, error) {
|
|
svc, err := chat.NewService(ctx, options...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &messageCreator{svc.Spaces.Messages}, nil
|
|
}
|
|
|
|
// Create creates a createCall struct for google chat. In order to execute sending
|
|
// the message utilize the `.Do` method found on the createCall.
|
|
func (m *messageCreator) Create(parent string, message *chat.Message) callCreator {
|
|
return m.SpacesMessagesService.Create(parent, message)
|
|
}
|
|
|
|
// Service encapsulates the google chat client along with internal state for storing
|
|
// chat spaces.
|
|
type Service struct {
|
|
messageCreator spacesMessageCreator
|
|
spaces []string
|
|
}
|
|
|
|
// New returns an instance of the google chat notification service.
|
|
func New(options ...option.ClientOption) (*Service, error) {
|
|
ctx := context.Background()
|
|
svc, err := newMessageCreator(ctx, options...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s := &Service{
|
|
messageCreator: svc,
|
|
spaces: []string{},
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
// NewWithContext returns an instance of the google chat notification service with the
|
|
// specified context. Utilize this constructor if the message requires the context to
|
|
// be set.
|
|
func NewWithContext(ctx context.Context, options ...option.ClientOption) (*Service, error) {
|
|
svc, err := newMessageCreator(ctx, options...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s := &Service{
|
|
messageCreator: svc,
|
|
spaces: []string{},
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
// AddReceivers takes a name of authorized spaces and appends them to the internal
|
|
// spaces slice. The Send method will send a given message to all those spaces.
|
|
func (s *Service) AddReceivers(spaces ...string) {
|
|
s.spaces = append(s.spaces, spaces...)
|
|
}
|
|
|
|
// Send takes a message subject and a message body and sends them to all the spaces
|
|
// previously set.
|
|
func (s *Service) Send(ctx context.Context, subject, message string) error {
|
|
// Treating subject as message title
|
|
msg := &chat.Message{Text: subject + "\n" + message}
|
|
for _, space := range s.spaces {
|
|
parent := fmt.Sprintf("spaces/%s", space)
|
|
select {
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
default:
|
|
if _, err := s.messageCreator.Create(parent, msg).Do(); err != nil {
|
|
return fmt.Errorf("send message to the google chat space %q: %w", space, err)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|