summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--internal/platforms/linkedin/linkedin.go21
-rw-r--r--internal/platforms/linkedin/oauth2/oauth2.go (renamed from gosdir/db/platforms/linkedin/oauth2/oauth2.go)61
3 files changed, 49 insertions, 37 deletions
diff --git a/.gitignore b/.gitignore
index e5b047f..9ac4315 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-gosdir
-gos
+./gosdir
+./gos
diff --git a/internal/platforms/linkedin/linkedin.go b/internal/platforms/linkedin/linkedin.go
index 6205234..768def5 100644
--- a/internal/platforms/linkedin/linkedin.go
+++ b/internal/platforms/linkedin/linkedin.go
@@ -6,31 +6,34 @@ import (
"encoding/json"
"fmt"
"io"
- "log"
"net/http"
- "codeberg.org/snonux/gos/gosdir/db/platforms/linkedin/oauth2"
"codeberg.org/snonux/gos/internal/config"
"codeberg.org/snonux/gos/internal/entry"
+ "codeberg.org/snonux/gos/internal/platforms/linkedin/oauth2"
)
// TODO: Also implemebt a Text Platform output, which then laster can be
// processed by Gemtexter as a page
func Post(ctx context.Context, args config.Args, ent entry.Entry) error {
- secrets, err := oauth2.AccessToken(args)
+ content, err := ent.Content()
+ if err != nil {
+ return nil
+ }
+
+ personID, accessToken, err := oauth2.LinkedInOauth2Creds(args)
if err != err {
return err
}
- // TODO: Don't log this anymore
- log.Println("DEBUG", "Got access token", secrets)
- return nil
+
+ return post(personID, accessToken, content)
}
-func postMessage(secrets config.Secrets, message string) error {
+func post(personID, accessToken, message string) error {
const url = "https://api.linkedin.com/v2/posts"
post := map[string]interface{}{
- "author": fmt.Sprintf("urn:li:person:%s", secrets.LinkedInPesonID),
+ "author": fmt.Sprintf("urn:li:person:%s", personID),
"commentary": message,
"visibility": "PUBLIC",
"distribution": map[string]interface{}{
@@ -52,7 +55,7 @@ func postMessage(secrets config.Secrets, message string) error {
return fmt.Errorf("Error creating request: %w", err)
}
- req.Header.Add("Authorization", "Bearer "+secrets.LinkedInAccessToken)
+ req.Header.Add("Authorization", "Bearer "+accessToken)
req.Header.Set("Content-Type", "application/json")
req.Header.Add("X-RestLi-Protocol-Version", "2.0.0")
diff --git a/gosdir/db/platforms/linkedin/oauth2/oauth2.go b/internal/platforms/linkedin/oauth2/oauth2.go
index cf3adf5..6a692b3 100644
--- a/gosdir/db/platforms/linkedin/oauth2/oauth2.go
+++ b/internal/platforms/linkedin/oauth2/oauth2.go
@@ -3,6 +3,7 @@ package oauth2
import (
"context"
"encoding/json"
+ "errors"
"fmt"
"io"
"log"
@@ -15,11 +16,12 @@ import (
var (
oauthConfig *oauth2.Config
- oauthPersonId string
oauthAccessToken string
+ oauthPersonID string
+ errCh chan error
)
-func getLinkedInID(token *oauth2.Token) (string, error) {
+func getOauthPersonID(token *oauth2.Token) (string, error) {
const url = "https://api.linkedin.com/v2/userinfo"
req, err := http.NewRequest("GET", url, nil)
@@ -59,54 +61,61 @@ func oauthIndexHandler(w http.ResponseWriter, r *http.Request) {
}
func oauthCallbackHandler(w http.ResponseWriter, r *http.Request) {
+ defer close(errCh)
code := r.URL.Query().Get("code")
token, err := oauthConfig.Exchange(context.Background(), code)
if err != nil {
- http.Error(w, "Failed to exchange token", http.StatusInternalServerError)
- return
- }
-
- linkedInID, err := getLinkedInID(token)
- if err != nil {
- fmt.Println(err)
_, _ = w.Write([]byte(err.Error()))
+ errCh <- err
return
}
- _, _ = w.Write([]byte("Successfully fetched the LinkedInID\n"))
+ oauthAccessToken = token.AccessToken
+ _, _ = w.Write([]byte("Successfully fetched LinkedIn access token\n"))
- if err := postMessage(token, linkedInID, "test"); err != nil {
- fmt.Println(err)
+ if oauthPersonID, err = getOauthPersonID(token); err != nil {
_, _ = w.Write([]byte(err.Error()))
+ errCh <- err
return
}
- _, _ = w.Write([]byte("Successfully posted a message to LinkedIn!\n"))
+ _, _ = w.Write([]byte("Successfully fetched LinkedIn person ID\n"))
}
-// TODO: Fetch the access token and user ID and store it i na file in .config/gos/...
-// TODO: Separate posting of the message and fetching of the userID and access token
-func AccessToken(args config.Args) (config.Secrets, error) {
- if args.Secrets.LinkedInAccessToken != "" && args.Secrets.LinkedInPersonID != "" {
+func LinkedInOauth2Creds(args config.Args) (string, string, error) {
+ secrets := args.Secrets
+ if secrets.LinkedInAccessToken != "" && secrets.LinkedInPersonID != "" {
// TODO: Check, whether the access token is still valid. If not, get a new one.
- return args.Secrets, nil
+ return secrets.LinkedInPersonID, secrets.MastodonAccessToken, nil
}
oauthConfig = &oauth2.Config{
- ClientID: args.Secrets.LinkedInClientID,
- ClientSecret: args.Secrets.LinkedInSecret,
- RedirectURL: args.Secrets.LinkedInRedirectURL,
+ ClientID: secrets.LinkedInClientID,
+ ClientSecret: secrets.LinkedInSecret,
+ RedirectURL: secrets.LinkedInRedirectURL,
Scopes: []string{"openid", "profile", "w_member_social"},
Endpoint: linkedin.Endpoint,
}
+ errCh := make(chan error)
http.HandleFunc("/", oauthIndexHandler)
http.HandleFunc("/callback", oauthCallbackHandler)
- log.Println("Listening on http://localhost:8080 for LinkedIn oauth2")
- err := http.ListenAndServe(":8080", nil)
+ go func() {
+ log.Println("Listening on http://localhost:8080 for LinkedIn oauth2")
+ if err := http.ListenAndServe(":8080", nil); err != nil {
+ errCh <- err
+ }
+ }()
- args.Secrets.MastodonAccessToken = oauthAccessToken
- args.Secrets.LinkedInPersonID = oauthPersonId
+ var errs error
+ for err := range errCh {
+ errs = errors.Join(errs, err)
+ }
+ if errs != nil {
+ return "", "", errs
+ }
- return args.Secrets, err
+ secrets.MastodonAccessToken = oauthAccessToken
+ secrets.LinkedInPersonID = oauthPersonID
+ return oauthPersonID, oauthAccessToken, secrets.WriteToDisk(args.SecretsConfigPath)
}