From dc49ae2515d325f026ffddfadaf915bea9e76313 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 22 Jul 2025 10:24:53 +0530 Subject: [PATCH 1/5] feat: Exclude account settings page from upgrade paywall (#11998) This pull request includes a small change to the `Dashboard.vue` file. The change adds `'general_settings_index'` to the list of route names checked for inclusion. --- app/javascript/dashboard/routes/dashboard/Dashboard.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/dashboard/routes/dashboard/Dashboard.vue b/app/javascript/dashboard/routes/dashboard/Dashboard.vue index ae54e9a7c..3d2610727 100644 --- a/app/javascript/dashboard/routes/dashboard/Dashboard.vue +++ b/app/javascript/dashboard/routes/dashboard/Dashboard.vue @@ -56,6 +56,7 @@ export default { return [ 'billing_settings_index', 'settings_inbox_list', + 'general_settings_index', 'agent_list', ].includes(this.$route.name); }, From c4b076dbb2e741d5da7544835c2d14d70b1d0d65 Mon Sep 17 00:00:00 2001 From: Vishnu Narayanan Date: Tue, 22 Jul 2025 14:24:25 +0530 Subject: [PATCH 2/5] feat: allow setting up only web/worker deployments for linux (#12004) ## cwctl - allow setting up only web/worker deployments for linux - allow upgrades to a custom branch - experimental ``` Usage Examples: # Convert existing full deployment to web-only (for web ASG) cwctl --convert web # Convert existing full deployment to worker-only (for worker ASG) cwctl --convert worker # Convert specialized deployment back to full cwctl --convert full # Fresh installs still work as before cwctl -i --web-only # New web-only install cwctl -i --worker-only # New worker-only instal ``` - Upgrading to custom branches is risky, as other dependencies like node or db might have changed ``` cwctl --upgrade # Upgrade to master branch - default cwctl -U v4.3.0 # Upgrade to specific release branch cwctl --upgrade feat/new-feature # Upgrade to feature branch ``` --- VERSION_CW | 2 +- VERSION_CWCTL | 2 +- deployment/chatwoot-web.target | 6 + deployment/chatwoot-worker.target | 6 + deployment/setup_20.04.sh | 248 ++++++++++++++++++++++++++---- 5 files changed, 235 insertions(+), 29 deletions(-) create mode 100644 deployment/chatwoot-web.target create mode 100644 deployment/chatwoot-worker.target diff --git a/VERSION_CW b/VERSION_CW index 4eba2a62e..fdc669880 100644 --- a/VERSION_CW +++ b/VERSION_CW @@ -1 +1 @@ -3.13.0 +4.4.0 diff --git a/VERSION_CWCTL b/VERSION_CWCTL index 944880fa1..15a279981 100644 --- a/VERSION_CWCTL +++ b/VERSION_CWCTL @@ -1 +1 @@ -3.2.0 +3.3.0 diff --git a/deployment/chatwoot-web.target b/deployment/chatwoot-web.target new file mode 100644 index 000000000..759c7c443 --- /dev/null +++ b/deployment/chatwoot-web.target @@ -0,0 +1,6 @@ +[Unit] +Description=Chatwoot Web Server +Wants=chatwoot-web.1.service + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/deployment/chatwoot-worker.target b/deployment/chatwoot-worker.target new file mode 100644 index 000000000..265cb1156 --- /dev/null +++ b/deployment/chatwoot-worker.target @@ -0,0 +1,6 @@ +[Unit] +Description=Chatwoot Background Worker +Wants=chatwoot-worker.1.service + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/deployment/setup_20.04.sh b/deployment/setup_20.04.sh index 75320bbd3..d1091da3c 100644 --- a/deployment/setup_20.04.sh +++ b/deployment/setup_20.04.sh @@ -17,9 +17,9 @@ fi # Global variables # option --output/-o requires 1 argument -LONGOPTS=console,debug,help,install,Install:,logs:,restart,ssl,upgrade,webserver,version -OPTIONS=cdhiI:l:rsuwv -CWCTL_VERSION="3.2.0" +LONGOPTS=console,debug,help,install,Install:,logs:,restart,ssl,upgrade,Upgrade:,webserver,version,web-only,worker-only,convert: +OPTIONS=cdhiI:l:rsuU:wvWK +CWCTL_VERSION="3.3.0" pg_pass=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 15 ; echo '') CHATWOOT_HUB_URL="https://hub.2.chatwoot.com/events" @@ -42,7 +42,7 @@ fi # read getopt’s output this way to handle the quoting right: eval set -- "$PARSED" -c=n d=n h=n i=n I=n l=n r=n s=n u=n w=n v=n BRANCH=master SERVICE=web +c=n d=n h=n i=n I=n l=n r=n s=n u=n U=n w=n v=n W=n K=n C=n BRANCH=master SERVICE=web DEPLOYMENT_TYPE=full CONVERT_TO="" # Iterate options in order and nicely split until we see -- while true; do case "$1" in @@ -83,6 +83,12 @@ while true; do ;; -u|--upgrade) u=y + BRANCH="master" + break + ;; + -U|--Upgrade) + U=y + BRANCH="$2" break ;; -w|--webserver) @@ -93,6 +99,36 @@ while true; do v=y shift ;; + -W|--web-only) + W=y + DEPLOYMENT_TYPE=web + shift + ;; + -K|--worker-only) + K=y + DEPLOYMENT_TYPE=worker + shift + ;; + --convert) + C=y + CONVERT_TO="$2" + case "$CONVERT_TO" in + web) + DEPLOYMENT_TYPE=web + ;; + worker) + DEPLOYMENT_TYPE=worker + ;; + full) + DEPLOYMENT_TYPE=full + ;; + *) + echo "Invalid conversion type. Use: web, worker, or full" + exit 3 + ;; + esac + shift 2 + ;; --) shift break @@ -107,7 +143,7 @@ done # log if debug flag set if [ "$d" == "y" ]; then echo "console: $c, debug: $d, help: $h, install: $i, Install: $I, BRANCH: $BRANCH, \ - logs: $l, SERVICE: $SERVICE, ssl: $s, upgrade: $u, webserver: $w" + logs: $l, SERVICE: $SERVICE, ssl: $s, upgrade: $u, Upgrade: $U, webserver: $w, web-only: $W, worker-only: $K, convert: $C, convert-to: $CONVERT_TO, deployment-type: $DEPLOYMENT_TYPE" fi # exit if script is not run as root @@ -379,23 +415,84 @@ EOF ############################################################################## # Setup Chatwoot systemd services and cwctl CLI # Globals: -# None +# DEPLOYMENT_TYPE # Arguments: # None # Outputs: # None ############################################################################## function configure_systemd_services() { - cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service - cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service - cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target + # Check if this is a conversion from existing deployment + local existing_full_deployment=false + if [ -f "/etc/systemd/system/chatwoot.target" ]; then + existing_full_deployment=true + fi + + if [ "$DEPLOYMENT_TYPE" == "web" ]; then + echo "Setting up web-only deployment" + + # Stop and disable existing services if converting + if [ "$existing_full_deployment" = true ]; then + echo "Converting from full deployment to web-only" + systemctl stop chatwoot.target || true + systemctl disable chatwoot.target || true + systemctl stop chatwoot-worker.1.service || true + systemctl disable chatwoot-worker.1.service || true + fi + + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.target /etc/systemd/system/chatwoot-web.target + + systemctl daemon-reload + systemctl enable chatwoot-web.target + systemctl start chatwoot-web.target + + elif [ "$DEPLOYMENT_TYPE" == "worker" ]; then + echo "Setting up worker-only deployment" + + # Stop and disable existing services if converting + if [ "$existing_full_deployment" = true ]; then + echo "Converting from full deployment to worker-only" + systemctl stop chatwoot.target || true + systemctl disable chatwoot.target || true + systemctl stop chatwoot-web.1.service || true + systemctl disable chatwoot-web.1.service || true + fi + + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.target /etc/systemd/system/chatwoot-worker.target + + systemctl daemon-reload + systemctl enable chatwoot-worker.target + systemctl start chatwoot-worker.target + + else + echo "Setting up full deployment (web + worker)" + + # Stop existing specialized deployments if converting back to full + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + echo "Converting from web-only to full deployment" + systemctl stop chatwoot-web.target || true + systemctl disable chatwoot-web.target || true + fi + if [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + echo "Converting from worker-only to full deployment" + systemctl stop chatwoot-worker.target || true + systemctl disable chatwoot-worker.target || true + fi + + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target + + systemctl daemon-reload + systemctl enable chatwoot.target + systemctl start chatwoot.target + fi cp /home/chatwoot/chatwoot/deployment/chatwoot /etc/sudoers.d/chatwoot cp /home/chatwoot/chatwoot/deployment/setup_20.04.sh /usr/local/bin/cwctl chmod +x /usr/local/bin/cwctl - - systemctl enable chatwoot.target - systemctl start chatwoot.target } ############################################################################## @@ -427,7 +524,15 @@ function setup_ssl() { cd chatwoot sed -i "s/http:\/\/0.0.0.0:3000/https:\/\/$domain_name/g" .env EOF - systemctl restart chatwoot.target + + # Restart the appropriate chatwoot target + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + systemctl restart chatwoot-web.target + elif [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + systemctl restart chatwoot-worker.target + else + systemctl restart chatwoot.target + fi } ############################################################################## @@ -624,17 +729,27 @@ Usage: cwctl [OPTION]... Install and manage your Chatwoot installation. Example: cwctl -i master +Example: cwctl -i --web-only (for web server ASG) +Example: cwctl -i --worker-only (for worker ASG) +Example: cwctl --convert web (convert existing to web-only) +Example: cwctl --convert worker (convert existing to worker-only) +Example: cwctl --convert full (convert back to full deployment) +Example: cwctl --upgrade (upgrade to latest master) +Example: cwctl -U develop (upgrade to develop branch) Example: cwctl -l web Example: cwctl --logs worker -Example: cwctl --upgrade Example: cwctl -c Installation/Upgrade: -i, --install Install the latest stable version of Chatwoot - -I Install Chatwoot from a git branch + -I BRANCH Install Chatwoot from a git branch -u, --upgrade Upgrade Chatwoot to the latest stable version + -U BRANCH Upgrade Chatwoot from a git branch (EXPERIMENTAL) -s, --ssl Fetch and install SSL certificates using LetsEncrypt -w, --webserver Install and configure Nginx webserver with SSL + -W, --web-only Install only the web server (for ASG deployment) + -K, --worker-only Install only the background worker (for ASG deployment) + --convert TYPE Convert existing deployment (TYPE: web, worker, full) Management: -c, --console Open ruby console @@ -831,7 +946,31 @@ EOF function upgrade() { cwctl_upgrade_check get_cw_version - echo "Upgrading Chatwoot to v$CW_VERSION" + echo "Upgrading Chatwoot to v$CW_VERSION (branch: $BRANCH)" + + # Warning for non-master branch upgrades + if [ "$BRANCH" != "master" ]; then + cat << EOF + +⚠️ WARNING: Branch-specific upgrades are EXPERIMENTAL +⚠️ Switching between different versions/branches may cause: + - Database migration conflicts + - Asset compilation errors + - Configuration incompatibilities + - Data corruption or loss + +⚠️ This is NOT recommended for production environments. +⚠️ Always backup your database before proceeding. + +EOF + read -p "Do you understand the risks and want to continue? [y/N]: " user_input + user_input=${user_input:-N} + if [[ ! "$user_input" =~ ^([yY][eE][sS]|[yY])$ ]]; then + echo "Upgrade cancelled." + exit 1 + fi + fi + sleep 3 # Check if CW_VERSION is 4.0 or above @@ -857,8 +996,9 @@ function upgrade() { # Navigate to the Chatwoot directory cd chatwoot - # Pull the latest version of the master branch - git checkout master && git pull + # Pull the latest version of the specified branch + git fetch + git checkout "$BRANCH" && git pull # Ensure the ruby version is upto date # Parse the latest ruby version @@ -878,18 +1018,35 @@ function upgrade() { EOF - # Copy the updated targets - cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service - cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service - cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target + # Copy the updated services and targets based on existing deployment + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + echo "Updating web-only deployment" + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.target /etc/systemd/system/chatwoot-web.target + elif [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + echo "Updating worker-only deployment" + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.target /etc/systemd/system/chatwoot-worker.target + else + echo "Updating full deployment" + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target + fi cp /home/chatwoot/chatwoot/deployment/chatwoot /etc/sudoers.d/chatwoot # TODO:(@vn) handle cwctl updates systemctl daemon-reload - # Restart the chatwoot server - systemctl restart chatwoot.target + # Restart the appropriate chatwoot target + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + systemctl restart chatwoot-web.target + elif [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + systemctl restart chatwoot-worker.target + else + systemctl restart chatwoot.target + fi } @@ -903,8 +1060,40 @@ EOF # None ############################################################################## function restart() { - systemctl restart chatwoot.target - systemctl status chatwoot.target + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + systemctl restart chatwoot-web.target + systemctl status chatwoot-web.target + elif [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + systemctl restart chatwoot-worker.target + systemctl status chatwoot-worker.target + else + systemctl restart chatwoot.target + systemctl status chatwoot.target + fi +} + +############################################################################## +# Convert existing Chatwoot deployment to different type (--convert) +# Globals: +# DEPLOYMENT_TYPE +# Arguments: +# None +# Outputs: +# None +############################################################################## +function convert_deployment() { + echo "Converting Chatwoot deployment to: $DEPLOYMENT_TYPE" + + # Check if Chatwoot is installed + if [ ! -d "/home/chatwoot/chatwoot" ]; then + echo "Chatwoot installation not found. Use --install first." + exit 1 + fi + + # Run the systemd service configuration which handles conversion logic + configure_systemd_services + + echo "Deployment converted successfully to: $DEPLOYMENT_TYPE" } ############################################################################## @@ -1107,7 +1296,7 @@ function main() { ssl fi - if [ "$u" == "y" ]; then + if [ "$u" == "y" ] || [ "$U" == "y" ]; then report_event "cwctl" "upgrade" > /dev/null 2>&1 upgrade fi @@ -1122,6 +1311,11 @@ function main() { version fi + if [ "$C" == "y" ]; then + report_event "cwctl" "convert" > /dev/null 2>&1 + convert_deployment + fi + } main "$@" From 69ad953ae6801c6fd418d52d7fd511658f66d4ad Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 22 Jul 2025 14:26:55 +0530 Subject: [PATCH 3/5] fix: bubble color for outgoing email (#12003) --- .../components-next/message/bubbles/Email/Index.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/javascript/dashboard/components-next/message/bubbles/Email/Index.vue b/app/javascript/dashboard/components-next/message/bubbles/Email/Index.vue index 2e03e97af..63b5f8eef 100644 --- a/app/javascript/dashboard/components-next/message/bubbles/Email/Index.vue +++ b/app/javascript/dashboard/components-next/message/bubbles/Email/Index.vue @@ -119,7 +119,13 @@ const handleSeeOriginal = () => { >