Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e92a963088 | |||
| f3a8246e34 | |||
| c9f50e452b | |||
| c820d015e7 | |||
| 78cbd1f370 | |||
| 70d2bab52d | |||
| 166a6366f8 | |||
| ac8a64c4c1 | |||
| 2ee8a5e286 | |||
| 9d2620faea |
@@ -5,7 +5,7 @@
|
||||
<display-name>Package - MokoSuiteCross</display-name>
|
||||
<org>MokoConsulting</org>
|
||||
<description>Cross-posting Joomla content to social media, email marketing, and chat platforms</description>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
|
||||
</identity>
|
||||
<governance>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: Gitea.Workflow
|
||||
# INGROUP: mokocli.Automation
|
||||
# VERSION: 01.05.00
|
||||
# VERSION: 01.06.00
|
||||
# BRIEF: Auto-create feature branch when an issue is opened
|
||||
|
||||
name: "Universal: Issue Branch"
|
||||
|
||||
+5
-16
@@ -1,6 +1,10 @@
|
||||
# Changelog
|
||||
## [Unreleased]
|
||||
|
||||
## [01.06.00] --- 2026-06-23
|
||||
|
||||
## [01.06.00] --- 2026-06-23
|
||||
|
||||
## [01.05.00] --- 2026-06-23
|
||||
|
||||
## [01.05.00] --- 2026-06-23
|
||||
@@ -35,24 +39,9 @@
|
||||
- **Medium**: Fixed getUserId() returning array instead of string on error
|
||||
- **Bluesky**: Replaced md5() with hash('sha256', ...) for cache key
|
||||
- **ServiceController**: Exception details no longer exposed to client
|
||||
- **License warning**: Removed duplicate from system plugin -- install script already shows it with direct edit link
|
||||
|
||||
## [01.04.01] --- 2026-06-21
|
||||
|
||||
|
||||
## [01.04.01] --- 2026-06-21
|
||||
|
||||
|
||||
## [01.04.00] --- 2026-06-21
|
||||
|
||||
### Fixed
|
||||
- **Package manifest**: Added missing `plg_system_mokosuitecross_events` and `plg_system_mokosuitecross_gallery` to `pkg_mokosuitecross.xml` — these system plugins were not installed with the package
|
||||
- **Cleanup**: Removed old `src/` directory (pre-rename cruft with `mokojoomcross` files)
|
||||
|
||||
## [01.03.00] --- 2026-06-21
|
||||
|
||||
|
||||
<!-- VERSION: 01.05.00 -->
|
||||
|
||||
All notable changes to MokoSuiteCross will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# MokoSuiteCross
|
||||
|
||||
<!-- VERSION: 01.05.00 -->
|
||||
<!-- VERSION: 01.06.00 -->
|
||||
|
||||
Cross-posting Joomla content to social media, email marketing, and chat platforms for Joomla 5/6.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="component" method="upgrade">
|
||||
<name>com_mokosuitecross</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="content" method="upgrade">
|
||||
<name>Content - MokoSuiteCross</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - ActivityPub (Fediverse)</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Google Blogger</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Bluesky</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Brevo (Sendinblue)</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Constant Contact</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - ConvertKit</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Dev.to</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Discord</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Facebook / Meta</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Ghost</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Google Business Profile</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Google Chat</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Hashnode</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Instagram</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-06-23</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - LinkedIn</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Mailchimp</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Mastodon</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Matrix / Element</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Medium</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - MokoSuiteCalendar Events</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - MokoSuiteGallery</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Nostr</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Ntfy Push Notifications</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Pinterest</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Reddit</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - RSS Feed</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - SendGrid</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Slack</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Microsoft Teams</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Telegram</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Threads (Meta)</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - TikTok</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Tumblr</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - X / Twitter</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Generic Webhook</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - WhatsApp Business</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - WordPress</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>MokoSuiteCross - Youtube</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-06-23</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="system" method="upgrade">
|
||||
<name>System - MokoSuiteCross</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -34,20 +34,10 @@ class MokoSuiteCross extends CMSPlugin implements SubscriberInterface
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
'onAfterRoute' => 'onAfterRoute',
|
||||
'onAfterRender' => 'onAfterRender',
|
||||
];
|
||||
}
|
||||
|
||||
public function onAfterRoute(): void
|
||||
{
|
||||
$app = $this->getApplication();
|
||||
|
||||
if ($app->isClient('administrator')) {
|
||||
$this->warnMissingLicenseKey();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process queued posts on page load (backend and/or frontend).
|
||||
*
|
||||
@@ -93,59 +83,6 @@ class MokoSuiteCross extends CMSPlugin implements SubscriberInterface
|
||||
\Joomla\Component\MokoSuiteCross\Administrator\Helper\QueueProcessor::processQueue(5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warn administrators once per session when no license key is configured.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function warnMissingLicenseKey(): void
|
||||
{
|
||||
$session = Factory::getSession();
|
||||
|
||||
if ($session->get('mokosuitecross.license_warned', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = Factory::getUser();
|
||||
|
||||
if ($user->guest || !$user->authorise('core.manage')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$session->set('mokosuitecross.license_warned', true);
|
||||
|
||||
try {
|
||||
$db = Factory::getDbo();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('extra_query'))
|
||||
->from($db->quoteName('#__update_sites'))
|
||||
->where($db->quoteName('name') . ' = ' . $db->quote('MokoSuiteCross Updates'))
|
||||
->setLimit(1);
|
||||
$db->setQuery($query);
|
||||
$extraQuery = (string) $db->loadResult();
|
||||
|
||||
if (!empty($extraQuery)) {
|
||||
parse_str($extraQuery, $parsed);
|
||||
|
||||
if (!empty($parsed['dlid']) && preg_match('/^MOKO-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/', $parsed['dlid'])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->getApplication()->enqueueMessage(
|
||||
'<strong>Moko Consulting License Key Required</strong> — '
|
||||
. 'No download key is configured. Updates will not be available until a valid license key is entered. '
|
||||
. 'Go to <a href="index.php?option=com_installer&view=updatesites">System → Update Sites</a> '
|
||||
. 'and enter your license key (<code>MOKO-XXXX-XXXX-XXXX-XXXX</code>) in the Download Key field '
|
||||
. 'for the MokoSuiteCross update site.',
|
||||
'warning'
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
// Don't break admin over a license check
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the last page-load run timestamp.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="system" method="upgrade">
|
||||
<name>System - MokoSuiteCross Events</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="system" method="upgrade">
|
||||
<name>System - MokoSuiteCross Gallery</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="task" method="upgrade">
|
||||
<name>Task - MokoSuiteCross Queue Processor</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="webservices" method="upgrade">
|
||||
<name>Web Services - MokoSuiteCross</name>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<extension type="package" method="upgrade">
|
||||
<name>MokoSuiteCross</name>
|
||||
<packagename>mokosuitecross</packagename>
|
||||
<version>01.05.00</version>
|
||||
<version>01.06.00</version>
|
||||
<creationDate>2026-05-28</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
# MokoSuiteCross Wiki
|
||||
|
||||
**MokoSuiteCross** — Cross-posting Joomla content to social media, email marketing, and chat platforms.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Install `pkg_mokosuitecross-*.zip` via Joomla Extensions → Install
|
||||
2. Navigate to **Components → MokoSuiteCross → Services**
|
||||
3. Add your first service (e.g., Telegram, Discord, Facebook)
|
||||
4. Publish an article — it's automatically cross-posted to all active services
|
||||
|
||||
## Getting Started
|
||||
|
||||
- [Installation](getting-started/Installation)
|
||||
- [Configuration](getting-started/Configuration)
|
||||
|
||||
## User Guide
|
||||
|
||||
- [Services](user-guide/Services)
|
||||
- [Telegram](services/Telegram)
|
||||
- [Message Templates](user-guide/Message-Templates)
|
||||
- [Troubleshooting](user-guide/Troubleshooting)
|
||||
|
||||
## Developer
|
||||
|
||||
- [Developer Guide](developer/Developer-Guide)
|
||||
- [Adding Custom Services](developer/Adding-Custom-Services)
|
||||
- [REST API](developer/REST-API)
|
||||
|
||||
## Architecture
|
||||
|
||||
MokoSuiteCross uses a **plugin-based service architecture**. Each social platform is a separate Joomla plugin in the custom `mokosuitecross` plugin group. This means:
|
||||
|
||||
- Install only the platforms you need
|
||||
- Third-party developers can add new platforms as plugins
|
||||
- Each service plugin implements `MokoSuiteCrossServiceInterface`
|
||||
- Services support both **default bot/app** mode (pre-configured by Moko) and **custom** mode (bring your own API keys)
|
||||
|
||||
## Database Tables
|
||||
|
||||
| Table | Purpose |
|
||||
|-------|---------|
|
||||
| `#__mokosuitecross_services` | Connected service accounts |
|
||||
| `#__mokosuitecross_posts` | Cross-post queue and history |
|
||||
| `#__mokosuitecross_templates` | Per-platform message templates |
|
||||
| `#__mokosuitecross_logs` | Activity and error logs |
|
||||
@@ -1,74 +0,0 @@
|
||||
# Adding Custom Services
|
||||
|
||||
MokoSuiteCross uses a plugin-based architecture. Any developer can create a new service plugin.
|
||||
|
||||
## Plugin Structure
|
||||
|
||||
Create a Joomla plugin in the `mokosuitecross` group:
|
||||
|
||||
```
|
||||
plg_mokosuitecross_myservice/
|
||||
├── myservice.xml # Plugin manifest (group="mokosuitecross")
|
||||
├── myservice.php # Legacy stub (empty)
|
||||
├── src/
|
||||
│ └── Extension/
|
||||
│ └── MyserviceService.php # Implements MokoSuiteCrossServiceInterface
|
||||
├── services/
|
||||
│ └── provider.php # DI container registration
|
||||
└── language/
|
||||
└── en-GB/
|
||||
├── plg_mokosuitecross_myservice.ini
|
||||
└── plg_mokosuitecross_myservice.sys.ini
|
||||
```
|
||||
|
||||
## Implement the Interface
|
||||
|
||||
Your Extension class must implement `MokoSuiteCrossServiceInterface`:
|
||||
|
||||
```php
|
||||
namespace Joomla\Plugin\MokoSuiteCross\Myservice\Extension;
|
||||
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\Component\MokoSuiteCross\Administrator\Service\MokoSuiteCrossServiceInterface;
|
||||
use Joomla\Event\SubscriberInterface;
|
||||
|
||||
class MyserviceService extends CMSPlugin implements SubscriberInterface, MokoSuiteCrossServiceInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return ['onMokoSuiteCrossGetServices' => 'onMokoSuiteCrossGetServices'];
|
||||
}
|
||||
|
||||
public function onMokoSuiteCrossGetServices(&$services): void
|
||||
{
|
||||
$services[] = $this;
|
||||
}
|
||||
|
||||
public function getServiceType(): string { return 'myservice'; }
|
||||
public function getServiceName(): string { return 'My Service'; }
|
||||
public function getMaxLength(): int { return 500; }
|
||||
public function supportsMedia(): bool { return true; }
|
||||
|
||||
public function publish(string $message, array $media, array $credentials, array $params): array
|
||||
{
|
||||
// Your API integration here
|
||||
return ['success' => true, 'platform_post_id' => '...', 'response' => [...]];
|
||||
}
|
||||
|
||||
public function validateCredentials(array $credentials): array
|
||||
{
|
||||
return ['valid' => true, 'message' => 'OK', 'account_name' => '...'];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Required Methods
|
||||
|
||||
| Method | Returns | Purpose |
|
||||
|--------|---------|---------|
|
||||
| `getServiceType()` | string | Unique identifier (lowercase, no spaces) |
|
||||
| `getServiceName()` | string | Display name in admin UI |
|
||||
| `publish()` | array | Send content to the platform |
|
||||
| `validateCredentials()` | array | Test if credentials work |
|
||||
| `getMaxLength()` | int | Character limit (0 = no limit) |
|
||||
| `supportsMedia()` | bool | Whether images can be attached |
|
||||
@@ -1,337 +0,0 @@
|
||||
# Developer Guide
|
||||
|
||||
This guide covers building new service plugins for MokoSuiteCross — from directory structure through testing.
|
||||
|
||||
## Plugin Directory Structure
|
||||
|
||||
Each service plugin lives in its own package under `source/packages/`:
|
||||
|
||||
```
|
||||
plg_mokosuitecross_myservice/
|
||||
├── myservice.xml ← Joomla manifest (type="plugin", group="mokosuitecross")
|
||||
├── myservice.php ← Legacy loader stub (empty, required by Joomla)
|
||||
├── services/
|
||||
│ └── provider.php ← DI container: registers the Extension class
|
||||
└── src/
|
||||
└── Extension/
|
||||
└── MyServiceService.php ← Main class: implements the interface
|
||||
```
|
||||
|
||||
## MokoSuiteCrossServiceInterface
|
||||
|
||||
Every service plugin **must** implement `MokoSuiteCrossServiceInterface`. The interface defines 5 methods:
|
||||
|
||||
```php
|
||||
namespace Joomla\Component\MokoSuiteCross\Administrator\Service;
|
||||
|
||||
interface MokoSuiteCrossServiceInterface
|
||||
{
|
||||
/**
|
||||
* Unique identifier matching the service_type in service.xml.
|
||||
* Must match exactly (e.g. 'mastodon', 'telegram').
|
||||
*/
|
||||
public function getServiceType(): string;
|
||||
|
||||
/**
|
||||
* Human-readable display name (e.g. 'Mastodon', 'Telegram').
|
||||
*/
|
||||
public function getServiceName(): string;
|
||||
|
||||
/**
|
||||
* Post content to the platform.
|
||||
*
|
||||
* @param string $message Rendered message text (already template-processed)
|
||||
* @param array $media Array of media file paths (images)
|
||||
* @param array $credentials Decrypted credential key-value pairs from the service record
|
||||
* @param array $params Plugin params + service params merged
|
||||
* @return array ['success' => bool, 'platform_post_id' => string, 'response' => array]
|
||||
*/
|
||||
public function publish(string $message, array $media, array $credentials, array $params): array;
|
||||
|
||||
/**
|
||||
* Test whether the stored credentials are valid.
|
||||
*
|
||||
* @param array $credentials Decrypted credential key-value pairs
|
||||
* @return array ['valid' => bool, 'message' => string, 'account_name' => string]
|
||||
*/
|
||||
public function validateCredentials(array $credentials): array;
|
||||
|
||||
/**
|
||||
* Platform character limit (0 = unlimited).
|
||||
*/
|
||||
public function getMaxLength(): int;
|
||||
|
||||
/**
|
||||
* Whether this service supports image/media attachments.
|
||||
*/
|
||||
public function supportsMedia(): bool;
|
||||
}
|
||||
```
|
||||
|
||||
## Step-by-Step: Creating a New Service Plugin
|
||||
|
||||
### 1. Create the manifest (`myservice.xml`)
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||
<name>plg_mokosuitecross_myservice</name>
|
||||
<author>Moko Consulting</author>
|
||||
<version>1.0.0</version>
|
||||
<description>MyService integration for MokoSuiteCross</description>
|
||||
<namespace path="src">Joomla\Plugin\MokoSuiteCross\MyService</namespace>
|
||||
<files>
|
||||
<filename plugin="myservice">myservice.php</filename>
|
||||
<folder>services</folder>
|
||||
<folder>src</folder>
|
||||
</files>
|
||||
<!-- Optional: plugin-level params (e.g. default bot tokens) -->
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic">
|
||||
<field name="default_token" type="password"
|
||||
label="Default Bot Token"
|
||||
description="Pre-configured token for default mode" />
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
```
|
||||
|
||||
### 2. Create the legacy stub (`myservice.php`)
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Legacy stub — required by Joomla plugin loader. Intentionally empty.
|
||||
```
|
||||
|
||||
### 3. Create the DI provider (`services/provider.php`)
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Extension\PluginInterface;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Joomla\Plugin\MokoSuiteCross\MyService\Extension\MyServiceService;
|
||||
|
||||
return new class implements ServiceProviderInterface {
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->set(
|
||||
PluginInterface::class,
|
||||
function (Container $container) {
|
||||
$dispatcher = $container->get(DispatcherInterface::class);
|
||||
$plugin = new MyServiceService($dispatcher, (array) PluginHelper::getPlugin('mokosuitecross', 'myservice'));
|
||||
$plugin->setApplication(Factory::getApplication());
|
||||
return $plugin;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 4. Create the Extension class
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Joomla\Plugin\MokoSuiteCross\MyService\Extension;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\Component\MokoSuiteCross\Administrator\Service\MokoSuiteCrossServiceInterface;
|
||||
use Joomla\Event\SubscriberInterface;
|
||||
|
||||
class MyServiceService extends CMSPlugin implements SubscriberInterface, MokoSuiteCrossServiceInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
'onMokoSuiteCrossGetServices' => 'onMokoSuiteCrossGetServices',
|
||||
];
|
||||
}
|
||||
|
||||
public function onMokoSuiteCrossGetServices(&$services): void
|
||||
{
|
||||
$services[] = $this;
|
||||
}
|
||||
|
||||
public function getServiceType(): string
|
||||
{
|
||||
return 'myservice';
|
||||
}
|
||||
|
||||
public function getServiceName(): string
|
||||
{
|
||||
return 'My Service';
|
||||
}
|
||||
|
||||
public function publish(string $message, array $media, array $credentials, array $params): array
|
||||
{
|
||||
// Your API integration here
|
||||
// $credentials contains the decrypted values from service.xml fields
|
||||
// e.g. $credentials['api_key'], $credentials['webhook_url']
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'platform_post_id' => 'abc123',
|
||||
'response' => ['status' => 'ok'],
|
||||
];
|
||||
}
|
||||
|
||||
public function validateCredentials(array $credentials): array
|
||||
{
|
||||
// Test the credentials against the platform API
|
||||
return [
|
||||
'valid' => true,
|
||||
'message' => 'Connected',
|
||||
'account_name' => 'MyAccount',
|
||||
];
|
||||
}
|
||||
|
||||
public function getMaxLength(): int
|
||||
{
|
||||
return 0; // 0 = no limit
|
||||
}
|
||||
|
||||
public function supportsMedia(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Add credential fields to `service.xml`
|
||||
|
||||
In `source/packages/com_mokosuitecross/forms/service.xml`, add your fields with `showon`:
|
||||
|
||||
```xml
|
||||
<!-- ======== MY SERVICE ======== -->
|
||||
<field
|
||||
name="cred_myservice_api_key"
|
||||
type="password"
|
||||
label="COM_MOKOSUITECROSS_CRED_MYSERVICE_KEY"
|
||||
showon="service_type:myservice"
|
||||
size="60"
|
||||
/>
|
||||
```
|
||||
|
||||
### 6. Add language strings to `com_mokosuitecross.ini`
|
||||
|
||||
```ini
|
||||
COM_MOKOSUITECROSS_CRED_MYSERVICE_KEY="API Key"
|
||||
```
|
||||
|
||||
### 7. Add to the service_type dropdown (if not already listed)
|
||||
|
||||
In the `<field name="service_type">` list in `service.xml`, add:
|
||||
|
||||
```xml
|
||||
<option value="myservice">My Service</option>
|
||||
```
|
||||
|
||||
## How `showon` Credential Fields Work
|
||||
|
||||
Joomla's `showon` attribute controls field visibility client-side via JavaScript:
|
||||
|
||||
| Pattern | Meaning |
|
||||
|---------|---------|
|
||||
| `showon="service_type:telegram"` | Show when service type is Telegram |
|
||||
| `showon="service_type:telegram[AND]cred_mode:custom"` | Show when Telegram AND custom mode |
|
||||
| `showon="service_type:webhook[AND]cred_webhook_auth_type:bearer,basic"` | Show when webhook AND auth is bearer or basic |
|
||||
|
||||
Fields are hidden/shown without page reloads. The form data for hidden fields is still submitted but ignored by the component.
|
||||
|
||||
## Dispatch Pipeline
|
||||
|
||||
The cross-posting flow works like this:
|
||||
|
||||
1. **Article published** → System plugin (`plg_system_mokosuitecross`) catches `onContentAfterSave`
|
||||
2. **Queue creation** → For each enabled service, a `#__mokosuitecross_posts` row is created with status `queued`
|
||||
3. **Queue processing** → Either the Scheduled Task or page-load fallback picks up queued posts
|
||||
4. **Service dispatch** → `QueueProcessor` fires `onMokoSuiteCrossGetServices` event in the `mokosuitecross` plugin group
|
||||
5. **Plugin response** → Each registered service plugin adds itself to the `$services` array
|
||||
6. **Matching** → The processor finds the plugin whose `getServiceType()` matches the service record's `service_type`
|
||||
7. **Publishing** → `publish()` is called with the rendered message, media paths, decrypted credentials, and params
|
||||
8. **Result** → The post record is updated with `posted`/`failed` status and the platform response
|
||||
|
||||
## Default Bot Mode
|
||||
|
||||
Some services (Telegram, Discord, Slack, Teams, Facebook, Threads) support a **default mode** where pre-configured MokoSuite credentials are used. This is controlled by:
|
||||
|
||||
1. The `cred_mode` field in `service.xml` (shown for services listed in its `showon`)
|
||||
2. Plugin-level params in the plugin manifest (`<config>` section) that store default tokens
|
||||
3. The service plugin's `publish()` method checks `$credentials['mode']`:
|
||||
- `'default'` → use plugin params (`$this->params->get('default_token')`)
|
||||
- `'custom'` → use the per-service credentials from `$credentials`
|
||||
|
||||
## OAuth Integration
|
||||
|
||||
For services requiring OAuth (Facebook, LinkedIn, Twitter, Pinterest, etc.):
|
||||
|
||||
1. **OAuthHelper** (`source/packages/com_mokosuitecross/src/Helper/OAuthHelper.php`) handles:
|
||||
- Authorization URL generation with state parameter
|
||||
- Code-to-token exchange
|
||||
- Token storage back to the service record's credentials
|
||||
|
||||
2. **OauthController** provides two endpoints:
|
||||
- `task=oauth.authorize` → redirects to the platform's auth page
|
||||
- `task=oauth.callback` → handles the redirect, exchanges code for token
|
||||
|
||||
3. Plugin params store the OAuth Client ID and Secret (set in Extensions → Plugins)
|
||||
|
||||
4. In `edit.php`, services listed in `$oauthServices` get a "Connect to {Service}" button
|
||||
|
||||
## Testing Your Plugin
|
||||
|
||||
1. **Syntax check**: `php -l source/packages/plg_mokosuitecross_myservice/src/Extension/MyServiceService.php`
|
||||
2. **Install**: Include the plugin in `pkg_mokosuitecross.xml` or install the plugin ZIP standalone
|
||||
3. **Enable**: Extensions → Plugins → search "mokosuitecross myservice" → Enable
|
||||
4. **Add service**: Components → MokoSuiteCross → Services → New → select your service type
|
||||
5. **Verify fields**: Confirm your credential fields appear when your service type is selected
|
||||
6. **Test post**: Publish an article and check the Post Queue for results
|
||||
|
||||
## Example: Building a "Fediverse" Service
|
||||
|
||||
Imagine building a service for a Mastodon-compatible platform:
|
||||
|
||||
```php
|
||||
public function publish(string $message, array $media, array $credentials, array $params): array
|
||||
{
|
||||
$instanceUrl = rtrim($credentials['instance_url'] ?? '', '/');
|
||||
$token = $credentials['access_token'] ?? '';
|
||||
|
||||
$ch = curl_init($instanceUrl . '/api/v1/statuses');
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => json_encode(['status' => $message]),
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $token,
|
||||
],
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
$data = json_decode($response, true) ?: [];
|
||||
|
||||
if ($httpCode === 200 && !empty($data['id'])) {
|
||||
return ['success' => true, 'platform_post_id' => $data['id'], 'response' => $data];
|
||||
}
|
||||
|
||||
return ['success' => false, 'platform_post_id' => '', 'response' => $data];
|
||||
}
|
||||
```
|
||||
|
||||
This pattern — curl to API, check response code, return structured result — is the same for every service plugin. The only differences are the API endpoint, authentication method, and payload format.
|
||||
@@ -1,57 +0,0 @@
|
||||
# REST API
|
||||
|
||||
MokoSuiteCross includes a WebServices plugin that provides REST API endpoints via Joomla's API application.
|
||||
|
||||
## Authentication
|
||||
|
||||
All endpoints require a Joomla API token. Generate one in **Users → Manage → [User] → API Tokens**.
|
||||
|
||||
Include the token in the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_API_TOKEN
|
||||
```
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
https://yoursite.com/api/index.php/v1/mokosuitecross/
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
### Posts
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/v1/mokosuitecross/posts` | List all cross-posts |
|
||||
| GET | `/v1/mokosuitecross/posts/:id` | Get single post details |
|
||||
| POST | `/v1/mokosuitecross/posts` | Create a cross-post entry |
|
||||
| DELETE | `/v1/mokosuitecross/posts/:id` | Delete a post |
|
||||
|
||||
### Services
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/v1/mokosuitecross/services` | List connected services |
|
||||
| GET | `/v1/mokosuitecross/services/:id` | Get service details |
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
# List all posts
|
||||
curl -H "Authorization: Bearer YOUR_TOKEN" \
|
||||
https://yoursite.com/api/index.php/v1/mokosuitecross/posts
|
||||
|
||||
# List services
|
||||
curl -H "Authorization: Bearer YOUR_TOKEN" \
|
||||
https://yoursite.com/api/index.php/v1/mokosuitecross/services
|
||||
```
|
||||
|
||||
## Filtering
|
||||
|
||||
Posts support query parameters:
|
||||
- `filter[status]=posted` — Filter by status (queued, posting, posted, failed, scheduled)
|
||||
- `filter[service_id]=5` — Filter by service
|
||||
- `page[limit]=20` — Pagination limit
|
||||
- `page[offset]=0` — Pagination offset
|
||||
@@ -1,39 +0,0 @@
|
||||
# Configuration
|
||||
|
||||
Navigate to **Components → MokoSuiteCross** to access the admin panel.
|
||||
|
||||
## Global Settings
|
||||
|
||||
Go to **Options** (toolbar gear icon) to configure:
|
||||
|
||||
| Setting | Default | Description |
|
||||
|---------|---------|-------------|
|
||||
| Auto-post on Publish | Yes | Automatically cross-post when articles are published |
|
||||
| Max Retries | 3 | How many times to retry a failed post |
|
||||
| Retry Delay | 300s | Seconds between retry attempts |
|
||||
| Log Retention | 90 days | How long to keep activity logs |
|
||||
| Default Template | `{title}\n\n{introtext}\n\n{url}` | Fallback message template |
|
||||
|
||||
## Message Templates
|
||||
|
||||
Templates use placeholders that are replaced with article data:
|
||||
|
||||
| Placeholder | Description |
|
||||
|-------------|-------------|
|
||||
| `{title}` | Article title |
|
||||
| `{url}` | Full article URL |
|
||||
| `{introtext}` | Article intro text (stripped of HTML, max 280 chars) |
|
||||
| `{image}` | Article intro image URL |
|
||||
| `{category}` | Article category name |
|
||||
| `{author}` | Article author name |
|
||||
|
||||
You can create per-platform templates. The system checks for a platform-specific template first, then falls back to the default.
|
||||
|
||||
## Service Modes
|
||||
|
||||
Services that support universal bots offer two modes:
|
||||
|
||||
- **Default Mode** — Uses the pre-configured MokoSuite bot/app. API keys are stored in the component's encrypted global params and never exposed in the individual service record.
|
||||
- **Custom Mode** — You provide your own API keys, tokens, and credentials.
|
||||
|
||||
Services supporting default mode: **Telegram** (@mokosuite_bot), **Facebook**, **Discord**, **Slack**
|
||||
@@ -1,33 +0,0 @@
|
||||
# Installation
|
||||
|
||||
## Requirements
|
||||
|
||||
- Joomla 5.x or 6.x
|
||||
- PHP 8.1+
|
||||
- cURL extension enabled
|
||||
|
||||
## Install
|
||||
|
||||
1. Download the latest `pkg_mokosuitecross-*.zip` from [Releases](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteCross/releases)
|
||||
2. In Joomla Administrator → **Extensions → Install → Upload Package File**
|
||||
3. Upload and install the package
|
||||
|
||||
The installer automatically:
|
||||
- Enables the system plugin (triggers cross-posting on article publish)
|
||||
- Enables the content plugin (shows cross-post status badges in admin)
|
||||
- Enables the webservices plugin (REST API)
|
||||
- Enables all service plugins in the `mokosuitecross` group
|
||||
|
||||
## Migrating from Perfect Publisher Pro
|
||||
|
||||
If Perfect Publisher Pro is installed, MokoSuiteCross detects it and offers one-click migration:
|
||||
|
||||
1. Install MokoSuiteCross (PP Pro can remain installed)
|
||||
2. Navigate to **Components → MokoSuiteCross → Dashboard**
|
||||
3. Click **"Migrate from Perfect Publisher Pro"**
|
||||
4. Review detected services and confirm import
|
||||
5. Imported services are created in **disabled** state — verify credentials before enabling
|
||||
|
||||
## Uninstall
|
||||
|
||||
Uninstalling the package removes all MokoSuiteCross database tables and data. Export any needed data before uninstalling.
|
||||
@@ -1,62 +0,0 @@
|
||||
# Telegram Service
|
||||
|
||||
Cross-post Joomla articles to Telegram channels, groups, or users.
|
||||
|
||||
## Setup
|
||||
|
||||
### Default Bot (@mokosuite_bot)
|
||||
|
||||
1. Add MokoSuiteCross service with type **Telegram**
|
||||
2. Set mode to **Default**
|
||||
3. Enter your **Chat ID** (channel, group, or user)
|
||||
4. Add @mokosuite_bot to your channel/group as admin
|
||||
|
||||
The default bot token is embedded in the plugin and hidden from the admin UI. No API key configuration is needed.
|
||||
|
||||
### Custom Bot
|
||||
|
||||
1. Create a bot via [@BotFather](https://t.me/BotFather)
|
||||
2. Add MokoSuiteCross service with type **Telegram**
|
||||
3. Set mode to **Custom**
|
||||
4. Enter your Bot Token and Chat ID
|
||||
5. Add your bot to the target channel/group as admin
|
||||
|
||||
## Credentials Format
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "default",
|
||||
"chat_id": "-100xxxxxxxxxx"
|
||||
}
|
||||
```
|
||||
|
||||
Or for custom bot:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "custom",
|
||||
"bot_token": "123456:ABC-DEF...",
|
||||
"chat_id": "-100xxxxxxxxxx"
|
||||
}
|
||||
```
|
||||
|
||||
## Finding Your Chat ID
|
||||
|
||||
- **Channel**: Forward a message from your channel to @userinfobot
|
||||
- **Group**: Add @userinfobot to the group temporarily
|
||||
- **User**: Send a message to @userinfobot
|
||||
|
||||
Channel IDs typically start with `-100`.
|
||||
|
||||
## Plugin Settings
|
||||
|
||||
Configure defaults in **Extensions → Plugins → MokoSuiteCross - Telegram**:
|
||||
|
||||
| Setting | Default | Description |
|
||||
|---------|---------|-------------|
|
||||
| Message Format | HTML | Parse mode (HTML, Markdown, MarkdownV2) |
|
||||
| Disable Link Preview | No | Disable automatic link preview |
|
||||
|
||||
## Character Limit
|
||||
|
||||
Telegram supports up to **4,096 characters** per message.
|
||||
@@ -1,77 +0,0 @@
|
||||
# Message Templates
|
||||
|
||||
MokoSuiteCross uses message templates to format the content sent to each platform. Templates support placeholders that are replaced with article data at post time.
|
||||
|
||||
## Managing Templates
|
||||
|
||||
Navigate to **Components → MokoSuiteCross → Templates** to create and edit templates.
|
||||
|
||||
## Template Priority
|
||||
|
||||
When cross-posting, the system looks for templates in this order:
|
||||
1. **Platform-specific template** — matches the service type exactly (e.g., "twitter")
|
||||
2. **Default template** — fallback used when no platform-specific template exists
|
||||
|
||||
## Available Placeholders
|
||||
|
||||
| Placeholder | Description | Example |
|
||||
|-------------|-------------|---------|
|
||||
| `{title}` | Article title | "New Product Launch" |
|
||||
| `{url}` | Full article URL | "https://example.com/article/123" |
|
||||
| `{introtext}` | Intro text (280 chars, HTML stripped) | "We're excited to announce..." |
|
||||
| `{fulltext}` | Full text (500 chars, HTML stripped) | Extended content |
|
||||
| `{image}` | Intro image full URL | "https://example.com/images/photo.jpg" |
|
||||
| `{category}` | Article category name | "News" |
|
||||
| `{author}` | Author display name | "John Smith" |
|
||||
| `{date}` | Publish date (YYYY-MM-DD) | "2026-05-28" |
|
||||
|
||||
## Example Templates
|
||||
|
||||
### Default (all platforms)
|
||||
```
|
||||
{title}
|
||||
|
||||
{introtext}
|
||||
|
||||
{url}
|
||||
```
|
||||
|
||||
### Twitter / X (280 char limit)
|
||||
```
|
||||
{title}
|
||||
|
||||
{url}
|
||||
```
|
||||
|
||||
### Mastodon (with hashtags)
|
||||
```
|
||||
{title}
|
||||
|
||||
{introtext}
|
||||
|
||||
{url}
|
||||
|
||||
#Joomla #{category}
|
||||
```
|
||||
|
||||
### Mailchimp (HTML email)
|
||||
```html
|
||||
<h1>{title}</h1>
|
||||
<p>{introtext}</p>
|
||||
<p><a href="{url}">Read the full article</a></p>
|
||||
```
|
||||
|
||||
### Telegram (HTML format)
|
||||
```html
|
||||
<b>{title}</b>
|
||||
|
||||
{introtext}
|
||||
|
||||
<a href="{url}">Read more</a>
|
||||
```
|
||||
|
||||
## Per-Article Override
|
||||
|
||||
In the article editor, the **Cross-Posting** tab lets you:
|
||||
- Skip cross-posting entirely for a specific article
|
||||
- Select which services to post to (instead of all enabled services)
|
||||
@@ -1,60 +0,0 @@
|
||||
# Services
|
||||
|
||||
MokoSuiteCross supports 9 platforms. Each is a separate plugin that can be enabled or disabled independently.
|
||||
|
||||
## Social Media
|
||||
|
||||
| Platform | Plugin | Character Limit | Media | Default Bot |
|
||||
|----------|--------|----------------|-------|-------------|
|
||||
| **Facebook** | plg_mokosuitecross_facebook | No limit | Yes | Yes |
|
||||
| **X / Twitter** | plg_mokosuitecross_twitter | 280 | Yes | No |
|
||||
| **LinkedIn** | plg_mokosuitecross_linkedin | 3,000 | Yes | No |
|
||||
| **Mastodon** | plg_mokosuitecross_mastodon | 500 | Yes | No |
|
||||
| **Bluesky** | plg_mokosuitecross_bluesky | 300 | Yes | No |
|
||||
|
||||
## Email Marketing
|
||||
|
||||
| Platform | Plugin | Character Limit | Media | Default Bot |
|
||||
|----------|--------|----------------|-------|-------------|
|
||||
| **Mailchimp** | plg_mokosuitecross_mailchimp | No limit | Yes | No |
|
||||
|
||||
## Chat / Messaging
|
||||
|
||||
| Platform | Plugin | Character Limit | Media | Default Bot |
|
||||
|----------|--------|----------------|-------|-------------|
|
||||
| **Telegram** | plg_mokosuitecross_telegram | 4,096 | Yes | Yes (@mokosuite_bot) |
|
||||
| **Discord** | plg_mokosuitecross_discord | 2,000 | Yes | Yes (webhook) |
|
||||
| **Slack** | plg_mokosuitecross_slack | 40,000 | Yes | Yes (webhook) |
|
||||
|
||||
## Default vs Custom Mode
|
||||
|
||||
Services with "Default Bot" support offer two operating modes:
|
||||
|
||||
- **Default Mode**: Uses a pre-configured bot/app token managed by Moko. The admin only needs to provide a destination (chat ID, page ID, etc.). The API key is stored in the plugin's configuration and never visible in the service record.
|
||||
|
||||
- **Custom Mode**: The admin provides their own API keys, tokens, or webhook URLs. Full control, but requires setting up your own app/bot on the platform.
|
||||
|
||||
Configure default tokens in **Extensions → Plugins → MokoSuiteCross - [Platform]**.
|
||||
|
||||
## Adding a Service
|
||||
|
||||
1. Go to **Components → MokoSuiteCross → Services**
|
||||
2. Click **New**
|
||||
3. Select the service type
|
||||
4. Enter a title and choose credentials mode
|
||||
5. For **Default mode**: enter only the destination (chat ID, channel, etc.)
|
||||
6. For **Custom mode**: enter your full API credentials as JSON
|
||||
7. Save and enable
|
||||
|
||||
## Credentials Format
|
||||
|
||||
Each service expects specific JSON fields. See the individual service pages:
|
||||
- [[Telegram]] — bot_token, chat_id
|
||||
- [[Facebook]] — page_access_token, page_id
|
||||
- [[Discord]] — webhook_url
|
||||
- [[Slack]] — webhook_url
|
||||
- [[LinkedIn]] — access_token, organization_id
|
||||
- [[Mastodon]] — instance_url, access_token
|
||||
- [[Bluesky]] — handle, app_password
|
||||
- [[Mailchimp]] — api_key, list_id
|
||||
- [[Twitter (X)]] — bearer_token, api_key, api_secret
|
||||
@@ -1,48 +0,0 @@
|
||||
# Troubleshooting
|
||||
|
||||
## Posts Stuck in "Queued" Status
|
||||
|
||||
**Cause**: The queue processor isn't running.
|
||||
|
||||
**Fix**:
|
||||
1. Check **Components → MokoSuiteCross → Options → Queue Processing** — ensure it's set to "Scheduler" or "Both"
|
||||
2. If using Scheduler: verify a task exists in **System → Scheduled Tasks** of type "MokoSuiteCross - Process Queue"
|
||||
3. If using Page-load: ensure the system plugin is enabled and check the throttle interval
|
||||
|
||||
## Posts Failing
|
||||
|
||||
**Cause**: Invalid credentials or platform API changes.
|
||||
|
||||
**Fix**:
|
||||
1. Check the error message in **Components → MokoSuiteCross → Post Queue** (hover over the red "Failed" badge)
|
||||
2. Check **Activity Logs** for detailed error messages
|
||||
3. Go to **Services** and verify credentials
|
||||
4. For services using Default mode, check the plugin params in **Extensions → Plugins**
|
||||
|
||||
## "No service plugin found" Warning
|
||||
|
||||
**Cause**: The service plugin for that platform is disabled.
|
||||
|
||||
**Fix**: Go to **Extensions → Plugins**, search for "MokoSuiteCross", and enable the relevant service plugin.
|
||||
|
||||
## Cross-posting Not Triggering on Publish
|
||||
|
||||
**Cause**: Auto-post is disabled or system plugin is inactive.
|
||||
|
||||
**Fix**:
|
||||
1. Check **Components → MokoSuiteCross → Options** — "Auto-post on Publish" should be "Yes"
|
||||
2. Verify **Extensions → Plugins → System - MokoSuiteCross** is enabled
|
||||
3. Check that at least one service is configured and enabled
|
||||
|
||||
## Duplicate Posts
|
||||
|
||||
MokoSuiteCross has a built-in duplicate guard. If you're seeing duplicates:
|
||||
1. Check if the article was saved multiple times in quick succession
|
||||
2. Check if both page-load and scheduler are running (shouldn't cause duplicates, but verify)
|
||||
3. Review the **Activity Logs** for the article in question
|
||||
|
||||
## OAuth Connection Failing
|
||||
|
||||
1. Verify the OAuth Client ID and Secret are correct in the plugin params
|
||||
2. Check that the redirect URI matches: `https://yoursite.com/administrator/index.php?option=com_mokosuitecross&task=oauth.callback`
|
||||
3. Ensure your Joomla site uses HTTPS (required by most OAuth providers)
|
||||
Reference in New Issue
Block a user