How Telegram 2-Way Communication Enables Remote Sync and Re-Authentication in docker-icloudpd
The docker-icloudpd container uses a Telegram Bot API polling loop to accept remote commands for immediate syncs and MFA re-authentication, enabling full remote management without SSH access.
The boredazfcuk/docker-icloudpd project implements an optional Telegram 2-way communication channel that transforms a passive notification system into an interactive remote control interface. This bidirectional flow allows users to trigger downloads and refresh expired iCloud cookies from any Telegram client, eliminating the need to exec into running containers.
How Telegram 2-Way Communication Works in docker-icloudpd
The architecture separates inbound commands from outbound notifications using two distinct mechanisms:
- Inbound (Telegram → Container): A persistent polling loop in
sync-icloud.shqueries the TelegramgetUpdatesendpoint every cycle, parsing messages for valid command signatures. - Outbound (Container → Telegram): The
sendmessage.shhelper formats status updates and authentication prompts, posting them viacurlto thesendMessageAPI.
This design ensures that even if the container loses network connectivity temporarily, it resumes command processing from the last processed update ID stored in /config/telegram_update_id.num.
Remote Sync via Telegram Commands
The Polling Loop in sync-icloud.sh
When telegram_polling=true is set, launcher.sh initializes the offset file at lines 691-698:
telegram_update_id_offset_file="/config/telegram_update_id.num"
if [ ! -f "${telegram_update_id_offset_file}" ]; then
echo -n 0 > "${telegram_update_id_offset_file}"
fi
During each sync cycle, sync-icloud.sh (lines 2408-2413) retrieves pending messages:
telegram_update_id_offset="$(head -1 "${telegram_update_id_offset_file}")"
telegram_update_id_offset_inc=$((telegram_update_id_offset + 1))
latest_updates="$(curl --request POST --silent \
--data "allowed_updates=message" \
--data "offset=${telegram_update_id_offset_inc}" \
"${telegram_base_url}/getUpdates" | jq .result[] 2>/dev/null)"
Triggering a Remote Sync
The container recognizes commands formatted as <user> sync, where <user> defaults to boredazfcuk. Lines 2434-2445 in sync-icloud.sh parse the message:
if [[ "${check_update_text_lc}" == "${user_lc} sync"* ]]; then
send_notification "remotesync" \
"iCloudPD remote download initiated" "0" \
"iCloudPD has detected a remote download request for Apple ID: ${apple_id}"
synchronise_user
fi
To trigger a download from your phone, simply message your bot:
boredazfcuk sync
Remote Re-Authentication Workflow
Initiating Authentication from Telegram
When the iCloud cookie expires, sending <user> auth starts the re-authentication pipeline. Lines 2444-2452 in sync-icloud.sh detect this command and spawn the authentication helper:
elif [[ "${check_update_text_lc}" == "${user_lc} auth"* ]]; then
send_notification "remotesync" \
"iCloudPD remote authentication initiated" "0" \
"iCloudPD has detected a remote authentication request for Apple ID: ${apple_id}"
/usr/local/bin/authenticate.exp &
fi
The MFA Code Handshake
The reauth.sh script (line 35) performs an --auth-only run of icloudpd to generate the MFA challenge. While waiting, the container sends a prompt via sendmessage.sh (lines 23-27):
auth_log_text="Please select option to send the SMS code to:%0A${auth_log_numbers}%0AReply with '${user} <option ${option_list}>' to select the mobile number, or reply with '${user} <mfa code>' to use an Apple iDevice MFA code"
send_message "$(echo -e "${notification_icon} *${notification_title}*%0A${auth_log_text}")"
The user replies with either the option number (for SMS) or the 6-digit code (from a trusted device), which the polling loop captures and passes to authenticate.exp to complete the iCloud sign-in.
Configuration and Setup
Enable Telegram 2-way communication by setting these environment variables, documented in CONFIGURATION.md (lines 149-159):
telegram_token=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
telegram_chat_id=987654321
telegram_polling=true # enable the 60s polling loop
telegram_server=proxy.mycdn.com # optional proxy for blocked regions
telegram_http=false # use HTTPS (default)
Example docker-compose.yml configuration:
services:
icloudpd:
image: boredazfcuk/icloudpd
environment:
- notification_type=telegram
- telegram_token=${TELEGRAM_TOKEN}
- telegram_chat_id=${TELEGRAM_CHAT_ID}
- telegram_polling=true
- user=boredazfcuk
volumes:
- ./config:/config
- ./photos:/home/user/iCloud
Summary
- Telegram 2-way communication in docker-icloudpd uses a polling loop in
sync-icloud.shto read commands andsendmessage.shto post responses. - Remote sync is triggered by sending
<user> syncto the bot, which callssynchronise_userimmediately. - Remote re-authentication starts with
<user> auth, spawningauthenticate.expandreauth.shto handle MFA challenges via Telegram replies. - State persistence uses
/config/telegram_update_id.numto ensure no commands are missed between restarts. - Configuration requires only
telegram_token,telegram_chat_id, andtelegram_polling=trueto enable full remote management.
Frequently Asked Questions
What commands can I send via Telegram to control docker-icloudpd?
You can send two primary commands formatted as <user> <command>, where <user> defaults to boredazfcuk. Sending boredazfcuk sync triggers an immediate download cycle via the synchronise_user function in sync-icloud.sh. Sending boredazfcuk auth initiates the re-authentication workflow by spawning authenticate.exp to refresh expired iCloud cookies.
How does docker-icloudpd handle MFA codes securely over Telegram?
When you trigger remote authentication, reauth.sh performs an --auth-only run of icloudpd to generate the MFA challenge. The container then sends a prompt via sendmessage.sh listing available phone numbers for SMS or requesting the 6-digit code from a trusted device. Your reply containing the code is parsed by the polling loop in sync-icloud.sh (lines 2434-2452) and passed directly to the authenticate.exp Expect script, which injects it into the authentication dialog without logging the secret to persistent storage.
Can I use Telegram 2-way communication without enabling polling?
No. The inbound command channel requires telegram_polling=true in your configuration. This setting activates the polling loop in sync-icloud.sh that queries the Telegram Bot API's getUpdates endpoint every sync cycle. Without polling enabled, the container can only send outbound notifications via sendmessage.sh but cannot receive or process remote commands for sync or authentication.
What happens if the Telegram bot doesn't respond to authentication requests?
If the bot fails to respond, first verify that telegram_polling is set to true and that your telegram_token and telegram_chat_id are correct in /config/icloudpd.conf. The container stores the last processed update ID in /config/telegram_update_id.num; if this offset becomes corrupted, delete the file to reset the polling state. Check the container logs for curl errors reaching the Telegram API—if you're in a restricted network, configure telegram_server as a proxy. The authentication workflow requires the Expect script authenticate.exp to be present in /usr/local/bin/; if missing, the auth command will fail silently.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →