Social Media X Sync
social_media_x_sync · OCA/social
-
Security25/25No findings
-
Activity25/25Human commit this month
-
Required by5/250 modules depend on it
-
Maturity5/25In 1 Odoo series since 17.0
Heuristic over the facts below, not an audit · How it's computed
Description
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.
Dependencies
Code analysis
Extracted from the source by best-effort static analysis (no code is executed); details may be incomplete.
Views touched 3
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
social_account_view_form_inherit_sync_x |
social.account.view.form.inherit.sync.x | social.account | form | Inherits social_media_x.social_account_view_form_inherit |
social_post_account_view_search_inherit |
social.post.account.view.search.inherit.social.media.x.sync | social.post.account | search | Inherits social_media_base.social_post_account_view_search |
social_post_account_view_tree_inherit |
social.post.account.view.tree.inherit.social.media.x.sync | social.post.account | tree | Inherits social_media_sync.social_post_account_view_tree_inherit |
HTTP endpoints 0
No HTTP endpoints found for this module.
Models touched 2
-
enable_sinceBooleandefault=Falsehelp='Read only the posts published after the last one already synchronized, to consume fewer API requests. The metrics of the previous posts are no longer updated while this option is on.' -
last_post_refCharcopy=Falsehelp='Reference of the newest tweet read from X, used to ask only for the ones published after it.'string='Last Post' -
post_since_idMany2one → social.post.accountcompute='_compute_post_since_id'domain=[('media_type', '=', 'x')]help='This post is updated with each request with the latest one.'store=True args: 'social.post.account'
No public methods.
No new fields.
Public methods (8)-
action_like_comment(self, comment_ref=None, author_urn=None) -
action_like_post(self, author_urn=None) -
action_unlike_comment(self, comment_ref=None, author_urn=None) -
action_unlike_post(self, author_urn=None) -
create_comment(self, post_data, context=None) -
create_x_comment(self, post_data)Publish a reply to this post, with its attachments if any. :rtype: dict -
delete_comment(self, comment_ref)Delete a comment the account wrote on this publication. On X a comment is a tweet, and X only deletes the tweets of the account that asks, so the call is the one that deletes a publication, with the user context of the account. The client only offers it on the comments the account wrote, and a reference Odoo holds as a publication of the account is refused before asking X, archived ones included: the reference comes from the client, and this is not the path that deletes a publication. A tweet that is already gone counts as deleted: what was asked for is done. Nothing raises from here, because the client waits for a dict. :param comment_ref: identifier of the comment on X. :return: ``success`` and, on a failure, the ``message`` to show. :rtype: dict -
get_comments(self)Read the replies to this post. :return: ``success`` and the list of comments, or the error message. :rtype: dict