OdooWiki OCA HUB

Social Media X

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

This module provides the necessary functionality for basic interaction with the X social media.

Main features:

  • User account integration.
  • Post creation.
  • Reports with agnostic metrics, on the account card of the Dashboard. The figures are read back from X by the connector itself: the publications of the last 30 days are refreshed once a day, and the card of the account adds up the counters its publications hold. A synchronization module widens what is known — the publications Odoo did not send, and the history older than that window — but the card is not empty without one.
  • Reposts and quotes, the two figures only X reports. They are shown as Reposts and Quotes in the Statistics dialog of a publication, opened from the menu of its card on the Dashboard, and they count towards the Interactions total and the Engagement rate of the publication and of the account.
  • What X will not publish, shown on the post while it is written. The message is checked against the characters the plan of the account allows, 280 without X Premium and 25 000 with it, and the medias against 4 images of at most 5 MB each — 15 MB for a GIF — in JPG, PNG, WEBP or GIF, and one video of at most 512 MB in MP4. X takes images or a video, never both in the same post, so a post mixing them is refused instead of warned about. The same checks refuse the publication if the post reaches it anyway, through an import or an RPC call.
  • The credit balance of the developer App that pays the calls to the X API, on the account form. It is read from X every 2 hours and from the buttons of the account, and the responsible of the account is warned when it drops under a threshold set on the account or is used up.

**An X account will never draw a time series in Social Media > Statistics.** That screen reads a history per day, and the metrics the API v2 answers are the current lifetime counters of each post, with no way of asking for them grouped by day. Giving X a series means either repeating the lifetime counter on every day, which draws a cumulative curve of a different shape than the other social media on the same graph, or storing the delta between two readings, which is false for any day the scheduled action did not run. Neither is a measurement, so nothing is written: an account of X shows the standard empty view there, and its figures live on its card of the Dashboard, which is where they mean something.

auto_awesome What this module does

AI-generated from the code · Odoo 17.0

Connect X (Twitter) accounts to Odoo and publish posts with images or videos directly from the social dashboard, then read back the likes, impressions, replies, reposts and quotes of each publication.

This module adds X as a social media you can link to Odoo and publish to. From the social media dashboard you open the X card, press to add an account and go through the X authorization flow; the account name, username and profile picture are then filled in automatically, and the account is flagged as X Premium or not.

On the account card you can store the developer App credentials (API Key, API Secret, read and write tokens), which only administrators see. The module also shows the remaining credit balance of the App in US dollars, read again every two hours and when you press Update account or refresh statistics, with a warning threshold you can set; the responsible is warned in the chatter and on screen when the balance drops under it or is used up.

When composing a post you can select X accounts (they are preselected for the active company). The module checks what X accepts: maximum length of the message (280 characters, or 25 000 for X Premium accounts), number and size of images and videos, and it refuses to send the same post twice to accounts sharing the same X username to avoid spam errors.

On each publication line you can refresh statistics: likes, impressions, replies, reposts and quotes are read from X, and an engagement rate is computed as interactions over impressions. Reposts and quotes appear in the statistics dialog of the publication. If X refuses a post or hits a request limit, the user gets an explanation and the time to retry.

Required by other modules

Models and fields (6)
  • social.post · extends an existing model
  • social.media · extends an existing modelmedia_type
  • social.account · extends an existing modelx_api_key (API Key), x_premium, x_api_secret (API Secret), x_credit_warned, x_credit_balance (Credit Balance (USD)), x_credit_warning (Credit Warning (USD)), rate_limit_endpoint, x_access_token_oauth1 (Token for write), x_access_token_oauth2 (Token for read), x_credit_balance_date (Credit Balance Read On), x_access_secret_oauth1
  • social.post.account · extends an existing model
  • wizard.social.account · extends an existing modelx_api_key (API Key), oauth_token, x_api_secret (API Secret)
  • social.statistics.mixin · extends an existing modelquote_count, retweet_count

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 requires the following Python libraries:

  • tweepy 4.0 or above, because the module uses the client of the X API v2 (tweepy.Client) besides the v1.1 client for the media upload.
  • requests_oauthlib

You can install them with:

pip install tweepy requests_oauthlib

To configure this module, you need to: Please note that you must have a developer account.

Important: the X API v2 endpoints used by this module require a developer App connected to a Pay Per Use project and an account with credit on the pay-per-use pricing of X, see about the X API. There is no Free access tier: an App left on the Default project, whose plan is Standard Basic, cannot spend against the API and is refused, so the account cannot be associated with it. Pay per use is not a subscription — there is no monthly fee and no minimum purchase, the App only needs a positive credit balance — but the balance has to be there before the first call. The association wizard shows this warning, and when X rejects the request for this reason the module replaces the raw error with a message that asks to connect the App to a Pay Per Use project in Project Access > Manage, not the Default project on Standard Basic, to make sure the account has credit in the Developer Console, and that points to the pricing page. Note that such an App can be refused at two different moments: when the request token is asked, before any authorization screen is shown, and the wizard answers with that message; or later, when the module reads the authorized user, and the message is then delivered on the Dashboard.

A call made with an App that cannot spend answers 403 Forbidden, either with "reason": "client-not-enrolled" or asking for an App attached to a Project, since only an enrolled App can belong to one. Every endpoint this module uses is affected: linking the account, refreshing the data of the account, publishing (message and media upload), deleting, checking whether a publication is still online and reading the figures of the recent ones.

What each call of the module costs, according to the pricing of X:

| What the module does | Endpoint | Price | | --- | --- | --- | | Publish a post | Post creation | $0.015 | | Publish a post carrying a link | Post creation with URL | $0.200 | | Read the figures of its own publications | Owned read | $0.001 per post | | Read the authorized user | Users | $0.010 |

A post that carries a link costs more than ten times a post that does not. X bills the link itself, whether it is tracked or not: social_media_base only routes the links of a publication through link_tracker when it promotes a marketing campaign, and a tracked link is still a link. Whether a post carries one is the single decision that moves the bill of a database that only publishes.

The same resource asked for twice within 24 hours is charged once, which is what keeps the scheduled actions of the module cheap: the check of network updates every two hours and the daily refresh of the figures read the same publications over and over.

So a database that only publishes spends cents a month: this module reads nothing but its own publications, at the price of an owned read, and the credit balance of the App, once per API Key, which is not among the calls the pricing of X lists. What grows with the account is the history, and the history is read by Social Media X Sync, which is a separate module nobody has to install. A deployment that publishes and watches its own figures does not need it.

There is no way around the API for what this module does. Publishing on X through anything else means either a reseller that pays the same API and charges for it on top, or driving the web with the session of the user, which its terms of service forbid and this module does not implement.

  • X API pricing and plans: https://docs.x.com/x-api/getting-started/pricing
  • Rate limits according to plan: https://docs.x.com/x-api/fundamentals/rate-limits
  • How to get access to the API: https://docs.x.com/x-api/getting-started/getting-access

Creating the developer account The developer account is not the X account: it is the enrolment of that X account in the API, and it is asked for once per organization, not per social account published from Odoo.

  • Sign in at the Developer Console with the X account that owns the App and press Start Building. It does not have to be the account whose posts Odoo publishes — the App belongs to whoever administers it, and each account authorizes it afterwards from the wizard of Social Media X. Accept the Developer Agreement and Policy if X asks for it.
  • Create a project. The use case declared here is what X reads if it ever reviews the App. A project starts on the default plan of its product, so it can be born on Standard Basic, the plan of the Default project that the console may already show with Plan: Free. Only a project on Pay Per Use spends against the credit balance, so that is the one the App has to be connected to, see Project Access below.
  • Create the App. The App is the set of keys, and the project is what those keys are allowed to call, so an App connected to no project answers 403 to everything, and so does an App connected only to the Default project on Standard Basic. Do not take for granted which project a new App is connected to: check what its Project Access shows, as described below.
  • Add a payment method in Billing > Billing information with Add Payment Method, following the steps X asks for.
  • Buy credits from the Dashboard or from Billing > Credits, before associating any account in Odoo: reading the authorized user is already a billed call, so an App with no balance fails at the association itself and never reaches the Dashboard of Odoo. A spend cap per billing cycle is set on that same screen, and it is what keeps a mistake from spending more than intended — when the cap is reached X blocks the requests until the next cycle.

The screens below are the ones of the developer portal. X moves them from time to time; the names of the settings are what matters, not where the picture puts them.

The steps required for using it are defined below:

  • Go to the Developer Console
  • Create a developer account as described above.
  • Once the account is created, go to Access > Apps and select the App. What it shows as Project Access is the project its keys call through, with its plan in brackets. An App on Default project-… (Standard Basic), as in the picture below, cannot spend against the API and X refuses it.
  • In that case press Manage on Project Access. The dialog lists the projects of the account, each with its plan and a Connect or Disconnect button: press Connect on the Pay Per Use one. The keys work on every project the App is connected to, and the limits and endpoints follow the plan of that project. The keys do not have to be regenerated: an App connected this way associates with the Consumer Key and Secret it already had. Start a new project, at the bottom of the same dialog, offers the Ads, Enterprise and Community Notes products, none of which is the Pay Per Use project this module needs. Once connected, the page of the App shows the Pay Per Use project under Project Access.
  • Open Settings to reach the authentication settings of the App.
  • Once on the page, in the App Permissions section, select Read and write, which is what the endpoints this module calls need.
  • Go to the App Type section and select Web App, Automated App or Bot.
  • Then, in the Callback URI / Redirect URL section, add a new address. Here are the steps to get that URL in Odoo:
  • Go to Settings > Technical > Parameters > System Parameters.
  • Search for web.base.url
  • Copy the base URL and concatenate it with the endpoint. Example: web.base.url: http://192.168.1.7:8017 endpoint: /social_x/callback (this value is fixed) callback_url: http://192.168.1.7:8017/social_x/callback
  • Then go to the Website URL section and add your X profile address. Example: https://x.com/AccountTest
  • Finally, go to the Keys & Tokens tab of the App, press the Regenerate button of the Consumer Key, and then in the window that appears, confirm the generation of the API Key and API Key Secret values. The Console lists that pair under OAuth 1.0 Keys as the Consumer Key, which is the same thing this module and X itself call API Key and API Key Secret. X shows the pair once, and regenerating it again invalidates the one already stored in Odoo: an App whose keys were regenerated after being registered in Odoo answers {"code": 32, "message": "Could not authenticate you."} to the association.

Learn more at the X Developer Console

Registering the API Key and API Key Secret. Integration of a user account.

  • Go to Social Media > Configuration > Social Media
  • Click on the Associate Account button for the desired social media.
  • A wizard will open for you to add the API Key and API Key Secret obtained from your developer account.
  • By clicking the Associate button here, you'll be taken to a X authentication page, which lists what the App is allowed to do with the account. Once you authorize it, you'll be taken back to the system and the Dashboard view, where you'll see your posts.
  • An App that cannot spend against the API is refused here, after the authorization: X answers the reading of the authorized user with 403, the account is not created and the Dashboard explains it. The authorization itself is granted, so nothing has to be undone on the X side. The cause is either the project or the balance, and the Developer Console tells them apart: if the Project Access of the App shows the Default project on Standard Basic, connect the App to the Pay Per Use project as described above; if it already shows a Pay Per Use project, the account has no credit left, so buy credits in Billing > Credits. Then associate again.
  • Once you have completed these steps and everything is working correctly, you can see your account in Social Media > Configuration > Accounts
  • Note that the account credentials (API Key, API Secret and tokens) are only visible to users with administration rights (Settings). The account form shows the API Key in read-only mode and the API Secret masked; the tokens are never displayed.
  • The authorization flow is bound to the session that started it: the request token returned by X only works for the user who opened the wizard. A callback without a request token, or with the request token of another user, is refused without creating or modifying anything; the user gets the generic notice The account could not be associated. Check the server log for details. and the exact reason is kept in the server log, so the raw answer of the provider is never exposed.
  • Each X account has to be associated with its own pair of credentials: if an account already exists (even archived) with the same API Key and API Secret, the association is refused with An account with that information already exists. Create a different developer App for that account.
  • Besides the OAuth 1.0a authorization of the user, the module obtains an application-only bearer token (OAuth 2.0 client credentials) from the same API Key and API Secret; that is the one the reads about the posts answer to — the figures of the recent publications and the check that one of them is still online — while reading the authorized user, which is what the association and the update of the data of the account do, travels with the OAuth 1.0a credentials of the user, see about the X API. If X does not deliver it, the account is not created and the notice The account was not created: the OAuth2 access token could not be obtained. is shown. In the same way, if X does not answer the access token correctly when closing the authorization, the account is not created and the user gets the same generic notice, the reason returned by X being kept in the server log.
  • Publishing with images or video uses the media upload endpoint of the X API v1.1 besides the v2 endpoints. The App has to have access to both: on a plan without that access, the publications with attachments fail even though the text-only ones work.
  • The X account being authorized has to be active and not protected, and the App needs read and write permission. Odoo does not check it beforehand: if X refuses, the error returned by X is displayed on the Dashboard and the account is not associated.
  • If the X account is already linked to an account of another Odoo user, the association is refused and nothing is overwritten: only the responsible user of the account and the Social Media / Administrator group can relink it.

List of posts generated from Odoo.

Only posts generated using Odoo are displayed.

  • Go to Social Media > Posts

Generate a post.

This feature acts as a template for generating multiple posts from a single view, depending on the selected accounts.

  • Go to Social Media > Posts > New or Go to Social Media > Dashboard > Add Post
  • Fill in the required fields
  • When the post is created, every X account of the active company is selected by default in Accounts; review the list and remove the ones you do not want to use before saving.
  • Save
  • Click on the Post button
  • A publication shares the images and the video of its post, so the dashboard card shows them, and its video indicator, as soon as X accepts the message. Nothing waits for an import.

Update token, API Key, API Secret and account data

  • Go to Social Media > Configuration > Accounts
  • Select the account
  • Click on the Update account button
  • In the wizard that appears, if none of the checkboxes are selected and the Update button is pressed, the system will update only the account's data, its X Premium plan included, see X Premium plan of the account below, and read the credit balance of the App again, see Credit balance of the App below.
  • If the Update keys checkbox is selected, the current API Key and API Secret values will be displayed by default. Modify any of these values and authentication will be performed again through X to update these values and the token.
  • Selecting the Update token checkbox will update the current token.
  • Associating the account and updating it end with a success notice and stamp the date of Last Update Account on the account form. Associating it, associating it again, Update token and Update keys show The account was associated successfully on the Dashboard once X sends the user back; Update with no checkbox selected shows The account was updated successfully. If X refuses the figures of the account right after associating it, its error is shown after the success notice.

X Premium plan of the account

How long the message of a post may be depends on the plan of the X user who authorized the account: 280 characters without X Premium and 25 000 with it. Odoo reads that plan from X, it is not set by hand.

  • Go to Social Media > Configuration > Accounts, select the X account and open the Configuration tab. The X Premium switch shows the plan X reported for the account and cannot be changed from the form. It is not carried over when an account is duplicated.
  • The plan is read from X when the account is associated, when it is associated again from Update account with Update keys or Update token, and by Update account with no checkbox selected. The switch is on when X reports any plan of X Premium, whatever its level (Basic, Premium or Premium+), and off when X reports that the user has no subscription. If X does not report the plan, the switch keeps the value it had.
  • The automatic check for updates does not read it. A subscription bought or cancelled on X is seen in Odoo after pressing Update account.
  • X Premium is a subscription of the X user, bought on x.com while signed in with that user, from the Premium entry of its menu. It is not bought in the Developer Console (console.x.com), which belongs to the developer App: its project, its keys, the pay-per-use plan and its credits, see Configuration. The credits of the App do not grant X Premium: an App with credit publishes on an account without the subscription, and that account is still limited to 280 characters.

Credit balance of the App

The calls to the X API are paid from the credits bought for the developer App, see Configuration. The account form shows what is left of them, so the balance can be followed from Odoo and not only from the Developer Console.

  • Go to Social Media > Configuration > Accounts, select the X account and open the Configuration tab.
  • Credit Balance (USD) is the total balance X reports for the App, never negative, with the date it was read next to it. The row stays hidden until the balance has been read once. The accounts of other social media do not show it.
  • The balance belongs to the App that pays the calls, not to the X account: the accounts registered with the same API Key show the same figure, and X is asked once per API Key for all of them.
  • It is read again by the automatic check for updates that runs every 2 hours, when the account is associated, by Update account with no checkbox selected and by Update statistics of the account form.
  • If X or the network does not answer, the balance and its date are left as they were and the reason is only written in the server log: the date tells how old the figure is. The user is not warned and the account is not marked as needing an update. When X answers that the requests for the balance are exhausted, the readings wait for the window to end, without any notice.
  • Credit Warning (USD), on the same tab, is the amount under which the responsible of the account is warned, 1.00 by default. At 0, the warning is only given when the balance is used up.
  • The warning is given when a reading finds the balance under the threshold, once per drop: the following readings under it do not repeat it, and a reading at or over the threshold arms it again. Raising the threshold over the current balance counts as a drop, so the next reading warns.
  • When the balance reaches 0 the warning says it is used up: X blocks every call until credits are bought in the Developer Console.
  • The warning is posted as a note on the chatter of the account that notifies its responsible, which keeps it when nobody is connected while the check runs, and it is shown as a notice to the responsible who is connected, blue when the balance is low and red when it is used up. When the balance is read while the account is being associated, the notice of the user who associates it is shown once X sends the user back to Odoo.
  • Every account holding the same API Key warns its own responsible.

Archive Account X

  • Go to Social Media > Configuration > Accounts
  • Select the account and use the standard Actions > Archive entry of the account form.
  • Please note that all data associated with this account will be archived.
  • To use an archived account again, open it in Social Media > Configuration > Accounts (Archived filter) and use the standard Actions > Unarchive entry: the account and its data are restored instead of creating a duplicate. Update account only reactivates it when Update keys or Update token is ticked, because those are the options that send the user back to X to authorize again. The Associate Account wizard is not the way to do it when the same API Key and API Secret are reused, because it refuses the keys already registered on another account, archived ones included.
  • An archived account can be deleted permanently with the Delete permanently button, only available to a social media administrator. The X publications stay online, only the Odoo history is removed.

X limits and validations

What X refuses is checked in Odoo before the publication is sent. The post shows the reason while it is being written, saving is never blocked, and the publication of the account that raises the objection is refused instead of being sent and failing on X. The same checks are applied when the post reaches the publication through an import or an RPC call, so nothing gets past them.

  • The message is checked against the characters the plan of the account allows: 280 without X Premium and 25 000 with it, see the creation of a post. The plan is the X Premium switch of the account form, read from X, see X Premium plan of the account above. A longer message is reported on the post and the publication is not sent. A post selecting several X accounts is measured against the strictest of them while it is written, and every publication against its own account when it is sent, so only the line that cannot publish is refused. An account whose subscription was cancelled after the plan was last read still shows X Premium, sends the post and X refuses it: that line is left as Failed with the reason and a hint to read the plan again with Update account, see Posts refused by X below.
  • X publishes 4 images or 1 video per publication and never both kinds in the same message, see the media upload documentation. A post mixing them is refused instead of being warned about, and so is one carrying more than four images or more than one video. When the post carries a video, the preview of X shows the video alone, without its images, while the form keeps warning that X refuses the post; the preview of any other social media of the same post is not affected.
  • The images are checked against the formats X publishes, JPG, PNG, WEBP and GIF, and against 5 MB each, 15 MB for a GIF. The video is checked against MP4 and 512 MB. The message names the files that cannot be published.
  • The file picker is not filtered: it accepts any file of type image/* or video/*, and the check is what refuses the ones X does not take.
  • The duration of the video is not checked in Odoo: a video X considers too long is refused by X and the line is left as Failed with the error it returned.
  • A post is refused when it selects two X accounts with the same username: There are X accounts with the same username (...), please check to avoid spam errors. X rejects the same content sent twice from the same account for spam reasons, see the creation of a post, so the post is stopped in Odoo instead of failing halfway through.

Posts refused by X

When X refuses a publication, its line is left as Failed with the reason, which is also posted on the chatter of the post. The other accounts of the post are published as usual, and if every account was refused the post goes back to Draft. What the reason says depends on the answer of X:

  • The developer App cannot spend against the API. X answers 403 Forbidden, either with client-not-enrolled or asking for an App attached to a Project. The reason asks to connect the App to a Pay Per Use project in Project Access > Manage, not the Default project on Standard Basic, and to make sure the account has credit in the Developer Console, see Configuration. It gives the address of the X API pricing page, written as plain text because the reason of a failed publication is kept as text.
  • A message longer than 280 characters, sent by an account X reported as X Premium. X answers 400 Bad Request or 403 Forbidden and the reason is X refused the post of {account}: {answer of X}. What an account may publish depends on its plan, and X reported X Premium for this account when it was last read. Press Update account to read the plan again before trying again. This hint is only given when both conditions hold: it is how a subscription cancelled after the plan was last read shows up.
  • Any other refusal, a 400 Bad Request or a 403 Forbidden for the permissions of the App or the content of the post: X refused the post of {account}: {answer of X}.

The images and the video are uploaded as part of the same publication, so an upload X refuses is explained the same way. None of these refusals marks the account as needing an update: the plan, the permissions of the App or the content of the post are not fixed by authorizing the account again. Only a 401 Unauthorized is taken as a problem with the credentials, see X credentials below.

Rate limits

  • The rate limit is tracked per endpoint. The ones this module spends are linking the account, refreshing the data of the account, publishing (message and media upload), deleting, reading a single post, reading the figures of the recent ones (get_posts) and reading the credit balance of the App; a synchronization module adds its own to the same record. When X answers that it is exhausted, Odoo stores the window it returns and a notice is shown with the limit of the plan, the remaining requests and the time of the next attempt. That stored window is what stops a deletion, a check of a single post and a refresh of the figures before they are attempted; linking the account and publishing are tried all the same and report the limit only once X has refused them, and the refresh of the data of the account does not track its limit at all. If X does not say when the window resets, 60 seconds are assumed. The credit balance is the exception to the notice: its window is stored on every account of the same API Key and waited for in silence, see Credit balance of the App.
  • If X refuses a publication because the requests of the plan are exhausted, the line is left as Failed with the message X did not accept the post. The account may have reached the limit of requests of its plan: check the account and try again later. It is not a content error: wait for the window to end and press Post again, which only sends the failed accounts.
  • A deletion the window does not let happen stops with the message The post could not be deleted on X. The account may have reached the limit of requests of its plan: check the account and try again later., and the publication stays in Odoo. Deleting the line while the tweet is still on X would leave the publication with nothing pointing at it, so the deletion waits for the window to end.
  • Opening a publication, from its form or from its card on the dashboard, reads the tweet on X first. One deleted there answers Not Found and the publication is marked as Deleted on the spot, keeping its reference. The read spends one request of the plan and respects the same window as the rest: while the limit of the get_post endpoint is exhausted the publication is left untouched rather than asked about.
  • The X accounts are walked by the automatic check for updates that runs every 2 hours. The only thing it asks X by itself is the credit balance of the App, one request per API Key: the token of X does not expire and its API reports no figures by day, so the rest of the pass only hands the accounts over to whoever synchronizes them. Without a synchronization module installed, reading the balance is all that happens on that pass.

Figures of a publication

  • The figures of the posts published in the last 30 days — likes, replies, impressions, retweets and quotes — are read back from X once a day, by the Social: Refresh the statistics of the recent publications scheduled action, and on the spot by the Update button of the dashboard and Update statistics of the account form.
  • The Statistics dialog of a publication, opened from the menu of its card on the Dashboard, also shows its Engagement: its likes, replies, retweets and quotes over its impressions, as a ratio from 0 to 1, and 0 while it has no impressions. X reports no rate of its own, so it is derived from those figures every time they are read, by this refresh or by the import of a synchronization module.
  • Nothing walks the timeline to do it: Odoo already knows the identifier of every post it asks about, so they are read by batches of 100 ids per request on its own get_posts endpoint. Reading the timeline is what imports what Odoo did not publish, and that is a synchronization module.
  • Daily and not every two hours because the figures of a publication move slowly while the quota of the plan is counted per day: the window is what bounds what a run spends and the interval is what bounds how many runs there are. For the same reason the buttons read the same bounded window and never the whole account.
  • While the window of get_posts is exhausted the pass asks X for nothing and the publications keep the figures they have, with the date of the reading they come from. What was read before the limit was reached is kept: those requests are spent either way.
  • A post missing from the answer is left untouched. X does not report a post that was deleted or hidden, which is not the same as a post whose figures are zero, so its line keeps its last figures and its date.

Dashboard actions

  • Deleting a publication from the dashboard deletes the post on X first. If X refuses the deletion, the operation is cancelled with the error returned by X and the publication keeps existing both on X and in Odoo.
  • The direct calls to X made while linking the account (token requests and download of the profile image) have a timeout of 10 seconds. If the connection or X take longer, the association fails and has to be repeated.

X credentials

The OAuth 1.0a tokens of X do not expire, so there is nothing to renew: they only stop working when the access is revoked from the X application or the keys are changed. When that happens X answers 401 Unauthorized to the publication, the reason is kept on the failed publication and the account is marked as needing an update. Odoo cannot renew it by itself: associate the account again from Update account. Deleting a publication from Odoo with such a token does not mark the account: the deletion is cancelled and only the error returned by X is shown.

Uninstalling the module

Uninstalling Social Media X does not delete the accounts nor their publication history:

  • The access tokens are cleared, so no credential outlives the module.
  • The X accounts are archived, together with their posts.
  • The X specific data of this module is lost, because Odoo drops the columns of an uninstalled module: the API Key, the API Secret, the OAuth 1 tokens, the app-only bearer token, the rate limit window of each endpoint, the credit balance with its date, the warning threshold, which goes back to its default, and the X Premium switch, which is read from X again when the account is associated after reinstalling. The fields of a synchronization module go with that module, not with this one.
  • The identifier of each account and publication on X is kept, so installing the module back and associating the account again reactivates the archived history and updates it, instead of importing everything as duplicated records.
  • The server log of the uninstallation shows two ERROR lines of bad query: DELETE FROM "social_media", which violates the foreign key social_account_media_id_fkey. They are expected: Odoo tries to delete the X record of Social Media, the archived accounts still point at it, so the deletion is refused and the uninstallation goes on. That record, its identifier and the X value of the media type are kept, and that is what lets the reinstallation reuse the same record instead of creating a second one, and the new association recover the history.
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.