forked from nikoksr/notify
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplivo.go
112 lines (94 loc) · 2.67 KB
/
plivo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package plivo
import (
"context"
"errors"
"fmt"
"net/http"
"strings"
plivo "github.com/plivo/plivo-go/v7"
)
// ClientOptions allow you to configure a Plivo SDK client.
type ClientOptions struct {
AuthID string // If empty, env variable PLIVO_AUTH_ID will be used
AuthToken string // If empty, env variable PLIVO_AUTH_TOKEN will be used
// Optional
HTTPClient *http.Client // Bring Your Own Client
}
// MessageOptions allow you to configure options for sending a message.
type MessageOptions struct {
Source string // a Plivo source phone number or a Plivo Powerpack UUID
// Optional
CallbackURL string // URL to which status update callbacks for the message should be sent
CallbackMethod string // The HTTP method to be used when calling CallbackURL - GET or POST(default)
}
// plivoMsgClient abstracts Plivo SDK for writing unit tests.
type plivoMsgClient interface {
Create(plivo.MessageCreateParams) (*plivo.MessageCreateResponseBody, error)
}
// Service is a Plivo client.
type Service struct {
client plivoMsgClient
mopts MessageOptions
destinations []string
}
// New creates a new instance of plivo service.
func New(cOpts *ClientOptions, mOpts *MessageOptions) (*Service, error) {
if cOpts == nil {
return nil, errors.New("client-options cannot be nil")
}
if mOpts == nil {
return nil, errors.New("message-options cannot be nil")
}
if mOpts.Source == "" {
return nil, errors.New("source cannot be empty")
}
client, err := plivo.NewClient(
cOpts.AuthID,
cOpts.AuthToken,
&plivo.ClientOptions{
HttpClient: cOpts.HTTPClient,
},
)
if err != nil {
return nil, err
}
return &Service{
client: client.Messages,
mopts: *mOpts,
}, nil
}
// AddReceivers adds the given destination phone numbers to the notifier.
func (s *Service) AddReceivers(phoneNumbers ...string) {
s.destinations = append(s.destinations, phoneNumbers...)
}
// Send sends a SMS via Plivo to all previously added receivers.
func (s *Service) Send(ctx context.Context, subject, message string) error {
text := subject + "\n" + message
var dst string
switch len(s.destinations) {
case 0:
return errors.New("no receivers added")
case 1:
dst = s.destinations[0]
default:
// multiple destinations, use bulk message syntax
// see: https://www.plivo.com/docs/sms/api/message#bulk-messaging
dst = strings.Join(s.destinations, "<")
}
select {
case <-ctx.Done():
return ctx.Err()
default:
_, err := s.client.Create(plivo.MessageCreateParams{
Dst: dst,
Text: text,
Src: s.mopts.Source,
URL: s.mopts.CallbackURL,
Method: s.mopts.CallbackMethod,
})
if err != nil {
return fmt.Errorf("send SMS to %q: %w", dst, err)
}
}
return nil
}