This module brings back into Odoo what an account already published on
its social media: the posts themselves, the figures each of them
collected, and their comments and reactions.
This module implements the API of no social media in particular: it
brings the scheduled actions, the frontend and the common interface, and
a synchronization connector is what implements the calls for one social
media. The only thing it fetches on its own is the media of an imported
publication, from the URL the connector hands it.
This module depends on Social Media Base and is not installed with it:
an Odoo that only writes and publishes does not need it, and the whole
point of having it apart is not paying for what it does.
It brings nothing of its own for a social media in particular. A
synchronization connector is what implements the calls for one of them,
the same way Social Media Linkedin or Social Media X implement
publishing. Installed without one, the scheduled actions run, find
nothing to ask anybody, and leave everything as it is.
Nothing has to be configured for this module to work: it uses the
accounts, the credentials and the groups of Social Media Base.
What is worth reviewing is the two scheduled actions it adds, in
Settings / Technical / Automation / Scheduled Actions:
- Social: Initial sync of the new accounts runs monthly, and is also
triggered on the spot every time an account is linked. It only picks
up the accounts still waiting for that first import, so the monthly
run is a safety net rather than the normal path.
- Social: Full resync of the accounts runs weekly. It is the only pass
that notices a publication deleted on the social media, and the most
expensive one: it reads every publication of every account, one call
per page. Making it run more often is what turns a deletion noticed a
few days late into a quota problem.
Both intervals are the ones to move if the social media of an account is
strict about quotas.
The retention of the downloaded medias is one system parameter, in
Settings / Technical / Parameters / System Parameters, which only an
administrator reaches: social_media_sync.media_max_age_days. The
module installs it at 0, so it is there to be found, and zero is no
policy at all: no media is ever released.
A system parameter holds text, and this one is read as a number of days.
A value that cannot be read as one — a word — is taken as no policy and
leaves a warning in the log; an empty value, zero and any negative
number are no policy too and are not worth a warning. No media is
released in any of those cases.
Written as a positive number of days, the daily vacuum releases the
images and videos this module downloaded for the imported publications
older than that, and the files are deleted a day later. One run reaches
a thousand of the aged publications that still hold medias. A
publication already released leaves the next run instead of taking the
place of another one, so a database holding more aged publications than
that is released in full over the following runs. Two things to weigh
before writing a number:
- What is lost is the media itself. The card of an aged publication is
drawn with no image and no placeholder in its place. The link to the
social media, where the media still is, stays.
- What is kept is what each social media made of that media. The next
synchronization pass knows the publication already had it and does not
ask for it again, so the policy frees the disk once instead of paying
for the same bytes every week.
Only the publications imported from a social media are reached. The
medias of a post published from Odoo are editorial content and are never
aged out, whatever the age of the post.
The size of each downloaded media is capped by a second system
parameter, in the same place: social_media_sync.media_max_size_mb.
The module installs it at 100, in megabytes, and an update of the
module does not overwrite what an administrator wrote in it. A media is
held whole in memory while the import runs, and the cap is what keeps
one large video from exhausting it.
A media larger than the cap is not downloaded. When the social media
announces the size of the file, the download stops before reading it;
when it does not, it stops as soon as what was read goes past the cap.
The publication is imported without that media, and a warning in the log
names the media, its size and this parameter. As the publication does
not hold that media, every synchronization pass asks for it again and
stops at the cap again, until the parameter is raised above its size. A
long video can well be larger than 100 megabytes, so an account
publishing them is the one to raise it for.
Zero is no cap at all, and so are an empty value, any negative number
and a parameter that was deleted: every media is downloaded whatever its
size, and nothing is logged. A value that cannot be read as a whole
number of megabytes — a word, a decimal — does not remove the cap: it is
taken as 100 and leaves a warning in the log.
social.post.account.actor_urn holds who the social media says
published a publication: the organization page on LinkedIn, the author
of the tweet on X. The import is what fills it, and no view shows it, so
nothing reads it back yet. It looks like it belongs to the reactions,
which take the actor performing them as an argument, and it is the kind
of field the family either starts using or drops.
Social Media Sync
This module brings back into Odoo what an account already published on its social media: the posts themselves, the figures each of them collected, and their comments and reactions.
It is separate from Social Media Base because of what it costs. Base asks the social media for a fixed number of things per account — publish, delete, the daily series of the page, the figures of the publications of the last 30 days — and that number does not change whether the account published once or ten thousand times. Everything whose cost grows with the history of the account lives here: one call per page of posts, one call per publication to check it is still there, one call per comment thread. An installation that only writes and publishes does not have to pay for any of it.
Social Media Base never depends on this module nor calls into it. Where base needs something only the synchronization knows how to do, it declares an empty hook and carries on, so base works installed alone.
Main features:
This module implements the API of no social media in particular: it brings the scheduled actions, the frontend and the common interface, and a synchronization connector is what implements the calls for one social media. The only thing it fetches on its own is the media of an imported publication, from the URL the connector hands it.
Table of contents
Installation
This module depends on Social Media Base and is not installed with it: an Odoo that only writes and publishes does not need it, and the whole point of having it apart is not paying for what it does.
It brings nothing of its own for a social media in particular. A synchronization connector is what implements the calls for one of them, the same way Social Media Linkedin or Social Media X implement publishing. Installed without one, the scheduled actions run, find nothing to ask anybody, and leave everything as it is.
Configuration
Nothing has to be configured for this module to work: it uses the accounts, the credentials and the groups of Social Media Base.
What is worth reviewing is the two scheduled actions it adds, in Settings / Technical / Automation / Scheduled Actions:
Both intervals are the ones to move if the social media of an account is strict about quotas.
The retention of the downloaded medias is one system parameter, in Settings / Technical / Parameters / System Parameters, which only an administrator reaches: social_media_sync.media_max_age_days. The module installs it at 0, so it is there to be found, and zero is no policy at all: no media is ever released.
A system parameter holds text, and this one is read as a number of days. A value that cannot be read as one — a word — is taken as no policy and leaves a warning in the log; an empty value, zero and any negative number are no policy too and are not worth a warning. No media is released in any of those cases.
Written as a positive number of days, the daily vacuum releases the images and videos this module downloaded for the imported publications older than that, and the files are deleted a day later. One run reaches a thousand of the aged publications that still hold medias. A publication already released leaves the next run instead of taking the place of another one, so a database holding more aged publications than that is released in full over the following runs. Two things to weigh before writing a number:
Only the publications imported from a social media are reached. The medias of a post published from Odoo are editorial content and are never aged out, whatever the age of the post.
The size of each downloaded media is capped by a second system parameter, in the same place: social_media_sync.media_max_size_mb. The module installs it at 100, in megabytes, and an update of the module does not overwrite what an administrator wrote in it. A media is held whole in memory while the import runs, and the cap is what keeps one large video from exhausting it.
A media larger than the cap is not downloaded. When the social media announces the size of the file, the download stops before reading it; when it does not, it stops as soon as what was read goes past the cap. The publication is imported without that media, and a warning in the log names the media, its size and this parameter. As the publication does not hold that media, every synchronization pass asks for it again and stops at the cap again, until the parameter is raised above its size. A long video can well be larger than 100 megabytes, so an account publishing them is the one to raise it for.
Zero is no cap at all, and so are an empty value, any negative number and a parameter that was deleted: every media is downloaded whatever its size, and nothing is logged. A value that cannot be read as a whole number of megabytes — a word, a decimal — does not remove the cap: it is taken as 100 and leaves a warning in the log.
Usage
Importing what an account already published.
What each notice on a card announces.
Three different things can be pending on an account, and each one has its own notice and its own way out. They are independent: an account may be carrying one, two or the three of them at once, and none of them says anything about the others.
Only a social media whose API can tell that an account moved without reading its publications raises the third one. Where it cannot —reading the timeline is the import— nothing is announced between two runs, and those accounts are imported on every pass instead.
Noticing what was deleted on the social media.
Comments and reactions.
Known issues / Roadmap
actor_urn
social.post.account.actor_urn holds who the social media says published a publication: the organization page on LinkedIn, the author of the tweet on X. The import is what fills it, and no view shows it, so nothing reads it back yet. It looks like it belongs to the reactions, which take the actor performing them as an argument, and it is the kind of field the family either starts using or drops.
Storage of the imported medias
The import downloads the medias of every publication it brings in and stores them as ordinary ir.attachment records, so the filestore grows with the history of the accounts and not with what is published from Odoo: an account importing years of publications brings in years of images.
An imported publication has no post to share attachments with, so nothing is shared here: one image of one publication is one attachment, and the same image published on two accounts is imported twice. media_refs does not change that, and is not there for it: it is what tells the next synchronization which references this publication already holds, so that a media is downloaded once and not on every pass. The bytes of two identical images still land on the same file, because the filestore keys its files by the hash of their content; what multiplies is the rows.
What ages them out is one number for the whole database. social_media_sync.media_max_age_days reaches every imported publication older than it, whatever its account, so there is no way to keep the medias of one account and age out those of another, and a publication kept only for its figures still costs its images until that age is reached. The deletion itself belongs to the vacuum: _gc_aged_post_medias releases what the policy reaches, the next synchronization releases what the social media no longer serves, and _gc_lost_media_attachments deletes both a day later. Serving those bytes from somewhere else is configured at the level of Odoo, through ir_attachment.location, not from here.
Bug Tracker
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed feedback.
Do not contact contributors directly about support or help with technical issues.
Credits
Authors
Contributors
Maintainers
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
Current maintainer:
This module is part of the OCA/social project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.