You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+20-7Lines changed: 20 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -81,18 +81,28 @@ Persist .last-post-date only if at least one platform actually published
81
81
82
82
**Step 2 — Get your access token**
83
83
1. Go to [linkedin.com/developers/tools/oauth](https://www.linkedin.com/developers/tools/oauth)
84
-
2. Select your app, tick scopes: `w_member_social`, `openid`, `profile`
85
-
3. Tick the redirect URL checkbox → **Request access token** → copy it → `LINKEDIN_ACCESS_TOKEN`
84
+
2. If you are posting to your personal profile, tick scopes: `w_member_social`, `openid`, `profile`
85
+
3. If you are posting to a company page, your app must have organization posting access and the authenticated member must consent to `w_organization_social`
86
+
4. Tick the redirect URL checkbox → **Request access token** → copy it → `LINKEDIN_ACCESS_TOKEN`
86
87
87
88
> ⚠️ LinkedIn tokens **expire after 60 days**. Set a calendar reminder to regenerate before expiry.
Copy the `sub` value → your URN is `urn:li:person:THAT_VALUE` → `LINKEDIN_PERSON_URN`
96
+
Copy the `sub` value → your URN is `urn:li:person:THAT_VALUE` → `LINKEDIN_AUTHOR_URN`
97
+
98
+
For a company page:
99
+
1. Use the company page's numeric organization URN: `urn:li:organization:xxxxxxxx`
100
+
2. Set that value as `LINKEDIN_AUTHOR_URN`
101
+
3. Make sure the LinkedIn member who generated the token is allowed to post for that page
94
102
95
-
> To post as a company page instead: `urn:li:organization:xxxxxxxx`
103
+
> Backward compatibility: `LINKEDIN_PERSON_URN` still works, but `LINKEDIN_AUTHOR_URN` is the clearer setting going forward.
104
+
105
+
> If you use an organization URN with a token that only has `w_member_social`, LinkedIn will reject the publish request with a 403-class authorization error.
96
106
97
107
---
98
108
@@ -203,7 +213,7 @@ npm install
203
213
204
214
# 2. Configure environment
205
215
cp .env.example .env
206
-
# Fill in at minimum: ANTHROPIC_API_KEY, LINKEDIN_ACCESS_TOKEN, LINKEDIN_PERSON_URN
216
+
# Fill in at minimum: ANTHROPIC_API_KEY, LINKEDIN_ACCESS_TOKEN, LINKEDIN_AUTHOR_URN
207
217
# Recommended for first run: NEWS_NICHE=business-architect, POSTING_STYLE=business-architect
208
218
209
219
# 3. Test LinkedIn credentials first (no Claude credits needed)
@@ -233,7 +243,7 @@ Go to repo → **Settings → Secrets and variables → Actions → New reposito
233
243
|---|---|
234
244
|`ANTHROPIC_API_KEY`| Claude API key from console.anthropic.com |
|`LINKEDIN_AUTHOR_URN`|`urn:li:person:xxxxxx`for a member profile or `urn:li:organization:xxxxxx` for a company page|
237
247
238
248
#### Recommended
239
249
@@ -347,6 +357,9 @@ Set the `POST_INTERVAL_DAYS` GitHub Secret to any number of days. No code change
347
357
**Posts stopped after ~60 days**
348
358
→ LinkedIn token expired. Regenerate at [linkedin.com/developers/tools/oauth](https://www.linkedin.com/developers/tools/oauth) and update `LINKEDIN_ACCESS_TOKEN`.
349
359
360
+
**LinkedIn company-page post fails with HTTP 403**
361
+
→ `LINKEDIN_AUTHOR_URN` is set to `urn:li:organization:...` but the access token is missing org-posting permission or the authenticated member is not allowed to post for that page. Regenerate the token with `w_organization_social` and confirm the member has a valid page role.
362
+
350
363
**`AuthenticationError: invalid x-api-key`**
351
364
→ Check `ANTHROPIC_API_KEY` — must start with `sk-ant-`, no extra spaces.
return`You are writing a LinkedIn post on behalf of a senior software architect who BUILDS custom software systems for ecommerce, healthcare, and hospitality businesses. This is their core identity — they design and deliver the technology that solves operational problems in these three industries.
11
-
12
-
CRITICAL — every post must reflect this identity:
13
-
- The author is not a commentator or analyst — they are a builder and technology partner
14
-
- Frame every insight from the perspective of: "this is why businesses in [ecommerce/healthcare/hospitality] need better software — and this is what I build to solve it"
15
-
- The closing must always position the author as someone who solves this problem through software, not just someone observing it
16
-
17
-
The audience is: ecommerce founders, healthcare executives, hospitality operators, and investors evaluating technology capabilities.
18
-
19
-
The tone must be:
20
-
- Authoritative: the author has built these systems and knows the trade-offs
21
-
- Outcome-focused: connect every technology point to a business result
22
-
- Client-facing: the reader should think "this person understands my industry and could build this for us"
13
+
return`<role>
14
+
You are writing a LinkedIn post on behalf of a senior software architect who BUILDS custom software systems for ecommerce, healthcare, and hospitality businesses. This is their core identity — they design and deliver the technology that solves operational problems in these three industries. Voice: direct, no buzzwords, authoritative from hands-on experience.
15
+
</role>
23
16
24
-
Write ONLY from what you read below — never add facts not present in the content.
25
-
Write in clear natural English only. If the source material is in another language, translate the meaning into English without adding or changing facts.
- Authoritative: the author has built these systems and knows the trade-offs first-hand
36
+
- Outcome-focused: connect every technology point to a specific business result
37
+
- Client-facing: the reader should think "this person understands my industry and could build this for us"
38
+
- No filler phrases ("game-changing", "data silos", "seamless integration") unless those exact words appear in the article
39
+
</tone>
40
+
41
+
<grounding>
42
+
Write ONLY from what you read in source_material above — the author's credibility with ecommerce founders and healthcare executives depends on every claim being verifiable. Invented facts would directly damage the trust the post is trying to build.
38
43
39
-
Before writing, identify from the content above:
40
-
- The specific product name, feature name, or technology being announced (e.g. "Locale Aware Catalogs", "GPT-4o", "Kubernetes 1.30")
41
-
- One concrete statistic, number, or company name from the article (e.g. "118 of the Top 2000 retailers", "Reebok Europe")
42
-
- The exact business problem this addresses (use the article's framing, not your own)
44
+
Write in clear natural English only. If the source material is in another language, translate the meaning without adding or changing facts.
45
+
</grounding>
43
46
44
-
These 3 anchors MUST appear in your post. Do not replace them with generic phrases.
47
+
<pre_write>
48
+
Before drafting, identify these 3 anchors from source_material (do not output this section — internal reasoning only):
49
+
1. The specific product name, feature name, or technology being announced (e.g. "Locale Aware Catalogs", "Cosmos Data Platform", "OPERA Cloud 24.2")
50
+
2. One concrete statistic, number, or company name from the article (e.g. "118 of the Top 2000 retailers", "Reebok Europe", "40% reduction in manual reconciliation")
51
+
3. The exact business problem this addresses — use the article's framing, not your own
45
52
46
-
Write a LinkedIn post using this EXACT structure:
53
+
After drafting, verify: do all 3 anchors appear verbatim in your post? If any is missing, revise before outputting.
54
+
</pre_write>
55
+
56
+
<output_format>
57
+
Use this exact structure:
47
58
48
59
💡 Industry Insight — ${date}
49
60
@@ -52,28 +63,90 @@ Write a LinkedIn post using this EXACT structure:
52
63
[Body: 2 sentences. Sentence 1: what specifically is happening (name the feature/product). Sentence 2: what this means for operations. Both must be traceable directly to the article content.]
53
64
54
65
What this means for your business:
55
-
• [Specific impact — must reference something named in the article, not generic "data silos" or "API complexity"]
66
+
• [Specific impact — must reference something named in the article, not generic industry buzzwords]
56
67
• [Risk or cost of inaction — what the article says breaks or falls behind]
57
68
• [What the author builds to solve exactly this problem — this bullet can reflect the author's expertise]
58
69
59
70
[Closing: a direct question positioning the author as someone who solves this — e.g. "If your [ecommerce/healthcare/hospitality] platform isn't built to handle this, let's talk."]
60
71
61
72
Source: ${topStory.url}
73
+
</output_format>
62
74
63
-
STRICT RULES:
64
-
- Every claim must be supported by the article content above — nothing invented
75
+
<strict_rules>
76
+
- Every claim must be supported by the article content — nothing invented
65
77
- The specific product/feature name from the article MUST appear in the post
66
78
- At least one concrete statistic or company name from the article MUST appear in the post
67
-
- Use the factual anchors above as hard constraints, not inspiration
68
-
- Do NOT use generic phrases ("data silos", "fragmented builds", "evolving APIs") unless those exact words appear in the article
79
+
- Use the factual anchors as hard constraints, not inspiration
69
80
- Total post length: ${lengthRule}
70
-
- Hashtags: generate 6–10 hashtags relevant to the actual article topic and specific industry. Mix broad (#SoftwareDevelopment #DigitalTransformation) with specific topic tags. Place at the end.
71
-
- Output ONLY the post text`;
81
+
- Hashtags: generate 6–10 hashtags relevant to the actual article topic and industry. Mix broad (#SoftwareDevelopment #DigitalTransformation) with specific topic tags. Place at the end.
82
+
- Output ONLY the post text
83
+
</strict_rules>
84
+
85
+
<examples>
86
+
<example label="ecommerce">
87
+
💡 Industry Insight — March 15, 2025
88
+
89
+
Reebok Europe's catalog management broke under 14-language localization — Shopware's new Locale Aware Catalogs solve exactly what custom middleware can't.
90
+
91
+
Shopware 6.7 introduces Locale Aware Catalogs, decoupling product data from regional pricing and language rules. For multi-market retailers, this eliminates the sync failures that cause overselling and missed promotions across regions.
92
+
93
+
What this means for your business:
94
+
• Reebok Europe reduced catalog-sync errors by removing manual locale overrides — now automated per-market
95
+
• Retailers without this architecture face inventory drift during peak events like Black Friday and regional sales windows
96
+
• I build catalog and pricing layers for ecommerce platforms that handle this at scale without custom middleware
97
+
98
+
If your ecommerce platform serves more than one market and you're still patching locale mismatches manually, let's talk.
Epic's Cosmos Data Platform now aggregates de-identified records from 260 million patients — and most health systems still can't query their own data without a 3-week IT ticket.
109
+
110
+
Epic released a federated query layer inside Cosmos that lets clinical teams run population-level cohort searches without exporting to a separate analytics warehouse. For mid-size hospital networks, this closes the gap between EHR data and actual operational decisions.
111
+
112
+
What this means for your business:
113
+
• Health systems in the Cosmos network can now identify high-risk readmission cohorts in hours, not weeks — without touching raw HL7 feeds
114
+
• Facilities locked into siloed departmental reporting miss the CMS quality benchmarks tied to population health metrics
115
+
• I build clinical data integration layers for healthcare operators that surface this kind of insight without requiring a full Epic implementation or a separate data warehouse
116
+
117
+
If your care teams are still waiting on IT to pull patient cohort reports, let's talk.
Oracle OPERA Cloud 24.4 introduced real-time rate parity enforcement across OTA channels — and hotel groups running legacy PMS systems just lost another margin point without knowing it.
128
+
129
+
OPERA Cloud 24.4 added a native channel manager sync that pushes rate changes to Booking.com, Expedia, and direct booking simultaneously within 90 seconds. For full-service hotel groups, this eliminates the 4–6 hour lag where OTAs undercut direct rates during demand spikes.
130
+
131
+
What this means for your business:
132
+
• Hotel groups on OPERA Cloud 24.4 recovered an average of 1.8% direct booking share in Q4 2024 by closing the rate-update window
133
+
• Properties still running batch-sync PMS integrations are silently leaking direct revenue every time a revenue manager updates rates manually
134
+
• I build PMS integration layers for hospitality operators that replicate this channel-sync behavior without a full OPERA Cloud migration
135
+
136
+
If your revenue management system still syncs rates on a schedule instead of in real time, let's talk.
0 commit comments