summaryrefslogtreecommitdiff
path: root/internal/platforms
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-10-27 11:51:09 +0200
committerPaul Buetow <paul@buetow.org>2024-10-27 11:51:09 +0200
commit42f41d6def543e596a68b2ac1d9836913b51f86f (patch)
tree38697aa765687689f640a443b204cdcfd681e496 /internal/platforms
parentf9a1a4dd6f154c08f308431b821cc23e5dac8942 (diff)
also include the preview in the prompt
Diffstat (limited to 'internal/platforms')
-rw-r--r--internal/platforms/linkedin/escapes.go48
-rw-r--r--internal/platforms/linkedin/linkedin.go23
-rw-r--r--internal/platforms/linkedin/preview.go80
3 files changed, 93 insertions, 58 deletions
diff --git a/internal/platforms/linkedin/escapes.go b/internal/platforms/linkedin/escapes.go
index 6c18a76..5f803a5 100644
--- a/internal/platforms/linkedin/escapes.go
+++ b/internal/platforms/linkedin/escapes.go
@@ -1,11 +1,7 @@
package linkedin
import (
- "fmt"
- "net/http"
"strings"
-
- "golang.org/x/net/html"
)
// https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/little-text-format?view=li-lms-2024-01#language-grammar
@@ -41,47 +37,3 @@ func escapeLinkedInText(input string) string {
return builder.String()
}
-
-// fetchTitle fetches the HTML page at the given URL and returns the content of the <title> tag.
-func fetchTitle(url string) (string, error) {
- // Send a GET request to the URL
- resp, err := http.Get(url)
- if err != nil {
- return "", fmt.Errorf("failed to get URL: %v", err)
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- return "", fmt.Errorf("failed to get a successful response: %v", resp.StatusCode)
- }
-
- // Parse the HTML document
- doc, err := html.Parse(resp.Body)
- if err != nil {
- return "", fmt.Errorf("failed to parse HTML: %v", err)
- }
-
- // Traverse the document and find the <title> tag
- var title string
- var f func(*html.Node)
- f = func(n *html.Node) {
- if n.Type == html.ElementNode && n.Data == "title" {
- if n.FirstChild != nil {
- title = n.FirstChild.Data
- }
- return
- }
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- f(c)
- }
- }
-
- // Call the function to search for the title
- f(doc)
-
- if title == "" {
- return "", fmt.Errorf("no title element found")
- }
-
- return title, nil
-}
diff --git a/internal/platforms/linkedin/linkedin.go b/internal/platforms/linkedin/linkedin.go
index a6507a3..6646937 100644
--- a/internal/platforms/linkedin/linkedin.go
+++ b/internal/platforms/linkedin/linkedin.go
@@ -48,7 +48,14 @@ func post(ctx context.Context, args config.Args, sizeLimit int, ent entry.Entry)
return err
}
- question := fmt.Sprintf("Do you want to post this message to Linkedin (URLs: %v)?", urls)
+ newCtx, cancel = context.WithTimeout(ctx, linkedInTimeout)
+ defer cancel()
+ prev, err := NewPreview(newCtx, urls)
+ if err != nil {
+ return err
+ }
+
+ question := fmt.Sprintf("Do you want to post this message to Linkedin (%v)?", prev)
if err := prompt.DoYouWantThis(question, content); err != nil {
if errors.Is(err, prompt.ErrEditContent) {
if err := ent.Edit(); err != nil {
@@ -61,10 +68,10 @@ func post(ctx context.Context, args config.Args, sizeLimit int, ent entry.Entry)
newCtx, cancel = context.WithTimeout(ctx, linkedInTimeout)
defer cancel()
- return callLinkedInAPI(newCtx, personID, accessToken, content, urls)
+ return callLinkedInAPI(newCtx, personID, accessToken, content, prev)
}
-func callLinkedInAPI(ctx context.Context, personID, accessToken, content string, urls []string) error {
+func callLinkedInAPI(ctx context.Context, personID, accessToken, content string, prev preview) error {
const url = "https://api.linkedin.com/rest/posts"
post := map[string]interface{}{
@@ -80,15 +87,11 @@ func callLinkedInAPI(ctx context.Context, personID, accessToken, content string,
"isReshareDisabledByAuthor": false,
}
- if len(urls) > 0 {
- title, err := fetchTitle(urls[0])
- if err != nil {
- return err
- }
+ if !prev.Empty() {
post["content"] = map[string]interface{}{
"article": map[string]interface{}{
- "title": title,
- "source": urls[0],
+ "title": prev.title,
+ "source": prev.url,
},
}
}
diff --git a/internal/platforms/linkedin/preview.go b/internal/platforms/linkedin/preview.go
new file mode 100644
index 0000000..3d2b556
--- /dev/null
+++ b/internal/platforms/linkedin/preview.go
@@ -0,0 +1,80 @@
+package linkedin
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+
+ "golang.org/x/net/html"
+)
+
+type preview struct {
+ title, url string
+}
+
+func NewPreview(ctx context.Context, urls []string) (preview, error) {
+ if len(urls) == 0 {
+ return preview{}, nil
+ }
+ title, err := fetchTitle(ctx, urls[0])
+ if err == nil && title == "" {
+ title = urls[0]
+ }
+ return preview{title: title, url: urls[0]}, err
+}
+
+func (p preview) String() string {
+ return fmt.Sprintf("Title: %s; URL: %s", p.title, p.url)
+}
+
+func (p preview) Empty() bool {
+ return p.url == ""
+}
+
+// fetchTitle fetches the HTML page at the given URL and returns the content of the <title> tag.
+func fetchTitle(ctx context.Context, url string) (string, error) {
+ req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
+ if err != nil {
+ return "", fmt.Errorf("failed to create request: %v", err)
+ }
+
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return "", fmt.Errorf("failed to get URL: %v", err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ return "", fmt.Errorf("failed to get a successful response: %v", resp.StatusCode)
+ }
+
+ // Parse the HTML document
+ doc, err := html.Parse(resp.Body)
+ if err != nil {
+ return "", fmt.Errorf("failed to parse HTML: %v", err)
+ }
+
+ // Traverse the document and find the <title> tag
+ var title string
+ var f func(*html.Node)
+ f = func(n *html.Node) {
+ if n.Type == html.ElementNode && n.Data == "title" {
+ if n.FirstChild != nil {
+ title = n.FirstChild.Data
+ }
+ return
+ }
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
+ f(c)
+ }
+ }
+
+ // Call the function to search for the title
+ f(doc)
+
+ if title == "" {
+ return "", fmt.Errorf("no title element found")
+ }
+
+ return title, nil
+}