feat(notification/telegram): specify channel as a telegram endpoint property
parent
3f2ccfa9e1
commit
078bd8db09
|
@ -11616,9 +11616,6 @@ components:
|
||||||
messageTemplate:
|
messageTemplate:
|
||||||
description: The message template as a flux interpolated string.
|
description: The message template as a flux interpolated string.
|
||||||
type: string
|
type: string
|
||||||
channel:
|
|
||||||
description: Id of the telegram channel.
|
|
||||||
type: string
|
|
||||||
parseMode:
|
parseMode:
|
||||||
description: Parse mode of the message text per https://core.telegram.org/bots/api#formatting-options . Defaults to "MarkdownV2" .
|
description: Parse mode of the message text per https://core.telegram.org/bots/api#formatting-options . Defaults to "MarkdownV2" .
|
||||||
type: string
|
type: string
|
||||||
|
@ -11778,10 +11775,14 @@ components:
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: "#/components/schemas/NotificationEndpointBase"
|
- $ref: "#/components/schemas/NotificationEndpointBase"
|
||||||
- type: object
|
- type: object
|
||||||
|
required: [token, channel]
|
||||||
properties:
|
properties:
|
||||||
token:
|
token:
|
||||||
description: Specifies the Telegram bot token. See https://core.telegram.org/bots#creating-a-new-bot .
|
description: Specifies the Telegram bot token. See https://core.telegram.org/bots#creating-a-new-bot .
|
||||||
type: string
|
type: string
|
||||||
|
channel:
|
||||||
|
description: ID of the telegram channel, a chat_id in https://core.telegram.org/bots/api#sendmessage .
|
||||||
|
type: string
|
||||||
NotificationEndpointType:
|
NotificationEndpointType:
|
||||||
type: string
|
type: string
|
||||||
enum: ["slack", "pagerduty", "http", "telegram"]
|
enum: ["slack", "pagerduty", "http", "telegram"]
|
||||||
|
|
|
@ -62,7 +62,8 @@ func TestValidEndpoint(t *testing.T) {
|
||||||
OrgID: influxTesting.MustIDBase16Ptr(id3),
|
OrgID: influxTesting.MustIDBase16Ptr(id3),
|
||||||
Status: influxdb.Active,
|
Status: influxdb.Active,
|
||||||
},
|
},
|
||||||
Token: influxdb.SecretField{Key: id1 + "-token"},
|
Token: influxdb.SecretField{Key: id1 + "-token"},
|
||||||
|
Channel: "-1001406363649",
|
||||||
},
|
},
|
||||||
err: &influxdb.Error{
|
err: &influxdb.Error{
|
||||||
Code: influxdb.EInvalid,
|
Code: influxdb.EInvalid,
|
||||||
|
@ -146,11 +147,23 @@ func TestValidEndpoint(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid telegram token",
|
name: "empty telegram channel",
|
||||||
src: &endpoint.Telegram{
|
src: &endpoint.Telegram{
|
||||||
Base: goodBase,
|
Base: goodBase,
|
||||||
Token: influxdb.SecretField{Key: id1 + "-token"},
|
Token: influxdb.SecretField{Key: id1 + "-token"},
|
||||||
},
|
},
|
||||||
|
err: &influxdb.Error{
|
||||||
|
Code: influxdb.EInvalid,
|
||||||
|
Msg: "empty telegram channel",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid telegram token",
|
||||||
|
src: &endpoint.Telegram{
|
||||||
|
Base: goodBase,
|
||||||
|
Token: influxdb.SecretField{Key: id1 + "-token"},
|
||||||
|
Channel: "-1001406363649",
|
||||||
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ type Telegram struct {
|
||||||
Base
|
Base
|
||||||
// Token is the telegram bot token, see https://core.telegram.org/bots#creating-a-new-bot
|
// Token is the telegram bot token, see https://core.telegram.org/bots#creating-a-new-bot
|
||||||
Token influxdb.SecretField `json:"token"`
|
Token influxdb.SecretField `json:"token"`
|
||||||
|
// Channel is an ID of the telegram channel, see https://core.telegram.org/bots/api#sendmessage
|
||||||
|
Channel string `json:"channel"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackfillSecretKeys fill back the secret field key during the unmarshalling
|
// BackfillSecretKeys fill back the secret field key during the unmarshalling
|
||||||
|
@ -45,6 +47,12 @@ func (s Telegram) Valid() error {
|
||||||
Msg: "empty telegram bot token",
|
Msg: "empty telegram bot token",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if s.Channel == "" {
|
||||||
|
return &influxdb.Error{
|
||||||
|
Code: influxdb.EInvalid,
|
||||||
|
Msg: "empty telegram channel",
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -353,7 +353,6 @@ func TestJSON(t *testing.T) {
|
||||||
UpdatedAt: timeGen2.Now(),
|
UpdatedAt: timeGen2.Now(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Channel: "channel1",
|
|
||||||
MessageTemplate: "blah",
|
MessageTemplate: "blah",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
type Telegram struct {
|
type Telegram struct {
|
||||||
Base
|
Base
|
||||||
MessageTemplate string `json:"messageTemplate"`
|
MessageTemplate string `json:"messageTemplate"`
|
||||||
Channel string `json:"channel"`
|
|
||||||
ParseMode string `json:"parseMode"`
|
ParseMode string `json:"parseMode"`
|
||||||
DisableWebPagePreview bool `json:"disableWebPagePreview"`
|
DisableWebPagePreview bool `json:"disableWebPagePreview"`
|
||||||
}
|
}
|
||||||
|
@ -52,7 +51,7 @@ func (s *Telegram) generateFluxASTBody(e *endpoint.Telegram) []ast.Statement {
|
||||||
statements = append(statements, s.generateFluxASTNotificationDefinition(e))
|
statements = append(statements, s.generateFluxASTNotificationDefinition(e))
|
||||||
statements = append(statements, s.generateFluxASTStatuses())
|
statements = append(statements, s.generateFluxASTStatuses())
|
||||||
statements = append(statements, s.generateLevelChecks()...)
|
statements = append(statements, s.generateLevelChecks()...)
|
||||||
statements = append(statements, s.generateFluxASTNotifyPipe())
|
statements = append(statements, s.generateFluxASTNotifyPipe(e))
|
||||||
|
|
||||||
return statements
|
return statements
|
||||||
}
|
}
|
||||||
|
@ -77,9 +76,9 @@ func (s *Telegram) generateFluxASTEndpoint(e *endpoint.Telegram) ast.Statement {
|
||||||
return flux.DefineVariable("telegram_endpoint", call)
|
return flux.DefineVariable("telegram_endpoint", call)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Telegram) generateFluxASTNotifyPipe() ast.Statement {
|
func (s *Telegram) generateFluxASTNotifyPipe(e *endpoint.Telegram) ast.Statement {
|
||||||
endpointProps := []*ast.Property{}
|
endpointProps := []*ast.Property{}
|
||||||
endpointProps = append(endpointProps, flux.Property("channel", flux.String(s.Channel)))
|
endpointProps = append(endpointProps, flux.Property("channel", flux.String(e.Channel)))
|
||||||
endpointProps = append(endpointProps, flux.Property("text", flux.String(s.MessageTemplate)))
|
endpointProps = append(endpointProps, flux.Property("text", flux.String(s.MessageTemplate)))
|
||||||
endpointProps = append(endpointProps, flux.Property("silent", s.generateSilent()))
|
endpointProps = append(endpointProps, flux.Property("silent", s.generateSilent()))
|
||||||
endpointFn := flux.Function(flux.FunctionParams("r"), flux.Object(endpointProps...))
|
endpointFn := flux.Function(flux.FunctionParams("r"), flux.Object(endpointProps...))
|
||||||
|
@ -132,12 +131,6 @@ func (s Telegram) Valid() error {
|
||||||
Msg: "Telegram MessageTemplate is invalid",
|
Msg: "Telegram MessageTemplate is invalid",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.Channel == "" {
|
|
||||||
return &influxdb.Error{
|
|
||||||
Code: influxdb.EInvalid,
|
|
||||||
Msg: "Telegram Channel is invalid",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ func TestTelegram_GenerateFlux(t *testing.T) {
|
||||||
},
|
},
|
||||||
rule: &rule.Telegram{
|
rule: &rule.Telegram{
|
||||||
MessageTemplate: "blah",
|
MessageTemplate: "blah",
|
||||||
Channel: "-12345",
|
|
||||||
Base: rule.Base{
|
Base: rule.Base{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
EndpointID: 3,
|
EndpointID: 3,
|
||||||
|
@ -69,11 +68,11 @@ func TestTelegram_GenerateFlux(t *testing.T) {
|
||||||
ID: idPtr(3),
|
ID: idPtr(3),
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
},
|
},
|
||||||
Token: influxdb.SecretField{Key: "3-key"},
|
Token: influxdb.SecretField{Key: "3-key"},
|
||||||
|
Channel: "-12345",
|
||||||
},
|
},
|
||||||
rule: &rule.Telegram{
|
rule: &rule.Telegram{
|
||||||
MessageTemplate: "blah",
|
MessageTemplate: "blah",
|
||||||
Channel: "-12345",
|
|
||||||
Base: rule.Base{
|
Base: rule.Base{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
EndpointID: 3,
|
EndpointID: 3,
|
||||||
|
@ -139,11 +138,11 @@ all_statuses
|
||||||
ID: idPtr(3),
|
ID: idPtr(3),
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
},
|
},
|
||||||
Token: influxdb.SecretField{Key: "3-key"},
|
Token: influxdb.SecretField{Key: "3-key"},
|
||||||
|
Channel: "-12345",
|
||||||
},
|
},
|
||||||
rule: &rule.Telegram{
|
rule: &rule.Telegram{
|
||||||
MessageTemplate: "blah",
|
MessageTemplate: "blah",
|
||||||
Channel: "-12345",
|
|
||||||
DisableWebPagePreview: true,
|
DisableWebPagePreview: true,
|
||||||
ParseMode: "HTML",
|
ParseMode: "HTML",
|
||||||
Base: rule.Base{
|
Base: rule.Base{
|
||||||
|
@ -233,7 +232,6 @@ func TestTelegram_Valid(t *testing.T) {
|
||||||
name: "valid template",
|
name: "valid template",
|
||||||
rule: &rule.Telegram{
|
rule: &rule.Telegram{
|
||||||
MessageTemplate: "blah",
|
MessageTemplate: "blah",
|
||||||
Channel: "-12345",
|
|
||||||
Base: rule.Base{
|
Base: rule.Base{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
EndpointID: 3,
|
EndpointID: 3,
|
||||||
|
@ -255,7 +253,6 @@ func TestTelegram_Valid(t *testing.T) {
|
||||||
name: "missing MessageTemplate",
|
name: "missing MessageTemplate",
|
||||||
rule: &rule.Telegram{
|
rule: &rule.Telegram{
|
||||||
MessageTemplate: "",
|
MessageTemplate: "",
|
||||||
Channel: "-12345",
|
|
||||||
Base: rule.Base{
|
Base: rule.Base{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
EndpointID: 3,
|
EndpointID: 3,
|
||||||
|
@ -280,7 +277,6 @@ func TestTelegram_Valid(t *testing.T) {
|
||||||
name: "missing EndpointID",
|
name: "missing EndpointID",
|
||||||
rule: &rule.Telegram{
|
rule: &rule.Telegram{
|
||||||
MessageTemplate: "",
|
MessageTemplate: "",
|
||||||
Channel: "-12345",
|
|
||||||
Base: rule.Base{
|
Base: rule.Base{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
// EndpointID: 3,
|
// EndpointID: 3,
|
||||||
|
@ -301,30 +297,6 @@ func TestTelegram_Valid(t *testing.T) {
|
||||||
Msg: "Notification Rule EndpointID is invalid",
|
Msg: "Notification Rule EndpointID is invalid",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "missing Channel",
|
|
||||||
rule: &rule.Telegram{
|
|
||||||
MessageTemplate: "blah",
|
|
||||||
Base: rule.Base{
|
|
||||||
ID: 1,
|
|
||||||
EndpointID: 3,
|
|
||||||
OwnerID: 4,
|
|
||||||
OrgID: 5,
|
|
||||||
Name: "foo",
|
|
||||||
Every: mustDuration("1h"),
|
|
||||||
StatusRules: []notification.StatusRule{
|
|
||||||
{
|
|
||||||
CurrentLevel: notification.Critical,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TagRules: []notification.TagRule{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
err: &influxdb.Error{
|
|
||||||
Code: influxdb.EInvalid,
|
|
||||||
Msg: "Telegram Channel is invalid",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
t.Run(c.name, func(t *testing.T) {
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
|
|
@ -43,8 +43,14 @@ const EndpointOptions: FC<Props> = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case 'telegram': {
|
case 'telegram': {
|
||||||
const {token} = endpoint as TelegramNotificationEndpoint
|
const {token, channel} = endpoint as TelegramNotificationEndpoint
|
||||||
return <EndpointOptionsTelegram token={token} onChange={onChange} />
|
return (
|
||||||
|
<EndpointOptionsTelegram
|
||||||
|
token={token}
|
||||||
|
channel={channel}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
case 'http': {
|
case 'http': {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -13,10 +13,11 @@ import {
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
token: string
|
token: string
|
||||||
|
channel: string
|
||||||
onChange: (e: ChangeEvent<HTMLInputElement>) => void
|
onChange: (e: ChangeEvent<HTMLInputElement>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const EndpointOptionsTelegram: FC<Props> = ({token, onChange}) => {
|
const EndpointOptionsTelegram: FC<Props> = ({token, channel, onChange}) => {
|
||||||
return (
|
return (
|
||||||
<Panel>
|
<Panel>
|
||||||
<Panel.Header>
|
<Panel.Header>
|
||||||
|
@ -35,6 +36,15 @@ const EndpointOptionsTelegram: FC<Props> = ({token, onChange}) => {
|
||||||
type={InputType.Password}
|
type={InputType.Password}
|
||||||
/>
|
/>
|
||||||
</FormElement>
|
</FormElement>
|
||||||
|
<FormElement label="Chat ID">
|
||||||
|
<Input
|
||||||
|
name="channel"
|
||||||
|
value={channel}
|
||||||
|
testID="channel"
|
||||||
|
onChange={onChange}
|
||||||
|
type={InputType.Text}
|
||||||
|
/>
|
||||||
|
</FormElement>
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
</Grid.Row>
|
</Grid.Row>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -64,6 +64,7 @@ export const reducer = (
|
||||||
...baseProps,
|
...baseProps,
|
||||||
type: 'telegram',
|
type: 'telegram',
|
||||||
token: '',
|
token: '',
|
||||||
|
channel: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,11 +63,10 @@ const RuleMessageContents: FC<Props> = ({rule}) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case 'telegram': {
|
case 'telegram': {
|
||||||
const {messageTemplate, channel} = rule
|
const {messageTemplate} = rule
|
||||||
return (
|
return (
|
||||||
<TelegramMessage
|
<TelegramMessage
|
||||||
messageTemplate={messageTemplate}
|
messageTemplate={messageTemplate}
|
||||||
channel={channel}
|
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import React, {FC, ChangeEvent} from 'react'
|
import React, {FC, ChangeEvent} from 'react'
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import {Form, TextArea, Input} from '@influxdata/clockface'
|
import {Form, TextArea} from '@influxdata/clockface'
|
||||||
import {TelegramNotificationRuleBase} from 'src/types/alerting'
|
import {TelegramNotificationRuleBase} from 'src/types/alerting'
|
||||||
|
|
||||||
interface EventHandlers {
|
interface EventHandlers {
|
||||||
|
@ -10,23 +10,19 @@ interface EventHandlers {
|
||||||
}
|
}
|
||||||
type Props = Omit<TelegramNotificationRuleBase, 'type'> & EventHandlers
|
type Props = Omit<TelegramNotificationRuleBase, 'type'> & EventHandlers
|
||||||
|
|
||||||
const TelegramMessage: FC<Props> = ({messageTemplate, channel, onChange}) => {
|
const TelegramMessage: FC<Props> = ({messageTemplate, onChange}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<Form.Element label="Message Template">
|
||||||
<Form.Element label="Channel ID">
|
<TextArea
|
||||||
<Input value={channel} name="channel" onChange={onChange} />
|
name="messageTemplate"
|
||||||
</Form.Element>
|
testID="slack-message-template--textarea"
|
||||||
<Form.Element label="Message Template">
|
value={messageTemplate}
|
||||||
<TextArea
|
onChange={onChange}
|
||||||
name="messageTemplate"
|
rows={3}
|
||||||
testID="slack-message-template--textarea"
|
/>
|
||||||
value={messageTemplate}
|
</Form.Element>
|
||||||
onChange={onChange}
|
/*
|
||||||
rows={3}
|
// keep it simple, the following elements are possible, but too advanced
|
||||||
/>
|
|
||||||
</Form.Element>
|
|
||||||
{/*
|
|
||||||
// keep it simple, these following elements are possible, but too advanced
|
|
||||||
<Form.Element label="Parse Mode">
|
<Form.Element label="Parse Mode">
|
||||||
<Input value={parseMode} name="parseMode" onChange={onChange} />
|
<Input value={parseMode} name="parseMode" onChange={onChange} />
|
||||||
</Form.Element>
|
</Form.Element>
|
||||||
|
@ -38,8 +34,7 @@ const TelegramMessage: FC<Props> = ({messageTemplate, channel, onChange}) => {
|
||||||
type={InputType.Checkbox}
|
type={InputType.Checkbox}
|
||||||
/>
|
/>
|
||||||
</Form.Element>
|
</Form.Element>
|
||||||
*/}
|
*/
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,6 @@ export const getRuleVariantDefaults = (
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
messageTemplate: messageTemplate,
|
messageTemplate: messageTemplate,
|
||||||
channel: '',
|
|
||||||
parseMode: 'MarkdownV2',
|
parseMode: 'MarkdownV2',
|
||||||
disableWebPagePreview: false,
|
disableWebPagePreview: false,
|
||||||
type: 'telegram',
|
type: 'telegram',
|
||||||
|
|
Loading…
Reference in New Issue