summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-10-19 21:02:14 +0300
committerPaul Buetow <paul@buetow.org>2024-10-19 21:02:14 +0300
commite02dcb943263da2fa701a7aba96b5dc41c14ffe0 (patch)
treeca34f499a37f39a65bb239f632057698141e1dec
parentc072a8a06c9634948497f4ef5e69b832c80be195 (diff)
fix linkedin escapes
-rw-r--r--internal/platforms/linkedin/escapes.go39
-rw-r--r--internal/platforms/linkedin/escapes_test.go15
-rw-r--r--internal/platforms/linkedin/linkedin.go13
-rw-r--r--internal/platforms/mastodon/mastodon.go7
-rw-r--r--internal/schedule/schedule.go2
5 files changed, 70 insertions, 6 deletions
diff --git a/internal/platforms/linkedin/escapes.go b/internal/platforms/linkedin/escapes.go
new file mode 100644
index 0000000..5f803a5
--- /dev/null
+++ b/internal/platforms/linkedin/escapes.go
@@ -0,0 +1,39 @@
+package linkedin
+
+import (
+ "strings"
+)
+
+// https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/little-text-format?view=li-lms-2024-01#language-grammar
+func escapeLinkedInText(input string) string {
+ var builder strings.Builder
+
+ reservedChars := map[rune]string{
+ '"': "\\\"",
+ '|': "\\|",
+ '{': "\\{",
+ '}': "\\}",
+ // '@': "\\@",
+ '[': "\\[",
+ ']': "\\]",
+ '(': "\\(",
+ ')': "\\)",
+ '<': "\\<",
+ '>': "\\>",
+ //'#': "\\#",
+ '\\': "\\\\",
+ '*': "\\*",
+ '_': "\\_",
+ '~': "\\~",
+ }
+
+ for _, char := range input {
+ if escapeSeq, ok := reservedChars[char]; ok {
+ builder.WriteString(escapeSeq)
+ } else {
+ builder.WriteRune(char)
+ }
+ }
+
+ return builder.String()
+}
diff --git a/internal/platforms/linkedin/escapes_test.go b/internal/platforms/linkedin/escapes_test.go
new file mode 100644
index 0000000..b1f9203
--- /dev/null
+++ b/internal/platforms/linkedin/escapes_test.go
@@ -0,0 +1,15 @@
+package linkedin
+
+import (
+ "testing"
+)
+
+func TestLinkedInEscapes(t *testing.T) {
+ var (
+ input = `This is a test message with special characters: " {} @ [] () <> # \ * _ ~ |`
+ expected = `This is a test message with special characters: \" \{\} @ \[\] \(\) \<\> # \\ \* \_ \~ \|`
+ )
+ if escaped := escapeLinkedInText(input); escaped != expected {
+ t.Errorf("expected '%s' but got '%s'", expected, escaped)
+ }
+}
diff --git a/internal/platforms/linkedin/linkedin.go b/internal/platforms/linkedin/linkedin.go
index c283fbc..f6d89f5 100644
--- a/internal/platforms/linkedin/linkedin.go
+++ b/internal/platforms/linkedin/linkedin.go
@@ -14,6 +14,7 @@ import (
"codeberg.org/snonux/gos/internal/entry"
"codeberg.org/snonux/gos/internal/platforms/linkedin/oauth2"
"codeberg.org/snonux/gos/internal/prompt"
+ "github.com/fatih/color"
)
var errUnauthorized = errors.New("unauthorized access, refresh or create token?")
@@ -58,7 +59,7 @@ func callLinkedInAPI(ctx context.Context, personID, accessToken, content string)
post := map[string]interface{}{
"author": fmt.Sprintf("urn:li:person:%s", personID),
- "commentary": content, // TODO: Can't post (...) paretenthesis? escape them? TEST AGAIN!
+ "commentary": escapeLinkedInText(content),
"visibility": "PUBLIC",
"distribution": map[string]interface{}{
"feedDistribution": "MAIN_FEED",
@@ -88,15 +89,17 @@ func callLinkedInAPI(ctx context.Context, personID, accessToken, content string)
return fmt.Errorf("Error sending request: %w", err)
}
defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+ color.Cyan(string(body))
if resp.StatusCode != http.StatusCreated {
- body, _ := io.ReadAll(resp.Body)
- err = fmt.Errorf("failed to post to LinkedIn. Status: %s\n%s\n", resp.Status, body)
+ err = fmt.Errorf("failed to post to LinkedIn. Status: %s\n", resp.Status)
if resp.StatusCode == http.StatusUnauthorized {
err = errors.Join(err, errUnauthorized)
}
}
return err
}
-
-// TODO: Implement Gemini output?
diff --git a/internal/platforms/mastodon/mastodon.go b/internal/platforms/mastodon/mastodon.go
index f582b4c..0a87d74 100644
--- a/internal/platforms/mastodon/mastodon.go
+++ b/internal/platforms/mastodon/mastodon.go
@@ -6,12 +6,14 @@ import (
"encoding/json"
"errors"
"fmt"
+ "io"
"log"
"net/http"
"codeberg.org/snonux/gos/internal/config"
"codeberg.org/snonux/gos/internal/entry"
"codeberg.org/snonux/gos/internal/prompt"
+ "github.com/fatih/color"
)
func Post(ctx context.Context, args config.Args, sizeLimit int, ent entry.Entry) error {
@@ -51,6 +53,11 @@ func Post(ctx context.Context, args config.Args, sizeLimit int, ent entry.Entry)
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+ color.Cyan(string(body))
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
diff --git a/internal/schedule/schedule.go b/internal/schedule/schedule.go
index 5512e4d..be2b6f8 100644
--- a/internal/schedule/schedule.go
+++ b/internal/schedule/schedule.go
@@ -26,7 +26,7 @@ func Run(args config.Args, platform string) (entry.Entry, error) {
}
log.Println("For", platform, "stats:", stats)
- if stats.targetHit() {
+ if stats.targetHit(args.PauseDays) {
return entry.Zero, ErrNothingToSchedule
}