This module brings back into Odoo what an X account already published: the posts of its timeline, the figures each of them collected, and their comments.
It is the X half of Social Media Sync, split from Social Media X along the same line: what a call costs. The connector asks X for a fixed number of things per account — link it, refresh its card, publish, delete, read the figures of the publications of the last 30 days, read the single publication that is being opened — 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: the timeline that answers up to a hundred publications and one download per media not stored yet, and up to five calls per publication whose comments are read, one per page of the conversation.
An Odoo that only publishes on X installs Social Media X alone and pays for none of it.
Main features:
- Import of the publications of the timeline, with their photos, videos and animated GIFs, and of the figures each of them collected, on demand, through the scheduled actions of Social Media Sync and through the check for updates of Social Media Base, which on X imports instead of flagging the account.
- Comments of a publication, read from the dashboard: the conversation is walked page by page up to a ceiling, and the replies of a comment are nested from what was read instead of being asked for apart. A comment answers the publication, and answering a comment answers that comment, which on X is a post like any other.
- Recommend on a publication and on each comment and reply of its thread, which gives or withdraws the like of the account on X. Which ones the account already liked is read from its latest likes on X, when the account is imported and when the thread is opened.
- Delete on the comments the account wrote, which deletes them on X: X only deletes the posts of the account that asks, so the entry is not offered on the comments of other people.
- Reading only what was published after a chosen publication, with Enable since, for an account that does not need its whole history read again.
Statistics account The figures of the account are the sum of the publications Odoo holds for it. A publication deleted on X is marked Deleted and keeps the figures of the last read, so it goes on counting; the figures only fall when the record itself is removed in Odoo.
The figures of the card are the sum of every publication of the account stored in Odoo, with no window and no ceiling. What the hundred publications of one timeline page limit is how far back an import reaches, and what the 30-day window of Social Media X limits is which publications get their figures read back from X; anything older keeps the last figures that were read for it and keeps being counted. Only original publications are stored and counted: retweets, replies and quotes are discarded on import.
- The eye icon: Total number of views, which may include multiple views by the same user.
- The hand icon: the interactions (likes, comments, retweets and quotes) of every publication stored for the account, a publication deleted on X included, which keeps the figures of the last read. They are the metrics X returns for a post.
- The star icon: the engagement of the account, the interactions of its publications over their impressions. X reports no rate of its own, so it is derived from those counters, and it counts the retweets and the quotes as interactions like any other.
If the X API rate limit is reached while refreshing the statistics, the last metrics stored on the account are kept instead of failing.
auto_awesome What this module does
AI-generated from the code · Odoo 17.0Brings an X account's existing timeline into Odoo: its posts, their figures, their media and their comment threads, so users can read, like, reply to and delete comments from Odoo.
This module lets Odoo pull in what an X account already published, instead of only pushing new posts out. On the social account form a new option, "Enable since", makes the import read only the posts published after the last one already synchronized, which saves API calls; a "Last Post" reference and a linked post record keep track of that checkpoint. Turning the option off clears both.
When the timeline is read, each tweet becomes a post in Odoo with its text, author, publication date, counters and media. Photos are downloaded, and videos or animated GIFs are stored as mp4 files, choosing the best quality available; a post with a video is flagged even if the file could not be downloaded. Retweets, replies and quoted posts are skipped, so only original publications are imported. The account's own likes are read too, so posts already liked by the account are marked as such.
On each post, users can open the conversation: replies are read page by page (up to a fixed limit), with their authors, images, like status and reply counts, and replies to replies are attached to the right comment. From the dialog users can like or unlike a post or a comment, write a reply (with images), and delete a comment the account wrote. Deleting a publication through the comment action is refused.
Errors are handled gracefully: expired credentials flag the account, quota limits show a message, and a deleted post is reported as such. The import runs through the existing update check, each account in its own savepoint so one failure does not undo the others.
Depends on
Models and fields (2)
- social.account · extends an existing modelenable_since, last_post_ref (Last Post), post_since_id
- 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-03Confirmation status: 1 confirmed, 8 with no information of 9 versions.
Sources · Odoo 17.0
Confirmed on 2026-11-03 in branch 17.0 of OCA/social.
terminal Installation and usage
OCA documentation · Odoo 17.0Installation
Source · Odoo 17.0This module is installed on its own as soon as Social Media Sync and Social Media X 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 an X account from being left without the half that belongs to it.
Installing Social Media X alone is a valid installation: the account is linked, publishes and deletes, reads back the figures of the publications of the last 30 days, and marks as Deleted the publication that is opened after being deleted on X.
It adds no Python dependency of its own: it asks the connector for the tweepy client and never builds one.
Configuration
Source · Odoo 17.0Nothing has to be configured for this module: it reads X with the credentials the account already holds, which are configured in Social Media X.
What those credentials need is an App able to spend against the API, the same one the connector requires: the timeline of the user, the recent search, the likes of the account and the deletion of its comments, which this module spends, are X API v2 endpoints, so a developer App outside a Project answers 403 to them as it does to the rest. See the configuration of Social Media X and the pricing of the X API.
This module is where the pay-per-use bill of an X account is decided. Reading a publication of the account costs $0.001, but the replies the comments dialog reads are posts of other people, at $0.005 each, and it asks for up to five pages of a hundred while it stays open, refreshing itself every two minutes. The 24-hour deduplication of X charges the same reply once however many times it is read, so what is paid is the replies that are new, not the dialog being open; even so, a busy thread is the most expensive thing the modules do against X. The Enable since date below is the lever: nothing before it is ever read.
Opening the dialog also reads one page of the latest likes of the account, up to a hundred posts charged one by one, and so does every import of the account; the refreshes of the dialog do not read it again. The usage explains what that page shows and what it does not.
Each comment or reply sent from the dashboard, whether X accepts it or not, each Recommend pressed on the card of a publication, and each comment deleted from the dashboard once X has deleted it, reads the account again: the dashboard then runs for the account of the publication what its Update button runs, the read of the figures of the recent publications of Social Media X and another read of the timeline by this module, with its page of likes. Those reads are charged like any other.
The videos and animated GIFs of the timeline are downloaded whole, and each file is held to the size cap of Social Media Sync, the system parameter social_media_sync.media_max_size_mb. A long video can be larger than what it allows, so an account publishing them is the one to raise it for. Leaving the videos and the animated GIFs out of Odoo altogether, while the photos are still downloaded, is what social_media_sync.download_videos written as False does. See the configuration of Social Media Sync for both.
Enable since
- Go to Social Media > Configuration > Accounts
- Select the account
- Select Enable since
- The Post since field is then enabled, allowing you to select the post to start the search for in the next post retrieval. The import no longer reads what is older than that publication, but the figures of the publications of the last 30 days are read back all the same by Social Media X; older than that, each publication keeps the last figures that were read for it.
Scheduled actions
The passes over an X account are the ones Social Media Sync declares, plus two of Social Media Base: the check for updates and the daily refresh of the figures of the recent publications.
- Social: Checking social media updates, every 2 hours, reads the timeline of every X account. X has no cheap answer to whether anything moved — the only endpoint that knows is the timeline, and reading it is already the import — so this pass imports instead of flagging the account.
- Initial sync of the new accounts, monthly, imports the timeline of an account that was just linked. Linking one triggers this action immediately as well, so its card is filled from the first moment.
- Full resync, weekly, reads the timeline of an X account exactly as the ordinary import does, so it notices nothing that was deleted there. A publication deleted on X is marked Deleted when someone opens it from the dashboard or from its form, which is a check of Social Media X.
- Social: Refresh the statistics of the recent publications, daily, reads the publications of the last 30 days by identifier, which is a call of Social Media X and not of this module.
An account whose first import has not run yet is left out of the bihourly check, because that check and the initial import write the same row from two threads.
Usage
Source · Odoo 17.0Importing the publications
- The timeline of the account is read with the posts of a user, which answers up to 100 publications in a single request and is not paginated: what is older than those hundred is not imported, in order to spare the requests of the plan. Retweets and replies are excluded, so only the original publications of the account are stored.
- Each media of a publication is downloaded once and stored as an attachment, and a media already stored is not asked for again. A photo is downloaded from the address X answers with it, and one answered without an address is not stored. A video or an animated GIF has no such address: X lists the files it serves for it, and the mp4 of the highest quality is the one downloaded, which for an animated GIF is the single mp4 X makes of it. The card of the publication counts its videos, and its form plays them.
- No file above the size cap of Social Media Sync is downloaded. The cap applies to every file on its own, not to the publication as a whole.
- A video that is not downloaded — X lists no mp4 for it, the download fails or the file is above the cap — still leaves the publication marked as having a video, and its form says that the video was not downloaded. The next pass that reads the publication tries the download again.
- While the system parameter
social_media_sync.download_videosisFalse, no video and no animated GIF is downloaded, and the photos still are. The publication is marked as having a video all the same, and its form says that the video was not downloaded. The videos already downloaded stay, and once the parameter is back toTruethe next import downloads the ones missing from the publications it reads. - The files come from the servers X delivers its media from, not from its API, so downloading them spends no credits of the plan.
- The Update button of the dashboard runs the same import on demand, over every account shown.
- The text of a publication is stored as X wrote it, without the
https://t.co/…link X appends to it for each of its photos, videos or animated GIFs, which are stored apart as attachments. The links the author wrote, and the one a quote points at, stay in the text. - The module adds the With Reposts and With Quotes filters to the search panel of the dashboard, next to the filters of impressions and interactions of Social Media Sync.
- The list of publications of the dashboard offers the Reposts and Quotes columns, right after Shares. The list is shared by every social media, so both are hidden until they are chosen from the optional columns of the list.
- With Enable since the import only asks for what was published after the stored publication, so the older publications are no longer read by this import. The ones published in the last 30 days are refreshed all the same by Social Media X, which reads their figures by identifier. The card of the account is unaffected either way: the figures are written on each publication, and the card adds up every publication stored.
Comments
- A comment or a reply written on an X thread may carry images. The composer offers the upload, the files travel to X with the reply and are shown on the published comment.
- The video or the animated GIF of a reply is shown by its cover, as one more image of the comment. It is not played in Odoo: it is watched on X.
- The text of a comment read from X is shown the same way as the text of an imported publication: without the links X appends for its media, and with the links its author wrote.
- The comments of a publication are read with the recent search endpoint of X, which only covers the last 7 days: the replies to older publications are not shown on the dashboard even though the post has them. Retweets and quotes are excluded as well, only the replies are listed.
- The conversation is read a hundred replies at a time, following the token X answers with until it runs out or five pages have been read. Read to the end, how many replies each comment has is counted in Odoo and never asked to X again; cut short by that ceiling or by the limit of requests of the plan, no number is stated, and the dashboard offers to unfold the replies of every comment.
- Answering a publication and answering one of its comments are the same call to X: on X a comment is a post like any other, and what changes is the post being replied to.
Recommending and deleting
- Recommend is offered on the card of every publication of X and on each comment and reply of its thread. Pressing it gives the like of the account on X, and pressing it on what is already Recommended withdraws it. The like is always given as the account the publication belongs to.
- Delete, in the menu of a comment, is offered only on the comments the account wrote that answer the publication. X only deletes the posts of the account that asks, so the comments of other people do not offer it, and a reply inside a thread does not offer it either. After a confirmation the post is deleted on X and the thread is read again without it. A comment already gone from X counts as deleted.
- When X refuses the call, its reason is shown instead. An App that cannot spend against the API is explained as such, with the link to the pricing of X, and credentials X no longer accepts mark the account as needing to be authorized again. An error X does not explain on a Recommend makes Odoo ask about the publication itself, which is marked Deleted if it is gone from X.
What Odoo sees of the likes
- X cannot be asked whether the account liked a given post. What it offers is the list of the latest posts the account liked, and Odoo reads a single page of it, the hundred latest, at two moments: on every import of the account, once its timeline has answered, to mark the publications the account recommended; and when the dialog of the comments opens, to mark the comments and replies.
- A like older than those hundred is not seen: the publication or the comment is drawn as not recommended. Pressing Recommend there gives a like X already holds; X answers that it is given, and the entry is drawn right from then on.
- The refresh of the dialog every two minutes, and the reload after a comment is sent or deleted, do not read the likes again. The comments already on screen keep the like they had, and the new ones arrive not recommended. A like given or withdrawn on x.com while the dialog is open is seen the next time the dialog opens; on a publication, on the next import.
- The like of a publication is stored on it, and every import writes it again on the publications its page of the timeline answers. The like of a comment is not stored in Odoo: the dialog reads it again each time it opens.
- A page of likes that cannot be read never stops the import or the comments. The import leaves the publications as they were marked, and the dialog draws its comments as not recommended.
What it costs
- The page of likes is charged by X for every post it answers, up to a hundred, and a post read twice in the same day is charged once. It is read once per account on every import — the Update button, the check for updates every two hours, the initial sync and the full resync — and once each time the dialog of the comments of a publication opens.
- Recommend on a comment is one call to X, and the card is not refreshed after it.
- Recommend on the card of a publication is one call to X, and then, whether X accepted it or not, the card is refreshed the way its Update button refreshes the account: the figures of the recent publications, the timeline and the page of likes.
- Delete is one call to X. The thread is then read again, and a deletion X accepted refreshes the card the same way Recommend does.
- What X charges for each of those calls is on the pricing of the X API.
What this module does not detect
- Its own passes do not detect a publication deleted on X: a publication deleted there is marked Deleted only by the check Social Media X makes when the publication is opened.
Rate limits
The endpoints this module spends from the plan of the account are the timeline of the user, the recent search of the comments, the publication of a reply, the like and its withdrawal, which share one window, the list of the latest likes of the account and the deletion of a comment. Each of them has its own window on the account, the same record where Social Media X stores the windows of the endpoints it spends —the read of a single post and the read of the figures by identifier—, and when X answers that one is exhausted Odoo stops calling that endpoint until the window expires.
While the window of the comments lasts, opening the conversation of a publication shows the notice The comments could not be read from X. The account may have reached the limit of requests of its plan. instead of an empty thread, and a refresh in that state leaves the comments already on screen untouched.
While the window of the replies lasts, publishing a comment answers The comment could not be published on X. The account may have reached the limit of requests of its plan. instead of reporting a reply X never received. The text of the composer is not kept, but the comment being answered stays aimed at, so the retry starts under the same comment.
While the window of the likes lasts, Recommend answers The recommendation could not be sent to X. The account may have reached the limit of requests of its plan. and the entry stays as it was drawn. While the window of the deletion lasts, Delete answers The comment could not be deleted on X. The account may have reached the limit of requests of its plan. and the comment stays. While the window of the list of likes lasts, the import and the dialog go on without it, as when the page cannot be read.
Uninstalling
Uninstalling this module leaves the account linked and able to publish. What goes with it is the checkpoint of the import: Enable since, Post since and the reference of the last publication read.
Installation instructions, the distribution package, dependencies and configuration steps are not shown because they have not yet been verified in the module documentation for any version.
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.