OdooWiki OCA HUB

Social Media LinkedIn Sync

social_media_linkedin_sync folder_open OCA/social open_in_new
Social Network License: AGPL-3

This module brings back into Odoo what a LinkedIn page already published: the posts themselves, the figures each of them collected, and their comments and reactions.

It is the LinkedIn half of Social Media Sync, split from Social Media Linkedin along the same line: what a call costs. The connector asks LinkedIn for a fixed number of things per account — publish, delete, the daily figures of the whole page — and that number does not change whether the page published once or ten thousand times. Everything whose cost grows with the history of the page lives here: reading the feed one page at a time, asking LinkedIn about the publications missing from it a hundred URNs at a time, and one call per comment thread. The figures of the publications are read by Social Media Linkedin, in as many calls as the 4 KB limit of the query string needs, whoever hands it the identifiers.

An Odoo that only publishes on LinkedIn installs Social Media Linkedin alone and pays for none of it.

Main features:

  • Import of the publications of the page, with their images and their video, and of the statistics each of them collected, on demand and through the scheduled actions of Social Media Sync.
  • Full resynchronization of a page, the only pass that notices a publication deleted on LinkedIn. Missing from the feed never marks anything on its own: LinkedIn is asked about each suspect by its URN, one call per hundred of them, and only a 404 writes the deletion. The Posts API publishes asynchronously (PUBLISH_REQUESTED), answers the author finder in reader context, and states that a page returning fewer results than asked is not the end of the feed — so a publication that is alive can be absent from a listing read whole.
  • Publications deleted on LinkedIn recognised while the dashboard is being used: a reaction or a comment answered with a 404 makes Odoo ask LinkedIn about the publication itself, and only its confirmation marks the line as deleted.
  • Comment threads read from the dashboard, with their replies, and Recommend on a publication and on each of its comments, which also withdraws the reaction it made.
  • Detection of pages that moved since the last import, which puts a notice on the dashboard inviting the user to press Update. It costs at most two calls per account, and reuses the daily figures the connector already read on the same pass instead of asking LinkedIn for the same days twice.

auto_awesome What this module does

AI-generated from the code · Odoo 17.0

Imports a LinkedIn page's publications into Odoo, together with their images, videos, comments and reactions, and keeps them up to date by checking whether the page has moved since the last import.

This module completes the LinkedIn connector by bringing back into Odoo what a LinkedIn page already published. It is installed automatically alongside the LinkedIn connector and adds its behaviour to the social account and publication screens.

What users get: - The publications of a LinkedIn page are imported into the social dashboard, with their text, publication date, images and videos. - Comments and replies of each publication are read, and the name and logo of the organizations behind them are shown. - Users can like or unlike a publication or a comment from Odoo; the reaction is sent to LinkedIn and the card is updated. - Images deleted on LinkedIn are removed from the Odoo card, while images attached by hand in Odoo are left alone.

Automatic behaviours: - A regular check compares the daily figures of the whole page with the last stored reading and flags the account as having updates to import, without importing anything by itself. - A full resynchronisation walks the whole feed page by page and marks publications that disappeared from LinkedIn as deleted. - The number of feed pages read per pass is limited by a system setting. - If the account's token lacks the permission needed to read publications, the responsible user receives a message in their Inbox asking them to authorize the account again; this warning is sent only once until the account is reconnected.

A system-only field stores the last daily figures of the page, used as the comparison point for the update check.

Models and fields (2)
  • social.account · extends an existing modellinkedin_missing_sync_scopes, linkedin_sync_scopes_notified, linkedin_statistics_checkpoint (Statistics Checkpoint)
  • social.post.account · extends an existing model

Text generated by AI (DeepSeek) from reading the Odoo 17.0 code on GitHub; it may contain mistakes, so check the code before deciding. The module is very large and only part of the code was read. View the code on GitHub

Availability by version

Reviewed: 2026-11-03
Confirmed (verified in repository and branch) Estimated (unverified) No information

Confirmation status: 1 confirmed, 8 with no information of 9 versions.

terminal Installation and usage

OCA documentation · Odoo 17.0

This module is installed on its own as soon as Social Media Sync and Social Media Linkedin are both present, which is what a bridge module is for: the choice to synchronize was already made by whoever installed Social Media Sync, and this only keeps a LinkedIn page from being left without the half that belongs to it.

Installing Social Media Linkedin alone is a valid installation: the account is linked, publishes, deletes and shows the daily figures of its page.

The mark the update check compares against

social.account.linkedin_statistics_checkpoint is stored by this module and holds the daily figures LinkedIn reported for the whole page as of the last import. An account that has no mark yet is given one on the first pass of the bihourly check and announced as having nothing to import, so installing this module on a database that already publishes on LinkedIn does not put the notice up on every account at once.

Nothing has to be configured for this module to work: it uses the LinkedIn accounts and credentials of Social Media Linkedin, and the scheduled actions of Social Media Sync.

It asks LinkedIn for nothing the connector does not already ask for. Reading the feed of a page, its comments and its reactions travels on r_organization_social, which Social Media Linkedin requests on its own, granted by the Community Management API product that connector already needs.

What does not follow on its own is the accounts already associated. An access token keeps the scopes it was issued with, so an account authorized before that permission was requested does not hold it and its history cannot be imported until it is authorized again. Refreshing the token is not enough: open the account, press Update account with Update keys ticked and authorize on LinkedIn again.

The accounts concerned say so themselves, so nothing has to be looked up: a warning is drawn on the account form for as long as the permission is missing, the responsible user is notified by the check that runs every two hours, and the import refuses with the name of the missing permission instead of the bare error LinkedIn answers.

The video of a post is downloaded whole, and the file is held to the size cap of Social Media Sync, the system parameter social_media_sync.media_max_size_mb, installed at 100 megabytes. LinkedIn takes videos of up to 500 MB, so a page publishing long videos is the one to raise it for. Leaving the videos out of Odoo altogether is what social_media_sync.download_videos written as False does: no video is downloaded and LinkedIn is not even asked where to download one from, while the images still are. See the configuration of Social Media Sync for both.

System parameters

One key is worth knowing about, and it is only written by hand in Settings > Technical > Parameters > System Parameters: until then the module uses the default the code carries. It is bounded when it is read, so a value outside its range is brought back into it.

| Parameter | Default | Unit | Bounds | | --- | --- | --- | --- | | social_media_linkedin_sync.posts_max_pages | 50 | pages of 100 publications | 1 to 500 |

It is how far into the feed of a page one pass reads. The default covers five thousand publications, and it is not a limit of LinkedIn: it is what keeps a feed that never ends from looping forever.

A page with a longer history has to raise it. A feed read short comes back partial, and the weekly full resync — the only pass that notices a publication deleted on LinkedIn — does not look for deletions in a feed it could not read whole. Nothing breaks and nothing is said beyond a warning in the log naming the number of pages, so the symptom is publications that stay posted in Odoo after being deleted on LinkedIn.

Raising it costs calls: each page is one call against the Posts API, so 500 pages are 500 calls per pass of every account, plus what reading their figures adds. That is why the ceiling exists.

Importing what a page already published.

  • The Update button of the dashboard imports the publications of the pages. Without this module that button refreshes the daily series of the page and the figures of the publications of the last 30 days; with it, it also brings in the publications Odoo does not have yet and the figures of the ones older than that window.
  • The import discovers the publications three ways: one publication by its reference, the whole feed page by page, or — the ordinary path — the first page of the feed sorted by last modification, which is what catches what changed since the previous pass.
  • It also downloads the medias of the publications created outside of Odoo, so those images appear on the dashboard only after the import. An image LinkedIn could not say where to download from, or whose download fails, is not stored, and the next pass that reads the publication tries again.
  • The video of a post is downloaded too, and only once: a video the publication already holds, including the one of a post published from Odoo, is not asked for again. The card of the publication counts it, and its form plays it.
  • A video above the size cap of Social Media Sync, one LinkedIn is still processing, or one whose download fails is not stored. The publication is still marked as having a video, its form says that the video was not downloaded, and the next pass that reads the publication tries again.
  • No video is downloaded while the system parameter social_media_sync.download_videos is False, and LinkedIn is not asked where to download it from either; the images still are. The publication is still marked as having a video and its form says that the video was not downloaded. The videos already downloaded stay, and once the parameter is back to True the next pass that reads a publication still missing its video downloads it; the Full resync is the pass that reads them all.
  • The publication mirrors what is online: an image removed from the post on LinkedIn is dropped from the dashboard card on the next import. Only the medias downloaded from LinkedIn are managed this way, so a file attached by hand in Odoo is never removed.
  • An import of the whole page leaves a mark with the figures of the last watched days. The bihourly check compares against that mark, which is why importing is what takes the notice down; refreshing a single publication takes it down too but leaves the mark alone, since one publication says nothing about the rest of the page.
  • The first import asks for the time series again on an account whose association could not read it, which is the retry of a backfill that failed and not a repetition of it. How far back the series goes is the connector's business: Social Media Linkedin fills it as far back as LinkedIn answers by day the moment the account is linked, and rebuilds it from the Rebuild statistics history button of the account form.

Comments and reactions.

  • The comment thread of a publication is read from the dashboard, and its replies with it: LinkedIn serves the replies of a comment apart, so they are asked for when the thread is opened.
  • A comment and a reply are written under the organization, and the thread offers to delete a comment: LinkedIn is the one deciding whether the organization may, and its refusal is reported instead of removing it here.
  • Recommend is offered on the publication and on each of its comments, sent under the organization. LinkedIn holds one reaction per account and only LIKE is sent, so the entry is a toggle: it shows a filled thumb on what the organization already recommended, and pressing it there withdraws the reaction. What LinkedIn holds is read back on every import, so a reaction made or withdrawn from LinkedIn itself reaches the dashboard on the next pass.
  • LinkedIn does not accept an image in a comment, so the composer offers no upload on a LinkedIn thread.

Publications deleted on LinkedIn.

  • Posts deleted directly on LinkedIn are marked as Deleted on LinkedIn in Odoo, so the dashboard keeps their history. Only the Full resync button and the weekly scheduled action notice them, not the ordinary import, so a deletion can take up to a week to be reported.
  • Opening a publication asks LinkedIn first, so one deleted there is reported and marked right away instead of waiting for the weekly pass.

Full resync of a page

  • Go to Social Media > Configuration > Accounts, select the account and click on the Full resync button of the header.
  • The Update button of the dashboard reads one page of the feed, the one sorted by last modification, and refreshes the figures of every publication by its identifier. That is enough for everything except one thing: it cannot notice that a publication was deleted on LinkedIn, because a publication missing from the page it read is not necessarily gone.
  • Full resync is what reads the whole feed and marks as Deleted on LinkedIn what is no longer there. It is also the expensive pass, one call per hundred publications against the daily quota, so it asks for confirmation.
  • The scheduled action Social: Full resync of the accounts does the same weekly for every account, so pressing the button is only needed to see a deletion reported sooner.
  • A publication edited on LinkedIn long enough ago to have fallen off that first page keeps the text Odoo already had until a full resync. Its figures are refreshed all the same.

How the synchronization spends the LinkedIn quota

The throttle limits of LinkedIn are counted per day, per application and per endpoint, so what matters is not the total number of calls but how they spread.

  • The scheduled action checking for updates costs two calls per account and run, whatever the number of publications, one when it does find something, and only one for an account already announcing publications to import or for one whose credentials expired: the daily series of the page is written for them all the same, and what is skipped is the second call, the peek at the feed that could only confirm what the dashboard already says or fail on a token known to be dead. No call at all is spent on an account with no organization linked, since the finder is addressed by organization and there is nothing to ask. It reads the figures LinkedIn reports for the whole page day by day and compares them against the ones the last import left: no publication is read one by one to decide whether the dashboard should announce updates. Running every two hours, that is around 24 calls a day per account.
  • The Update button does not walk the feed. The statistics are asked for by publication identifier, and those identifiers are already stored in Odoo, so one page of the feed is enough: the one sorted by last modification, which is what brings the publications created or edited on LinkedIn. That is one call instead of one per hundred publications.
  • The figures of the publications are not read here: the import hands the identifiers to Social Media Linkedin, which is where that reading lives, so the same three calls answer the page whether they are asked for by this import or by the daily refresh of the connector.
  • Those figures are asked in as many calls as the 4 KB limit of the query string needs, since those endpoints take every identifier in the URL and none of them paginates. Around a hundred publications fit in one call, so a full feed takes several. https://learn.microsoft.com/en-us/linkedin/marketing/community-management/organizations/share-statistics
  • Full resync is the expensive pass, one call per hundred publications. The button does it for the account it is pressed on; the weekly scheduled action does it for every account of the database. It walks the feed page by page (count=100) up to as many pages as social_media_linkedin_sync.posts_max_pages allows, fifty by default, that is 5000 publications, and a page is only taken as the last one when it comes back empty, because LinkedIn documents that a page may carry fewer publications than asked while more are left. On an account whose feed is longer than that, the answer is incomplete and the sweep that marks as Deleted what is no longer on LinkedIn is skipped for that run: reporting nothing is preferable to marking a publication that is still online.

What the check for updates does and does not notice

  • It only tells that something on the page moved, not which publication moved. It does not need to: the only thing it decides is whether the dashboard shows the notice inviting to synchronize. A change that cancels itself out between two runs, a reaction removed and another one added, leaves the figures of the page where they were and goes unnoticed until the next synchronization.
  • It watches the daily figures of the page, over a window of the last seven days, and not the lifetime totals the same endpoint answers when no time interval is given. The two are two separate reads of LinkedIn's own data, so they are not guaranteed to agree at every instant; this module only relies on the daily buckets. One consequence worth knowing: activity older than the seven-day window is not announced. It is imported all the same when the user synchronizes, because the import reads the publications themselves and not this window.
  • The engagement is not compared. It is a ratio of the clicks, reactions, comments and shares over the impressions, so it cannot move without one of those moving, and it is the only non-integer figure of the set.
  • The statistics endpoint only answers activity of the last 12 months, on a rolling window. A publication older than that stops being counted, which can move the figures of the page on its own, with nobody having interacted with anything. The check announces updates once when that happens and the next import reconciles it.
info

Data imported from GitHub: this sheet reflects the latest catalog review, not a live lookup. Always check the module documentation and staging before installing in production.