remove ability to set telegram API, clarify params
This commit is contained in:
committed by
Umputun
parent
ea15b28bf6
commit
d6167980f4
@@ -216,7 +216,7 @@ type NotifyGroup struct {
|
||||
QueueSize int `long:"queue" env:"QUEUE" description:"size of notification queue" default:"100"`
|
||||
Telegram struct {
|
||||
Channel string `long:"chan" env:"CHAN" description:"telegram channel for admin notifications"`
|
||||
API string `long:"api" env:"API" default:"https://api.telegram.org/bot" description:"telegram api prefix"`
|
||||
API string `long:"api" env:"API" default:"https://api.telegram.org/bot" description:"[deprecated, not used] telegram api prefix"`
|
||||
Token string `long:"token" env:"TOKEN" description:"[deprecated, use --telegram.token] telegram token"`
|
||||
Timeout time.Duration `long:"timeout" env:"TIMEOUT" default:"5s" description:"[deprecated, use --telegram.timeout] telegram timeout"`
|
||||
} `group:"telegram" namespace:"telegram" env-namespace:"TELEGRAM"`
|
||||
@@ -361,6 +361,9 @@ func (s *ServerCommand) HandleDeprecatedFlags() (result []DeprecatedFlag) {
|
||||
s.Telegram.Token = s.Notify.Telegram.Token
|
||||
result = append(result, DeprecatedFlag{Old: "notify.telegram.timeout", New: "telegram.timeout", Version: "1.9"})
|
||||
}
|
||||
if s.Notify.Telegram.API != "https://api.telegram.org/bot" {
|
||||
result = append(result, DeprecatedFlag{Old: "notify.telegram.api", Version: "1.9"})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -877,8 +880,12 @@ func (s *ServerCommand) makeNotify(dataStore *service.DataStore, authenticator *
|
||||
}
|
||||
destinations = append(destinations, slack)
|
||||
case "telegram":
|
||||
tg, err := notify.NewTelegram(s.Telegram.Token, s.Notify.Telegram.Channel,
|
||||
s.Telegram.Timeout, s.Notify.Telegram.API)
|
||||
telegramParams := notify.TelegramParams{
|
||||
AdminChannelID: s.Notify.Telegram.Channel,
|
||||
Token: s.Telegram.Token,
|
||||
Timeout: s.Telegram.Timeout,
|
||||
}
|
||||
tg, err := notify.NewTelegram(telegramParams)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create telegram notification destination")
|
||||
}
|
||||
|
||||
+5
-2
@@ -46,8 +46,11 @@ func main() {
|
||||
Revision: revision,
|
||||
})
|
||||
for _, entry := range c.HandleDeprecatedFlags() {
|
||||
log.Printf("[WARN] --%s is deprecated since v%s and will be removed in the future, please use --%s instead",
|
||||
entry.Old, entry.Version, entry.New)
|
||||
deprecationNote := fmt.Sprintf("[WARN] --%s is deprecated since v%s and will be removed in the future", entry.Old, entry.Version)
|
||||
if entry.New != "" {
|
||||
deprecationNote += fmt.Sprintf(", please use --%s instead", entry.New)
|
||||
}
|
||||
log.Print(deprecationNote)
|
||||
}
|
||||
err := c.Execute(args)
|
||||
if err != nil {
|
||||
|
||||
@@ -16,38 +16,44 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// TelegramParams contain settings for telegram notifications
|
||||
type TelegramParams struct {
|
||||
AdminChannelID string // unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
Token string // token for telegram bot API interactions
|
||||
Timeout time.Duration // http client timeout
|
||||
|
||||
apiPrefix string // changed only in tests
|
||||
}
|
||||
|
||||
// Telegram implements notify.Destination for telegram
|
||||
type Telegram struct {
|
||||
channelID string // unique identifier for the target chat or username of the target channel (in the format @channelusername)
|
||||
token string
|
||||
apiPrefix string
|
||||
timeout time.Duration
|
||||
TelegramParams
|
||||
}
|
||||
|
||||
const telegramTimeOut = 5000 * time.Millisecond
|
||||
const telegramAPIPrefix = "https://api.telegram.org/bot"
|
||||
|
||||
// NewTelegram makes telegram bot for notifications
|
||||
func NewTelegram(token, channelID string, timeout time.Duration, api string) (*Telegram, error) {
|
||||
if _, err := strconv.ParseInt(channelID, 10, 64); err != nil {
|
||||
channelID = "@" + channelID // if channelID not a number enforce @ prefix
|
||||
func NewTelegram(params TelegramParams) (*Telegram, error) {
|
||||
res := Telegram{TelegramParams: params}
|
||||
if _, err := strconv.ParseInt(res.AdminChannelID, 10, 64); err != nil {
|
||||
res.AdminChannelID = "@" + res.AdminChannelID // if channelID not a number enforce @ prefix
|
||||
}
|
||||
|
||||
res := Telegram{channelID: channelID, token: token, apiPrefix: api, timeout: timeout}
|
||||
if res.apiPrefix == "" {
|
||||
res.apiPrefix = telegramAPIPrefix
|
||||
}
|
||||
if res.timeout == 0 {
|
||||
res.timeout = telegramTimeOut
|
||||
if res.Timeout == 0 {
|
||||
res.Timeout = telegramTimeOut
|
||||
}
|
||||
log.Printf("[DEBUG] create new telegram notifier for chan %s, timeout=%s, api=%s", channelID, res.timeout, res.timeout)
|
||||
log.Printf("[DEBUG] create new telegram notifier for api=%s, timeout=%s", res.apiPrefix, res.Timeout)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
err := repeater.NewDefault(5, time.Millisecond*250).Do(ctx, func() error {
|
||||
client := http.Client{Timeout: res.timeout}
|
||||
resp, err := client.Get(fmt.Sprintf("%s%s/getMe", res.apiPrefix, token))
|
||||
client := http.Client{Timeout: res.Timeout}
|
||||
resp, err := client.Get(fmt.Sprintf("%s%s/getMe", res.apiPrefix, res.Token))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "can't initialize telegram notifications")
|
||||
}
|
||||
@@ -88,9 +94,9 @@ func NewTelegram(token, channelID string, timeout time.Duration, api string) (*T
|
||||
func (t *Telegram) Send(ctx context.Context, req Request) error {
|
||||
var err error
|
||||
|
||||
if t.channelID != "" {
|
||||
if t.AdminChannelID != "" {
|
||||
err = t.sendAdminNotification(ctx, req)
|
||||
if err != nil{
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "problem sending admin telegram notification")
|
||||
}
|
||||
}
|
||||
@@ -99,14 +105,14 @@ func (t *Telegram) Send(ctx context.Context, req Request) error {
|
||||
}
|
||||
|
||||
func (t *Telegram) sendAdminNotification(ctx context.Context, req Request) error {
|
||||
log.Printf("[DEBUG] send admin telegram notification to %s, comment id %s", t.channelID, req.Comment.ID)
|
||||
log.Printf("[DEBUG] send admin telegram notification to %s, comment id %s", t.AdminChannelID, req.Comment.ID)
|
||||
|
||||
msg, err := buildTelegramMessage(req)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to make telegram message body")
|
||||
}
|
||||
|
||||
err = t.sendMessage(ctx, msg, t.channelID)
|
||||
err = t.sendMessage(ctx, msg, t.AdminChannelID)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to send admin notification about %s", req.Comment.ID)
|
||||
}
|
||||
@@ -115,14 +121,14 @@ func (t *Telegram) sendAdminNotification(ctx context.Context, req Request) error
|
||||
|
||||
func (t *Telegram) sendMessage(ctx context.Context, b []byte, chatID string) error {
|
||||
u := fmt.Sprintf("%s%s/sendMessage?chat_id=%s&parse_mode=Markdown&disable_web_page_preview=true",
|
||||
t.apiPrefix, t.token, chatID)
|
||||
t.apiPrefix, t.Token, chatID)
|
||||
r, err := http.NewRequest("POST", u, bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to make telegram request")
|
||||
}
|
||||
r.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
client := http.Client{Timeout: t.timeout}
|
||||
client := http.Client{Timeout: t.Timeout}
|
||||
r = r.WithContext(ctx)
|
||||
resp, err := client.Do(r)
|
||||
if err != nil {
|
||||
@@ -186,5 +192,5 @@ func (t *Telegram) SendVerification(_ context.Context, _ VerificationRequest) er
|
||||
}
|
||||
|
||||
func (t *Telegram) String() string {
|
||||
return "telegram: " + t.channelID
|
||||
return "telegram: " + t.AdminChannelID
|
||||
}
|
||||
|
||||
@@ -20,45 +20,85 @@ func TestTelegram_New(t *testing.T) {
|
||||
ts := mockTelegramServer()
|
||||
defer ts.Close()
|
||||
|
||||
tb, err := NewTelegram("good-token", "remark_test", 2*time.Second, ts.URL+"/")
|
||||
tb, err := NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "good-token",
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, tb)
|
||||
assert.Equal(t, "@remark_test", tb.channelID, "@ added")
|
||||
assert.Equal(t, tb.Timeout, time.Second*5)
|
||||
assert.Equal(t, "@remark_test", tb.AdminChannelID, "@ added")
|
||||
|
||||
st := time.Now()
|
||||
_, err = NewTelegram("bad-resp", "remark_test", 2*time.Second, ts.URL+"/")
|
||||
_, err = NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "bad-resp",
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.EqualError(t, err, "unexpected telegram response {OK:false Result:{FirstName:comments_test ID:707381019 IsBot:false UserName:remark42_test_bot}}")
|
||||
assert.True(t, time.Since(st) >= 250*5*time.Millisecond)
|
||||
|
||||
_, err = NewTelegram("non-json-resp", "remark_test", 2*time.Second, ts.URL+"/")
|
||||
_, err = NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "non-json-resp",
|
||||
Timeout: 2 * time.Second,
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "can't decode response:")
|
||||
|
||||
_, err = NewTelegram("404", "remark_test", 2*time.Second, ts.URL+"/")
|
||||
_, err = NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "404",
|
||||
Timeout: 2 * time.Second,
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.EqualError(t, err, "unexpected telegram status code 404")
|
||||
|
||||
_, err = NewTelegram("no-such-thing", "remark_test", 2*time.Second, "http://127.0.0.1:4321/")
|
||||
_, err = NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "no-such-thing",
|
||||
apiPrefix: "http://127.0.0.1:4321/",
|
||||
})
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "can't initialize telegram notifications")
|
||||
assert.Contains(t, err.Error(), "dial tcp 127.0.0.1:4321: connect: connection refused")
|
||||
|
||||
_, err = NewTelegram("good-token", "remark_test", 2*time.Second, "")
|
||||
_, err = NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "no-such-thing",
|
||||
apiPrefix: "",
|
||||
})
|
||||
assert.Error(t, err, "empty api url not allowed")
|
||||
|
||||
_, err = NewTelegram("good-token", "remark_test", 0, ts.URL+"/")
|
||||
_, err = NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "good-token",
|
||||
Timeout: 2 * time.Second,
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.NoError(t, err, "0 timeout allowed as default")
|
||||
|
||||
tb, err = NewTelegram("good-token", "1234567890", 2*time.Second, ts.URL+"/")
|
||||
tb, err = NewTelegram(TelegramParams{
|
||||
AdminChannelID: "1234567890",
|
||||
Token: "good-token",
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, tb)
|
||||
assert.Equal(t, "1234567890", tb.channelID, "no @ prefix")
|
||||
assert.Equal(t, "1234567890", tb.AdminChannelID, "no @ prefix")
|
||||
}
|
||||
|
||||
func TestTelegram_Send(t *testing.T) {
|
||||
ts := mockTelegramServer()
|
||||
defer ts.Close()
|
||||
|
||||
tb, err := NewTelegram("good-token", "remark_test", 2*time.Second, ts.URL+"/")
|
||||
tb, err := NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "good-token",
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, tb)
|
||||
c := store.Comment{Text: "some text", ParentID: "1", ID: "999"}
|
||||
@@ -78,7 +118,11 @@ func TestTelegram_Send(t *testing.T) {
|
||||
err = tb.Send(context.TODO(), Request{Comment: c, parent: cp})
|
||||
assert.NoError(t, err)
|
||||
|
||||
tb, err = NewTelegram("non-json-resp", "remark_test", 2*time.Second, ts.URL+"/")
|
||||
tb, err = NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "non-json-resp",
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.Error(t, err, "should fail")
|
||||
err = tb.Send(context.TODO(), Request{Comment: c, parent: cp})
|
||||
require.Error(t, err)
|
||||
@@ -96,7 +140,11 @@ func TestTelegram_SendVerification(t *testing.T) {
|
||||
ts := mockTelegramServer()
|
||||
defer ts.Close()
|
||||
|
||||
tb, err := NewTelegram("good-token", "remark_test", 2*time.Second, ts.URL+"/")
|
||||
tb, err := NewTelegram(TelegramParams{
|
||||
AdminChannelID: "remark_test",
|
||||
Token: "good-token",
|
||||
apiPrefix: ts.URL + "/",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, tb)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user