mirror of
https://github.com/bbernhard/signal-cli-rest-api.git
synced 2026-11-01 09:49:30 +00:00
Merge adf0ee16e1231e5b8fff5ad82b54a44eaf4e87c5 into 787d204e155d0c73840a615a5e90c697bacaa6f1
This commit is contained in:
commit
e0df77cabf
@ -138,6 +138,7 @@ type SendMessageV2 struct {
|
||||
QuoteMessage *string `json:"quote_message,omitempty"`
|
||||
QuoteMentions []ds.MessageMention `json:"quote_mentions,omitempty"`
|
||||
TextMode *string `json:"text_mode,omitempty" enums:"normal,styled"`
|
||||
TextStyles []string `json:"text_styles,omitempty" example:"0:5:BOLD,10:3:ITALIC"`
|
||||
EditTimestamp *int64 `json:"edit_timestamp,omitempty"`
|
||||
NotifySelf *bool `json:"notify_self,omitempty"`
|
||||
LinkPreview *ds.LinkPreviewType `json:"link_preview,omitempty"`
|
||||
@ -508,7 +509,7 @@ func (a *Api) Send(c *gin.Context) {
|
||||
|
||||
// @Summary Send a signal message.
|
||||
// @Tags Messages
|
||||
// @Description Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \*italic text\*, \*\*bold text\*\*, ~strikethrough text~, ||spoiler||, \`monospace\`. If you want to escape a formatting character, prefix it with two backslashes.
|
||||
// @Description Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \*italic text\*, \*\*bold text\*\*, ~strikethrough text~, ||spoiler||, \`monospace\`. If you want to escape a formatting character, prefix it with two backslashes. Alternatively, pass the styles directly via text_styles in signal-cli's 'start:length:STYLE' format (STYLE is one of BOLD, ITALIC, SPOILER, STRIKETHROUGH, MONOSPACE); text_styles can't be combined with text_mode 'styled'.
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 201 {array} ds.SendMessageResponse
|
||||
@ -547,8 +548,21 @@ func (a *Api) SendV2(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.TextStyles) > 0 && req.TextMode != nil && *req.TextMode == "styled" {
|
||||
c.JSON(400, Error{Msg: "'text_styles' can't be combined with text_mode 'styled'!"})
|
||||
return
|
||||
}
|
||||
|
||||
for _, textStyle := range req.TextStyles {
|
||||
if !utils.IsValidTextStyle(textStyle) {
|
||||
c.JSON(400, Error{Msg: "Invalid text style '" + textStyle + "' - expected format is 'start:length:STYLE' (e.g. '0:5:BOLD')"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// the default text mode doesn't apply when the text styles are passed directly
|
||||
textMode := req.TextMode
|
||||
if textMode == nil {
|
||||
if textMode == nil && len(req.TextStyles) == 0 {
|
||||
defaultSignalTextMode := utils.GetEnv("DEFAULT_SIGNAL_TEXT_MODE", "normal")
|
||||
if defaultSignalTextMode == "styled" {
|
||||
styledStr := "styled"
|
||||
@ -564,7 +578,7 @@ func (a *Api) SendV2(c *gin.Context) {
|
||||
data, err := a.signalClient.SendV2(
|
||||
req.Number, req.Message, req.Recipients, req.Base64Attachments, req.Sticker,
|
||||
req.Mentions, req.QuoteTimestamp, req.QuoteAuthor, req.QuoteMessage, req.QuoteMentions,
|
||||
textMode, req.EditTimestamp, req.NotifySelf, req.LinkPreview, req.ViewOnce)
|
||||
textMode, req.TextStyles, req.EditTimestamp, req.NotifySelf, req.LinkPreview, req.ViewOnce)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *client.RateLimitErrorType:
|
||||
|
||||
@ -501,8 +501,8 @@ func (s *SignalClient) send(signalCliSendRequest ds.SignalCliSendRequest) (*ds.S
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signalCliTextFormatStrings := []string{}
|
||||
if signalCliSendRequest.TextMode != nil && *signalCliSendRequest.TextMode == "styled" {
|
||||
signalCliTextFormatStrings := signalCliSendRequest.TextStyles
|
||||
if len(signalCliTextFormatStrings) == 0 && signalCliSendRequest.TextMode != nil && *signalCliSendRequest.TextMode == "styled" {
|
||||
textstyleParser := utils.NewTextstyleParser(signalCliSendRequest.Message)
|
||||
signalCliSendRequest.Message, signalCliTextFormatStrings = textstyleParser.Parse()
|
||||
}
|
||||
@ -954,7 +954,7 @@ func (s *SignalClient) getJsonRpc2Clients() []*JsonRpc2Client {
|
||||
}
|
||||
|
||||
func (s *SignalClient) SendV2(number string, message string, recps []string, base64Attachments []string, sticker string, mentions []ds.MessageMention,
|
||||
quoteTimestamp *int64, quoteAuthor *string, quoteMessage *string, quoteMentions []ds.MessageMention, textMode *string, editTimestamp *int64, notifySelf *bool,
|
||||
quoteTimestamp *int64, quoteAuthor *string, quoteMessage *string, quoteMentions []ds.MessageMention, textMode *string, textStyles []string, editTimestamp *int64, notifySelf *bool,
|
||||
linkPreview *ds.LinkPreviewType, viewOnce *bool) (*[]ds.SendMessageResponse, error) {
|
||||
if len(recps) == 0 {
|
||||
return nil, errors.New("Please provide at least one recipient")
|
||||
@ -1006,7 +1006,7 @@ func (s *SignalClient) SendV2(number string, message string, recps []string, bas
|
||||
signalCliSendRequest := ds.SignalCliSendRequest{Number: number, Message: message, Recipients: []string{group}, Base64Attachments: base64Attachments,
|
||||
RecipientType: ds.Group, Sticker: sticker, Mentions: mentions, QuoteTimestamp: quoteTimestamp,
|
||||
QuoteAuthor: quoteAuthor, QuoteMessage: quoteMessage, QuoteMentions: quoteMentions,
|
||||
TextMode: textMode, EditTimestamp: editTimestamp, NotifySelf: notifySelf, LinkPreview: linkPreview, ViewOnce: viewOnce}
|
||||
TextMode: textMode, TextStyles: textStyles, EditTimestamp: editTimestamp, NotifySelf: notifySelf, LinkPreview: linkPreview, ViewOnce: viewOnce}
|
||||
resp, err := s.send(signalCliSendRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -1018,7 +1018,7 @@ func (s *SignalClient) SendV2(number string, message string, recps []string, bas
|
||||
signalCliSendRequest := ds.SignalCliSendRequest{Number: number, Message: message, Recipients: numbers, Base64Attachments: base64Attachments,
|
||||
RecipientType: ds.Number, Sticker: sticker, Mentions: mentions, QuoteTimestamp: quoteTimestamp,
|
||||
QuoteAuthor: quoteAuthor, QuoteMessage: quoteMessage, QuoteMentions: quoteMentions,
|
||||
TextMode: textMode, EditTimestamp: editTimestamp, NotifySelf: notifySelf, LinkPreview: linkPreview, ViewOnce: viewOnce}
|
||||
TextMode: textMode, TextStyles: textStyles, EditTimestamp: editTimestamp, NotifySelf: notifySelf, LinkPreview: linkPreview, ViewOnce: viewOnce}
|
||||
resp, err := s.send(signalCliSendRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -1030,7 +1030,7 @@ func (s *SignalClient) SendV2(number string, message string, recps []string, bas
|
||||
signalCliSendRequest := ds.SignalCliSendRequest{Number: number, Message: message, Recipients: usernames, Base64Attachments: base64Attachments,
|
||||
RecipientType: ds.Username, Sticker: sticker, Mentions: mentions, QuoteTimestamp: quoteTimestamp,
|
||||
QuoteAuthor: quoteAuthor, QuoteMessage: quoteMessage, QuoteMentions: quoteMentions,
|
||||
TextMode: textMode, EditTimestamp: editTimestamp, NotifySelf: notifySelf, LinkPreview: linkPreview, ViewOnce: viewOnce}
|
||||
TextMode: textMode, TextStyles: textStyles, EditTimestamp: editTimestamp, NotifySelf: notifySelf, LinkPreview: linkPreview, ViewOnce: viewOnce}
|
||||
resp, err := s.send(signalCliSendRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -47,6 +47,7 @@ type SignalCliSendRequest struct {
|
||||
QuoteMessage *string
|
||||
QuoteMentions []MessageMention
|
||||
TextMode *string
|
||||
TextStyles []string
|
||||
EditTimestamp *int64
|
||||
NotifySelf *bool
|
||||
LinkPreview *LinkPreviewType
|
||||
|
||||
@ -468,6 +468,16 @@ const docTemplate = `{
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"text_styles": {
|
||||
"example": [
|
||||
"0:5:BOLD",
|
||||
"10:3:ITALIC"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"view_once": {
|
||||
"type": "boolean"
|
||||
}
|
||||
@ -5113,7 +5123,7 @@ const docTemplate = `{
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\` + "`" + `monospace\\` + "`" + `. If you want to escape a formatting character, prefix it with two backslashes.",
|
||||
"description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\` + "`" + `monospace\\` + "`" + `. If you want to escape a formatting character, prefix it with two backslashes. Alternatively, pass the styles directly via text_styles in signal-cli's 'start:length:STYLE' format (STYLE is one of BOLD, ITALIC, SPOILER, STRIKETHROUGH, MONOSPACE); text_styles can't be combined with text_mode 'styled'.",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Input Data",
|
||||
|
||||
@ -463,6 +463,16 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"text_styles": {
|
||||
"example": [
|
||||
"0:5:BOLD",
|
||||
"10:3:ITALIC"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"view_once": {
|
||||
"type": "boolean"
|
||||
}
|
||||
@ -5108,7 +5118,7 @@
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\`monospace\\`. If you want to escape a formatting character, prefix it with two backslashes.",
|
||||
"description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: \\*italic text\\*, \\*\\*bold text\\*\\*, ~strikethrough text~, ||spoiler||, \\`monospace\\`. If you want to escape a formatting character, prefix it with two backslashes. Alternatively, pass the styles directly via text_styles in signal-cli's 'start:length:STYLE' format (STYLE is one of BOLD, ITALIC, SPOILER, STRIKETHROUGH, MONOSPACE); text_styles can't be combined with text_mode 'styled'.",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Input Data",
|
||||
|
||||
@ -2,6 +2,7 @@ package utils
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf16"
|
||||
"unicode/utf8"
|
||||
)
|
||||
@ -28,6 +29,20 @@ const (
|
||||
|
||||
const EscapeCharacter rune = '\\'
|
||||
|
||||
// IsValidTextStyle checks a signal-cli text style in the format start:length:STYLE
|
||||
func IsValidTextStyle(textStyle string) bool {
|
||||
parts := strings.SplitN(textStyle, ":", 3)
|
||||
if len(parts) != 3 {
|
||||
return false
|
||||
}
|
||||
for _, num := range parts[:2] {
|
||||
if _, err := strconv.ParseUint(num, 10, 32); err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return StringInSlice(parts[2], []string{Bold, Italic, Monospace, Strikethrough, Spoiler})
|
||||
}
|
||||
|
||||
func getUtf16StringLength(s string) int {
|
||||
runes := []rune(s) //turn string to slice
|
||||
|
||||
|
||||
@ -163,3 +163,16 @@ func TestBoldItalic(t *testing.T) {
|
||||
expectMessageEqual(t, message, "Bold Italic Text")
|
||||
expectFormatStringsEqual(t, signalCliFormatStrings, []string{"0:16:BOLD", "0:16:ITALIC"})
|
||||
}
|
||||
|
||||
func TestIsValidTextStyle(t *testing.T) {
|
||||
for _, textStyle := range []string{"0:5:BOLD", "10:3:ITALIC", "2:1:SPOILER", "0:4:STRIKETHROUGH", "7:2:MONOSPACE"} {
|
||||
if !IsValidTextStyle(textStyle) {
|
||||
t.Errorf("expected %q to be valid", textStyle)
|
||||
}
|
||||
}
|
||||
for _, textStyle := range []string{"", "foo", "0:5", "0:5:bold", "0:5:NORMAL", "-1:5:BOLD", "+1:5:BOLD", "a:5:BOLD", "0:5:BOLD:X"} {
|
||||
if IsValidTextStyle(textStyle) {
|
||||
t.Errorf("expected %q to be invalid", textStyle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user