summaryrefslogtreecommitdiff
path: root/internal/platforms/linkedin/linkedin.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-17 22:03:10 +0200
committerPaul Buetow <paul@buetow.org>2026-02-17 22:03:10 +0200
commit5f53f241189af3fceb26395af383809cd4fa3bf0 (patch)
tree4ffabc358ec85ed1da425f72e1357e80f340b2c1 /internal/platforms/linkedin/linkedin.go
parenta8cb28d2257cff652fc4f8a9768b66b9d69fd68a (diff)
fix: improve LinkedIn API posting and authenticationv1.2.4
- Add token validation before using cached credentials to prevent stale token issues - Add proper error handling for image upload initialization with helpful 426 messages - Skip data URI images instead of attempting to download them - Update default LinkedIn API version to 202601 (January 2026) - latest active version - Fix re-authentication flow for expired tokens Amp-Thread-ID: https://ampcode.com/threads/T-019c6d28-4526-7738-b593-9bd584baa478 Co-authored-by: Amp <amp@ampcode.com>
Diffstat (limited to 'internal/platforms/linkedin/linkedin.go')
-rw-r--r--internal/platforms/linkedin/linkedin.go27
1 files changed, 23 insertions, 4 deletions
diff --git a/internal/platforms/linkedin/linkedin.go b/internal/platforms/linkedin/linkedin.go
index 11291fb..16688d5 100644
--- a/internal/platforms/linkedin/linkedin.go
+++ b/internal/platforms/linkedin/linkedin.go
@@ -27,9 +27,10 @@ func addCommonHeaders(req *http.Request, accessToken, liVersion string) {
req.Header.Set("Authorization", "Bearer "+accessToken)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-RestLi-Protocol-Version", "2.0.0")
- if liVersion != "" {
- req.Header.Set("LinkedIn-Version", liVersion)
+ if liVersion == "" {
+ liVersion = "202601" // Default to latest stable version
}
+ req.Header.Set("LinkedIn-Version", liVersion)
}
func Post(ctx context.Context, args config.Args, sizeLimit int, en entry.Entry) error {
@@ -147,7 +148,7 @@ func postMessageToLinkedInAPI(ctx context.Context, personID, accessToken, conten
} else if resp.StatusCode == http.StatusUpgradeRequired {
// 426 often indicates a non-active LinkedIn-Version header.
// Provide a clear hint to configure a valid version.
- err = fmt.Errorf("%w; LinkedIn API version likely inactive. Set an active 'LinkedInVersion' in config (e.g. 202502) or remove to use default. Response: %s", err, string(body))
+ err = fmt.Errorf("%w; LinkedIn API version likely inactive. Set an active 'LinkedInVersion' in config (e.g. 202601) or remove to use default. Response: %s", err, string(body))
}
}
return err
@@ -191,6 +192,24 @@ func initializeImageUpload(ctx context.Context, personURN, accessToken string, l
}
defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return "", "", fmt.Errorf("error reading response: %w", err)
+ }
+
+ if resp.StatusCode != http.StatusOK {
+ err := fmt.Errorf("image upload initialization failed. Status: %s\n%s\n",
+ resp.Status, string(body))
+ if resp.StatusCode == http.StatusUnauthorized {
+ err = errors.Join(err, errUnauthorized)
+ } else if resp.StatusCode == http.StatusUpgradeRequired {
+ // 426 often indicates a non-active LinkedIn-Version header.
+ // Provide a clear hint to configure a valid version.
+ err = fmt.Errorf("%w; LinkedIn API version likely inactive. Set an active 'LinkedInVersion' in config (e.g. 202601) or remove to use default. Response: %s", err, string(body))
+ }
+ return "", "", err
+ }
+
type InitializeUploadResponse struct {
Value struct {
UploadURL string `json:"uploadUrl"`
@@ -198,7 +217,7 @@ func initializeImageUpload(ctx context.Context, personURN, accessToken string, l
} `json:"value"`
}
var response InitializeUploadResponse
- if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
+ if err := json.Unmarshal(body, &response); err != nil {
return "", "", fmt.Errorf("error decoding response: %w", err)
}