Make /s replace the whole message; fix replies and whitespace corruption
This commit is contained in:
parent
ee6653c0c6
commit
9f04ed51bd
|
@ -3,10 +3,10 @@ package telegram
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
|
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
|
||||||
|
|
||||||
|
@ -114,6 +114,24 @@ func parseCommand(cmdline string) (string, []string) {
|
||||||
return bodyFields[0][1:], bodyFields[1:]
|
return bodyFields[0][1:], bodyFields[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func rawCmdArguments(cmdline string, start uint8) (string) {
|
||||||
|
var state uint
|
||||||
|
// /cmd ababa galamaga
|
||||||
|
// 01 2 3 45
|
||||||
|
startState := uint(3 + 2 * start)
|
||||||
|
for i, r := range cmdline {
|
||||||
|
isOdd := state % 2 == 1
|
||||||
|
isSpace := unicode.IsSpace(r)
|
||||||
|
if (!isOdd && !isSpace) || (isOdd && isSpace) {
|
||||||
|
state += 1
|
||||||
|
}
|
||||||
|
if state == startState {
|
||||||
|
return cmdline[i:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) unsubscribe(chatID int64) {
|
func (c *Client) unsubscribe(chatID int64) {
|
||||||
gateway.SendPresence(
|
gateway.SendPresence(
|
||||||
c.xmpp,
|
c.xmpp,
|
||||||
|
@ -263,7 +281,7 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) string
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := c.client.SetBio(&client.SetBioRequest{
|
_, err := c.client.SetBio(&client.SetBioRequest{
|
||||||
Bio: strings.Join(args, " "),
|
Bio: rawCmdArguments(cmdline, 0),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Couldn't set bio").Error()
|
return errors.Wrap(err, "Couldn't set bio").Error()
|
||||||
|
@ -371,13 +389,9 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
if c.me == nil {
|
if c.me == nil {
|
||||||
return "@me is not initialized", true
|
return "@me is not initialized", true
|
||||||
}
|
}
|
||||||
if len(args) < 2 {
|
if len(args) < 1 {
|
||||||
return "Not enough arguments", true
|
return "Not enough arguments", true
|
||||||
}
|
}
|
||||||
regex, err := regexp.Compile(args[0])
|
|
||||||
if err != nil {
|
|
||||||
return err.Error(), true
|
|
||||||
}
|
|
||||||
|
|
||||||
messages, err := c.getLastMessages(chatID, "", c.me.ID, 1)
|
messages, err := c.getLastMessages(chatID, "", c.me.ID, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -392,13 +406,17 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
return "Last message is empty", true
|
return "Last message is empty", true
|
||||||
}
|
}
|
||||||
|
|
||||||
messageText, ok := message.Content.(*client.MessageText)
|
content := c.ProcessOutgoingMessage(0, rawCmdArguments(cmdline, 0), "")
|
||||||
if !ok {
|
|
||||||
return "Last message is not a text!", true
|
|
||||||
}
|
|
||||||
|
|
||||||
text := regex.ReplaceAllString(messageText.Text.Text, strings.Join(args[1:], " "))
|
if content != nil {
|
||||||
c.ProcessOutgoingMessage(chatID, text, message.ID, "")
|
c.client.EditMessageText(&client.EditMessageTextRequest{
|
||||||
|
ChatID: chatID,
|
||||||
|
MessageID: message.ID,
|
||||||
|
InputMessageContent: content,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return "Message processing error", true
|
||||||
|
}
|
||||||
// add @contact
|
// add @contact
|
||||||
case "add":
|
case "add":
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
|
@ -441,7 +459,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
|
|
||||||
_, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
_, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
||||||
Title: args[0],
|
Title: args[0],
|
||||||
Description: strings.Join(args[1:], " "),
|
Description: rawCmdArguments(cmdline, 1),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Error(), true
|
return err.Error(), true
|
||||||
|
@ -454,7 +472,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool)
|
||||||
|
|
||||||
_, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
_, err := c.client.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
||||||
Title: args[0],
|
Title: args[0],
|
||||||
Description: strings.Join(args[1:], " "),
|
Description: rawCmdArguments(cmdline, 1),
|
||||||
IsChannel: true,
|
IsChannel: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -25,7 +25,7 @@ import (
|
||||||
var errOffline = errors.New("TDlib instance is offline")
|
var errOffline = errors.New("TDlib instance is offline")
|
||||||
|
|
||||||
var spaceRegex = regexp.MustCompile(`\s+`)
|
var spaceRegex = regexp.MustCompile(`\s+`)
|
||||||
var replyRegex = regexp.MustCompile("> ?([0-9]{10,})")
|
var replyRegex = regexp.MustCompile("\\A>>? ?([0-9]+)\\n")
|
||||||
|
|
||||||
const newlineChar string = "\n"
|
const newlineChar string = "\n"
|
||||||
|
|
||||||
|
@ -483,83 +483,68 @@ func (c *Client) messageToPrefix(message *client.Message, fileString string) str
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessOutgoingMessage executes commands or sends messages to mapped chats
|
// ProcessOutgoingMessage executes commands or sends messages to mapped chats
|
||||||
func (c *Client) ProcessOutgoingMessage(chatID int64, text string, messageID int64, returnJid string) {
|
func (c *Client) ProcessOutgoingMessage(chatID int64, text string, returnJid string) client.InputMessageContent {
|
||||||
if messageID == 0 && strings.HasPrefix(text, "/") {
|
if !c.Online() {
|
||||||
// try to execute a command
|
// we're offline
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if returnJid != "" && strings.HasPrefix(text, "/") {
|
||||||
|
// try to execute commands
|
||||||
response, isCommand := c.ProcessChatCommand(chatID, text)
|
response, isCommand := c.ProcessChatCommand(chatID, text)
|
||||||
if response != "" {
|
if response != "" {
|
||||||
gateway.SendMessage(returnJid, strconv.FormatInt(chatID, 10), response, c.xmpp)
|
gateway.SendMessage(returnJid, strconv.FormatInt(chatID, 10), response, c.xmpp)
|
||||||
}
|
}
|
||||||
// do not send on success
|
// do not send on success
|
||||||
if isCommand {
|
if isCommand {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.Online() {
|
log.Warnf("Sending message to chat %v", chatID)
|
||||||
// we're offline
|
|
||||||
return
|
// quotations
|
||||||
|
var reply int64
|
||||||
|
replySlice := replyRegex.FindStringSubmatch(text)
|
||||||
|
if len(replySlice) > 1 {
|
||||||
|
reply, _ = strconv.ParseInt(replySlice[1], 10, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Warnf("Send message to chat %v", chatID)
|
// attach a file
|
||||||
|
var file *client.InputFileRemote
|
||||||
if messageID != 0 {
|
if chatID != 0 && c.content.Upload != "" && strings.HasPrefix(text, c.content.Upload) {
|
||||||
formattedText := &client.FormattedText{
|
file = &client.InputFileRemote{
|
||||||
Text: text,
|
ID: text,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove first line from text
|
||||||
|
if file != nil || reply != 0 {
|
||||||
|
newlinePos := strings.Index(text, newlineChar)
|
||||||
|
if newlinePos != -1 {
|
||||||
|
text = text[newlinePos+1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedText := &client.FormattedText{
|
||||||
|
Text: text,
|
||||||
|
}
|
||||||
|
|
||||||
|
var message client.InputMessageContent
|
||||||
|
if file != nil {
|
||||||
|
// we can try to send a document
|
||||||
|
message = &client.InputMessageDocument{
|
||||||
|
Document: file,
|
||||||
|
Caption: formattedText,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// compile our message
|
// compile our message
|
||||||
message := &client.InputMessageText{
|
message = &client.InputMessageText{
|
||||||
Text: formattedText,
|
Text: formattedText,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
c.client.EditMessageText(&client.EditMessageTextRequest{
|
if chatID != 0 {
|
||||||
ChatID: chatID,
|
|
||||||
MessageID: messageID,
|
|
||||||
InputMessageContent: message,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// quotations
|
|
||||||
var reply int64
|
|
||||||
replySlice := replyRegex.FindStringSubmatch(text)
|
|
||||||
if len(replySlice) > 1 {
|
|
||||||
reply, _ = strconv.ParseInt(replySlice[1], 10, 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// attach a file
|
|
||||||
var file *client.InputFileRemote
|
|
||||||
if c.content.Upload != "" && strings.HasPrefix(text, c.content.Upload) {
|
|
||||||
file = &client.InputFileRemote{
|
|
||||||
ID: text,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove first line from text
|
|
||||||
if file != nil || reply != 0 {
|
|
||||||
newlinePos := strings.Index(text, newlineChar)
|
|
||||||
if newlinePos != -1 {
|
|
||||||
text = text[newlinePos+1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
formattedText := &client.FormattedText{
|
|
||||||
Text: text,
|
|
||||||
}
|
|
||||||
|
|
||||||
var message client.InputMessageContent
|
|
||||||
if file != nil {
|
|
||||||
// we can try to send a document
|
|
||||||
message = &client.InputMessageDocument{
|
|
||||||
Document: file,
|
|
||||||
Caption: formattedText,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// compile our message
|
|
||||||
message = &client.InputMessageText{
|
|
||||||
Text: formattedText,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := c.client.SendMessage(&client.SendMessageRequest{
|
_, err := c.client.SendMessage(&client.SendMessageRequest{
|
||||||
ChatID: chatID,
|
ChatID: chatID,
|
||||||
ReplyToMessageID: reply,
|
ReplyToMessageID: reply,
|
||||||
|
@ -569,10 +554,13 @@ func (c *Client) ProcessOutgoingMessage(chatID int64, text string, messageID int
|
||||||
gateway.SendMessage(
|
gateway.SendMessage(
|
||||||
returnJid,
|
returnJid,
|
||||||
strconv.FormatInt(chatID, 10),
|
strconv.FormatInt(chatID, 10),
|
||||||
fmt.Sprintf("Message not sent: %s", err.Error()),
|
fmt.Sprintf("Not sent: %s", err.Error()),
|
||||||
c.xmpp,
|
c.xmpp,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ func HandleMessage(s xmpp.Sender, p stanza.Packet) {
|
||||||
if len(toParts) > 1 {
|
if len(toParts) > 1 {
|
||||||
toIDInt, err := strconv.ParseInt(toID, 10, 64)
|
toIDInt, err := strconv.ParseInt(toID, 10, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
session.ProcessOutgoingMessage(toIDInt, msg.Body, 0, msg.From)
|
session.ProcessOutgoingMessage(toIDInt, msg.Body, msg.From)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
|
|
Loading…
Reference in a new issue