Je possède actuellement un sujet sur un site, que j’aimerais avoir également sur un autre site. Bien que je puisse le lier par hyperlien, ce que j’aimerais vraiment, c’est la possibilité de le modifier sur l’un ou l’autre site, et que les modifications soient reflétées sur les deux. Cela m’évite d’avoir une version du sujet qui est très obsolète, et maintient plutôt les deux sujets constamment à jour. Cela me permet également de décentraliser les informations de mon site.
Quelques réflexions sur la fonctionnalité
Pour commencer, un site resterait l’hôte/propriétaire du sujet, et l’autre (ou les autres) le refléterait essentiellement. En allant plus loin, je me demande même si un sujet pourrait être hérité par un sujet miroir si l’original est supprimé.
Le sujet devrait conserver la possibilité d’être caché, fermé, etc. sur les sites miroirs.
Les réponses ne devraient pas être synchronisées – chaque site a une base d’utilisateurs différente, donc je ne vois pas comment la synchronisation des réponses pourrait fonctionner.
Je comprends que la mise en œuvre d’une telle fonctionnalité est loin d’être triviale, mais je me demande si cela a déjà été étudié, et quels résultats/expériences existent déjà ?
Avoir du contenu dupliqué sur plusieurs sites est un gros problème pour le référencement naturel (SEO). Il est peu probable que cela soit pris en charge.
Quel est le cas d’utilisation ou le but ? Vous voulez essentiellement que les autres sites soient une sauvegarde du site principal ?
Pourriez-vous donner plus d’informations à ce sujet ? De mon point de vue, cela réduirait le contenu dupliqué.
La sauvegarde n’est pas l’objectif, mais plutôt de créer un point de vérité unique pour des sujets qui auraient du sens sur plus d’un site.
Pour donner un exemple concret, je suis en train de changer mon visa. J’ai un sujet dans mon Discourse privé qui est essentiellement une liste de contrôle de ce qui doit être fait. Cependant, mes amis pourraient également trouver cela utile, alors je crée le même sujet sur notre Discourse partagé. Le problème est que je dois synchroniser les informations des deux sujets séparément au lieu de simplement mettre à jour un seul sujet. Cela signifie que l’un des sujets manque souvent d’informations clés.
Je suppose que cela pourrait même être possible avec juste une clé API pour l’autre site ? Peut-être quelque chose comme un bouton/une section dans l’éditeur où une liste de clés API et d’URL pour le sujet cible peut être créée. Lorsque vous apportez des modifications à un sujet source, vous pouvez cliquer sur quelque chose comme « pousser les modifications vers les clones de ce sujet ». Tout ce que cela ferait serait de pousser la mise à jour vers les sujets sur d’autres instances.
Mettez les informations en un seul endroit où tout le monde peut les voir. Un lien est un moyen de faire cela.
Mais vous avez des informations secrètes que vous souhaitez rendre disponibles ailleurs. C’est autre chose. C’est tout à fait possible avec un plugin. C’est le genre de problème où la solution artificielle demande 10 fois plus de travail que le problème réel. (Je passe souvent des heures à automatiser une tâche qui ne doit se produire qu’une seule fois, par exemple.)
Mais vous devriez le mettre quelque part où il ne serait disponible qu’à l’utilisateur qui l’a posté. Ou le rendre global au site ?
Encore une fois, ils doivent être par utilisateur et dans le sérialiseur uniquement pour l’utilisateur actuel (ou peut-être le stocker dans le profil utilisateur ?). Et vous auriez besoin d’une structure de données pour mapper les clés d’API aux différents sites. Cela ressemble à quelque chose que je penserais pouvoir faire en 2 à 5 heures.
Donc, vous devez stocker quelque part l’URL des autres sites qui sont censés avoir ce sujet. La façon de créer ce post pourrait également être compliquée ; le moyen le plus simple est de le créer manuellement et d’inclure l’URL de ce sujet sur le site source. Vous pourriez probablement stocker cela dans le post brut sous une sorte de BBcode ou quelque chose de similaire. Cela vous permettrait de créer un composant qui créerait le bouton et le lien pour chacun d’eux, puis vous auriez du code Rails qui mettrait en file d’attente un travail qui essaierait de le publier sur le(s) autre(s) site(s). Mais les sites récepteurs n’auraient pas besoin de code - vous pourriez utiliser l’API pour pousser une modification au post.
Cela ressemble au genre de chose que je penserais pouvoir faire en 5 à 10 heures, mais qui en prendrait probablement le double. Si cela vous amuse, alors cela pourrait être un projet intéressant.
Cela pourrait également être fait via une petite application externe qui écouterait un webhook envoyé lors des modifications sur votre site source, puis utiliserait l’API pour publier sur le site miroir.
Un plugin pourrait ajouter un champ de sujet personnalisé pour l’URL de la source du document principal. (Je suppose qu’il faudrait aussi des champs pour un nom d’utilisateur distant et une clé API si le document principal doit être caché, comme je pense que c’est votre cas, mais cette partie pourrait attendre. Ou peut-être qu’ils pourraient vivre dans un champ personnalisé d’utilisateur. Ce serait à celui qui a généré la clé de s’assurer que la clé API a des privilèges en lecture seule).
Lors de la création d’un sujet, vous saisiriez quelque chose comme « remote: https://meta.discourse.org/t/synchronising-crossposting-topics-across-different-discourse-sites/263269 » et lorsque le sujet serait créé, Discourse récupérerait le texte brut du sujet distant, l’insérerait dans raw en tant que modification et instancierait le topic_custom_field avec l’URL distante, ajoutant peut-être un « copié depuis url » en haut.
À ce stade, vous avez copié le sujet distant localement et en avez une trace.
Il pourrait alors y avoir un bouton « vérifier la source » qui récupérerait le sujet distant et enregistrerait updated_at du sujet distant et peut-être même le raw dans d’autres champs personnalisés (un travail pourrait également le faire périodiquement, économisant un peu d’UX). Vous pourriez alors avoir un bouton de mise à jour qui remplacerait le raw existant par celui du distant en tant que modification.
Si le site principal est public, alors cette partie est vraiment facile. L’ajout d’une clé API pour récupérer à partir d’un site privé complique les choses, la gestion d’un ensemble de clés API sur plusieurs sites complique encore plus. Si la source d’origine devait être remplacée, vous pourriez peut-être le faire avec la tâche rake remap, ou ajouter la possibilité de modifier le champ personnalisé avec l’URL distante lorsque vous en avez besoin.
Cette partie est gratuite, car cette solution permet aux sites secondaires de récupérer les données du site principal.
Exact. Et il peut y avoir un lien vers le site source, afin que les gens puissent aller à la source pour voir ces commentaires, ou peut-être même les intégrer via Embed comments from Discourse in your single page app.
Si vous avez un budget, n’hésitez pas à me contacter.
J’y pense depuis un moment, bien que cela n’ait pas beaucoup progressé jusqu’à récemment. Malheureusement, la synchronisation de Discourse à Discourse a perdu de sa valeur pour moi (il ne s’agissait que d’une poignée de sujets), mais ce qui a pris de la valeur, c’est le désir de synchroniser des fichiers markdown d’autres plateformes en général.
Notre cas d’utilisation dominant dans l’entreprise était d’avoir les readmes et les wikis des projets Gitlab disponibles dans Discourse (pour les commentaires et la recherche), mais avec le fichier Gitlab restant comme source unique de vérité. Mon manque de connaissances en Ruby a abouti à un script Python qui est certainement excessif dans sa mise en œuvre, mais satisfaisant dans sa fonctionnalité. La première version décente fait également une partie de ce que vous avez décrit. Certaines fonctionnalités :
contient un lien vers la source originale (fichier dans Gitlab)
contient un lien vers la révision spécifique (commit # Gitlab)
gère les images et les URL d’images
télécharge les images du dépôt Gitlab
les télécharge sur Discourse
remplace l’URL d’image d’origine par l’URL courte du téléchargement
ajoute une balise “synced_with_gitlab” pour qu’il soit facile de toutes les trouver
Cela a fonctionné plus ou moins de la même manière avec Github également. Les deux ont plus ou moins la même saveur de markdown, ce qui le rend assez élégant.
J’aimerais beaucoup rendre cela open source, mais je devrai voir ce que le service juridique en dit. De plus, c’est encore un peu un désordre python hacky. L’intention est de convertir cela en un plugin Ruby à un moment donné, mais je devrai voir si je peux trouver le temps nécessaire.
C’est vrai. Je m’attaque à nouveau à ce projet et j’envisage actuellement de créer une base de données avec :
Une table par plateforme (table Discourse, table Gitlab, etc.) pour tenir compte des nuances possibles
Chaque table de plateforme prenant en charge les webhooks et le polling via clé API
Chiffrement de la base de données ou de la clé API – je pense actuellement qu’il est préférable de chiffrer toute la base de données et d’y accéder via le script et une phrase secrète
Cela vous semble-t-il fou et trop complexe ? Une partie de moi veut construire une solution appropriée pour cela, ce qui impliquerait de tenir compte des deux possibilités - webhook et polling.
De plus, je serais très reconnaissant pour des suggestions concernant la sécurisation du contenu de la base de données. La pensée actuelle est de chiffrer la base de données avec une phrase secrète qui doit être fournie comme argument lors du démarrage du script, par exemple :
discourse-sync run password123
Juste pour vous inspirer, le webhook peut être super rapide :
Il s’agissait de deux sujets sur deux instances différentes. Le sujet de gauche est le sujet source, le sujet de droite est la cible.
Pour ce que ça vaut, cette idée m’a traversé l’esprit à plusieurs reprises également. Je ne suis pas sûr que nous ayons un sujet dédié à cela ici, mais si ce n’est pas le cas, nous devrions en créer un !
Théoriquement d’accord, malheureusement le monde de l’entreprise complique les choses :
les webhooks ne sont pas possibles dans l’entreprise en raison des politiques informatiques (nous sommes hébergés en dehors de l’entreprise par CDCK + nous ne pouvons pas autoriser le transfert de ports vers le monde extérieur sans un processus lourd) - par conséquent, la version API est un must
Les webhooks sont rapides, agréables et tout à fait raisonnables pour tout le monde, il est donc logique de les prendre en charge également
J’ai donc réalisé une version approximative de cela il y a un moment, cela fonctionne à merveille mais n’est pas extensible. Mauvaise conception de ma part : j’explorais l’idée d’utiliser un sujet avec un tableau markdown comme entrée. Super jusqu’à ce qu’il y ait plus de 30 entrées, alors c’est un désordre.
Une partie du cas d’utilisation de discourse à discourse que je vois est : un point de vérité unique pour la documentation (Meta) se synchronise avec les publications respectives sur d’autres instances. Cela signifie que si l’équipe change Core et met à jour la documentation utilisateur Meta, j’ai une version à jour de cette documentation dans mon instance nativement pour que tous les utilisateurs la trouvent.
Pour la V2, je prévois une base de données SQLlite comme entrée ci-dessus, et j’écrirai probablement en Rust cette fois au lieu de Python.
Ci-dessous une esquisse approximative.
graph TB
A[terminal] -- ~\u003ediscourse-sync run $PASSWORD --\u003e B[Rust Script]
B -- SQLCipher:Decrypt DB using Password --\u003e C[( sqlite: sources-and-targets')]
C -- 'Discourse' Table Data --\u003e B
B -.-\u003e D{Decision on Type}
D -- Webhook --\u003e E[Listen for Webhook Info]
D -- Polling --\u003e F[Polling API]
E --\u003e G[Receive New Information]
F --\u003e G
G --\u003e H[Parse and Process Data]
H --\u003e I[POST\n tgt_domain, tgt_usr, tgt_key, post_id]
I --'raw' and images--\u003e J[ Target Post ]
subgraph Rust Script Operations
B
D
E
F
G
H
I
end
Je serais très heureux de recevoir des commentaires et des suggestions à ce sujet
Oui, ceci est maintenant pris en charge par le plugin ActivityPub. Nous sommes très proches de l’utiliser en interne pour synchroniser la documentation entre meta et une instance interne, c’est d’ailleurs sur ma liste de tâches pour la semaine prochaine.
Il s’applique bien aux instances privées, dans la version actuelle du plugin AP, les instances privées peuvent suivre les catégories dans les instances Discourse publiques et donc recevoir les activités publiées de ces instances. (Mais le contenu de l’instance privée n’est pas publié, il s’agit donc d’une synchronisation unidirectionnelle, du public vers le privé uniquement.)
Donc, il semble que ActivityPub puisse fonctionner de la manière suivante :
Public – Public
Public – Privé
Privé – Public
Privé – Privé
C’est certainement utile dans de nombreux cas, comme la diffusion de documentation depuis Meta. Malheureusement, cela ne répond pas encore à l’un de mes cas d’utilisation, qui consiste à publier depuis une instance privée vers une autre instance privée. D’après mes recherches, ai-je raison de penser que le plugin ActivityPub ne supportera probablement pas ces cas d’utilisation à l’avenir ? Il me semble qu’ActivityPub a été conçu en pensant au public vers le public.
@Tris20 Intéressant ! Merci d’avoir partagé vos réflexions et quelques détails à ce sujet.
Ce que vous avez décrit est (l’un des) problèmes qu’ActivityPub a été conçu pour résoudre. Je ne veux pas trop vous décourager, mais pour être honnête, vous allez rencontrer un large éventail de défis en essayant d’accomplir cela de la manière dont vous le décrivez. Je ne vais pas vous donner un compte rendu exhaustif de chaque défi que vous devrez surmonter, mais pour vous donner une idée, le plugin ActivityPub a déjà près de 700 tests rspec et après un an de développement, il ne prend que très récemment en charge la synchronisation complète de sujet à sujet.
Il n’y a pas de limitation inhérente, à ma connaissance, à la prise en charge de la publication de Privé à Public et de Privé à Privé via ActivityPub. La question est de s’assurer que les préoccupations en matière d’accès et de sécurité sont satisfaites lors de l’utilisation d’instances privées.
Si je pouvais faire une suggestion. Pensez peut-être à la manière dont vous pouvez vous appuyer sur le travail que le plugin ActivityPub (et le standard ActivityPub) a déjà accompli à cet égard. Il existe en fait une solution au problème de synchronisation de contenu de Discourse à Discourse qui fonctionne actuellement. Elle ne couvre pas encore votre cas d’utilisation, mais elle résout la majorité des problèmes que vous devrez résoudre pour répondre à vos besoins.
Peut-être pourriez-vous réfléchir à la manière dont une synchronisation privée à privée pourrait fonctionner dans le plugin, c’est-à-dire comment les questions d’accès et de sécurité pourraient être traitées ? Ensuite, peut-être que vous et moi pourrions même travailler ensemble sur une PR pour l’ajouter en tant que fonctionnalité. Peut-être atteindrez-vous un point où vous sentirez qu’il n’est vraiment pas possible de réaliser ce que vous voulez réaliser dans le contexte du plugin (ou d’ActivityPub en tant que standard), mais le travail que vous aurez effectué pour atteindre ce point serait effectivement le même travail que vous auriez besoin de faire pour une solution indépendante, donc ce ne serait pas vain.
Il y a beaucoup de personnes intelligentes dans le monde d’ActivityPub, et je ne serais pas surpris si ce type de problème (c’est-à-dire la publication privée) a été considéré en profondeur auparavant. Un endroit où vous pourriez trouver des travaux antérieurs à ce sujet est SocialHub, le principal forum communautaire d’ActivityPub (Discourse bien sûr) qui utilise maintenant le plugin Discourse ActivityPub