summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-10-27 10:53:32 +0200
committerPaul Buetow <paul@buetow.org>2024-10-27 10:53:32 +0200
commit063d630bc1acbaaf1b9743a33bef559601b117d3 (patch)
tree96a9e6197f48e3d031945ed2bc033d5e1f904db6
parent0144d8d5840c9b7b5c2829870c5c64cf325a4528 (diff)
can share an article with preview text of the title
-rw-r--r--go.mod3
-rw-r--r--go.sum4
-rw-r--r--internal/platforms/linkedin/escapes.go48
-rw-r--r--internal/platforms/linkedin/linkedin.go15
4 files changed, 67 insertions, 3 deletions
diff --git a/go.mod b/go.mod
index 563eb4f..1b14607 100644
--- a/go.mod
+++ b/go.mod
@@ -11,5 +11,6 @@ require (
github.com/fatih/color v1.17.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
- golang.org/x/sys v0.18.0 // indirect
+ golang.org/x/net v0.30.0 // indirect
+ golang.org/x/sys v0.26.0 // indirect
)
diff --git a/go.sum b/go.sum
index 9f05b15..5f0b1c1 100644
--- a/go.sum
+++ b/go.sum
@@ -11,9 +11,13 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
+golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
diff --git a/internal/platforms/linkedin/escapes.go b/internal/platforms/linkedin/escapes.go
index 5f803a5..6c18a76 100644
--- a/internal/platforms/linkedin/escapes.go
+++ b/internal/platforms/linkedin/escapes.go
@@ -1,7 +1,11 @@
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
@@ -37,3 +41,47 @@ 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 ebd92b0..54752b9 100644
--- a/internal/platforms/linkedin/linkedin.go
+++ b/internal/platforms/linkedin/linkedin.go
@@ -57,7 +57,7 @@ func post(ctx context.Context, args config.Args, sizeLimit int, ent entry.Entry)
}
func callLinkedInAPI(ctx context.Context, personID, accessToken, content string, urls []string) error {
- const url = "https://api.linkedin.com/v2/posts"
+ const url = "https://api.linkedin.com/rest/posts"
post := map[string]interface{}{
"author": fmt.Sprintf("urn:li:person:%s", personID),
@@ -73,10 +73,20 @@ func callLinkedInAPI(ctx context.Context, personID, accessToken, content string,
}
if len(urls) > 0 {
- // TODO: Add media links to post structure
+ title, err := fetchTitle(urls[0])
+ if err != nil {
+ return err
+ }
+ post["content"] = map[string]interface{}{
+ "article": map[string]interface{}{
+ "title": title,
+ "source": urls[0],
+ },
+ }
}
payload, err := json.Marshal(post)
+ fmt.Println(string(payload))
if err != nil {
return fmt.Errorf("Error encoding JSON:%w", err)
}
@@ -88,6 +98,7 @@ func callLinkedInAPI(ctx context.Context, personID, accessToken, content string,
req.Header.Add("Authorization", "Bearer "+accessToken)
req.Header.Set("Content-Type", "application/json")
req.Header.Add("X-RestLi-Protocol-Version", "2.0.0")
+ req.Header.Add("LinkedIn-Version", "202409")
client := &http.Client{}
resp, err := client.Do(req)