Repository navigation
feat(linkedin): publish @[Name](urn) mentions as LinkedIn mentions - #15
Merged
Merged
Conversation
Text written as @[Name](urn:li:person:ID) or @[Name](urn:li:organization:ID) now becomes a real mention on every LinkedIn path: - ugcPosts and comments: the name is sent as plain text plus an attribute (start/length in UTF-16 units) pointing to the member or organization. - Article posts (little text): the mention is kept as a MentionElement and only its display name is escaped; everything else is still escaped. Claude-Session: https://claude.ai/code/session_01WQdhzab1mHnyisvobQRoXF
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
There is no way to mention a member or a company page in a LinkedIn post published through PostFlow.
/v2/ugcPosts. That API does not parse any mention syntax inshareCommentary.text; mentions have to be sent asattributeswith astart/lengthrange. PostFlow only sendstext./rest/posts, whosecommentaryis little text and does support@[Name](urn), butescapeLinkedInLittleTextescapes it (the testmention syntax stays literalpinned that).Real check: a post sent through PostFlow to a company page with
@[Welcome to La Secta](urn:li:organization:110315077)rendered those characters literally instead of linking the page.Fix
Use the little text mention syntax as the single way to write a mention in post text, and translate it per LinkedIn API:
@[Name](urn:li:person:ID)and@[Name](urn:li:organization:ID)are recognised (linkedInMentionPattern). Any other URN type stays literal.linkedInAttributedText): the mention is replaced byNameand an attribute links that range toMemberAttributedEntity/CompanyAttributedEntity. Offsets are counted in UTF-16 code units, so emoji and the Unicode bold/italic produced byformatPostTextForPublishbefore the mention don't shift the range. The media title uses the same rendered text, so the raw syntax never leaks there.escapeLinkedInLittleTextkeeps each mention as a MentionElement and escapes only its display name; everything else is escaped exactly as before.Because the mention lives in the text, nothing changes in the schema, the API contract, MCP or the CLI: every surface gets it for free.
README.mdand thepostflow-cliskill document the syntax and LinkedIn's name-matching rule (the name must match the member's first, last or full name, or the page's full name, case sensitive).Behavior change: text that already contained
@[Name](urn:li:person|organization:ID)used to be published literally and now becomes a mention. Themention syntax stays literalcase is replaced bymention stays a mention.Testing
gofmt -lis clean,go vet,go test ./internal/postflow/andgo test -race ./internal/postflow/pass locally (Go 1.27.4).TestLinkedInMentionsToAttributes(UTF-16 offsets, person + organization, other URN types untouched) andTestLinkedInPlainTextPathsSendMentionsAsAttributes(ugcPosts and comment payloads end to end throughPublish, with an ID containing underscores to check the Markdown formatter leaves it alone). Little text cases cover mentions mixed with reserved characters.go test ./...(db, worker, api, cli, parity). My sandbox could not downloadmodernc.org/sqliteandgolang.org/x/crypto, so please rely on CI for those.golangci-lintwas not run either.Not verified against LinkedIn yet
I'll check these with a real post once this is deployed:
start/lengthin UTF-16 units (it's a Java API, and its docs only say "character index").start + length must be less than the length of the text. If that is literal, a mention that ends the text would be rejected with a 400.message.attributes) use the same AttributedText shape asshareCommentary.Out of scope
https://claude.ai/code/session_01WQdhzab1mHnyisvobQRoXF