feat(telegram): add action to send telegram message (#147)
Signed-off-by: mudler <mudler@localai.io>
This commit is contained in:
committed by
GitHub
parent
864bf8b94c
commit
2b07dd79ec
@@ -46,6 +46,7 @@ const (
|
|||||||
ActionCounter = "counter"
|
ActionCounter = "counter"
|
||||||
ActionCallAgents = "call_agents"
|
ActionCallAgents = "call_agents"
|
||||||
ActionShellcommand = "shell-command"
|
ActionShellcommand = "shell-command"
|
||||||
|
ActionSendTelegramMessage = "send-telegram-message"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AvailableActions = []string{
|
var AvailableActions = []string{
|
||||||
@@ -79,6 +80,7 @@ var AvailableActions = []string{
|
|||||||
ActionCounter,
|
ActionCounter,
|
||||||
ActionCallAgents,
|
ActionCallAgents,
|
||||||
ActionShellcommand,
|
ActionShellcommand,
|
||||||
|
ActionSendTelegramMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
func Actions(actionsConfigs map[string]string) func(a *state.AgentConfig) func(ctx context.Context, pool *state.AgentPool) []types.Action {
|
func Actions(actionsConfigs map[string]string) func(a *state.AgentConfig) func(ctx context.Context, pool *state.AgentPool) []types.Action {
|
||||||
@@ -177,6 +179,8 @@ func Action(name, agentName string, config map[string]string, pool *state.AgentP
|
|||||||
a = actions.NewCallAgent(config, agentName, pool.InternalAPI())
|
a = actions.NewCallAgent(config, agentName, pool.InternalAPI())
|
||||||
case ActionShellcommand:
|
case ActionShellcommand:
|
||||||
a = actions.NewShell(config)
|
a = actions.NewShell(config)
|
||||||
|
case ActionSendTelegramMessage:
|
||||||
|
a = actions.NewSendTelegramMessageRunner(config)
|
||||||
default:
|
default:
|
||||||
xlog.Error("Action not found", "name", name)
|
xlog.Error("Action not found", "name", name)
|
||||||
return nil, fmt.Errorf("Action not found")
|
return nil, fmt.Errorf("Action not found")
|
||||||
@@ -341,5 +345,10 @@ func ActionsConfigMeta() []config.FieldGroup {
|
|||||||
Label: "Call Agents",
|
Label: "Call Agents",
|
||||||
Fields: actions.CallAgentConfigMeta(),
|
Fields: actions.CallAgentConfigMeta(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "send-telegram-message",
|
||||||
|
Label: "Send Telegram Message",
|
||||||
|
Fields: actions.SendTelegramMessageConfigMeta(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
160
services/actions/sendtelegrammessage.go
Normal file
160
services/actions/sendtelegrammessage.go
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
package actions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/go-telegram/bot"
|
||||||
|
"github.com/go-telegram/bot/models"
|
||||||
|
"github.com/mudler/LocalAGI/core/types"
|
||||||
|
"github.com/mudler/LocalAGI/pkg/config"
|
||||||
|
"github.com/mudler/LocalAGI/pkg/xstrings"
|
||||||
|
"github.com/sashabaranov/go-openai/jsonschema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MetadataTelegramMessageSent = "telegram_message_sent"
|
||||||
|
telegramMaxMessageLength = 3000
|
||||||
|
)
|
||||||
|
|
||||||
|
type SendTelegramMessageRunner struct {
|
||||||
|
token string
|
||||||
|
chatID int64
|
||||||
|
bot *bot.Bot
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSendTelegramMessageRunner(config map[string]string) *SendTelegramMessageRunner {
|
||||||
|
token := config["token"]
|
||||||
|
if token == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse chat ID from config if present
|
||||||
|
var chatID int64
|
||||||
|
if configChatID := config["chat_id"]; configChatID != "" {
|
||||||
|
var err error
|
||||||
|
chatID, err = strconv.ParseInt(configChatID, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := bot.New(token)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SendTelegramMessageRunner{
|
||||||
|
token: token,
|
||||||
|
chatID: chatID,
|
||||||
|
bot: b,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TelegramMessageParams struct {
|
||||||
|
ChatID int64 `json:"chat_id"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SendTelegramMessageRunner) Run(ctx context.Context, params types.ActionParams) (types.ActionResult, error) {
|
||||||
|
var messageParams TelegramMessageParams
|
||||||
|
err := params.Unmarshal(&messageParams)
|
||||||
|
if err != nil {
|
||||||
|
return types.ActionResult{}, fmt.Errorf("failed to unmarshal params: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.chatID != 0 {
|
||||||
|
messageParams.ChatID = s.chatID
|
||||||
|
}
|
||||||
|
|
||||||
|
if messageParams.ChatID == 0 {
|
||||||
|
return types.ActionResult{}, fmt.Errorf("chat_id is required either in config or parameters")
|
||||||
|
}
|
||||||
|
|
||||||
|
if messageParams.Message == "" {
|
||||||
|
return types.ActionResult{}, fmt.Errorf("message is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the message if it's too long
|
||||||
|
messages := xstrings.SplitParagraph(messageParams.Message, telegramMaxMessageLength)
|
||||||
|
|
||||||
|
if len(messages) == 0 {
|
||||||
|
return types.ActionResult{}, fmt.Errorf("empty message after splitting")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send each message part
|
||||||
|
for i, msg := range messages {
|
||||||
|
_, err = s.bot.SendMessage(ctx, &bot.SendMessageParams{
|
||||||
|
ChatID: messageParams.ChatID,
|
||||||
|
Text: msg,
|
||||||
|
ParseMode: models.ParseModeMarkdown,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return types.ActionResult{}, fmt.Errorf("failed to send telegram message part %d: %w", i+1, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.ActionResult{
|
||||||
|
Result: fmt.Sprintf("Message sent successfully to chat ID %d in %d parts", messageParams.ChatID, len(messages)),
|
||||||
|
Metadata: map[string]interface{}{
|
||||||
|
MetadataTelegramMessageSent: true,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SendTelegramMessageRunner) Definition() types.ActionDefinition {
|
||||||
|
if s.chatID != 0 {
|
||||||
|
return types.ActionDefinition{
|
||||||
|
Name: "send_telegram_message",
|
||||||
|
Description: "Send a message to a Telegram user or group",
|
||||||
|
Properties: map[string]jsonschema.Definition{
|
||||||
|
"message": {
|
||||||
|
Type: jsonschema.String,
|
||||||
|
Description: "The message to send",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Required: []string{"message"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.ActionDefinition{
|
||||||
|
Name: "send_telegram_message",
|
||||||
|
Description: "Send a message to a Telegram user or group",
|
||||||
|
Properties: map[string]jsonschema.Definition{
|
||||||
|
"chat_id": {
|
||||||
|
Type: jsonschema.Number,
|
||||||
|
Description: "The Telegram chat ID to send the message to (optional if configured in config)",
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
Type: jsonschema.String,
|
||||||
|
Description: "The message to send",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Required: []string{"message", "chat_id"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SendTelegramMessageRunner) Plannable() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendTelegramMessageConfigMeta returns the metadata for Send Telegram Message action configuration fields
|
||||||
|
func SendTelegramMessageConfigMeta() []config.Field {
|
||||||
|
return []config.Field{
|
||||||
|
{
|
||||||
|
Name: "token",
|
||||||
|
Label: "Telegram Token",
|
||||||
|
Type: config.FieldTypeText,
|
||||||
|
Required: true,
|
||||||
|
HelpText: "Telegram bot token for sending messages",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "chat_id",
|
||||||
|
Label: "Default Chat ID",
|
||||||
|
Type: config.FieldTypeText,
|
||||||
|
Required: false,
|
||||||
|
HelpText: "Default Telegram chat ID to send messages to (can be overridden in parameters)",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user