From 458eba1d561ff162e23767132cf1655bf726430c Mon Sep 17 00:00:00 2001 From: Andreas Dueren Date: Mon, 16 Jun 2025 11:26:11 -0600 Subject: [PATCH] Initial commit --- CHANGELOG.md | 29 +++++++++++++++ CLAUDE.md | 77 ++++++++++++++++++++++++++++++++++++++++ CloudronManifest.json | 31 ++++++++++++++++ DESCRIPTION.md | 31 ++++++++++++++++ Dockerfile.cloudron | 40 +++++++++++++++++++++ Makefile | 39 ++++++++++++++++++++ README.md | 32 +++++++++++++++++ logo.png | Bin 0 -> 55636 bytes start.sh | 80 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 359 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 CLAUDE.md create mode 100644 CloudronManifest.json create mode 100644 DESCRIPTION.md create mode 100644 Dockerfile.cloudron create mode 100644 Makefile create mode 100644 README.md create mode 100644 logo.png create mode 100755 start.sh diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e03df4c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +All notable changes to this Cloudron package will be documented in this file. + +## [1.0.0] - 2024-06-16 + +### Added +- Initial Cloudron package for mautrix-whatsapp bridge +- Support for PostgreSQL database via Cloudron addon +- Automatic configuration generation with Cloudron environment variables +- Health check endpoint for Cloudron monitoring +- QR code authentication workflow +- Comprehensive documentation and setup instructions + +### Features +- Matrix-WhatsApp bridge using mautrix-whatsapp v0.10.8 +- Two-way message bridging +- Media file support (images, videos, documents, audio) +- Group chat bridging +- Reaction support +- Read receipt synchronization +- Typing indicator bridging +- End-to-end encryption support in Matrix rooms + +### Configuration +- Automatic homeserver domain detection from Cloudron environment +- PostgreSQL connection string injection +- Log file configuration +- Registration file generation and management \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..d8c2c8e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,77 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is a Cloudron package for the mautrix-whatsapp Matrix-WhatsApp bridge. It wraps the Go implementation of mautrix-whatsapp into a Cloudron-compatible app with automatic configuration, database setup, and health monitoring. + +## Build and Development Commands + +### Build the Docker image +```bash +make build +``` + +### Package for Cloudron +```bash +make package +``` + +### Development deployment +```bash +make dev-install # Install on test Cloudron +make dev-update # Update existing installation +``` + +### Clean build artifacts +```bash +make clean +``` + +## Architecture + +### Core Components +- **Dockerfile.cloudron**: Multi-stage build using Go compiler with Cloudron base image +- **start.sh**: Bootstrap script handling configuration generation and WhatsApp authentication setup +- **CloudronManifest.json**: Defines PostgreSQL and localstorage addons, health check endpoint on port 29318 + +### Configuration Flow +The start.sh script implements a streamlined configuration process: + +1. **Initial Setup**: Generates config.yaml and registration.yaml using built-in mautrix-whatsapp templates +2. **Environment Integration**: Configures PostgreSQL connection and Cloudron domain settings using yq +3. **Authentication Ready**: Sets up for WhatsApp QR code authentication workflow + +### Key Design Patterns +- Uses Go binary compiled during Docker build for optimal performance +- All data persisted to `/app/data` with proper cloudron user ownership +- Configuration via yq YAML manipulation for cleaner updates +- Health check implemented using netcat since bridge doesn't provide native endpoint +- PostgreSQL connection string automatically injected from Cloudron addon + +### Environment Integration +- `CLOUDRON_POSTGRESQL_URL`: Database connection from PostgreSQL addon +- `CLOUDRON_APP_DOMAIN`: Used to derive Matrix homeserver domain and appservice URL +- Automatic domain extraction for homeserver configuration +- Port 29318 for appservice and health check endpoints + +## Development Notes + +### Go Binary Management +The bridge binary is built during Docker image creation from the official mautrix-whatsapp repository. Version updates require updating the git clone in Dockerfile.cloudron. + +### Database Schema +Uses PostgreSQL addon for persistence. The bridge handles its own schema migrations via the mautrix-whatsapp package. + +### WhatsApp Authentication +Unlike Telegram bridges, WhatsApp authentication requires QR code scanning or pairing codes. The bridge provides interactive authentication commands after startup. + +### Health Monitoring +Custom health check endpoint created using netcat on port 29318 since the bridge doesn't provide native health endpoints. + +### Configuration Differences from Telegram Bridge +- Go-based instead of Python (single binary deployment) +- Simpler configuration workflow (no complex token synchronization) +- WhatsApp Web protocol authentication instead of API tokens +- Different port allocation (29318 vs 29317) \ No newline at end of file diff --git a/CloudronManifest.json b/CloudronManifest.json new file mode 100644 index 0000000..cacc920 --- /dev/null +++ b/CloudronManifest.json @@ -0,0 +1,31 @@ +{ + "version": "1.0.0", + "upstreamVersion": "0.10.8", + "id": "dev.maunium.whatsapp.cloudronapp", + "title": "Matrix WhatsApp Bridge", + "author": "Tulir Asokan ", + "description": "file://DESCRIPTION.md", + "tagline": "Bridge between Matrix and WhatsApp", + "healthCheckPath": "/health", + "httpPort": 29318, + "icon": "logo.png", + "addons": { + "localstorage": {}, + "postgresql": {} + }, + "manifestVersion": 2, + "website": "https://docs.mau.fi/bridges/go/whatsapp/index.html", + "contactEmail": "support@cloudron.io", + "tags": [ + "matrix", + "whatsapp", + "chat", + "bridge", + "communication" + ], + "minBoxVersion": "7.1.0", + "postInstallMessage": "Mautrix-WhatsApp bridge is installed!\n\nPlease note you will need to:\n1. Configure your homeserver by setting up the registration\n2. Configure the bridge in the data directory\n3. Authenticate with WhatsApp using QR code or pairing code\n\nVisit https://docs.mau.fi/bridges/go/whatsapp/index.html for detailed instructions.", + "changelog": "file://CHANGELOG.md", + "documentationUrl": "https://docs.mau.fi/bridges/go/whatsapp/index.html", + "forumUrl": "https://matrix.to/#/#whatsapp:maunium.net" +} \ No newline at end of file diff --git a/DESCRIPTION.md b/DESCRIPTION.md new file mode 100644 index 0000000..9d1d581 --- /dev/null +++ b/DESCRIPTION.md @@ -0,0 +1,31 @@ +A Matrix-WhatsApp bridge that allows you to chat with WhatsApp users from your Matrix client. + +## Features + +- **Two-way bridging**: Send and receive messages between Matrix and WhatsApp +- **Media support**: Share images, videos, documents, and voice messages +- **Group chats**: Bridge WhatsApp groups to Matrix rooms +- **WhatsApp Web**: Uses WhatsApp Web protocol for reliable connectivity +- **End-to-end encryption**: Supports Matrix E2EE in bridged rooms +- **Reactions**: Bridge message reactions between platforms +- **Read receipts**: Sync read status between Matrix and WhatsApp +- **Typing indicators**: Show when users are typing +- **Contact sync**: Automatically create Matrix rooms for WhatsApp contacts + +## Requirements + +- Matrix homeserver with application service support +- WhatsApp account with phone number +- PostgreSQL database (provided by Cloudron) + +## Authentication + +The bridge uses WhatsApp Web's authentication system. You'll need to: + +1. Start the bridge and send `login` to the bridge bot +2. Scan the QR code with WhatsApp on your phone +3. The bridge will maintain the connection automatically + +## Support + +For help and discussion, join the Matrix room: [#whatsapp:maunium.net](https://matrix.to/#/#whatsapp:maunium.net) \ No newline at end of file diff --git a/Dockerfile.cloudron b/Dockerfile.cloudron new file mode 100644 index 0000000..5ac6660 --- /dev/null +++ b/Dockerfile.cloudron @@ -0,0 +1,40 @@ +FROM cloudron/base:5.0.0@sha256:04fd70dbd8ad6149c19de39e35718e024417c3e01dc9c6637eaf4a41ec4e596c + +# Install dependencies +RUN apt-get update && apt-get install -y \ + curl \ + ca-certificates \ + netcat-openbsd \ + bash \ + jq \ + yq \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Go +ENV GO_VERSION=1.21.4 +RUN curl -LO https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz \ + && tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz \ + && rm go${GO_VERSION}.linux-amd64.tar.gz +ENV PATH="/usr/local/go/bin:$PATH" + +# Create app directories +RUN mkdir -p /app/code /app/pkg /app/data +WORKDIR /app/code + +# Download and build mautrix-whatsapp +RUN git clone https://github.com/mautrix/whatsapp.git . \ + && go build -o /app/pkg/mautrix-whatsapp + +# Copy startup script +COPY start.sh /app/pkg/ + +# Set volumes and environment +VOLUME /app/data +ENV UID=1337 GID=1337 + +# Add health check endpoint +HEALTHCHECK --interval=60s --timeout=10s --start-period=30s --retries=3 \ + CMD curl -f http://localhost:29318/health || exit 1 + +CMD ["/app/pkg/start.sh"] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f7b54f8 --- /dev/null +++ b/Makefile @@ -0,0 +1,39 @@ +.PHONY: build clean package + +# Repository details - change as needed +CLOUDRON_APP_ID = dev.maunium.whatsapp.cloudronapp +CLOUDRON_TOKEN ?= + +# For development, we'll use the current git commit as the version +GIT_COMMIT = $(shell git rev-parse --short HEAD 2>/dev/null || echo "dev") +VERSION ?= dev-$(GIT_COMMIT) + +# Docker image for cloudron package building +CLOUDRON_BUILDER_IMAGE = cloudron/package-builder:5.0.0 + +all: build + +build: + docker build -t $(CLOUDRON_APP_ID) -f Dockerfile.cloudron . + +# Clean build artifacts +clean: + rm -rf build.log latest.tgz + +# Package for Cloudron in a consistent environment +package: + @mkdir -p build + docker run --rm -v "$(PWD):/app" $(CLOUDRON_BUILDER_IMAGE) build --set-version $(VERSION) + +# For development - install directly in a test Cloudron +dev-install: package + cloudron install --image $(CLOUDRON_APP_ID) --location whatsapp.example.com + +# Update the app in a dev Cloudron +dev-update: + cloudron update --app whatsapp.example.com --image $(CLOUDRON_APP_ID) + +# Publish to a Cloudron app store (requires token) +publish: + @if [ -z "$(CLOUDRON_TOKEN)" ]; then echo "CLOUDRON_TOKEN is not set"; exit 1; fi + cloudron appstore publish --app $(CLOUDRON_APP_ID) --token $(CLOUDRON_TOKEN) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..6160baa --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Matrix WhatsApp Bridge for Cloudron + +This is a Cloudron package for the [mautrix-whatsapp](https://github.com/mautrix/whatsapp) bridge. + +## Installation + +1. Install the app on your Cloudron +2. The app will generate a default configuration file on first run +3. Edit the configuration file at `/app/data/config.yaml` to set up your bridge +4. Restart the app to generate the registration file +5. Copy the registration file at `/app/data/registration.yaml` to your Matrix homeserver +6. Update your homeserver configuration to include the registration file +7. Restart your Matrix homeserver +8. Restart the bridge app + +## Configuration + +For detailed configuration instructions, please refer to the [official documentation](https://docs.mau.fi/bridges/go/whatsapp/index.html). + +## Authentication + +You will need to authenticate with WhatsApp to use the bridge. After starting the bridge: + +1. Send `login` to the bridge bot +2. Scan the QR code with WhatsApp on your phone, or use the pairing code method +3. The bridge will connect to WhatsApp Web + +## Support + +For support with the bridge itself, please visit [#whatsapp:maunium.net](https://matrix.to/#/#whatsapp:maunium.net) on Matrix. + +For issues with the Cloudron packaging, please file an issue on the GitHub repository. \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2d8588a339e2479330a74428e62bb858331f76d9 GIT binary patch literal 55636 zcmdqJ1zQ|V&@Q|ziw6k=x5a`>kl?To+}+*XH8=!FAhQU>8|SPlDoR5XTK=OiK8MDAOipZR7nXDB>(_u`|^tj54~c7BHjx912Pwq z6#@V%qfj0U;h_J6jU|+10f3Kh0RaC`0KgselK&n6;K~9392fuqJjnn6u0wjGA|LdI zf~kh2nXD{;4tkCV0K#AbV4-I)&>ujkB>?pI8~}h)f_`ALVgB#kY~cUg1=?oA{@?SL zhWJZMUQi;MmMR)98nQAx#`d;Mh9>q#rc55T4lfM=d>%Z|Q(IFPL$HUfjh!=(2S54W z7Cg}Nm&?rL;J-~=tog|`WEH?4?43-(@0nPbSjYvC!C)|-lZhFRl8D%U-J$>SlUumB zIPfqtySuwHxwA3ZJDD@T6&{MLSZ2jDU} zBD^Ou?~Fn1=L%#S)zqvjtr@JFq_bJc$VmBd?fJ3Ah)TMtnwNihn!jz*yoPORSykSr zr0{;f@W7LV{0#;G=Kuc(7aNT0j_e!|2nGNJUXSM;6pem7<_L>VQqDWph*MP|`a+rG zI3!mRsF4)*+2p-q0G&h+JVky+jnZpds;xPb06Fc~%h>W%N0C=9jd{hLc6J3WBkS<@ z1KaWik})JQgk10-2mrK13CJIjO)WwJLDp(O2QIoMx<1zIE2;$aU)^vP_BD`tCaJ<) zS)~tIwM&#_8^5~dIw=(gs^%H}C<;u-C->Et%0u?xJ(0)p(-+RmT}GvyXC7TdC{nR( zxN>!TJkH}FEm3-Ch*+HqQz4vXUexl`rap`sDZclKJI_=J&vz*)Qwc9{VWXn3eG^`T zTZolW>7iO>Camq0ua)vU5&by`fave<1d)fcRpL*J~&r=!c=2ZhxmIrqBOe ztnwau9@+cXjr;_ zekL)vUlG`4Zd0dQ#*puh>Is)#$Vz7kDDzg>OU6e=^lzsH{W%u?D0O}I8mcr(pgo;A z@tuY!-M0|Sut=puk|E_dEX@wQvDAKx%+EvveJYj0oyu{kWhPst%)H-8y!$@^7JSl_0tDy~3%PZ8+BE9Dk zKJaa$M)V5|PaX0`qGe*~0F4VyeiqbYQ1@UwBn<%5Q~ z0Pt)7Nu0ciz)~<6q#;?t@8J2GS)VljXwRh;pV?$+P4m$Y*9LzZq#FEYLE0_#%{7BXnE;zU}dVT=EG;g|U zr7pR0cw?5v*YQ-dE-l+1vICX>t<;jQ;>OJho#}iDw{-VRqDG&POraSXrdObU63F4( zb?o~EV1Nu##b*1w_WM_rjQlBuT-Nj9=R~bTqq|*w=OyX-H^*j!nD?f_koccwzQ?BF z#~(#!!t*Ar$t_Esw(-v+yDG`BK0$5FNgjavw8SQc0*-zSQ(4ecx!Cj+k9e`o@=EH=KoshmrvZTY z_oUgmk{EkrEbd)YRB)BCUo68%)ub}U42f{gQfrZ#bqn|uA?Z2Mg^*trN07XNyDH=Vxf@ov^%NqrssV=o@BnLXC4V~gUY}*p*8yjCO@k=ur z2QzenJQOAg!=Rlrbh(*AGNRCRV}vt!(RMTY z5O}@NhJa@QJI$*&#p&AH{O{;tL9oyW;*atYPyw%1{UPW9`S%B5n6_6cSItfSHLgh7 zV3PwZoLUmdO&T+Zl4(iEw``jV5JjWSpFh}iF#EN!jb9&-odu3YfjX>{5Vq?McEG|k zX}IRLcwa${Ua#Z~vuS9cGk!asZ^tHE`6$Tc>J_LP>(bS?rJplBw109;X{w^d8fTeF zlTZN)K=2TN)FQyZP#uFy2ttHhrz@bc2v?i_{(x1_cSJdxJwZR1`l^Ev>I}+AE`Mar z5&8nX(q$ddW3jbc>;?xZ91OUyu>^wJ_o3F!%a7}g0xYDe@Scqbju`00$NBDFk>iHH zYO`~`Dz$>&mOq8rl>~Os0%8u=f0_0CvHOY?-BMamN9E1pUFTc^ap5wdejosm3*?a7 z@dW^Ue7$xAl6EUAlYE=Ydh7|Ojg)wPW&>^nG)DQUkI|IG|dlK)fIaGWCa>~65T&U zqFujTqqK~oGS^&a4C~*yv`Vi9kYu;KUgt+l76x~4mX0)!9}D>YY^?vn^L|?1hs7|= zAsQCc42C8aD1#PVT)@)O1RSx+@YlgLpP(zV4|) z`f!?-g9iNT+GbN`Zx|pMG%;cP6comkkTtUFHh8roCB_g1 zFlIYBZ_^r$d%XZ_5AEJ50#W9D?p3eey*`P>S*~{+)U}6rqD%pDnH3fs&^|@A zrwwWi7tq(toa~0zQQAg@mgnxhhT=CqBIVp@U83K8o80~{Si-{D-$E5DY|)*w0Z^-9 zROo^;yr%@1mdW$YAp$)mvcnVV)e}VBHB6Rktq#(c6;}S7G9W4@eX9w!U^%a&Z%N>o z^cx|E!52;fmOAh;O*S^)=5B|rg8zV(T-&5x|2F{6K z!h8vf5Yi5SMwwT5pwHui{{mIn6_hBB_Vy!bFhA6ZAYck$tm67RH?5z#35A(@ zYzI$QUn4u^z-#ZI;gSSa+!>Zaq3O=}ovNFMQ0gyP?<&0k@!40U@JFaGxivmk^edF> z7$rd^*=g$;hQA8P*o z5GF(iI-?eO%>%T_nXws}v}#mCVW$9mSF{j-U0~3+5Mw7Ph>{#tT#R)?OxlerPFr+8 ze_^*GH`E9$5$7J3OEyXksB+u%IlQ(zrjCNjA??ag#(X^yy?5k)p{ufU!+kDKpo4nn zw%OiL|K6Ao5jxi%5OBvR@>oT6C%RHbS(HuswL}_%Z4MF!7b8^U!k$3p7D|P}Lvr3a z%3Wm}M% zay#PivhQVb(G2NU_9B=7-WOGOD;s+G=4J1MDkZyUJcF! zsQEt%8L)s1rtw~J5V3gx?{KW2t}dM!%LFDCv^O?AmR@T2diuYAbO+aQto(!EQ2oj<;by@`G}?l5qLCS znAgn+Y6zZZE_+UzyRd~qQGFZ3u2q%aOIcT_Ir}ifL|cESm3bR?Qhs|;(*FqxZRt{w zz|+?3+Pmv8k6Vh0#*8q8ECgXF1VbzgSJ^NfW`5*fuAauXiyP|lQoOZ+&P2aH5H;`D z^LL4@d+WF5OKEL*^vDb^V*@}DIC{fAYkmH+ zpQ`N#($LU-OZ@dA0cf8?ShV+-vIcgKVTKbmcQl1rcc2sQ#*>yx?3cADWK9-$kKN}Q zj+1BSXF2H;3W0;hXlU?JR+>9u262@L9bdVIOKLwyb$RFv5^ng-e|G=J5FbOr0kR_Q zBI0Mg9Pi0YmL?3}U4cSAxk-eF2jljhhVg5`YKf#@OjLX+Jk7r@K~&imywst$W8}P- zX}e}iv#fJg4m!RV{`ri8z4HlrOr>o`$ob^@CaTXqI)*9q2|1X5iw*&5nYA}%wo`5P z$)4Bm*8l-*P_S@&%X;$!3fPush{uT$+$36KUeB6E4>#*6lQ?F+|%B^pLDNlShJJnvs=nxJ;P3UsaryBM#P#(GhI_(?3B=ot2|P4JzB^w-P0qj!cKrffPY$RMLeR+e{RsE z`dyTDXOL4)T*>GSb(dg!8Mfbw$1_7El6?XtjE|DLoC*dXM7UUw*{GohPJ%G$e=+!?y!-y_ts1NA0X?8+5!NdN+ zhRig!hIl;z7XcalxV9~KI%yZ2mA4JY4F7TtMw{G<&dv7>oE6)hh<^R|&UUP`1k|#oYnZ6J#iK-2^q>RXiN#VY?`V`G+-~=~ay%Fdn(}Q;@QPk- zH`y`RNV5BWHoo!>;*8)iWfOqLO{lK6s9_wXZjwA4FAABz>dwbxA$Cq!LjeI#T&r$7 ztV+(*Cv29*I|iYaj&fO;^TmCk~cfam0~jH7h`FK zPjnjtUnPwFKQ559G7#pG)}8d^zMlr?X6vK<@>hEqs8&a|Cicba;L3IR^+dTti`-&c z`|jq6(_ZixdO#4lDwkXq?gkq*-H%~n*D#<{kY33nIeA;I%QjtgQP0IVt=dfHG%4o& z7ZIV_X+_G@gt^I`+%GT9bX=Wjb?;GAhI%cVDJ48u{CLLN%p&2*e)0fQ;FU2Kz-{io zunvM5Wh*C@Ea_jhOTG)0rEcvZG)7tru|FD5*Q*d+EY~zxyz=`qv;EL{lR<*j`eFxA z-1+KnBJUAt^Vm?!cA^*w^i45t6adx(MF5!%agDahhOfk?v4kqZE25q!Fi@vqGh62x&R^IHiA#L^kN zkT>DWR6un|#4mDpD-p*3n6c0R3BMf4mu2{#um$lDAT&q;A`yRV47ai(9STWR2BRWt zU$HB~zSyxpBoVY@RrS>M?yZUDYqYUUXtHsH->BC0h0Ep?(=~#Y?q9Izj|9jMWXL97 z^3&MOJGyLI$V4>?O$76#|57n|_AhDd4?a+U`%4g-`^c_o(#vv||HT{iuXn5z0BLQr zbf?B7O21i?XI#!IzCzS*PJhLL!NB7SFm+RT4#mTV*N2N74uKB9X0O5FC=j|NvDduQ z)|uwLg&QhFkx~3dA0mfH12w9$%eE0{I`k>M#$O7$Ldu7(kQ$bMdMGa=Vo$G9=BqnM zE6h2C6V|@ei~)!y@{lwB!{tQLRlSPsFvWTGPy+aWiB7}MlSx@u)qRNroJkjA^>9ar z7{=oNWTu5_HUDlMAGV~_bou8Xz3$VXJUPI0osww9TjRycMJO*->&lk<8GD;8vCCd& z6MFbtgK~7H5NyM|T?ej)26aoYu`eZ|%FgmwTK)M_i^v$fdqZ!->3r;XtqqCzPi1RJ z0l@s}k?$@O=1IRx=>O#P@Y#c;(n6`*|4=82Yhy-`R!REAq%mGrShBY=1Qv;LqU!<=u+m2|p4uza8fd6@fH+lB#yorzZ<3*F&EhVHVEjXXCuS>h>v3OuX zX*IAj(RjRwy2I`|Vt>R+V`CmQWGf>0kE#s0 zLkza$b2TWMQ?iJqADGW5p34QzX)P(s+DhXa6Vuw+T_U-1wf>pYCgLf-ylzHhek+}$ zWJDZOJ5b1SsAEmiBFcmEQE~M0?A?!6FoJBh)PL5;k^=df1m}~dEGihH0RD}N761NP z!)>9cv6~It@YFsf?3|;@ZrZ7?M zA9`l=kH$}SVkakO|HK4<{=@+22^MYg?X)T_bR-Kb%f_E_aBX9??Ac3-9yFZJ0d<_TZ;R=fWsRpb9dZWGcgN*mllQN0);is@A zAz#yP3QtE&rRkxcQ84O0 z&mCp({}{VNU^`{mg&^7VG!hAZTfk)EyW%+aQfNKE(E5=>ufy$WK>HNwKlMYhNr6M9 zpPv?963(k?()ZVYt7%_lR;7AjrSb&_g6o@FwyrOGdNu`5swPRp%AlQ{CPc;|=IPF9JuC1(55lUd-gvXZXe`L>OzakN6Rz@q z!mcYnlT(=cf5eR@gAqkJM)c7Q{AKPTvho`~pRwy(68E)+(9zqK$Awqu9d`dI6#z_m ztr1gq(PyRZ$B;Px`?di$zV20Di>1mouf+GU)8E1PB!SES;XJfvMS-!aahWx3>PXQnSP+fqi^dcCe@5eJy;6VDihd9QB}q zj8#gswV#Ag`hFh!f6@T}sEVSZyJ}Aw6NRJ6s?(D_zOJ=5!L~Mo?jt|KxF}y;E0-Z5 z;+8)kblUN0{-JH;d9rbK=vJ)G<@wNZWuxLtjKI^t)rx4O+d<-;S1sA6IpJrRCq?dm0Xn~A`@I0-0J46UHqYwQ%kkZUy$|BwsgqGbCJ2Nk}O2MIX1#M zN_4_<=nk5ZRbjBT9O=|VRcx@8zNm_bKGY{a5AOc7QFnY|`mF+9#V%qiGggbAq_wJE zB&I68_d%d?jcq&3M$5={ds=)vaCsVZM`{Xh^vI$lP22H{Y+l~rc^(o~*%E_3EpUkQ zFRnknK$snCzV_s_M*XP!b28l!v^!Idha)|8?9JTp=T+01H8l5mh3KOFy-}6e)1Es_ z^V5b}K<+11k-;K5rH*o`;xB05tb7N|Z(GTgr1I6ihYKNHLfP zsi%C*tLh2stE-Kd<1J@e7R@NF_`*6HYnNN#LeEi}kjyezrIA25qtu)0c5UWt;%)|#KC9TzA^kIcL89a=B1BQSV z?t!0Cff}CVc{CLIjp)vnn&F{T;GzE z8)#gJ8{<;vS*gR8TDOE2mM?kQR(a}Q4aS$gp>gcZT)-H91$@_v?x&MP ztk<)_XAvUtBn2bANc(_0tIz#Dqt3TizwJ0)_6Ay2mG@`PwqdIxM$5??AgDH+_{JWP zQ2qT3iJeLyvbRr+Tdh{9WKJ_F@nl@2GGTwptZBNk_xNBzd=abZyFg`>o_YRnF6}Lo zk@O=3DyG#joQvmIpv-a0%WtmLzZaZCjy=yg;_LK2{4K=r#ol?fI{5~-gk!n18X}99N86@H!VYQ1BIbREU zs3-GX1bF#sraDw$ZTFWX33=-$cSebAzVL3*xEn2h0`8)D{lb(0Zm2wURJlx4Gd%hP z90f=VcTHZs?QhU#%IY_S_w67ZbN<3u3=;r(jWH%piz)me9c0!^Jr$Uf;-WU8LV!is zp_krMk>|;tgBiI+BcJwr>-(=u;xx+-eK-ppI1QUeWpn}J-LSZ7vQhA`BgrCbnoqXg z2Af~+-BT#zld2$=#tWl077UMLd6%ny`aUPY`qx3)<$?TRS}}Akd_23@BiRcZ^X&8j z!PxayeU&7^tGfLr91J$|bfinTBc_9$VCftY#MiZqz zbhfqZcus`5);62*OGYG|+#3fPhn+}5O6Q1n!?J1FL$jrXq^Ug5@|uyqb=5Lctqby5 zIa(DEFy!@~;;-&aW#HVXp{T9qfN<*AR8}sxoz~G;P0*`D#BS~{{-CSn0lgyTy7Jvw z_`dJo658UNtOkF?p>-o*AhN>9%753mfPE>=5pLPN61!?vTWAd0Q}fO6scG#vHPFKw z#{Xpe_3ikkfRy{=PFry3G>af+OOu5fjrdAC)Wv7l-G@t>~}hSV4=>HZqp-BoWTXQ*+%=Aua9 zPQg)yTPS%m5Fx)JZPNKNn{4OU8Ok^DhrH!i>%tl+X)dBN&hU$0a< z=Xu1#{tx^+Ef^Sgq|a4v1$8vb>uOA3T1t+9sU!2qYZ_}zyDYPBXXYu=o1bp$TrU)c z*!Y4QgBOnE`dGs`q6|rHqpxJAo~b4$#%xkssyOoa`6kMm&y#DkDUxVKXa8_Ofg32A zEv^~2l!cp^c}!zHg+guAqLnQ+@yby2UC9@-P)*dqV3~=#6oV56En3H9s^G{ z<7BXC0q9NHXYncY^WSYl7tz_jlhhOIdM?!?WeZF7|6uQTW~1S4jS2#nt!Ek;t#K=H z_e^ax(>ewgsJNJr5r2wif62hfwAPls<`i7lSXr3=6T)F{HzCSTg5e=1ntOuobyU}^ zxbU)BsqgBS`h4dVy7!+oyWI|EL|GH@?7j}jOliiLUbcFLs)^hB8yf3*!=8ypjA##g z=F^&eep$Z)buLFAVfT*38d9@48&JR-diG~NORbAE`su-%*O=Ro&rtF>HVtMmN~sy> z7x6?6A_?F%f&daz*=8XsjNf5l?p!G-lrg->h#sQZ0kh5gD|h6}vk&GAGYx52)6&^` zLnS*CXo#;u+U3G8P)iC|&;J;pp>@9V{05Bx4w8~JMO$7rruPmQ@Nld<%rIxa!=2M> z;Y6$V4#K2~^2_3@@w5H?NkLmM!p*Xz7QU$@7M`(JZp04V{?&n`xdHFl$l8ad{Zj}hR&2djP|U+qVnJ6R z{DEghXg@JM4pZ37_e=(jnk}5cbRxh6w)POM5Jh1nkTv#}f|{2gGD>8!oVeL_XouyB z=OVF=inknZCE@EsEbm<;3mW+DjSX;F`I|`BT%0`7s~;P#)|<#;yx(vGm)Rsp#ef;j zt+uGU9FMx2ur<|Jr4<>^ zNlcr>h{-~b0^x9#Z&=pHEeR)1Gi5z0dw#KI?V)di$icLei3tpOnnxJt5<}H4=9?dC zst;Z3u-vu75L9WQRnBW9hAAA~vBGWld5vMVf_2(&bu}Z4%|=?ka#qhikD!l5f1?(n z9(N8(BO(=_Rn_aYEKF2{tHJ~MXq?OWej)rBr)>P#x=;48W}DkehO_G+(cL_tgIMi? zPTGBW!O}g{DwVy)dLdD;l5as(@4=I##`*@^YWvq(7ODtuu)oGET`6m0^8@*v%?JWf ziRd@D@^NLBbz=Zx|HrywnnDHo)DLkR#^1?Yhdl?lBWvwo@Y+wqH9knyM%}I5$`k+e zk+t{}8{)=P;Ht7MTo=|FH70#i6#Cp}>5bmg_}1EQ2S={3jlhY!Pgi@`vM{?8U(f-g zLLc~N{H$)$*+R@4b9wp#ae0VLI5Lmm)~2u8sqM7l0~1mOa<;uh5>aCkp{GC+s;8zq zji0LY^)$9?U14iq#(hx|%LEQ$dZfPw2_41u1xeix-La`}#zqu!^@Od5q5d?jbvwAv z(g$zaVniKQ1p|eWe z$z~V-&hxtu#pA{ee@&#aQNAmIT0PrjC%inOgWjY{&hZrCF8}0?q!+gxWqe|tNQn=O zepLDJJ6;uZpbzGrX4Bh&B|)w&y3wjm9P?Px1!&%NN|;F;O+L1P4Ao zBnur9+I5Z)Q+7%vA=QWCt?NGxOLW^lVMXn97}GzZGPh3N8hYtTGRl65a_5sd*)Bz9 zbyEmDzfM1G*$w+aL&MM%x9!pHuBn3oc1f&TAa=#(NqIt|Wwf4$K0w9==5R?UEJ+WI z7G9$_#P;HT{UeH|OekBKUz&i;EScg$;~H=5M_lmu5Q}F}^3CU6GbwjCpLWCw zAGfZKJDAakTEAWHaj9kT`?EXgqZx5?Ws}_eA@k+nFFg@au2tQ5lRNo%jxXwOX?sG% zODt7NL-e~WMQTE@%F!L;c~X9dIQ_w0$dM6TtP6QMnbW<{GUuNP4&B$^Tg#{i{o)@G z+2|@Cew=c&UvzD&J=I)@{Vsj;F+ADkcNTroyAMDo=Tr@r5P|lYTIs<=#doWx=M8za zvWzwySf)1mf568(7_XZeSF&esTfAq}?OY2ulylAOR&x*-2Wkcej7rQ&WPLw1y!?$E$;;m$Uyb^({E zl*}aQwEJ;>Sw<6A;;dd@*i8Ra8fLcY8}bJCAvlTnR50E9WjAho*W20UBpU6VZaU8R z7P`J(F{hC5Gr2?*MV*ko5T2P?@D;}*)XbJUzE@;A#n<}`z*b0@p}grs4{6`5)VT9u zmTf#4H$Z#8ovc7>i&9^9gQ3sgHs)}?SOYEEB#1j*a1rV#pUE|T`?EYM%d6kWOef7& zE`&8SpV%#DPG@6nl*G0?-?=KCb7q%cpskD4G&z~u`$hGK`EvTFUc51>bWlFFsjpK9 zm-v@B4%b_yEzYV|W0Ymz3-_ATYP$a2iY$~{);gGdbA&AWEKRn@AEXE(D^p?k1o^fd ziS%N$*srH{;R=swTR{OtuQAGdXuYwX`p2#Jb0(=g*KNQvH5B`sHT;!}4X@i48b(sC z_(oyWda9MfmZBY%f9uiC=JpT#GI;G(ini(MXcVliz#g~rMmE=xFJG${4db@`5Kv%-cSbpnhK0;m~?d)PGTx(C2y&tS1qFe8Hpj+PNYRuA#6fvpRba^0u8hpn4mAIok z(D65%o>ar@p@o8cKH@vh53AB_^I@2&q`xf1#NX6HYlq*R*TauO`r!_{+DyYJ=f6CNuV7*wJ&OuDL$ zm75M=q}48s?k{T+cX%xel^J?As}MqukJ4{y(U$jJ>a}H2dQ7|P*RiPNMyWjk80e}g zJp4@_Ol>i}SiKtwJk<`YjEs6~G!C0wHeWqVLduSg7Q_YloDldY?pW{9 zDe&y)dS~08DCc1wtgQ=H93pnG+j#y9u3XMx6r-Q>yl;FEksd* z;7R_#hePT&a`w_UJTJZU^s>+3IVU2O2^?P^^d=auAU1X2q3gHD2| zQdmiLLqktUZ&8nBe}`_E{r-;UJpi<_4F{z>^vjR>3PPV3IFSZE7vXOOAXXkZ#l<(r z&#JeE+x=(__`vZB)y3ZQ<29-r?j>X>?xKx|`S5pvI5*%oiIhY8BFT_kHZPvjx>v8n z=#W@bFz%^+?(V`2k1-88j_O1hBs4wdr&}CX$)_!*<$)A7N@IA27Ba!_j|Z7KR;?th zzNdAJ%r{h>1`DXA`KW4j9j`be@eyGZ9ViuVB0i{%yCx(#@)UOl5ZV1|W$me}w-)4I z_|t4WFxL^@7MD(lsjMJ|I+gutzp^#KQP}Ity_@H)Xyo;Gj~w`h&lJPg1itGs^9T*3 z(aRP27sZhod;teeP_!*>xc(ev&PCo>~NtwoV3z^UA)DT)pg4W3_QktC9K^zGWPW zBF5C1;ksMhtVH#JDX!mmcs}jCkt?M5zDe}+7WGM#eBJxU=r_I}^ob9I>}JUa0| z3F=6O7V5#+Fk}t3(;hj)O_8`>X#ST+rVSMrO1z1#93+f@OA}F3x zv=U*FOYyTVHcm68%M&-$eT{*af}S3jS>J~E2em`xxHOq4?Mu6N2w#`1Q(oqK|3Jv? zR)xt><*LA`9Ufd>GY3$*{{2xdb@d>nsf%8?D)F*v;!%M#3w(7Yx1cM z;np>bJ;k|JzN1|BBwPW6{Le;jQEL2rA4u*dDpz^eNlix3`GkX516Ky;bDKHl%jD4J zBZ$(<{R^eUotilnKL;vMM$Fo%Em3BlLaS($=nO(1+mV5rdldU58IB zr2YeFWZeBs^T6uE*%gtOZGqB5M=%eLx znf6yXTWq}ih%y_v35mONK90s_=7TwSU_yWi`gn&*kg=tI zRpNe;aT^KHY4mfoFn_tb_VO7rf`(kx?1hAz2F<~I&s^Jv%)49%OkP!yxz6V0eFR_F zUNm(D5dBUzD=}48#_3+A_Tf|kGBIAh?Zs}v$hu{gJxf1XLFXr(4l-~eyk-|p9_@tj z{@cjCSJZ=)xi&tT&F34{y>JdaZjxs(NfiY8E_7(rE0a zHsjK3ZCO>3cR^TV73~8mx(2v>uBUY)y&=ztA(I96m14yF502zMa9KbhO-{m})g1bu z#0nCp%ICp~G@>Z>se8tm+RNsrJulR@yrwi#XQxkLRq#WB`xLlDw_7@xL+7nqFj^zZ z1;j)}?%o|Vn`L&aqCDZGt(312o27!BTk#nz;qFyP1x{wFGkuRq_2X2AdlMiuw$Ao6 zY3<>l=giAm#opJSAOYm##G$sOSTnhGHw>Gm_EPoZg9V{`GZbx3M5rRZ8na(X>mbN9 z@?AO2wSVsVQ8Uskd3W=OUzZfDM^29{nQzT}33Z0D2;)f@{)wut)m# z)*tKb1ndGKg@YJ~&o0dQfMZoy6da@f|UTTZG#dN>)XAP z3er)r=te{Q`CQce=~nxd7JQ%V5DJ8x73`P~Z7F~<~2b%)Hh9Bt}AB93vF zMy#rLR(mxY+bs4`;qNyc+1E`%|# zv1L(lhj$p4jZOKze~8ERw|Csz5W|X&V~FaGcdi=wy=8-(CdtsLys29`5&}nA9y%7q0^rTb?5VqKWwWtyKaYh9D%}cxTGt-4( z(PtE{&{OJ?=fQz1u(g&V#K0faYgxv;soYn@?Pknq`?5uUsjjS?Z3_t&6tOJS?s%`? zO~&7T6Yxc1WvypfaBUdA&E7kj5pUVDNG2YOH2`7{p7EYFdNgHM0z2B+J-ewu|AJ!B00{gE-REX2KFp4V#$7X#C zIP2KSQyW+r-q}9Ho0sn$laq(1e)5fM%OsG8q|H)boL+f^snBYx5fr9*Hf>gvy_RcvtCnq;%1|721X8{9YkP+kZp%9fsw)r*7}Fie$w z38$N}pHhHmkvG}PS?$h}U0DDLB}FOE#}3^{5Zq@V>UmKDjf%Jh1dJxIyG{u6~UhYBWb4##mh_u*0nJ6Yk+ zE~SR_g|pPLk%y^oC$^U7P0GER3pKh5L+G|UjADPh^2VR=kv@06|7P&&ab)~DRwrJT zZe(Ar@p12D-@NZ+=hKXBX~pHzf=n!C)yr$EBCj#+N1ji{(Jfu?OMa^!3Cof%=9}(L zaU>)ue0qkyWD^3~>9sNKP9@A8U3l3&{FV+`a6mdP(Hs%8X`35Hvro+~f#)oFlo{J+ zl_*~#wmH1>>b?L$vOrummT^p;&_%Ehw54M&L0UNSh4|&EZZFPPmYs(r|3zi4+^!!# zW-U1jn>tTe`=~!~74P;RH9G!^z~%e6cE!;;T1IGUX-&xQLbMvRiWB)xjJX*MmLF1A z)sZ=&(Kh?lb1iYe<#XN7>`A=%A%4ps@8>%Y$M@N&afqK)8w4stpN>zX_V;I|y)8MZ z+ihK45P9F~h{w$dM_t;!&ER-Dl#_Tk7}Sbz&naaoZOOtSK+f;Bhaa=XeZFPY)WxlS%7ROYWx z22UQo6ZXQ#N|vc})$8@zwGcNh5P#V`CFPpmmL0DZo!gqTfblxo!)62Ss=iC$XbZxg zZ_SUq2svSC5o$`L3(>yJrvW9Bm=sQu%N6XQVVPPLWKr+L^Rnk}baOymX+y~+(lkL7e zbALn-GGsFq0f*9pOp0szHm+nA35*%EjlTKmZ+mh1F3QNnr8-sNF^2N=(a~MGz8{BX zVk&pQR(y*0X%p0?+?_2gHnc5;-VN_ok~gUCDBO5%l+WWTDpH(NA(%mkF7$Ty`_N2f zEt)XxYmAMG4W7@>0|M$wz5>Yzd>myseB=2UC&6GgVM}f3E@-F8L{K@_IR!FedW?Um zaT+G6Jn32~LcZD={`I+2P`6=RG>PBZT7!htF_mWxHaoDY*H(O1KyLF2i+aA9_75{t zru3{@^VH9!?**p;MAV2P68quS?!RtvUj0JMFQeDxix6Vq3xKnStjS24LBHVP-**A9 zgSKdY4%2;WBXNS0HSHPsME;G>*XJQBy>l0a#^&uSL=%=we~qO&Dz_;=;#+)M*&|kA zJtSBs*B&Z4e>;uEuXvbo!9}&lzZlv;?825WZ#Tl??c;)K2wwrKJT!sEdO9C}yapD! zrvA44__dmNNt)QL@LhOGgg-19BpV%=^V9ZdPHNTmhWps~LmN-oQF*u%J8YGXNvuML9Rc9 zu^6OA91!Ss6g;AUK5f0cERv?UspeYrA3)rwFq-fmG=98{bOIGGx(}`Z*;!srpXv}P#|ySk z3DY`lb=#mSpwQV@G>z9CVtDSwGVV)**w1b$Oud)X{QjZ?T9WO|_c>9wozNsw+9QAH z^&v$vhEwpBjkznX+5fTih6Gb4g1}4fj#&eyoUx(c4`!++*MPgB$=yyLU&Oia;>XsJ zHSVr!m;k^xGH_er+elZB`-#;FI=zo;?q9ysc*V5_LBl`?`}fr#L#ul}QLB80vD~Kn z;+o2Y{{t&Q)V@vfc#SZ1OdyxP1jPBEwrDoJtL#GGpLkQ8Lv&^1Lr(BqkqZR`K)_uB zvNrUMIqy4m+`UQoK2&M#T)yBrX}NCNVlv3%KboNdk)Oa^7c8pmcwKvs*&a)jSE zKIkZK+0~Z)(PtG-rFWHI$WubT-7d551Zv0?fl;LFCAq5nboKg@>vQ&|x&o!r=M!mv z@5rYkg717MAd7%6FMpfwsj4K8=x>kziJom+!b@1-EDiGuG$TIA!`4r3N>W^1&Yq;tx2+|yy5sk7GM_yE#8H^_`BS!E_KW(d4<@`|;fvB1 zvy!ZxszuHn#fx5|jld8PMPp8U8eLX)f$tYbnWDLqlfb7qT~(00MTKFM?E<4>BWYgY zbXrh6i>AdV(C}zAD{m!KV8u?$R{GhlJDh;Q^=w&O)&2^t>Uf1-?>fjV?OE*{O&?es!I zUz9d0s^^fc#(U90v=JNvGAUQ23TXwq+K-IY_$v7J#2${){s-r2KPXSuVpof?RbW

Mz*WQr?sBPqJ>mx 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 Setting up mautrix-whatsapp bridge" + +# Create necessary directories +mkdir -p /app/data +mkdir -p /app/data/logs + +# For Cloudron, we run as the cloudron user +UID=$(id -u cloudron) +GID=$(id -g cloudron) + +# Set ownership early to avoid permission issues +chown -R cloudron:cloudron /app/data + +# Configuration file paths +CONFIG_PATH="/app/data/config.yaml" +REGISTRATION_PATH="/app/data/registration.yaml" +BACKUP_PATH="/app/data/config.yaml.bak" + +# Create example config from built-in template +if [ ! -f "$CONFIG_PATH" ]; then + echo "=> Generating example configuration" + /usr/local/bin/gosu cloudron:cloudron /app/pkg/mautrix-whatsapp -g -c "$CONFIG_PATH" -r "$REGISTRATION_PATH" + + # Configure for Cloudron environment + if [ -n "${CLOUDRON_POSTGRESQL_URL:-}" ]; then + echo "=> Configuring PostgreSQL database" + yq eval ".database = \"$CLOUDRON_POSTGRESQL_URL\"" -i "$CONFIG_PATH" + fi + + if [ -n "${CLOUDRON_APP_DOMAIN:-}" ]; then + echo "=> Configuring homeserver and appservice settings" + BASE_DOMAIN=$(echo "$CLOUDRON_APP_DOMAIN" | cut -d. -f2-) + + # Update homeserver configuration + yq eval ".homeserver.address = \"https://matrix.$BASE_DOMAIN\"" -i "$CONFIG_PATH" + yq eval ".homeserver.domain = \"$BASE_DOMAIN\"" -i "$CONFIG_PATH" + + # Update appservice configuration + yq eval ".appservice.address = \"https://$CLOUDRON_APP_DOMAIN\"" -i "$CONFIG_PATH" + yq eval ".appservice.hostname = \"0.0.0.0\"" -i "$CONFIG_PATH" + yq eval ".appservice.port = 29318" -i "$CONFIG_PATH" + fi + + # Set log file path + yq eval ".logging.handlers.file.filename = \"/app/data/logs/mautrix-whatsapp.log\"" -i "$CONFIG_PATH" + + chown cloudron:cloudron "$CONFIG_PATH" "$REGISTRATION_PATH" + + echo "=> Initial configuration complete" + echo "=> IMPORTANT: Please review $CONFIG_PATH and configure your Matrix homeserver settings" + echo "=> You will need to:" + echo " 1. Copy $REGISTRATION_PATH to your Matrix homeserver" + echo " 2. Update your homeserver configuration to include the registration file" + echo " 3. Restart your Matrix homeserver" + echo " 4. Restart this bridge app" + echo " 5. Authenticate with WhatsApp using QR code scanning" +else + echo "=> Using existing configuration" +fi + +# Final permission fix before starting +chown -R cloudron:cloudron /app/data + +# Create a health check endpoint (run in background) +mkdir -p /run/health +echo '#!/bin/bash +echo "HTTP/1.1 200 OK" +echo "Content-Type: text/plain" +echo "" +echo "OK"' > /run/health/server.sh +chmod +x /run/health/server.sh +(cd /run/health && nohup nc -l -p 29318 -e ./server.sh > /dev/null 2>&1) & + +# Start the bridge +echo "=> Starting mautrix-whatsapp bridge" +exec /usr/local/bin/gosu cloudron:cloudron /app/pkg/mautrix-whatsapp -c "$CONFIG_PATH" \ No newline at end of file