From 2f6bbec3e9a24b9c76e38bbcc4f2d808385b425a Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Mon, 21 Aug 2023 18:38:38 +0200 Subject: [PATCH] added text formatting (bold & italic) for normal/native mode --- src/api/api.go | 3 +- src/client/client.go | 20 ++++++++--- src/utils/textstyleparser.go | 67 ++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 src/utils/textstyleparser.go diff --git a/src/api/api.go b/src/api/api.go index 8331057..44d5813 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -104,6 +104,7 @@ type SendMessageV2 struct { QuoteAuthor *string `json:"quote_author"` QuoteMessage *string `json:"quote_message"` QuoteMentions []client.MessageMention `json:"quote_mentions"` + TextMode *string `json:"text_mode"` } type TypingIndicatorRequest struct { @@ -368,7 +369,7 @@ func (a *Api) SendV2(c *gin.Context) { timestamps, err := a.signalClient.SendV2( req.Number, req.Message, req.Recipients, req.Base64Attachments, req.Sticker, - req.Mentions, req.QuoteTimestamp, req.QuoteAuthor, req.QuoteMessage, req.QuoteMentions) + req.Mentions, req.QuoteTimestamp, req.QuoteAuthor, req.QuoteMessage, req.QuoteMentions, req.TextMode) if err != nil { c.JSON(400, Error{Msg: err.Error()}) return diff --git a/src/client/client.go b/src/client/client.go index 38ff591..5f3f0c2 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -295,7 +295,7 @@ func (s *MessageMention) toString() string { func (s *SignalClient) send(number string, message string, recipients []string, base64Attachments []string, isGroup bool, sticker string, mentions []MessageMention, - quoteTimestamp *int64, quoteAuthor *string, quoteMessage *string, quoteMentions []MessageMention) (*SendResponse, error) { + quoteTimestamp *int64, quoteAuthor *string, quoteMessage *string, quoteMentions []MessageMention, textMode *string) (*SendResponse, error) { var resp SendResponse @@ -303,6 +303,11 @@ func (s *SignalClient) send(number string, message string, return nil, errors.New("Please specify at least one recipient") } + signalCliTextFormatStrings := []string{} + if textMode != nil && *textMode == "styled" { + message, signalCliTextFormatStrings = utils.ParseMarkdownMessage(message) + } + var groupId string = "" if isGroup { if len(recipients) > 1 { @@ -400,6 +405,11 @@ func (s *SignalClient) send(number string, message string, cmd = append(cmd, []string{"-g", groupId}...) } + if len(signalCliTextFormatStrings) > 0 { + cmd = append(cmd, "--text-style") + cmd = append(cmd, signalCliTextFormatStrings...) + } + if len(attachmentEntries) > 0 { cmd = append(cmd, "-a") for _, attachmentEntry := range attachmentEntries { @@ -527,7 +537,7 @@ func (s *SignalClient) VerifyRegisteredNumber(number string, token string, pin s } func (s *SignalClient) SendV1(number string, message string, recipients []string, base64Attachments []string, isGroup bool) (*SendResponse, error) { - timestamp, err := s.send(number, message, recipients, base64Attachments, isGroup, "", nil, nil, nil, nil, nil) + timestamp, err := s.send(number, message, recipients, base64Attachments, isGroup, "", nil, nil, nil, nil, nil, nil) return timestamp, err } @@ -547,7 +557,7 @@ func (s *SignalClient) getJsonRpc2Clients() []*JsonRpc2Client { } func (s *SignalClient) SendV2(number string, message string, recps []string, base64Attachments []string, sticker string, mentions []MessageMention, - quoteTimestamp *int64, quoteAuthor *string, quoteMessage *string, quoteMentions []MessageMention) (*[]SendResponse, error) { + quoteTimestamp *int64, quoteAuthor *string, quoteMessage *string, quoteMentions []MessageMention, textMode *string) (*[]SendResponse, error) { if len(recps) == 0 { return nil, errors.New("Please provide at least one recipient") } @@ -577,7 +587,7 @@ func (s *SignalClient) SendV2(number string, message string, recps []string, bas timestamps := []SendResponse{} for _, group := range groups { - timestamp, err := s.send(number, message, []string{group}, base64Attachments, true, sticker, mentions, quoteTimestamp, quoteAuthor, quoteMessage, quoteMentions) + timestamp, err := s.send(number, message, []string{group}, base64Attachments, true, sticker, mentions, quoteTimestamp, quoteAuthor, quoteMessage, quoteMentions, textMode) if err != nil { return nil, err } @@ -585,7 +595,7 @@ func (s *SignalClient) SendV2(number string, message string, recps []string, bas } if len(recipients) > 0 { - timestamp, err := s.send(number, message, recipients, base64Attachments, false, sticker, mentions, quoteTimestamp, quoteAuthor, quoteMessage, quoteMentions) + timestamp, err := s.send(number, message, recipients, base64Attachments, false, sticker, mentions, quoteTimestamp, quoteAuthor, quoteMessage, quoteMentions, textMode) if err != nil { return nil, err } diff --git a/src/utils/textstyleparser.go b/src/utils/textstyleparser.go new file mode 100644 index 0000000..e640fae --- /dev/null +++ b/src/utils/textstyleparser.go @@ -0,0 +1,67 @@ +package utils + +import ( + "strconv" +) + +const ( + Normal string = "NORMAL" + Bold = "BOLD" + Italic = "ITALIC" +) + +const ( + None int = 0 + BoldBegin = 1 + BoldEnd = 2 + ItalicBegin = 3 + ItalicEnd1 = 4 + ItalicEnd2 = 5 +) + +func ParseMarkdownMessage(message string) (string, []string) { + textFormat := Normal + textFormatBegin := 0 + textFormatEnd := 0 + state := None + signalCliFormatStrings := []string{} + fullString := "" + + runes := []rune(message) //turn string to slice + + for i, v := range runes { //iterate through rune + if v == '*' { + if state == BoldBegin { + if i-1 == textFormatBegin { + state = ItalicBegin + textFormat = Italic + textFormatBegin = i + } else { + state = BoldEnd + textFormatEnd = i - 1 + } + } else if state == None { + state = BoldBegin + textFormat = Bold + textFormatBegin = i + } else if state == ItalicBegin { + state = ItalicEnd1 + textFormatEnd = i - 1 + } else if state == ItalicEnd1 { + state = ItalicEnd2 + } + } else { + fullString += string(v) + } + + if state == BoldEnd || state == ItalicEnd2 { + signalCliFormatStrings = append(signalCliFormatStrings, strconv.Itoa(textFormatBegin)+":"+strconv.Itoa(textFormatEnd-textFormatBegin)+":"+textFormat) + state = None + textFormatBegin = 0 + textFormatEnd = 0 + textFormat = Normal + } + } + + return fullString, signalCliFormatStrings +}