diff --git a/pkg/interact/telegram.go b/pkg/interact/telegram.go index 68f341f5b..deba77053 100644 --- a/pkg/interact/telegram.go +++ b/pkg/interact/telegram.go @@ -5,8 +5,8 @@ import ( "fmt" "strings" "time" - "unicode/utf8" + "github.com/c9s/bbgo/pkg/util" log "github.com/sirupsen/logrus" "golang.org/x/time/rate" "gopkg.in/tucnak/telebot.v2" @@ -68,14 +68,13 @@ type TelegramReply struct { } func (r *TelegramReply) Send(message string) { - var left, right int - for left, right = 0, maxMessageSize; right < len(message); left, right = right, right+maxMessageSize { - for !utf8.RuneStart(message[right]) { - right-- + splits := util.StringSplitByLength(message, maxMessageSize) + for _, split := range splits { + if err := sendLimiter.Wait(ctx); err != nil { + log.WithError(err).Errorf("telegram send limit exceeded") } - checkSendErr(r.bot.Send(r.session.Chat, message[left:right])) + checkSendErr(r.bot.Send(r.session.Chat, split)) } - checkSendErr(r.bot.Send(r.session.Chat, message[left:])) } func (r *TelegramReply) Message(message string) { @@ -171,23 +170,17 @@ func (tm *Telegram) Start(ctx context.Context) { if reply.set { reply.build() if len(reply.message) > 0 || reply.menu != nil { - var left, right int - for left, right = 0, maxMessageSize; right < len(reply.message); left, right = right, right+maxMessageSize { - for !utf8.RuneStart(reply.message[right]) { - right-- - } + splits := util.StringSplitByLength(reply.message, maxMessageSize) + for i, split := range splits { if err := sendLimiter.Wait(ctx); err != nil { log.WithError(err).Errorf("telegram send limit exceeded") } - checkSendErr(tm.Bot.Send(m.Chat, reply.message[left:right])) - - } - if left < len(reply.message) { - if err := sendLimiter.Wait(ctx); err != nil { - log.WithError(err).Errorf("telegram send limit exceeded") + if i == len(splits)-1 { + // only set menu on the last message + checkSendErr(tm.Bot.Send(m.Chat, split, reply.menu)) + } else { + checkSendErr(tm.Bot.Send(m.Chat, split)) } - // only set menu on the last message - checkSendErr(tm.Bot.Send(m.Chat, reply.message[left:], reply.menu)) } } } diff --git a/pkg/util/string.go b/pkg/util/string.go index 268233acb..af3b25bf4 100644 --- a/pkg/util/string.go +++ b/pkg/util/string.go @@ -1,6 +1,9 @@ package util -import "strings" +import ( + "strings" + "unicode/utf8" +) func StringSliceContains(slice []string, needle string) bool { for _, s := range slice { @@ -27,3 +30,17 @@ func MaskKey(key string) string { maskKey += key[len(key)-h:] return maskKey } + +func StringSplitByLength(s string, length int) (result []string) { + var left, right int + for left, right = 0, length; right < len(s); left, right = right, right+length { + for !utf8.RuneStart(s[right]) { + right-- + } + result = append(result, s[left:right]) + } + if len(s)-left > 0 { + result = append(result, s[left:]) + } + return result +} diff --git a/pkg/util/string_test.go b/pkg/util/string_test.go index 7d55f425a..4f09a3a26 100644 --- a/pkg/util/string_test.go +++ b/pkg/util/string_test.go @@ -1,6 +1,10 @@ package util -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/assert" +) func TestMaskKey(t *testing.T) { type args struct { @@ -40,3 +44,10 @@ func TestMaskKey(t *testing.T) { }) } } + +func TestStringSplitByLength(t *testing.T) { + result := StringSplitByLength("1234567890", 3) + assert.Equal(t, result, []string{"123", "456", "789", "0"}) + result = StringSplitByLength("123許456", 4) + assert.Equal(t, result, []string{"123", "許4", "56"}) +}