OdooWiki OCA HUB

Social Media X

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

Este módulo proporciona la funcionalidad necesaria para la interacción básica con la red social X.

Características principales:

  • Integración de la cuenta de usuario.
  • Creación de publicaciones.
  • Informes con métricas agnósticas, en la tarjeta de la cuenta del Dashboard. Las cifras las vuelve a leer de X el propio conector: las publicaciones de los últimos 30 días se refrescan una vez al día, y la tarjeta de la cuenta suma los contadores que mantienen sus publicaciones. Un módulo de sincronización amplía lo que se conoce — las publicaciones que Odoo no envió, y el historial anterior a esa ventana — pero la tarjeta no está vacía sin él.
  • Reposts y quotes, las dos cifras que solo X informa. Se muestran como Reposts y Quotes en el diálogo Statistics de una publicación, abierto desde el menú de su tarjeta en el Dashboard, y cuentan para el total de Interactions y la tasa de Engagement de la publicación y de la cuenta.
  • Lo que X no publicará, mostrado en la publicación mientras se escribe. El mensaje se comprueba contra los caracteres que permite el plan de la cuenta, 280 sin X Premium y 25 000 con él, y los medias contra 4 imágenes de 5 MB como máximo cada una — 15 MB para un GIF — en JPG, PNG, WEBP o GIF, y un vídeo de 512 MB como máximo en MP4. X acepta imágenes o un vídeo, nunca ambos en la misma publicación, por lo que una publicación que los mezcla se rechaza en lugar de advertirse. Las mismas comprobaciones rechazan la publicación si la publicación llega a ella de todos modos, mediante una importación o una llamada RPC.
  • El saldo de crédito de la App de desarrollador que paga las llamadas a la API de X, en el formulario de la cuenta. Se lee de X cada 2 horas y desde los botones de la cuenta, y se advierte al responsable de la cuenta cuando baja de un umbral establecido en la cuenta o se agota.

**Una cuenta de X nunca dibujará una serie temporal en Social Media > Statistics.** Esa pantalla lee un historial por día, y las métricas que responde la API v2 son los contadores actuales de por vida de cada publicación, sin forma de pedirlos agrupados por día. Dar una serie a X significa o bien repetir el contador de por vida en cada día, lo que dibuja una curva acumulativa de forma distinta a la de las otras redes sociales en el mismo gráfico, o bien almacenar el delta entre dos lecturas, lo que es falso para cualquier día en que la acción programada no se ejecutó. Ninguna de las dos es una medición, así que no se escribe nada: una cuenta de X muestra allí la vista vacía estándar, y sus cifras viven en su tarjeta del Dashboard, que es donde significan algo.

Traducción automática al español (DeepSeek) de la descripción original de OCA, que está en inglés.

auto_awesome Qué hace este módulo

Generado por IA a partir del código · Odoo 17.0

Conecta cuentas de X (Twitter) a Odoo y publica posts con imágenes o vídeos directamente desde el panel de redes sociales, y luego lee los me gusta, impresiones, respuestas, reposts y citas de cada publicación.

Este módulo añade X como una red social a la que puedes vincular Odoo y publicar. Desde el panel de redes sociales abres la tarjeta de X, pulsas para añadir una cuenta y sigues el flujo de autorización de X; a continuación, el nombre de la cuenta, el nombre de usuario y la foto de perfil se rellenan automáticamente, y la cuenta se marca como X Premium o no.

En la tarjeta de la cuenta puedes almacenar las credenciales de la App de desarrollador (API Key, API Secret, tokens de lectura y escritura), que solo ven los administradores. El módulo también muestra el saldo de crédito restante de la App en dólares estadounidenses, que se lee de nuevo cada dos horas y al pulsar Update account o actualizar estadísticas, con un umbral de aviso que puedes establecer; se avisa al responsable en el chatter y en pantalla cuando el saldo baja de ese umbral o se agota.

Al redactar una publicación puedes seleccionar cuentas de X (vienen preseleccionadas para la compañía activa). El módulo comprueba lo que acepta X: longitud máxima del mensaje (280 caracteres, o 25 000 para cuentas X Premium), número y tamaño de imágenes y vídeos, y se niega a enviar la misma publicación dos veces a cuentas que comparten el mismo nombre de usuario de X para evitar errores de spam.

En cada línea de publicación puedes actualizar las estadísticas: los me gusta, las impresiones, las respuestas, los reposts y las citas se leen de X, y se calcula una tasa de interacción como interacciones sobre impresiones. Los reposts y las citas aparecen en el diálogo de estadísticas de la publicación. Si X rechaza una publicación o alcanza un límite de solicitudes, el usuario recibe una explicación y el tiempo para reintentar.

Lo necesitan otros módulos

Modelos y campos (6)
  • social.post · amplía un modelo existente
  • social.media · amplía un modelo existentemedia_type
  • social.account · amplía un modelo existentex_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 · amplía un modelo existente
  • wizard.social.account · amplía un modelo existentex_api_key (API Key), oauth_token, x_api_secret (API Secret)
  • social.statistics.mixin · amplía un modelo existentequote_count, retweet_count

Texto generado por IA (DeepSeek) al leer el código de la versión 17.0 en GitHub; puede contener errores, así que verifícalo en el código antes de decidir. El módulo es muy grande y solo se ha leído una parte del código. Ver el código en GitHub

Disponibilidad por versión

Revisado: 2026-11-03
Confirmado (verificado en repositorio y rama) Estimado (sin verificar) Sin información

Estado de confirmación: 1 confirmada, 8 sin información de 9 versiones.

terminal Instalación y uso

Documentación de OCA · Odoo 17.0

Este módulo requiere las siguientes librerías de Python:

  • tweepy 4.0 o superior, porque el módulo utiliza el cliente de la X API v2 (tweepy.Client) además del cliente v1.1 para la subida de medios.
  • requests_oauthlib

Puedes instalarlas con:

pip install tweepy requests_oauthlib

Para configurar este módulo, debe: Tenga en cuenta que debe tener una cuenta de desarrollador.

Importante: los endpoints de la API v2 de X que utiliza este módulo requieren una App de desarrollador conectada a un proyecto de Pago por Uso y una cuenta con crédito en la tarifa de pago por uso de X, consulte sobre la API de X. No existe un nivel de acceso Gratuito: una App que permanece en el proyecto Default, cuyo plan es Standard Basic, no puede gastar contra la API y es rechazada, por lo que la cuenta no puede asociarse a ella. El pago por uso no es una suscripción — no hay cuota mensual ni compra mínima, la App solo necesita un saldo de crédito positivo — pero el saldo tiene que estar ahí antes de la primera llamada. El asistente de asociación muestra esta advertencia, y cuando X rechaza la solicitud por este motivo el módulo sustituye el error en bruto por un mensaje que pide conectar la App a un proyecto de Pago por Uso en Project Access > Manage, no al proyecto Default en Standard Basic, para asegurarse de que la cuenta tiene crédito en la Developer Console, y que enlaza a la página de tarifas. Tenga en cuenta que dicha App puede ser rechazada en dos momentos distintos: cuando se solicita el token de solicitud, antes de que se muestre cualquier pantalla de autorización, y el asistente responde con ese mensaje; o más tarde, cuando el módulo lee el usuario autorizado, y el mensaje se entrega entonces en el Dashboard.

Una llamada realizada con una App que no puede gastar responde 403 Forbidden, ya sea con "reason": "client-not-enrolled" o solicitando una App adjunta a un Proyecto, ya que solo una App inscrita puede pertenecer a uno. Todos los endpoints que utiliza este módulo se ven afectados: vincular la cuenta, actualizar los datos de la cuenta, publicar (mensaje y carga de medios), eliminar, comprobar si una publicación sigue en línea y leer las cifras de las recientes.

Lo que cuesta cada llamada del módulo, según la tarifa de X:

| Qué hace el módulo | Endpoint | Precio | | --- | --- | --- | | Publicar una publicación | Creación de publicación | $0.015 | | Publicar una publicación que lleva un enlace | Creación de publicación con URL | $0.200 | | Leer las cifras de sus propias publicaciones | Lectura propia | $0.001 por publicación | | Leer el usuario autorizado | Usuarios | $0.010 |

Una publicación que lleva un enlace cuesta más de diez veces que una publicación que no lo lleva. X factura el enlace en sí, esté rastreado o no: social_media_base solo enruta los enlaces de una publicación a través de link_tracker cuando promueve una campaña de marketing, y un enlace rastreado sigue siendo un enlace. Que una publicación lleve uno es la única decisión que mueve la factura de una base de datos que solo publica.

El mismo recurso solicitado dos veces en 24 horas se cobra una vez, que es lo que mantiene baratas las acciones programadas del módulo: la comprobación de actualizaciones de la red cada dos horas y la actualización diaria de las cifras leen las mismas publicaciones una y otra vez.

Así que una base de datos que solo publica gasta céntimos al mes: este módulo no lee nada más que sus propias publicaciones, al precio de una lectura propia, y el saldo de crédito de la App, una vez por API Key, que no está entre las llamadas que enumera la tarifa de X. Lo que crece con la cuenta es el historial, y el historial lo lee Social Media X Sync, que es un módulo aparte que nadie tiene que instalar. Un despliegue que publica y vigila sus propias cifras no lo necesita.

No hay forma de evitar la API para lo que hace este módulo. Publicar en X a través de cualquier otra cosa significa o bien un revendedor que paga la misma API y lo cobra por encima, o bien manejar la web con la sesión del usuario, lo que sus términos de servicio prohíben y este módulo no implementa.

  • Tarifas y planes de la API de X: https://docs.x.com/x-api/getting-started/pricing
  • Límites de tasa según el plan: https://docs.x.com/x-api/fundamentals/rate-limits
  • Cómo obtener acceso a la API: https://docs.x.com/x-api/getting-started/getting-access

Creación de la cuenta de desarrollador La cuenta de desarrollador no es la cuenta de X: es la inscripción de esa cuenta de X en la API, y se solicita una vez por organización, no por cuenta social publicada desde Odoo.

  • Inicie sesión en la Developer Console con la cuenta de X propietaria de la App y pulse Start Building. No tiene que ser la cuenta cuyas publicaciones publica Odoo — la App pertenece a quien la administra, y cada cuenta la autoriza después desde el asistente de Social Media X. Acepte el Developer Agreement and Policy si X lo solicita.
  • Cree un proyecto. El caso de uso declarado aquí es lo que X lee si alguna vez revisa la App. Un proyecto comienza en el plan predeterminado de su producto, por lo que puede nacer en Standard Basic, el plan del proyecto Default que la consola puede mostrar ya con Plan: Free. Solo un proyecto en Pago por Uso gasta contra el saldo de crédito, así que es a ese al que la App tiene que estar conectada, consulte Project Access más abajo.
  • Cree la App. La App es el conjunto de claves, y el proyecto es lo que esas claves tienen permitido llamar, así que una App conectada a ningún proyecto responde 403 a todo, y lo mismo hace una App conectada solo al proyecto Default en Standard Basic. No dé por sentado a qué proyecto está conectada una App nueva: compruebe lo que muestra su Project Access, como se describe más abajo.
  • Añada un método de pago en Billing > Billing information con Add Payment Method, siguiendo los pasos que solicita X.
  • Compre créditos desde el Dashboard o desde Billing > Credits, antes de asociar cualquier cuenta en Odoo: leer el usuario autorizado ya es una llamada facturada, así que una App sin saldo falla en la propia asociación y nunca llega al Dashboard de Odoo. En esa misma pantalla se establece un límite de gasto por ciclo de facturación, y es lo que evita que un error gaste más de lo previsto — cuando se alcanza el límite X bloquea las solicitudes hasta el siguiente ciclo.

Las pantallas siguientes son las del portal de desarrolladores. X las mueve de vez en cuando; lo que importa son los nombres de los ajustes, no dónde los coloca la imagen.

Los pasos necesarios para usarlo se definen a continuación:

  • Vaya a la Developer Console
  • Cree una cuenta de desarrollador como se describe arriba.
  • Una vez creada la cuenta, vaya a Access > Apps y seleccione la App. Lo que muestra como Project Access es el proyecto a través del cual llaman sus claves, con su plan entre paréntesis. Una App en Default project-… (Standard Basic), como en la imagen de abajo, no puede gastar contra la API y X la rechaza.
  • En ese caso pulse Manage en Project Access. El diálogo enumera los proyectos de la cuenta, cada uno con su plan y un botón Connect o Disconnect: pulse Connect en el de Pago por Uso. Las claves funcionan en cada proyecto al que está conectada la App, y los límites y endpoints siguen el plan de ese proyecto. No hay que regenerar las claves: una App conectada de esta forma se asocia con el Consumer Key y Secret que ya tenía. Start a new project, en la parte inferior del mismo diálogo, ofrece los productos Ads, Enterprise y Community Notes, ninguno de los cuales es el proyecto de Pago por Uso que necesita este módulo. Una vez conectada, la página de la App muestra el proyecto de Pago por Uso en Project Access.
  • Abra Settings para llegar a los ajustes de autenticación de la App.
  • Una vez en la página, en la sección App Permissions, seleccione Read and write, que es lo que necesitan los endpoints que llama este módulo.
  • Vaya a la sección App Type y seleccione Web App, Automated App or Bot.
  • Después, en la sección Callback URI / Redirect URL, añada una nueva dirección. Estos son los pasos para obtener esa URL en Odoo:
  • Vaya a Settings > Technical > Parameters > System Parameters.
  • Busque web.base.url
  • Copie la URL base y concaténela con el endpoint. Ejemplo: web.base.url: http://192.168.1.7:8017 endpoint: /social_x/callback (este valor es fijo) callback_url: http://192.168.1.7:8017/social_x/callback
  • Después vaya a la sección Website URL y añada la dirección de su perfil de X. Ejemplo: https://x.com/AccountTest
  • Por último, vaya a la pestaña Keys & Tokens de la App, pulse el botón Regenerate del Consumer Key, y luego en la ventana que aparece, confirme la generación de los valores API Key y API Key Secret. La Console enumera ese par en OAuth 1.0 Keys como el Consumer Key, que es lo mismo que este módulo y X mismo llaman API Key y API Key Secret. X muestra el par una vez, y regenerarlo de nuevo invalida el ya almacenado en Odoo: una App cuyas claves se regeneraron después de registrarse en Odoo responde {"code": 32, "message": "Could not authenticate you."} a la asociación.

Más información en la X Developer Console

Registro de la API Key y API Key Secret. Integración de una cuenta de usuario.

  • Vaya a Social Media > Configuration > Social Media
  • Pulse el botón Associate Account para la red social deseada.
  • Se abrirá un asistente para añadir la API Key y API Key Secret obtenidas de su cuenta de desarrollador.
  • Al pulsar el botón Associate aquí, se le llevará a una página de autenticación de X, que enumera lo que la App tiene permitido hacer con la cuenta. Una vez que la autorice, se le devolverá al sistema y a la vista Dashboard, donde verá sus publicaciones.
  • Una App que no puede gastar contra la API es rechazada aquí, después de la autorización: X responde a la lectura del usuario autorizado con 403, la cuenta no se crea y el Dashboard lo explica. La autorización en sí se concede, así que no hay que deshacer nada en el lado de X. La causa es el proyecto o el saldo, y la Developer Console los distingue: si el Project Access de la App muestra el proyecto Default en Standard Basic, conecte la App al proyecto de Pago por Uso como se describe arriba; si ya muestra un proyecto de Pago por Uso, la cuenta no tiene crédito restante, así que compre créditos en Billing > Credits. Después asocie de nuevo.
  • Una vez que haya completado estos pasos y todo funcione correctamente, puede ver su cuenta en Social Media > Configuration > Accounts
  • Tenga en cuenta que las credenciales de la cuenta (API Key, API Secret y tokens) solo son visibles para usuarios con derechos de administración (Settings). El formulario de la cuenta muestra la API Key en modo de solo lectura y el API Secret enmascarado; los tokens nunca se muestran.
  • El flujo de autorización está vinculado a la sesión que lo inició: el token de solicitud devuelto por X solo funciona para el usuario que abrió el asistente. Una callback sin token de solicitud, o con el token de solicitud de otro usuario, se rechaza sin crear ni modificar nada; el usuario recibe el aviso genérico The account could not be associated. Check the server log for details. y el motivo exacto se guarda en el registro del servidor, de modo que la respuesta en bruto del proveedor nunca se expone.
  • Cada cuenta de X tiene que asociarse con su propio par de credenciales: si ya existe una cuenta (incluso archivada) con la misma API Key y API Secret, la asociación se rechaza con An account with that information already exists. Create a different developer App for that account.
  • Además de la autorización OAuth 1.0a del usuario, el módulo obtiene un token de portador solo de aplicación (credenciales de cliente OAuth 2.0) a partir de la misma API Key y API Secret; ese es al que responden las lecturas sobre las publicaciones — las cifras de las publicaciones recientes y la comprobación de que una de ellas sigue en línea — mientras que leer el usuario autorizado, que es lo que hacen la asociación y la actualización de los datos de la cuenta, viaja con las credenciales OAuth 1.0a del usuario, consulte sobre la API de X. Si X no lo entrega, la cuenta no se crea y se muestra el aviso The account was not created: the OAuth2 access token could not be obtained. Del mismo modo, si X no responde correctamente al token de acceso al cerrar la autorización, la cuenta no se crea y el usuario recibe el mismo aviso genérico, guardándose el motivo devuelto por X en el registro del servidor.
  • Publicar con imágenes o vídeo utiliza el endpoint de carga de medios de la API v1.1 de X además de los endpoints v2. La App tiene que tener acceso a ambos: en un plan sin ese acceso, las publicaciones con adjuntos fallan aunque las de solo texto funcionen.
  • La cuenta de X que se autoriza tiene que estar activa y no protegida, y la App necesita permiso de lectura y escritura. Odoo no lo comprueba de antemano: si X rechaza, el error devuelto por X se muestra en el Dashboard y la cuenta no se asocia.
  • Si la cuenta de X ya está vinculada a una cuenta de otro usuario de Odoo, la asociación se rechaza y no se sobrescribe nada: solo el usuario responsable de la cuenta y el grupo Social Media / Administrator pueden volver a vincularla.

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.

Documentación original de OCA, en inglés: aún no está traducida.

info

Datos importados de GitHub: esta ficha refleja la última revisión del catálogo, no una consulta en directo. Verifica siempre en la documentación del módulo y en staging antes de instalar en producción.