From 21db2fd2522031ff69806bf19f76bc83714cc356 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Thu, 4 Nov 2021 17:37:21 -0400 Subject: [PATCH 01/25] Added sendToTelegram in proxy and notifier --- api_auth_docker/api-sample.properties | 1 + .../templates/gatekeeper/api.properties | 1 + notifier_docker/.gitignore | 1 + notifier_docker/sample-env.properties | 37 +++++ notifier_docker/script/requesthandler.sh | 13 +- notifier_docker/script/web.sh | 11 +- proxy_docker/app/script/notify.sh | 41 ++++++ proxy_docker/app/script/requesthandler.sh | 10 +- proxy_docker/app/script/startproxy.sh | 2 +- proxy_docker/test/notify-telegram/.gitignore | 2 + .../test/notify-telegram/env.properties | 23 +++ proxy_docker/test/notify-telegram/run.sh | 135 ++++++++++++++++++ .../sample-env-notifier-test.properties | 34 +++++ 13 files changed, 304 insertions(+), 7 deletions(-) create mode 100644 notifier_docker/.gitignore create mode 100644 notifier_docker/sample-env.properties create mode 100644 proxy_docker/test/notify-telegram/.gitignore create mode 100644 proxy_docker/test/notify-telegram/env.properties create mode 100755 proxy_docker/test/notify-telegram/run.sh create mode 100644 proxy_docker/test/notify-telegram/sample-env-notifier-test.properties diff --git a/api_auth_docker/api-sample.properties b/api_auth_docker/api-sample.properties index 398781940..8356e22c8 100644 --- a/api_auth_docker/api-sample.properties +++ b/api_auth_docker/api-sample.properties @@ -72,3 +72,4 @@ action_conf=internal action_newblock=internal action_executecallbacks=internal action_ots_backoffice=internal +action_notify_telegram=internal diff --git a/cyphernodeconf_docker/templates/gatekeeper/api.properties b/cyphernodeconf_docker/templates/gatekeeper/api.properties index 2a50779d1..e50cd9fbf 100644 --- a/cyphernodeconf_docker/templates/gatekeeper/api.properties +++ b/cyphernodeconf_docker/templates/gatekeeper/api.properties @@ -80,3 +80,4 @@ action_conf=internal action_newblock=internal action_executecallbacks=internal action_ots_backoffice=internal +action_notify_telegram=internal diff --git a/notifier_docker/.gitignore b/notifier_docker/.gitignore new file mode 100644 index 000000000..da752e62e --- /dev/null +++ b/notifier_docker/.gitignore @@ -0,0 +1 @@ +env.properties diff --git a/notifier_docker/sample-env.properties b/notifier_docker/sample-env.properties new file mode 100644 index 000000000..6fe6ad439 --- /dev/null +++ b/notifier_docker/sample-env.properties @@ -0,0 +1,37 @@ +# Get your Telegram API Key by chating with the @BotFather +# Details here https://core.telegram.org/bots +# +# calling Telegram API +# example : +# https://api.telegram.org/bot+TELEGRAM_API_KEY/your-action +# https://api.telegram.org/botTELEGRAM_API_KEY/getMe +# returns: +# {"ok":true,"result":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} +# +# Add your Bot to a group and then get updates to get the chat.ID in order to send messages to this group afterwards. +# Below, the chat.id is chat.id:-TELEGRAM_CHAT_ID +# +# https://api.telegram.org/botTELEGRAM_API_KEY/getUpdates +# +#{"ok":true,"result":[{"update_id":701180871, +#"my_chat_member":{"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":false},"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"date":1635877254,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"member"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"left"}}},{"update_id":701180872, +#"message":{"message_id":7,"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877254,"left_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"left_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"}}},{"update_id":701180873, +#"my_chat_member":{"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"date":1635877290,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"left"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"member"}}},{"update_id":701180874, +#"message":{"message_id":8,"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877290,"new_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"new_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"new_chat_members":[{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"}]}}]} +# +# Bot says Hello World using the chat id returned previously +# https://api.telegram.org/botTOKEN/sendMessage?chat_id=CHAT-ID&text=Hello+World +# https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=-TELEGRAM_CHAT_ID&text=Hello+World +# +# returns: +# {"ok":true,"result":{"message_id":9,"from":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877783,"text":"Hello World"}} +# +# +# +# curl POST +# curl -X POST https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=TELEGRAM_CHAT_ID -H 'Content-Type: application/json' -d '{"text":"text in POST data"}' +# +TELEGRAM_BOT_URL=https://api.telegram.org/bot +TELEGRAM_API_KEY=TELEGRAM_API_KEY +TELEGRAM_CHAT_ID=-TELEGRAM_CHAT_ID + diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index f5888c8b7..378a88a72 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -11,6 +11,7 @@ main() { local cmd local response local response_topic + local url # Messages should have this form: # {"response-topic":"response/5541","cmd":"web","url":"2557df870b9a:1111/callback1conf","body":"eyJpZCI6IjUxIiwiYWRkc...dCI6MTUxNzYwMH0K"} @@ -26,6 +27,16 @@ main() { case "${cmd}" in web) + response=$(web "${msg}") + publish_response "${response}" "${response_topic}" ${?} + ;; + sendToTelegramGroup) + url=$(echo ${TELEGRAM_BOT_URL}${TELEGRAM_API_KEY}/sendMessage?chat_id=${TELEGRAM_CHAT_ID}) + trace "[main] telegram-url=${url}" + + msg=$(echo ${msg} | jq --arg url ${url} '. += {"url":$url}' ) + trace "[main] web-msg=${msg}" + response=$(web "${msg}") publish_response "${response}" "${response_topic}" ${?} ;; @@ -38,4 +49,4 @@ export TRACING=1 main trace "[requesthandler] exiting" -exit $? +exit $? \ No newline at end of file diff --git a/notifier_docker/script/web.sh b/notifier_docker/script/web.sh index 390dbb9c5..41e698a6e 100644 --- a/notifier_docker/script/web.sh +++ b/notifier_docker/script/web.sh @@ -64,11 +64,11 @@ curl_it() { fi if [ -n "${data}" ]; then - trace "[curl_it] curl ${tor} -o webresponse-${rnd} -m 20 -w \"%{http_code}\" -H \"Content-Type: application/json\" -H \"X-Forwarded-Proto: https\" -d \"${data}\" -k ${url}" - rc=$(curl ${tor} -o webresponse-${rnd} -m 20 -w "%{http_code}" -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d "${data}" -k ${url}) + trace "[curl_it] curl ${tor} -o webresponse-${rnd}\ -m 20 -w \"%{http_code}\" -H \"Content-Type: application/json\" -H \"X-Forwarded-Proto: https\" -d \"${data}\" -k ${url}" + rc=$(curl ${tor} -o \ webresponse-${rnd} -m 20 -w "%{http_code}" -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d "${data}" -k ${url}) returncode=$? else - trace "[curl_it] curl ${tor} -o webresponse-$$ -m 20 -w \"%{http_code}\" -k ${url}" + trace "[curl_it] curl ${tor} -o webresponse-${rnd} -m 20 -w \"%{http_code}\" -k ${url}" rc=$(curl ${tor} -o webresponse-${rnd} -m 20 -w "%{http_code}" -k ${url}) returncode=$? fi @@ -76,10 +76,13 @@ curl_it() { trace_rc ${returncode} if [ "${returncode}" -eq "0" ]; then - response=$(cat webresponse-${rnd} | base64 | tr -d '\n' ; rm webresponse-${rnd}) + response=$(cat webresponse-${rnd} | base64 | tr -d '\n') else response= fi + + rm webresponse-${rnd} + # When curl is unable to connect, http_code is "000" which is not a valid JSON number [ "${rc}" -eq "0" ] && rc=0 response="{\"curl_code\":${returncode},\"http_code\":${rc},\"body\":\"${response}\"}" diff --git a/proxy_docker/app/script/notify.sh b/proxy_docker/app/script/notify.sh index 42d9fa7b5..399ae3e17 100644 --- a/proxy_docker/app/script/notify.sh +++ b/proxy_docker/app/script/notify.sh @@ -49,4 +49,45 @@ notify_web() { return ${curl_code} || ${returncode} fi +} + +notify_telegram() { + trace "Entering notify_telegram()..." + + local body=$(echo "${1}" | base64 | tr -d '\n') + + local returncode + local response + local http_code + local curl_code + local msg + + msg="{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}" + + # We use the pid as the response-topic, so there's no conflict in responses. + trace "[notify_telegram] mosquitto_rr -h broker -W 21 -t notifier -e \"response/$$\" -m \"${msg}\"" + response=$(mosquitto_rr -h broker -W 21 -t notifier -e "response/$$" -m ${msg}) + returncode=$? + trace_rc ${returncode} + + # The response looks like this: {"curl_code":0,"http_code":200,"body":"..."} where the body + # is the base64(response body) but we don't need the response content here. + trace "[notify_telegram] response=${response}" + curl_code=$(echo "${response}" | jq -r ".curl_code") + trace "[notify_telegram] curl_code=${curl_code}" + http_code=$(echo "${response}" | jq -r ".http_code") + trace "[notify_telegram] http_code=${http_code}" + + echo "${response}" + + if [ "${curl_code}" -eq "0" ] && [ "${returncode}" -eq "0" ]; then + if [ "${http_code}" -lt "400" ]; then + return 0 + else + return ${http_code} + fi + else + return ${curl_code} || ${returncode} + fi + } \ No newline at end of file diff --git a/proxy_docker/app/script/requesthandler.sh b/proxy_docker/app/script/requesthandler.sh index cba8db816..e759b690c 100644 --- a/proxy_docker/app/script/requesthandler.sh +++ b/proxy_docker/app/script/requesthandler.sh @@ -4,7 +4,7 @@ # # -. ./db/config.sh +#. ./db/config.sh . ./sendtobitcoinnode.sh . ./callbacks_job.sh . ./watchrequest.sh @@ -817,6 +817,14 @@ main() { response_to_client "${response}" ${?} break ;; + notify_telegram) + # BODY {"text":"Proxy text in POST data"} + # + # curl -X POST http://localhost:8888/notify_telegram -H 'Content-Type: application/json' -d '{"text":"Proxy text in POST data"}' + response=$(notify_telegram "${line}") + response_to_client "${response}" ${?} + break + ;; esac break fi diff --git a/proxy_docker/app/script/startproxy.sh b/proxy_docker/app/script/startproxy.sh index d4d3c1fc2..e9779b962 100644 --- a/proxy_docker/app/script/startproxy.sh +++ b/proxy_docker/app/script/startproxy.sh @@ -47,7 +47,7 @@ chmod 0600 ${DB_FILE}_rawtx createCurlConfig ${WATCHER_BTC_NODE_RPC_CFG} ${WATCHER_BTC_NODE_RPC_USER} createCurlConfig ${SPENDER_BTC_NODE_RPC_CFG} ${SPENDER_BTC_NODE_RPC_USER} -. ${DB_PATH}/config.sh +#. ${DB_PATH}/config.sh if [ "${FEATURE_LIGHTNING}" = "true" ]; then ./waitanyinvoice.sh & fi diff --git a/proxy_docker/test/notify-telegram/.gitignore b/proxy_docker/test/notify-telegram/.gitignore new file mode 100644 index 000000000..1dc577d89 --- /dev/null +++ b/proxy_docker/test/notify-telegram/.gitignore @@ -0,0 +1,2 @@ +*.cid +env-notifier-test.properties diff --git a/proxy_docker/test/notify-telegram/env.properties b/proxy_docker/test/notify-telegram/env.properties new file mode 100644 index 000000000..e16320170 --- /dev/null +++ b/proxy_docker/test/notify-telegram/env.properties @@ -0,0 +1,23 @@ +TRACING=1 +WATCHER_BTC_NODE_RPC_URL=bitcoin:18443/wallet +WATCHER_BTC_NODE_DEFAULT_WALLET=watching01.dat +WATCHER_BTC_NODE_RPC_USER=regtest-34728e:regtest-3f00f07d2 +WATCHER_BTC_NODE_RPC_CFG=/proxy/watcher_btcnode_curlcfg.properties +SPENDER_BTC_NODE_RPC_URL=bitcoin:18443/wallet +SPENDER_BTC_NODE_DEFAULT_WALLET=spending01.dat +SPENDER_BTC_NODE_RPC_USER=regtest-34728e:regtest-3f00f07d2 +SPENDER_BTC_NODE_RPC_CFG=/proxy/spender_btcnode_curlcfg.properties +PROXY_LISTENING_PORT=8888 +# Variable substitutions don't work +DB_PATH=/proxy/db +DB_FILE=/proxy/db/proxydb +# Pycoin container +PYCOIN_CONTAINER=pycoin:7777 +# OTS container +OTSCLIENT_CONTAINER=otsclient:6666 +OTS_FILES=/otsfiles + +DERIVATION_PUB32=upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb +DERIVATION_PATH=0/n +WATCHER_BTC_NODE_PRUNED=false +XPUB_DERIVATION_GAP=100 diff --git a/proxy_docker/test/notify-telegram/run.sh b/proxy_docker/test/notify-telegram/run.sh new file mode 100755 index 000000000..abf5b3288 --- /dev/null +++ b/proxy_docker/test/notify-telegram/run.sh @@ -0,0 +1,135 @@ +#!/bin/sh + +NETWORK=cn-test-network +DATETIME=`date -u +"%FT%H%MZ"` +PROXY_IMAGE=api-proxy-docker-test +NOTIFIER_IMAGE=notifier-test +BROKER_IMAGE=eclipse-mosquitto:1.6-openssl + +echo Setting up to test `pwd` on $DATETIME + +create_test_network() +{ + local network=$(docker network ls | grep $NETWORK ); + + if [[ ! $network =~ $NETWORK ]]; then + docker network create $NETWORK + else + echo "Network found" + fi +} + +build_proxy() +{ + local image=$(docker image ls | grep $PROXY_IMAGE ); + + if [[ ! $image =~ $PROXY_IMAGE ]]; then + docker build -f ../../Dockerfile --no-cache -t $PROXY_IMAGE ../.. + else + echo "Proxy image found" + fi +} + +build_notifier() +{ + local image=$(docker image ls | grep $NOTIFIER_IMAGE ); + + if [[ ! $image =~ $NOTIFIER_IMAGE ]]; then + docker build -f ../../../notifier_docker/Dockerfile --no-cache -t $NOTIFIER_IMAGE ../../../notifier_docker + else + echo "Notifier image found" + fi +} + +curl_it() { + local returncode + local response + local webresponse=$(mktemp) + + local url=$(echo "${1}" | tr -d '"') + # Decode data that base base64 encoded + local data=$(echo "${2}" | base64 -d) + + if [ -n "${data}" ]; then + rc=$(curl -o ${webresponse} -m 20 -w "%{http_code}" -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d "${data}" -k ${url}) + returncode=$? + else + rc=$(curl -o ${webresponse} -m 20 -w "%{http_code}" -k ${url}) + returncode=$? + fi + + if [ "${returncode}" -eq "0" ]; then + response=$(cat ${webresponse} | base64 | tr -d '\n') + else + response= + fi + + rm ${webresponse} + + # When curl is unable to connect, http_code is "000" which is not a valid JSON number + [ "${rc}" -eq "0" ] && rc=0 + response="{\"curl_code\":${returncode},\"http_code\":${rc},\"body\":\"${response}\"}" + + echo "${response}" + + if [ "${returncode}" -eq "0" ]; then + if [ "${rc}" -lt "400" ]; then + return 0 + else + return ${rc} + fi + else + return ${returncode} + fi +} + + + +create_test_network +build_proxy +build_notifier + +#Run proxy +docker run --rm -p 8888:8888 --cidfile=proxy-id-file.cid -d -v `pwd`/../cyphernode/logs:/cnlogs -v `pwd`/../cyphernode/proxy:/proxy/db --network $NETWORK --name cn-proxy-test --env-file ./env.properties $PROXY_IMAGE `id -u`:`id -g` ./startproxy.sh + +#Run broker +docker run --cidfile=broker-id-file.cid -d --rm --network $NETWORK --name broker $BROKER_IMAGE + +#Run Notifier +docker run --cidfile=notifier-id-file.cid --rm -d -p 1883:1883 -p 9001:9001 -v `pwd`/../cyphernode/logs:/cnlogs --network $NETWORK --env-file ./env-notifier-test.properties --name notifier $NOTIFIER_IMAGE `id -u`:`id -g` ./startnotifier.sh + +################################################## +# Run some tests +################################################## + +echo -n " Testing helloworld... " +curl_it "http://localhost:8888/helloworld" +if [ "$?" -ne "0" ]; then + echo ">>>>> Failed" +fi + +echo -n " Testing notify_telegram... " + +curl_it "http://localhost:8888/notify_telegram" "$(echo {\"text\":\"Proxy text in POST data ${DATETIME}\"} | base64)" + +if [ "$?" -ne "0" ]; then + echo ">>>>> Failed" +fi + +echo 'Stopping container' +docker stop `cat proxy-id-file.cid` +docker stop `cat notifier-id-file.cid` +docker stop `cat broker-id-file.cid` + +rm -f *.cid + +echo 'Removing network' +docker network rm $NETWORK + + +echo 'Removing image' +docker image rm $PROXY_IMAGE +docker image rm $BROKER_IMAGE +docker image rm $NOTIFIER_IMAGE + +#echo "HTML Test and Report information for this run can be seen here: `pwd`/results/test-results-$DATETIME/index.html" diff --git a/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties b/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties new file mode 100644 index 000000000..39dae8a65 --- /dev/null +++ b/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties @@ -0,0 +1,34 @@ +# Get your Telegram API Key by chating with the @BotFather +# Details here https://core.telegram.org/bots + +# calling Telegram API +# example : +# https://api.telegram.org/bot+TELEGRAM_API_KEY/your-action +# https://api.telegram.org/bot2084591315:AAFMACg110Je88R5P6sifFSfEcLhvVuS-Hs/getMe +# returns: +# {"ok":true,"result":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} + +# Add your Bot to a group and then get updates to get the chat.ID in order to send messages to this group afterwards. +# Below, the chat.id is chat.id:-658390821 + +# https://api.telegram.org/bot2084591315:AAFMACg110Je88R5P6sifFSfEcLhvVuS-Hs/getUpdates + +#{"ok":true,"result":[{"update_id":701180871, +#"my_chat_member":{"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":false},"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"date":1635877254,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"member"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"left"}}},{"update_id":701180872, +#"message":{"message_id":7,"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877254,"left_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"left_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"}}},{"update_id":701180873, +#"my_chat_member":{"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"date":1635877290,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"left"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"member"}}},{"update_id":701180874, +#"message":{"message_id":8,"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877290,"new_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"new_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"new_chat_members":[{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"}]}}]} + +# Bot says Hello World using the chat id returned previously +# https://api.telegram.org/botTOKEN/sendMessage?chat_id=CHAT-ID&text=Hello+World +# https://api.telegram.org/bot2084591315:AAFMACg110Je88R5P6sifFSfEcLhvVuS-Hs/sendMessage?chat_id=-658390821&text=Hello+World +# +# returns: +# {"ok":true,"result":{"message_id":9,"from":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877783,"text":"Hello World"}} + +TELEGRAM_BOT_URL=https://api.telegram.org/bot +TELEGRAM_API_KEY= +TELEGRAM_CHAT_ID= + +TOR_HOST=tor +TOR_PORT=9050 \ No newline at end of file From 54d53dc63c2cb7ad44e4b06e48cd059f232f637b Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Thu, 4 Nov 2021 18:25:41 -0400 Subject: [PATCH 02/25] Removed test keys --- .../notify-telegram/sample-env-notifier-test.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties b/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties index 39dae8a65..c84ac1e12 100644 --- a/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties +++ b/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties @@ -4,14 +4,14 @@ # calling Telegram API # example : # https://api.telegram.org/bot+TELEGRAM_API_KEY/your-action -# https://api.telegram.org/bot2084591315:AAFMACg110Je88R5P6sifFSfEcLhvVuS-Hs/getMe +# https://api.telegram.org/boTELEGRAM_API_KEY/getMe # returns: # {"ok":true,"result":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} # Add your Bot to a group and then get updates to get the chat.ID in order to send messages to this group afterwards. # Below, the chat.id is chat.id:-658390821 -# https://api.telegram.org/bot2084591315:AAFMACg110Je88R5P6sifFSfEcLhvVuS-Hs/getUpdates +# https://api.telegram.org/botTELEGRAM_API_KEYgetUpdates #{"ok":true,"result":[{"update_id":701180871, #"my_chat_member":{"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":false},"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"date":1635877254,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"member"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"left"}}},{"update_id":701180872, @@ -20,8 +20,8 @@ #"message":{"message_id":8,"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877290,"new_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"new_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"new_chat_members":[{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"}]}}]} # Bot says Hello World using the chat id returned previously -# https://api.telegram.org/botTOKEN/sendMessage?chat_id=CHAT-ID&text=Hello+World -# https://api.telegram.org/bot2084591315:AAFMACg110Je88R5P6sifFSfEcLhvVuS-Hs/sendMessage?chat_id=-658390821&text=Hello+World +# https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=CHAT-ID&text=Hello+World +# https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=-658390821&text=Hello+World # # returns: # {"ok":true,"result":{"message_id":9,"from":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877783,"text":"Hello World"}} From 90ce08a41cb1b7684f34751ed36ad19c98575556 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Wed, 10 Nov 2021 14:01:30 -0500 Subject: [PATCH 03/25] Added Telegram feature in setup + test on CN start --- cyphernodeconf_docker/features.json | 4 + cyphernodeconf_docker/help.json | 1 + cyphernodeconf_docker/lib/app.js | 4 + .../schema/config-v0.2.5.json | 6 +- .../templates/installer/config.sh | 1 + .../installer/docker/docker-compose.yaml | 15 ++- .../templates/installer/testfeatures.sh | 34 +++++++ dist/setup.sh | 7 ++ notifier_docker/.gitignore | 1 - notifier_docker/Dockerfile | 2 +- notifier_docker/script/.gitignore | 1 + notifier_docker/script/requesthandler.sh | 29 ++++-- .../sample-config.sh} | 3 +- notifier_docker/script/web.sh | 4 +- proxy_docker/app/script/notify.sh | 4 + proxy_docker/app/script/requesthandler.sh | 14 +-- proxy_docker/app/script/startproxy.sh | 1 - proxy_docker/test/notify-telegram/.gitignore | 3 +- .../notify-telegram/Dockerfile-test-notify | 15 +++ .../test/notify-telegram/env.properties | 23 ----- .../test/notify-telegram/notifier-env.env | 2 + proxy_docker/test/notify-telegram/run.sh | 94 ++++--------------- .../sample-env-notifier-test.properties | 34 ------- .../test/notify-telegram/script/test.sh | 15 +++ 24 files changed, 149 insertions(+), 168 deletions(-) delete mode 100644 notifier_docker/.gitignore create mode 100644 notifier_docker/script/.gitignore rename notifier_docker/{sample-env.properties => script/sample-config.sh} (97%) create mode 100644 proxy_docker/test/notify-telegram/Dockerfile-test-notify delete mode 100644 proxy_docker/test/notify-telegram/env.properties create mode 100644 proxy_docker/test/notify-telegram/notifier-env.env delete mode 100644 proxy_docker/test/notify-telegram/sample-env-notifier-test.properties create mode 100644 proxy_docker/test/notify-telegram/script/test.sh diff --git a/cyphernodeconf_docker/features.json b/cyphernodeconf_docker/features.json index 9045fde70..76b50f25f 100644 --- a/cyphernodeconf_docker/features.json +++ b/cyphernodeconf_docker/features.json @@ -18,5 +18,9 @@ { "name": "Specter Cypherapp", "value": "specter" + }, + { + "name": "Telegram notifications", + "value": "telegram" } ] diff --git a/cyphernodeconf_docker/help.json b/cyphernodeconf_docker/help.json index eeb89fe3e..92776062a 100644 --- a/cyphernodeconf_docker/help.json +++ b/cyphernodeconf_docker/help.json @@ -45,5 +45,6 @@ "installer_mode": "Only one installation mode is supported, right now: local docker (self-hosted). Choose wisely ;-)", "installer_cleanup": "Do you want to remove this configurator Docker image after installation? This would free about 150MB of disk space.", "docker_mode": "Cyphernode Docker services can be run using Docker Swarm (https://docs.docker.com/engine/swarm/) or docker-compose (https://docs.docker.com/compose/overview/). Both will work, some users prefer one to another depending on deployment types, scalability, current framework, etc.", + "telegram": "Would you like to enable Telegram notifications - Some manual steps need to be carried once before first use. See /notifier_docker/sample-config.sh", "__default__": "" } diff --git a/cyphernodeconf_docker/lib/app.js b/cyphernodeconf_docker/lib/app.js index 2e34f18a8..10ef14463 100644 --- a/cyphernodeconf_docker/lib/app.js +++ b/cyphernodeconf_docker/lib/app.js @@ -551,6 +551,10 @@ module.exports = class App { clearnet: !this.isChecked('features', 'tor') || this.isChecked('clearnet', 'clearnet_lightning'), tor_hostname: this.sessionData.tor_lightning_hostname } + }, + telegram: { + networks: ['no-network'], + docker: "no-docker" } } diff --git a/cyphernodeconf_docker/schema/config-v0.2.5.json b/cyphernodeconf_docker/schema/config-v0.2.5.json index 4810ac5e4..96c81ae38 100644 --- a/cyphernodeconf_docker/schema/config-v0.2.5.json +++ b/cyphernodeconf_docker/schema/config-v0.2.5.json @@ -187,7 +187,8 @@ "lightning", "otsclient", "batcher", - "specter" + "specter", + "telegram" ], "title": "The feature", "default": "", @@ -196,7 +197,8 @@ "lightning", "otsclient", "batcher", - "specter" + "specter", + "telegram" ] } }, diff --git a/cyphernodeconf_docker/templates/installer/config.sh b/cyphernodeconf_docker/templates/installer/config.sh index f54fcd5fe..ba64b3049 100644 --- a/cyphernodeconf_docker/templates/installer/config.sh +++ b/cyphernodeconf_docker/templates/installer/config.sh @@ -1,6 +1,7 @@ INSTALLER_MODE=<%= installer_mode %> BITCOIN_INTERNAL=<%= (bitcoin_mode==="internal"?'true':'false') %> FEATURE_LIGHTNING=<%= (features.indexOf('lightning') != -1)?'true':'false' %> +FEATURE_TELEGRAM=<%= (features.indexOf('telegram') != -1)?'true':'false' %> FEATURE_BATCHER=<%= (features.indexOf('batcher') != -1)?'true':'false' %> FEATURE_SPECTER=<%= (features.indexOf('specter') != -1)?'true':'false' %> FEATURE_OTSCLIENT=<%= (features.indexOf('otsclient') != -1)?'true':'false' %> diff --git a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml index b53e1493c..b239b3585 100644 --- a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml +++ b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml @@ -156,6 +156,13 @@ services: - "OTSCLIENT_CONTAINER=otsclient:6666" - "OTS_FILES=/proxy/otsfiles" - "XPUB_DERIVATION_GAP=100" + <% if ( features.indexOf('lightning') !== -1 && lightning_implementation === 'c-lightning' ) { %> + - "FEATURE_LIGHTNING=true" + <% } %> + <% if ( features.indexOf('telegram') !== -1 ) { %> + - "FEATURE_TELEGRAM=true" + <% } %> + <% if ( devmode ) { %> ports: - "8888:8888" @@ -248,11 +255,15 @@ services: notifier: image: cyphernode/notifier:<%= notifier_version %> command: $USER ./startnotifier.sh - <% if ( features.indexOf('tor') !== -1 ) { %> environment: + - "TRACING=1" + <% if ( features.indexOf('tor') !== -1 ) { %> - "TOR_HOST=tor" - "TOR_PORT=9050" - <% } %> + <% } %> + <% if ( features.indexOf('telegram') !== -1 ) { %> + - "FEATURE_TELEGRAM=true" + <% } %> volumes: - "<%= logs_datapath %>:/cnlogs" networks: diff --git a/cyphernodeconf_docker/templates/installer/testfeatures.sh b/cyphernodeconf_docker/templates/installer/testfeatures.sh index 65acf024c..c74f8943f 100644 --- a/cyphernodeconf_docker/templates/installer/testfeatures.sh +++ b/cyphernodeconf_docker/templates/installer/testfeatures.sh @@ -111,6 +111,23 @@ checknotifier() { return 0 } +checknotifiertelegram() { + echo -en "\r\n\e[1;36mTesting Notifier Telegram... " > /dev/console + local response + local returncode + local body=$(echo "{\"text\":\"Hello world in Telegram at `date -u +"%FT%H%MZ"`\"}" | base64) + + response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}") + returncode=$? + [ "${returncode}" -ne "0" ] && return 115 + http_code=$(echo "${response}" | jq -r ".http_code") + [ "${http_code}" -ge "400" ] && return 118 + + echo -e "\e[1;36mNotifier Telegram rocks!" > /dev/console + + return 0 +} + checkots() { echo -en "\r\n\e[1;36mTesting OTSclient... " > /dev/console local rc @@ -350,6 +367,23 @@ fi finalreturncode=$((${returncode} | ${finalreturncode})) result="${result}$(feature_status ${returncode} 'Notifier error!')}" +<% if (features.indexOf('telegram') != -1) { %> +############################# +# NOTIFIER TELEGRAM # +############################# + +result="${result},{\"coreFeature\":true, \"name\":\"notifier telegram\",\"working\":" +status=$(echo "{${containers}}" | jq ".containers[] | select(.name == \"notifier\") | .active") +if [[ "${workingproxy}" = "true" && "${status}" = "true" ]]; then + timeout_feature checknotifiertelegram + returncode=$? +else + returncode=1 +fi +finalreturncode=$((${returncode} | ${finalreturncode})) +result="${result}$(feature_status ${returncode} 'Notifier Telegram error!')}" +<% } %> + ############################# # PYCOIN # ############################# diff --git a/dist/setup.sh b/dist/setup.sh index f1d336d34..be542718c 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -826,6 +826,13 @@ install_apps() { next fi fi + + if [[ $FEATURE_TELEGRAM == true ]]; then + step " enabled Telegram - Manual configuration needed before first time use (Bot and Group creation, API key) - see notifier_docker/script/sample-env.properties" + else + step " disabled Telegram" + fi + } install() { diff --git a/notifier_docker/.gitignore b/notifier_docker/.gitignore deleted file mode 100644 index da752e62e..000000000 --- a/notifier_docker/.gitignore +++ /dev/null @@ -1 +0,0 @@ -env.properties diff --git a/notifier_docker/Dockerfile b/notifier_docker/Dockerfile index 2b858a8cd..92fbdd3ae 100644 --- a/notifier_docker/Dockerfile +++ b/notifier_docker/Dockerfile @@ -8,7 +8,7 @@ WORKDIR ${HOME} COPY script/* ./ -RUN chmod +x startnotifier.sh requesthandler.sh \ +RUN chmod +x startnotifier.sh requesthandler.sh config.sh \ && chmod o+w . ENTRYPOINT ["su-exec"] diff --git a/notifier_docker/script/.gitignore b/notifier_docker/script/.gitignore new file mode 100644 index 000000000..cdd7c19c8 --- /dev/null +++ b/notifier_docker/script/.gitignore @@ -0,0 +1 @@ +config.sh diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index 378a88a72..e4bc565ab 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -3,6 +3,7 @@ . ./trace.sh . ./web.sh . ./response.sh +. ./config.sh main() { trace "Entering main()..." @@ -13,6 +14,12 @@ main() { local response_topic local url + if [ "${FEATURE_TELEGRAM}" = "true" ]; then + trace "[notifier] FEATURE_TELEGRAM is ENABLED" + else + trace "[notifier] FEATURE_TELEGRAM is DISABLED" + fi + # Messages should have this form: # {"response-topic":"response/5541","cmd":"web","url":"2557df870b9a:1111/callback1conf","body":"eyJpZCI6IjUxIiwiYWRkc...dCI6MTUxNzYwMH0K"} while read msg; do @@ -31,22 +38,24 @@ main() { publish_response "${response}" "${response_topic}" ${?} ;; sendToTelegramGroup) - url=$(echo ${TELEGRAM_BOT_URL}${TELEGRAM_API_KEY}/sendMessage?chat_id=${TELEGRAM_CHAT_ID}) - trace "[main] telegram-url=${url}" - - msg=$(echo ${msg} | jq --arg url ${url} '. += {"url":$url}' ) - trace "[main] web-msg=${msg}" - - response=$(web "${msg}") - publish_response "${response}" "${response_topic}" ${?} + if [ "${FEATURE_TELEGRAM}" = "true" ]; then + url=$(echo ${TELEGRAM_BOT_URL}${TELEGRAM_API_KEY}/sendMessage?chat_id=${TELEGRAM_CHAT_ID}) + trace "[main] telegram-url=${url}" + + msg=$(echo ${msg} | jq --arg url ${url} '. += {"url":$url}' ) + trace "[main] web-msg=${msg}" + + response=$(web "${msg}") + publish_response "${response}" "${response_topic}" ${?} + else + trace "[main] Telegram is NOT enabled - message not sent" + fi ;; esac trace "[main] msg processed" done } -export TRACING=1 - main trace "[requesthandler] exiting" exit $? \ No newline at end of file diff --git a/notifier_docker/sample-env.properties b/notifier_docker/script/sample-config.sh similarity index 97% rename from notifier_docker/sample-env.properties rename to notifier_docker/script/sample-config.sh index 6fe6ad439..313feb058 100644 --- a/notifier_docker/sample-env.properties +++ b/notifier_docker/script/sample-config.sh @@ -13,7 +13,7 @@ # # https://api.telegram.org/botTELEGRAM_API_KEY/getUpdates # -#{"ok":true,"result":[{"update_id":701180871, +# {"ok":true,"result":[{"update_id":701180871, #"my_chat_member":{"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":false},"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"date":1635877254,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"member"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"left"}}},{"update_id":701180872, #"message":{"message_id":7,"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877254,"left_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"left_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"}}},{"update_id":701180873, #"my_chat_member":{"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"date":1635877290,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"left"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"member"}}},{"update_id":701180874, @@ -35,3 +35,4 @@ TELEGRAM_BOT_URL=https://api.telegram.org/bot TELEGRAM_API_KEY=TELEGRAM_API_KEY TELEGRAM_CHAT_ID=-TELEGRAM_CHAT_ID +# Add those keys to /script/config.sh \ No newline at end of file diff --git a/notifier_docker/script/web.sh b/notifier_docker/script/web.sh index 41e698a6e..b7ad0b9fd 100644 --- a/notifier_docker/script/web.sh +++ b/notifier_docker/script/web.sh @@ -64,8 +64,8 @@ curl_it() { fi if [ -n "${data}" ]; then - trace "[curl_it] curl ${tor} -o webresponse-${rnd}\ -m 20 -w \"%{http_code}\" -H \"Content-Type: application/json\" -H \"X-Forwarded-Proto: https\" -d \"${data}\" -k ${url}" - rc=$(curl ${tor} -o \ webresponse-${rnd} -m 20 -w "%{http_code}" -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d "${data}" -k ${url}) + trace "[curl_it] curl ${tor} -o webresponse-${rnd} -m 20 -w \"%{http_code}\" -H \"Content-Type: application/json\" -H \"X-Forwarded-Proto: https\" -d \"${data}\" -k ${url}" + rc=$(curl ${tor} -o webresponse-${rnd} -m 20 -w "%{http_code}" -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d "${data}" -k ${url}) returncode=$? else trace "[curl_it] curl ${tor} -o webresponse-${rnd} -m 20 -w \"%{http_code}\" -k ${url}" diff --git a/proxy_docker/app/script/notify.sh b/proxy_docker/app/script/notify.sh index 399ae3e17..099fedc1e 100644 --- a/proxy_docker/app/script/notify.sh +++ b/proxy_docker/app/script/notify.sh @@ -51,6 +51,10 @@ notify_web() { } +# +# call notify_telegram "JSON data". See https://core.telegram.org/bots/api#sendmessage +# ex in shell script: notify_telegram "{\"text\":\"Unit testing notify_telegram at `date -u +"%FT%H%MZ"`\"}" +# notify_telegram() { trace "Entering notify_telegram()..." diff --git a/proxy_docker/app/script/requesthandler.sh b/proxy_docker/app/script/requesthandler.sh index e759b690c..7cb951377 100644 --- a/proxy_docker/app/script/requesthandler.sh +++ b/proxy_docker/app/script/requesthandler.sh @@ -1,10 +1,5 @@ #!/bin/sh # -# -# -# - -#. ./db/config.sh . ./sendtobitcoinnode.sh . ./callbacks_job.sh . ./watchrequest.sh @@ -76,6 +71,7 @@ main() { case "${cmd}" in helloworld) # GET http://192.168.111.152:8080/helloworld + response_to_client "Hello, world!" 0 break ;; @@ -817,14 +813,6 @@ main() { response_to_client "${response}" ${?} break ;; - notify_telegram) - # BODY {"text":"Proxy text in POST data"} - # - # curl -X POST http://localhost:8888/notify_telegram -H 'Content-Type: application/json' -d '{"text":"Proxy text in POST data"}' - response=$(notify_telegram "${line}") - response_to_client "${response}" ${?} - break - ;; esac break fi diff --git a/proxy_docker/app/script/startproxy.sh b/proxy_docker/app/script/startproxy.sh index e9779b962..8aa52dd31 100644 --- a/proxy_docker/app/script/startproxy.sh +++ b/proxy_docker/app/script/startproxy.sh @@ -47,7 +47,6 @@ chmod 0600 ${DB_FILE}_rawtx createCurlConfig ${WATCHER_BTC_NODE_RPC_CFG} ${WATCHER_BTC_NODE_RPC_USER} createCurlConfig ${SPENDER_BTC_NODE_RPC_CFG} ${SPENDER_BTC_NODE_RPC_USER} -#. ${DB_PATH}/config.sh if [ "${FEATURE_LIGHTNING}" = "true" ]; then ./waitanyinvoice.sh & fi diff --git a/proxy_docker/test/notify-telegram/.gitignore b/proxy_docker/test/notify-telegram/.gitignore index 1dc577d89..fe7c50984 100644 --- a/proxy_docker/test/notify-telegram/.gitignore +++ b/proxy_docker/test/notify-telegram/.gitignore @@ -1,2 +1 @@ -*.cid -env-notifier-test.properties +*.cid \ No newline at end of file diff --git a/proxy_docker/test/notify-telegram/Dockerfile-test-notify b/proxy_docker/test/notify-telegram/Dockerfile-test-notify new file mode 100644 index 000000000..604889401 --- /dev/null +++ b/proxy_docker/test/notify-telegram/Dockerfile-test-notify @@ -0,0 +1,15 @@ +FROM eclipse-mosquitto:1.6-openssl + +RUN apk --no-cache --update add jq curl su-exec + +ENV HOME /testnotifier + +WORKDIR ${HOME} + +COPY test/notify-telegram/script/test.sh ./ +COPY app/script/* ./ + +RUN chmod +x test.sh \ + && chmod o+w . + +ENTRYPOINT ["su-exec"] diff --git a/proxy_docker/test/notify-telegram/env.properties b/proxy_docker/test/notify-telegram/env.properties deleted file mode 100644 index e16320170..000000000 --- a/proxy_docker/test/notify-telegram/env.properties +++ /dev/null @@ -1,23 +0,0 @@ -TRACING=1 -WATCHER_BTC_NODE_RPC_URL=bitcoin:18443/wallet -WATCHER_BTC_NODE_DEFAULT_WALLET=watching01.dat -WATCHER_BTC_NODE_RPC_USER=regtest-34728e:regtest-3f00f07d2 -WATCHER_BTC_NODE_RPC_CFG=/proxy/watcher_btcnode_curlcfg.properties -SPENDER_BTC_NODE_RPC_URL=bitcoin:18443/wallet -SPENDER_BTC_NODE_DEFAULT_WALLET=spending01.dat -SPENDER_BTC_NODE_RPC_USER=regtest-34728e:regtest-3f00f07d2 -SPENDER_BTC_NODE_RPC_CFG=/proxy/spender_btcnode_curlcfg.properties -PROXY_LISTENING_PORT=8888 -# Variable substitutions don't work -DB_PATH=/proxy/db -DB_FILE=/proxy/db/proxydb -# Pycoin container -PYCOIN_CONTAINER=pycoin:7777 -# OTS container -OTSCLIENT_CONTAINER=otsclient:6666 -OTS_FILES=/otsfiles - -DERIVATION_PUB32=upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb -DERIVATION_PATH=0/n -WATCHER_BTC_NODE_PRUNED=false -XPUB_DERIVATION_GAP=100 diff --git a/proxy_docker/test/notify-telegram/notifier-env.env b/proxy_docker/test/notify-telegram/notifier-env.env new file mode 100644 index 000000000..8f0d73e78 --- /dev/null +++ b/proxy_docker/test/notify-telegram/notifier-env.env @@ -0,0 +1,2 @@ +TRACING=1 +FEATURE_TELEGRAM=true diff --git a/proxy_docker/test/notify-telegram/run.sh b/proxy_docker/test/notify-telegram/run.sh index abf5b3288..95b52df19 100755 --- a/proxy_docker/test/notify-telegram/run.sh +++ b/proxy_docker/test/notify-telegram/run.sh @@ -2,9 +2,9 @@ NETWORK=cn-test-network DATETIME=`date -u +"%FT%H%MZ"` -PROXY_IMAGE=api-proxy-docker-test NOTIFIER_IMAGE=notifier-test BROKER_IMAGE=eclipse-mosquitto:1.6-openssl +TEST_IMAGE=test-image echo Setting up to test `pwd` on $DATETIME @@ -19,14 +19,16 @@ create_test_network() fi } -build_proxy() +build_test_image() { - local image=$(docker image ls | grep $PROXY_IMAGE ); + local image=$(docker image ls | grep $TEST_IMAGE ); - if [[ ! $image =~ $PROXY_IMAGE ]]; then - docker build -f ../../Dockerfile --no-cache -t $PROXY_IMAGE ../.. + if [[ ! $image =~ $TEST_IMAGE ]]; then + + #/Users/philippelamy/werk/telegram/proxy_docker/test/notify-telegram/run.sh + docker build -f Dockerfile-test-notify --no-cache -t $TEST_IMAGE ../.. else - echo "Proxy image found" + echo "Test image found" fi } @@ -41,85 +43,28 @@ build_notifier() fi } -curl_it() { - local returncode - local response - local webresponse=$(mktemp) - - local url=$(echo "${1}" | tr -d '"') - # Decode data that base base64 encoded - local data=$(echo "${2}" | base64 -d) - - if [ -n "${data}" ]; then - rc=$(curl -o ${webresponse} -m 20 -w "%{http_code}" -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d "${data}" -k ${url}) - returncode=$? - else - rc=$(curl -o ${webresponse} -m 20 -w "%{http_code}" -k ${url}) - returncode=$? - fi - - if [ "${returncode}" -eq "0" ]; then - response=$(cat ${webresponse} | base64 | tr -d '\n') - else - response= - fi - - rm ${webresponse} - - # When curl is unable to connect, http_code is "000" which is not a valid JSON number - [ "${rc}" -eq "0" ] && rc=0 - response="{\"curl_code\":${returncode},\"http_code\":${rc},\"body\":\"${response}\"}" - - echo "${response}" - - if [ "${returncode}" -eq "0" ]; then - if [ "${rc}" -lt "400" ]; then - return 0 - else - return ${rc} - fi - else - return ${returncode} - fi -} - - create_test_network -build_proxy build_notifier - -#Run proxy -docker run --rm -p 8888:8888 --cidfile=proxy-id-file.cid -d -v `pwd`/../cyphernode/logs:/cnlogs -v `pwd`/../cyphernode/proxy:/proxy/db --network $NETWORK --name cn-proxy-test --env-file ./env.properties $PROXY_IMAGE `id -u`:`id -g` ./startproxy.sh +build_test_image #Run broker +echo 'running broker' docker run --cidfile=broker-id-file.cid -d --rm --network $NETWORK --name broker $BROKER_IMAGE #Run Notifier -docker run --cidfile=notifier-id-file.cid --rm -d -p 1883:1883 -p 9001:9001 -v `pwd`/../cyphernode/logs:/cnlogs --network $NETWORK --env-file ./env-notifier-test.properties --name notifier $NOTIFIER_IMAGE `id -u`:`id -g` ./startnotifier.sh +echo 'running notifier' +docker run --cidfile=notifier-id-file.cid --rm -d -p 1883:1883 -p 9001:9001 -v `pwd`/../cyphernode/logs:/cnlogs --network $NETWORK --env-file notifier-env.env --name notifier $NOTIFIER_IMAGE `id -u`:`id -g` ./startnotifier.sh -################################################## -# Run some tests -################################################## - -echo -n " Testing helloworld... " -curl_it "http://localhost:8888/helloworld" -if [ "$?" -ne "0" ]; then - echo ">>>>> Failed" -fi - -echo -n " Testing notify_telegram... " - -curl_it "http://localhost:8888/notify_telegram" "$(echo {\"text\":\"Proxy text in POST data ${DATETIME}\"} | base64)" - -if [ "$?" -ne "0" ]; then - echo ">>>>> Failed" -fi +#Run tests +echo 'running tests' +docker run --cidfile=test-image-id-file.cid --rm -d -v `pwd`/../cyphernode/logs:/cnlogs --network $NETWORK --name test-image $TEST_IMAGE `id -u`:`id -g` ./test.sh +sleep 5 echo 'Stopping container' -docker stop `cat proxy-id-file.cid` docker stop `cat notifier-id-file.cid` docker stop `cat broker-id-file.cid` +docker stop `cat test-image-id-file.cid` rm -f *.cid @@ -128,8 +73,5 @@ docker network rm $NETWORK echo 'Removing image' -docker image rm $PROXY_IMAGE -docker image rm $BROKER_IMAGE docker image rm $NOTIFIER_IMAGE - -#echo "HTML Test and Report information for this run can be seen here: `pwd`/results/test-results-$DATETIME/index.html" +docker image rm $TEST_IMAGE diff --git a/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties b/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties deleted file mode 100644 index c84ac1e12..000000000 --- a/proxy_docker/test/notify-telegram/sample-env-notifier-test.properties +++ /dev/null @@ -1,34 +0,0 @@ -# Get your Telegram API Key by chating with the @BotFather -# Details here https://core.telegram.org/bots - -# calling Telegram API -# example : -# https://api.telegram.org/bot+TELEGRAM_API_KEY/your-action -# https://api.telegram.org/boTELEGRAM_API_KEY/getMe -# returns: -# {"ok":true,"result":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} - -# Add your Bot to a group and then get updates to get the chat.ID in order to send messages to this group afterwards. -# Below, the chat.id is chat.id:-658390821 - -# https://api.telegram.org/botTELEGRAM_API_KEYgetUpdates - -#{"ok":true,"result":[{"update_id":701180871, -#"my_chat_member":{"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":false},"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"date":1635877254,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"member"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"left"}}},{"update_id":701180872, -#"message":{"message_id":7,"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877254,"left_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"left_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"}}},{"update_id":701180873, -#"my_chat_member":{"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"date":1635877290,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"left"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"status":"member"}}},{"update_id":701180874, -#"message":{"message_id":8,"from":{"id":1609436204,"is_bot":false,"first_name":"Phil","last_name":"Lamy","username":"phillamy","language_code":"en"},"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877290,"new_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"new_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"new_chat_members":[{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"}]}}]} - -# Bot says Hello World using the chat id returned previously -# https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=CHAT-ID&text=Hello+World -# https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=-658390821&text=Hello+World -# -# returns: -# {"ok":true,"result":{"message_id":9,"from":{"id":2084591315,"is_bot":true,"first_name":"Phil-logger","username":"PhilLoggerBot"},"chat":{"id":-658390821,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877783,"text":"Hello World"}} - -TELEGRAM_BOT_URL=https://api.telegram.org/bot -TELEGRAM_API_KEY= -TELEGRAM_CHAT_ID= - -TOR_HOST=tor -TOR_PORT=9050 \ No newline at end of file diff --git a/proxy_docker/test/notify-telegram/script/test.sh b/proxy_docker/test/notify-telegram/script/test.sh new file mode 100644 index 000000000..6ddb22cf1 --- /dev/null +++ b/proxy_docker/test/notify-telegram/script/test.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. notify.sh + +TRACING=1 + +export TRACING + +echo "Calling notify_telegram..." + +notify_telegram "{\"text\":\"Unit testing notify_telegram at `date -u +"%FT%H%MZ"`\"}" + +echo "Done..." + + From fdcd7ef2a377237806bb98be45b15f1858a6eadd Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Wed, 10 Nov 2021 14:24:31 -0500 Subject: [PATCH 04/25] undo change --- api_auth_docker/api-sample.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/api_auth_docker/api-sample.properties b/api_auth_docker/api-sample.properties index 8356e22c8..398781940 100644 --- a/api_auth_docker/api-sample.properties +++ b/api_auth_docker/api-sample.properties @@ -72,4 +72,3 @@ action_conf=internal action_newblock=internal action_executecallbacks=internal action_ots_backoffice=internal -action_notify_telegram=internal From 4ad38400ea2afbeab4cd8f3319b8dce0ff26a214 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Wed, 10 Nov 2021 14:27:35 -0500 Subject: [PATCH 05/25] undo change --- cyphernodeconf_docker/templates/gatekeeper/api.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/cyphernodeconf_docker/templates/gatekeeper/api.properties b/cyphernodeconf_docker/templates/gatekeeper/api.properties index e50cd9fbf..2a50779d1 100644 --- a/cyphernodeconf_docker/templates/gatekeeper/api.properties +++ b/cyphernodeconf_docker/templates/gatekeeper/api.properties @@ -80,4 +80,3 @@ action_conf=internal action_newblock=internal action_executecallbacks=internal action_ots_backoffice=internal -action_notify_telegram=internal From 9a155b945e3da5f043f216ae7a818ce3eeaa14ac Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Wed, 10 Nov 2021 14:36:15 -0500 Subject: [PATCH 06/25] removed empty line --- proxy_docker/app/script/requesthandler.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/proxy_docker/app/script/requesthandler.sh b/proxy_docker/app/script/requesthandler.sh index 7cb951377..233884408 100644 --- a/proxy_docker/app/script/requesthandler.sh +++ b/proxy_docker/app/script/requesthandler.sh @@ -71,7 +71,6 @@ main() { case "${cmd}" in helloworld) # GET http://192.168.111.152:8080/helloworld - response_to_client "Hello, world!" 0 break ;; From d3f11d9fdc247438f007020a77400150a360db8d Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Mon, 15 Nov 2021 12:01:02 -0500 Subject: [PATCH 07/25] move test in tests directory --- .../test.sh => app/tests/test-telegram.sh} | 8 +- proxy_docker/test/notify-telegram/.gitignore | 1 - .../notify-telegram/Dockerfile-test-notify | 15 ---- .../test/notify-telegram/notifier-env.env | 2 - proxy_docker/test/notify-telegram/run.sh | 77 ------------------- 5 files changed, 2 insertions(+), 101 deletions(-) rename proxy_docker/{test/notify-telegram/script/test.sh => app/tests/test-telegram.sh} (79%) mode change 100644 => 100755 delete mode 100644 proxy_docker/test/notify-telegram/.gitignore delete mode 100644 proxy_docker/test/notify-telegram/Dockerfile-test-notify delete mode 100644 proxy_docker/test/notify-telegram/notifier-env.env delete mode 100755 proxy_docker/test/notify-telegram/run.sh diff --git a/proxy_docker/test/notify-telegram/script/test.sh b/proxy_docker/app/tests/test-telegram.sh old mode 100644 new mode 100755 similarity index 79% rename from proxy_docker/test/notify-telegram/script/test.sh rename to proxy_docker/app/tests/test-telegram.sh index 6ddb22cf1..150bec030 --- a/proxy_docker/test/notify-telegram/script/test.sh +++ b/proxy_docker/app/tests/test-telegram.sh @@ -1,10 +1,7 @@ #!/bin/sh -. notify.sh - -TRACING=1 - -export TRACING +cd .. +. ./notify.sh echo "Calling notify_telegram..." @@ -12,4 +9,3 @@ notify_telegram "{\"text\":\"Unit testing notify_telegram at `date -u +"%FT%H%MZ echo "Done..." - diff --git a/proxy_docker/test/notify-telegram/.gitignore b/proxy_docker/test/notify-telegram/.gitignore deleted file mode 100644 index fe7c50984..000000000 --- a/proxy_docker/test/notify-telegram/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.cid \ No newline at end of file diff --git a/proxy_docker/test/notify-telegram/Dockerfile-test-notify b/proxy_docker/test/notify-telegram/Dockerfile-test-notify deleted file mode 100644 index 604889401..000000000 --- a/proxy_docker/test/notify-telegram/Dockerfile-test-notify +++ /dev/null @@ -1,15 +0,0 @@ -FROM eclipse-mosquitto:1.6-openssl - -RUN apk --no-cache --update add jq curl su-exec - -ENV HOME /testnotifier - -WORKDIR ${HOME} - -COPY test/notify-telegram/script/test.sh ./ -COPY app/script/* ./ - -RUN chmod +x test.sh \ - && chmod o+w . - -ENTRYPOINT ["su-exec"] diff --git a/proxy_docker/test/notify-telegram/notifier-env.env b/proxy_docker/test/notify-telegram/notifier-env.env deleted file mode 100644 index 8f0d73e78..000000000 --- a/proxy_docker/test/notify-telegram/notifier-env.env +++ /dev/null @@ -1,2 +0,0 @@ -TRACING=1 -FEATURE_TELEGRAM=true diff --git a/proxy_docker/test/notify-telegram/run.sh b/proxy_docker/test/notify-telegram/run.sh deleted file mode 100755 index 95b52df19..000000000 --- a/proxy_docker/test/notify-telegram/run.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh - -NETWORK=cn-test-network -DATETIME=`date -u +"%FT%H%MZ"` -NOTIFIER_IMAGE=notifier-test -BROKER_IMAGE=eclipse-mosquitto:1.6-openssl -TEST_IMAGE=test-image - -echo Setting up to test `pwd` on $DATETIME - -create_test_network() -{ - local network=$(docker network ls | grep $NETWORK ); - - if [[ ! $network =~ $NETWORK ]]; then - docker network create $NETWORK - else - echo "Network found" - fi -} - -build_test_image() -{ - local image=$(docker image ls | grep $TEST_IMAGE ); - - if [[ ! $image =~ $TEST_IMAGE ]]; then - - #/Users/philippelamy/werk/telegram/proxy_docker/test/notify-telegram/run.sh - docker build -f Dockerfile-test-notify --no-cache -t $TEST_IMAGE ../.. - else - echo "Test image found" - fi -} - -build_notifier() -{ - local image=$(docker image ls | grep $NOTIFIER_IMAGE ); - - if [[ ! $image =~ $NOTIFIER_IMAGE ]]; then - docker build -f ../../../notifier_docker/Dockerfile --no-cache -t $NOTIFIER_IMAGE ../../../notifier_docker - else - echo "Notifier image found" - fi -} - - -create_test_network -build_notifier -build_test_image - -#Run broker -echo 'running broker' -docker run --cidfile=broker-id-file.cid -d --rm --network $NETWORK --name broker $BROKER_IMAGE - -#Run Notifier -echo 'running notifier' -docker run --cidfile=notifier-id-file.cid --rm -d -p 1883:1883 -p 9001:9001 -v `pwd`/../cyphernode/logs:/cnlogs --network $NETWORK --env-file notifier-env.env --name notifier $NOTIFIER_IMAGE `id -u`:`id -g` ./startnotifier.sh - -#Run tests -echo 'running tests' -docker run --cidfile=test-image-id-file.cid --rm -d -v `pwd`/../cyphernode/logs:/cnlogs --network $NETWORK --name test-image $TEST_IMAGE `id -u`:`id -g` ./test.sh - -sleep 5 -echo 'Stopping container' -docker stop `cat notifier-id-file.cid` -docker stop `cat broker-id-file.cid` -docker stop `cat test-image-id-file.cid` - -rm -f *.cid - -echo 'Removing network' -docker network rm $NETWORK - - -echo 'Removing image' -docker image rm $NOTIFIER_IMAGE -docker image rm $TEST_IMAGE From 6ce3bd551f0529e3ed60e93484194418512b4430 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Sun, 21 Nov 2021 10:16:21 -0500 Subject: [PATCH 08/25] Added TG config to setup --- cyphernodeconf_docker/help.json | 5 ++ cyphernodeconf_docker/lib/app.js | 12 +++- .../prompters/050_notifier.js | 57 +++++++++++++++++ .../prompters/999_installer.js | 38 +++++++++++ .../schema/config-v0.2.5.json | 64 +++++++++++++++++++ .../templates/installer/config.sh | 1 + .../installer/docker/docker-compose.yaml | 11 +--- .../templates/installer/start.sh | 1 + .../templates/installer/stop.sh | 1 + .../templates/installer/testfeatures.sh | 5 +- .../templates/notifier/notifier.env | 12 ++++ dist/setup.sh | 16 +++-- doc/TELEGRAM.md | 34 ++++++++++ notifier_docker/Dockerfile | 2 +- notifier_docker/script/.gitignore | 1 - notifier_docker/script/requesthandler.sh | 18 +++++- notifier_docker/script/sample-config.sh | 38 ----------- notifier_docker/script/startnotifier.sh | 1 - 18 files changed, 256 insertions(+), 61 deletions(-) create mode 100644 cyphernodeconf_docker/prompters/050_notifier.js create mode 100644 cyphernodeconf_docker/templates/notifier/notifier.env create mode 100644 doc/TELEGRAM.md delete mode 100644 notifier_docker/script/.gitignore delete mode 100644 notifier_docker/script/sample-config.sh diff --git a/cyphernodeconf_docker/help.json b/cyphernodeconf_docker/help.json index 92776062a..6534bf5b8 100644 --- a/cyphernodeconf_docker/help.json +++ b/cyphernodeconf_docker/help.json @@ -46,5 +46,10 @@ "installer_cleanup": "Do you want to remove this configurator Docker image after installation? This would free about 150MB of disk space.", "docker_mode": "Cyphernode Docker services can be run using Docker Swarm (https://docs.docker.com/engine/swarm/) or docker-compose (https://docs.docker.com/compose/overview/). Both will work, some users prefer one to another depending on deployment types, scalability, current framework, etc.", "telegram": "Would you like to enable Telegram notifications - Some manual steps need to be carried once before first use. See /notifier_docker/sample-config.sh", + "notifier_datapath": "The Notifier's files will be stored in a container's mounted directory. Please provide the local mounted path to that directory. If running on OSX, check mountable directories in Docker's File Sharing configs.", + "notifier_datapath_custom": "Provide the full path name where the Notifier's files will be saved.", + "telegram_bot_url": "Provide Telegram URL to use for API calls. If you don't host a Telegram server, the default URL should work. Make sure your network rules let those outbound calls go through. There are no inbound (webhooks) calls for now", + "telegram_api_key": "Provide Telegram API key. Get your Telegram API Key by chating with the @BotFather. More info can be found here: https://core.telegram.org/bots", + "telegram_chat_id": "Provide Telegram chat id (an integer). Manual step are required: Add your Bot to a Telegram group you created and then get updates to get the chat.ID in order to send messages to this group afterwards", "__default__": "" } diff --git a/cyphernodeconf_docker/lib/app.js b/cyphernodeconf_docker/lib/app.js index 10ef14463..04698260d 100644 --- a/cyphernodeconf_docker/lib/app.js +++ b/cyphernodeconf_docker/lib/app.js @@ -365,7 +365,8 @@ module.exports = class App { 'proxy_datapath', 'bitcoin_datapath', 'lightning_datapath', - 'otsclient_datapath' + 'otsclient_datapath', + 'notifier_datapath' ]; for( let pathProp of pathProps ) { @@ -553,8 +554,13 @@ module.exports = class App { } }, telegram: { - networks: ['no-network'], - docker: "no-docker" + networks: ['cyphernodenet'], + docker: "cypernode/notifier", + extra: { + bot_url: this.config.data.telegram_bot_url, + api_key: this.config.data.telegram_api_key, + chat_id: this.config.data.telegram_chat_id + } } } diff --git a/cyphernodeconf_docker/prompters/050_notifier.js b/cyphernodeconf_docker/prompters/050_notifier.js new file mode 100644 index 000000000..383754747 --- /dev/null +++ b/cyphernodeconf_docker/prompters/050_notifier.js @@ -0,0 +1,57 @@ +const chalk = require('chalk'); + +const name = 'notifier'; + +const capitalise = function( txt ) { + return txt.charAt(0).toUpperCase() + txt.substr(1); +}; + +const prefix = function() { + return chalk.green(capitalise(name)+': '); +}; + +const featureCondition = function(props) { + return true; //props.features && props.features.indexOf( 'telegram' ) != -1; +}; + +module.exports = { + name: function() { + return name; + }, + prompts: function( utils ) { + return [ + { + when: featureCondition, + type: 'input', + name: 'telegram_bot_url', + default: utils.getDefault( 'telegram_bot_url' ), + message: prefix()+'The Telegram bot URL.'+utils.getHelp('telegram_bot_url'), + filter: utils.trimFilter, + validate: utils.notEmptyValidator + }, + { + when: featureCondition, + type: 'input', + name: 'telegram_api_key', + default: utils.getDefault( 'telegram_api_key' ), + message: prefix()+'The Telegram API key.'+utils.getHelp('telegram_api_key'), + filter: utils.trimFilter, + validate: utils.notEmptyValidator + }, + { + when: featureCondition, + type: 'input', + name: 'telegram_chat_id', + default: utils.getDefault( 'telegram_chat_id' ), + message: prefix()+'The Telegram chat id.'+utils.getHelp('telegram_chat_id'), + filter: utils.trimFilter, + validate: function( chat_id ) { + return utils.notEmptyValidator( chat_id ) && !isNaN( parseInt(chat_id) ) + } + } + ]; + }, + templates: function( props ) { + return [ 'notifier.env' ]; + } +}; diff --git a/cyphernodeconf_docker/prompters/999_installer.js b/cyphernodeconf_docker/prompters/999_installer.js index 8f2b20238..b112ff952 100644 --- a/cyphernodeconf_docker/prompters/999_installer.js +++ b/cyphernodeconf_docker/prompters/999_installer.js @@ -334,6 +334,44 @@ module.exports = { validate: utils.pathValidator, message: prefix()+'Where is your otsclient data?'+utils.getHelp('otsclient_datapath_custom'), }, + { + when: function(props) { return true }, + type: 'list', + name: 'notifier_datapath', + default: utils.getDefault( 'notifier_datapath' ), + choices: [ + { + name: utils.setupDir()+"/cyphernode/notifier", + value: utils.setupDir()+"/cyphernode/notifier" + }, + { + name: utils.defaultDataDirBase()+"/cyphernode/notifier", + value: utils.defaultDataDirBase()+"/cyphernode/notifier" + }, + { + name: utils.defaultDataDirBase()+"/.cyphernode/notifier", + value: utils.defaultDataDirBase()+"/.cyphernode/notifier" + }, + { + name: utils.defaultDataDirBase()+"/notifier", + value: utils.defaultDataDirBase()+"/notifier" + }, + { + name: "Custom path", + value: "_custom" + } + ], + message: prefix()+'Where do you want to store your Notifier data?'+utils.getHelp('notifier_datapath'), + }, + { + when: function(props) { return props.notifier_datapath === '_custom' }, + type: 'input', + name: 'notifier_datapath_custom', + default: utils.getDefault( 'notifier_datapath_custom' ), + filter: utils.trimFilter, + validate: utils.pathValidator, + message: prefix()+'Where is your Notifier data?'+utils.getHelp('notifier_datapath_custom'), + }, { type: 'confirm', name: 'gatekeeper_expose', diff --git a/cyphernodeconf_docker/schema/config-v0.2.5.json b/cyphernodeconf_docker/schema/config-v0.2.5.json index 96c81ae38..e75b3cb99 100644 --- a/cyphernodeconf_docker/schema/config-v0.2.5.json +++ b/cyphernodeconf_docker/schema/config-v0.2.5.json @@ -30,6 +30,7 @@ "gatekeeper_clientkeyspassword", "gatekeeper_datapath", "gatekeeper_port", + "notifier_datapath", "proxy_datapath", "logs_datapath", "traefik_datapath", @@ -146,8 +147,29 @@ "otsclient_datapath" ] } + }, + { + "if": { + "properties": { + "features": { + "contains": { + "enum": [ + "telegram" + ] + } + } + } + }, + "then": { + "required": [ + "telegram_bot_url", + "telegram_api_key", + "telegram_chat_id" + ] + } } ], + "properties": { "schema_version": { "type": "string", @@ -425,6 +447,22 @@ "/tmp/cyphernode/proxy" ] }, + "notifier_datapath": { + "$id": "#/properties/notifier_datapath", + "type": "string", + "title": "Notifier datapath", + "examples": [ + "/tmp/cyphernode/notifier" + ] + }, + "notifier_datapath_custom": { + "$id": "#/properties/notifier_datapath_custom", + "type": "string", + "title": "Notifier custom datapath", + "examples": [ + "/tmp/cyphernode/notifier" + ] + }, "otsclient_datapath": { "$id": "#/properties/otsclient_datapath", "type": "string", @@ -696,6 +734,32 @@ "00ff00", "00ffff" ] + }, + "telegram_bot_url": { + "$id": "#/properties/telegram_bot_url", + "type": "string", + "pattern": "string", + "title": "The Telegram bot URL", + "default": "https://api.telegram.org/bot", + "examples": [ + "https://api.telegram.org/bot" + ] + }, + "telegram_api_key": { + "$id": "#/properties/telegram_api_key", + "type": "string", + "title": "The Telegram bot API key", + "examples": [ + "2014591315:AAGAE9cZp6Of60ljpFC3VpSwi0yLyu5V2Go" + ] + }, + "telegram_chat_id": { + "$id": "#/properties/telegram_chat_id", + "type": "integer", + "title": "The Telegram chat id", + "examples": [ + "-658390821" + ] } } } diff --git a/cyphernodeconf_docker/templates/installer/config.sh b/cyphernodeconf_docker/templates/installer/config.sh index ba64b3049..c652c6979 100644 --- a/cyphernodeconf_docker/templates/installer/config.sh +++ b/cyphernodeconf_docker/templates/installer/config.sh @@ -21,6 +21,7 @@ TOR_TRAEFIK=<%= (torifyables && torifyables.indexOf('tor_traefik') !== -1)?'true TOR_BITCOIN=<%= (torifyables && torifyables.indexOf('tor_bitcoin') !== -1)?'true':'false' %> TOR_LIGHTNING=<%= (torifyables && torifyables.indexOf('tor_lightning') !== -1)?'true':'false' %> <% } %> +NOTIFIER_DATAPATH=<%= notifier_datapath %> DOCKER_MODE=<%= docker_mode %> RUN_AS_USER=<%= run_as_different_user?username:'' %> CLEANUP=<%= installer_cleanup?'true':'false' %> diff --git a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml index b239b3585..c4204360e 100644 --- a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml +++ b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml @@ -255,15 +255,8 @@ services: notifier: image: cyphernode/notifier:<%= notifier_version %> command: $USER ./startnotifier.sh - environment: - - "TRACING=1" - <% if ( features.indexOf('tor') !== -1 ) { %> - - "TOR_HOST=tor" - - "TOR_PORT=9050" - <% } %> - <% if ( features.indexOf('telegram') !== -1 ) { %> - - "FEATURE_TELEGRAM=true" - <% } %> + env_file: + - <%= notifier_datapath %>/notifier.env volumes: - "<%= logs_datapath %>:/cnlogs" networks: diff --git a/cyphernodeconf_docker/templates/installer/start.sh b/cyphernodeconf_docker/templates/installer/start.sh index 0ec016343..3ed208a9c 100644 --- a/cyphernodeconf_docker/templates/installer/start.sh +++ b/cyphernodeconf_docker/templates/installer/start.sh @@ -27,6 +27,7 @@ start_apps() { export TOR_DATAPATH export LIGHTNING_DATAPATH export BITCOIN_DATAPATH + export NOTIFIER_DATAPATH export LOGS_DATAPATH export APP_SCRIPT_PATH export APP_ID diff --git a/cyphernodeconf_docker/templates/installer/stop.sh b/cyphernodeconf_docker/templates/installer/stop.sh index 9ac13ab4d..4923581d6 100644 --- a/cyphernodeconf_docker/templates/installer/stop.sh +++ b/cyphernodeconf_docker/templates/installer/stop.sh @@ -31,6 +31,7 @@ stop_apps() { export TOR_DATAPATH export LIGHTNING_DATAPATH export BITCOIN_DATAPATH + export NOTIFIER_DATAPATH export APP_SCRIPT_PATH export APP_ID export DOCKER_MODE diff --git a/cyphernodeconf_docker/templates/installer/testfeatures.sh b/cyphernodeconf_docker/templates/installer/testfeatures.sh index c74f8943f..c18b2bb6a 100644 --- a/cyphernodeconf_docker/templates/installer/testfeatures.sh +++ b/cyphernodeconf_docker/templates/installer/testfeatures.sh @@ -115,9 +115,8 @@ checknotifiertelegram() { echo -en "\r\n\e[1;36mTesting Notifier Telegram... " > /dev/console local response local returncode - local body=$(echo "{\"text\":\"Hello world in Telegram at `date -u +"%FT%H%MZ"`\"}" | base64) - - response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}") + + response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramNoop\"}") returncode=$? [ "${returncode}" -ne "0" ] && return 115 http_code=$(echo "${response}" | jq -r ".http_code") diff --git a/cyphernodeconf_docker/templates/notifier/notifier.env b/cyphernodeconf_docker/templates/notifier/notifier.env new file mode 100644 index 000000000..5eb75d6b5 --- /dev/null +++ b/cyphernodeconf_docker/templates/notifier/notifier.env @@ -0,0 +1,12 @@ +TRACING=1 +<% if ( features.indexOf('tor') !== -1 ) { %> +TOR_HOST=tor +TOR_PORT=9050 +<% } %> + +<% if ( features.indexOf('telegram') !== -1 ) { %> +FEATURE_TELEGRAM=true +TELEGRAM_BOT_URL=<%= telegram_bot_url %> +TELEGRAM_API_KEY=<%= telegram_api_key %> +TELEGRAM_CHAT_ID=<%= telegram_chat_id %> +<% } %> diff --git a/dist/setup.sh b/dist/setup.sh index be542718c..252bd2ae4 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -110,7 +110,7 @@ sudo_if_required() { } modify_permissions() { - local directories=("$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$OTSCLIENT_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH") + local directories=("$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$OTSCLIENT_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH" "$NOTIFIER_DATAPATH") for d in "${directories[@]}" do if [[ -e $d ]]; then @@ -122,7 +122,7 @@ modify_permissions() { } modify_owner() { - local directories=("$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$OTSCLIENT_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH") + local directories=("$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$OTSCLIENT_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH" "$NOTIFIER_DATAPATH") local user=$(id -u $RUN_AS_USER):$(id -g $RUN_AS_USER) for d in "${directories[@]}" do @@ -462,6 +462,14 @@ install_docker() { copy_file $cyphernodeconf_filepath/installer/config.sh $PROXY_DATAPATH/config.sh 1 $SUDO_REQUIRED copy_file $cyphernodeconf_filepath/cyphernode/info.json $PROXY_DATAPATH/info.json 1 $SUDO_REQUIRED + if [ ! -d $NOTIFIER_DATAPATH ]; then + step " create $NOTIFIER_DATAPATH" + sudo_if_required mkdir -p $NOTIFIER_DATAPATH + next + fi + + copy_file $cyphernodeconf_filepath/notifier/notifier.env $NOTIFIER_DATAPATH/notifier.env 1 $SUDO_REQUIRED + if [[ $BITCOIN_INTERNAL == true ]]; then if [ ! -d $BITCOIN_DATAPATH ]; then step " create $BITCOIN_DATAPATH" @@ -652,7 +660,7 @@ install_docker() { check_directory_owner() { # if one directory does not have access rights for $RUN_AS_USER, we echo 1, else we echo 0 - local directories=("$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH") + local directories=("$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH" "$NOTIFIER_DATAPATH") local status=0 for d in "${directories[@]}" do @@ -756,7 +764,7 @@ sanity_checks_pre_install() { if [[ $sudo_reason == 'directories' ]]; then echo " or check your data volumes if they have the right owner." echo " The owner of the following folders should be '$RUN_AS_USER':" - local directories=("$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH") + local directories=("$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH" "$NOTIFIER_DATAPATH") local status=0 for d in "${directories[@]}" do diff --git a/doc/TELEGRAM.md b/doc/TELEGRAM.md new file mode 100644 index 000000000..d2fb77867 --- /dev/null +++ b/doc/TELEGRAM.md @@ -0,0 +1,34 @@ +# Telegram integration in Cyphernode. Please enjoy responsibly + +Get your Telegram API Key by chating with the @BotFather +Details here https://core.telegram.org/bots + +calling Telegram API + example : + https://api.telegram.org/bot+TELEGRAM_API_KEY/your-action + https://api.telegram.org/botTELEGRAM_API_KEY/getMe + returns: + {"ok":true,"result":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} + + Add your Bot to a group and then get updates to get the chat.ID in order to send messages to this group afterwards. + Below, the chat.id is chat.id:-TELEGRAM_CHAT_ID + + https://api.telegram.org/botTELEGRAM_API_KEY/getUpdates + + {"ok":true,"result":[{"update_id":701180871, + #"my_chat_member":{"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":false},"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"date":1635877254,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"member"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"left"}}},{"update_id":701180872, + #"message":{"message_id":7,"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877254,"left_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"left_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"}}},{"update_id":701180873, + #"my_chat_member":{"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"date":1635877290,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"left"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"member"}}},{"update_id":701180874, + #"message":{"message_id":8,"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877290,"new_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"new_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"new_chat_members":[{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"}]}}]} + +Bot says Hello World using the chat id returned previously + https://api.telegram.org/botTOKEN/sendMessage?chat_id=CHAT-ID&text=Hello+World + https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=-TELEGRAM_CHAT_ID&text=Hello+World + + returns: + {"ok":true,"result":{"message_id":9,"from":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877783,"text":"Hello World"}} + + + +curl POST example + curl -X POST https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=TELEGRAM_CHAT_ID -H 'Content-Type: application/json' -d '{"text":"text in POST data"}' diff --git a/notifier_docker/Dockerfile b/notifier_docker/Dockerfile index 92fbdd3ae..2b858a8cd 100644 --- a/notifier_docker/Dockerfile +++ b/notifier_docker/Dockerfile @@ -8,7 +8,7 @@ WORKDIR ${HOME} COPY script/* ./ -RUN chmod +x startnotifier.sh requesthandler.sh config.sh \ +RUN chmod +x startnotifier.sh requesthandler.sh \ && chmod o+w . ENTRYPOINT ["su-exec"] diff --git a/notifier_docker/script/.gitignore b/notifier_docker/script/.gitignore deleted file mode 100644 index cdd7c19c8..000000000 --- a/notifier_docker/script/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.sh diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index e4bc565ab..cfb0b26df 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -3,7 +3,6 @@ . ./trace.sh . ./web.sh . ./response.sh -. ./config.sh main() { trace "Entering main()..." @@ -38,6 +37,9 @@ main() { publish_response "${response}" "${response_topic}" ${?} ;; sendToTelegramGroup) + # example: + # local body=$(echo "{\"text\":\"Hello world in Telegram at `date -u +"%FT%H%MZ"`\"}" | base64) + # response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}") if [ "${FEATURE_TELEGRAM}" = "true" ]; then url=$(echo ${TELEGRAM_BOT_URL}${TELEGRAM_API_KEY}/sendMessage?chat_id=${TELEGRAM_CHAT_ID}) trace "[main] telegram-url=${url}" @@ -51,6 +53,20 @@ main() { trace "[main] Telegram is NOT enabled - message not sent" fi ;; + sendToTelegramNoop) + if [ "${FEATURE_TELEGRAM}" = "true" ]; then + url=$(echo ${TELEGRAM_BOT_URL}${TELEGRAM_API_KEY}/getMe) + trace "[main] telegram-url=${url}" + + msg=$(echo ${msg} | jq --arg url ${url} '. += {"url":$url}' ) + trace "[main] web-msg=${msg}" + + response=$(web "${msg}") + publish_response "${response}" "${response_topic}" ${?} + else + trace "[main] Telegram is NOT enabled - message not sent" + fi + ;; esac trace "[main] msg processed" done diff --git a/notifier_docker/script/sample-config.sh b/notifier_docker/script/sample-config.sh deleted file mode 100644 index 313feb058..000000000 --- a/notifier_docker/script/sample-config.sh +++ /dev/null @@ -1,38 +0,0 @@ -# Get your Telegram API Key by chating with the @BotFather -# Details here https://core.telegram.org/bots -# -# calling Telegram API -# example : -# https://api.telegram.org/bot+TELEGRAM_API_KEY/your-action -# https://api.telegram.org/botTELEGRAM_API_KEY/getMe -# returns: -# {"ok":true,"result":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} -# -# Add your Bot to a group and then get updates to get the chat.ID in order to send messages to this group afterwards. -# Below, the chat.id is chat.id:-TELEGRAM_CHAT_ID -# -# https://api.telegram.org/botTELEGRAM_API_KEY/getUpdates -# -# {"ok":true,"result":[{"update_id":701180871, -#"my_chat_member":{"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":false},"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"date":1635877254,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"member"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"left"}}},{"update_id":701180872, -#"message":{"message_id":7,"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877254,"left_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"left_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"}}},{"update_id":701180873, -#"my_chat_member":{"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"date":1635877290,"old_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"left"},"new_chat_member":{"user":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"status":"member"}}},{"update_id":701180874, -#"message":{"message_id":8,"from":{"id":1609436204,"is_bot":false,"first_name":"Roger","last_name":"Brulotte","username":"RogerBrulotte","language_code":"en"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877290,"new_chat_participant":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"new_chat_member":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"new_chat_members":[{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"}]}}]} -# -# Bot says Hello World using the chat id returned previously -# https://api.telegram.org/botTOKEN/sendMessage?chat_id=CHAT-ID&text=Hello+World -# https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=-TELEGRAM_CHAT_ID&text=Hello+World -# -# returns: -# {"ok":true,"result":{"message_id":9,"from":{"id":2084591315,"is_bot":true,"first_name":"Roger-logger","username":"RogerLoggerBot"},"chat":{"id":-TELEGRAM_CHAT_ID,"title":"Logging","type":"group","all_members_are_administrators":true},"date":1635877783,"text":"Hello World"}} -# -# -# -# curl POST -# curl -X POST https://api.telegram.org/botTELEGRAM_API_KEY/sendMessage?chat_id=TELEGRAM_CHAT_ID -H 'Content-Type: application/json' -d '{"text":"text in POST data"}' -# -TELEGRAM_BOT_URL=https://api.telegram.org/bot -TELEGRAM_API_KEY=TELEGRAM_API_KEY -TELEGRAM_CHAT_ID=-TELEGRAM_CHAT_ID - -# Add those keys to /script/config.sh \ No newline at end of file diff --git a/notifier_docker/script/startnotifier.sh b/notifier_docker/script/startnotifier.sh index 64bc336ee..c136bb8ab 100644 --- a/notifier_docker/script/startnotifier.sh +++ b/notifier_docker/script/startnotifier.sh @@ -1,5 +1,4 @@ #!/bin/sh - . ./trace.sh mosquitto_sub -h broker -t notifier | ./requesthandler.sh From 66b67881beb7c18ead04a622f351750623d8e680 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Sun, 21 Nov 2021 12:48:13 -0500 Subject: [PATCH 09/25] renamed prompter file notifier --- .../prompters/{050_notifier.js => 200_notifier.js} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename cyphernodeconf_docker/prompters/{050_notifier.js => 200_notifier.js} (95%) diff --git a/cyphernodeconf_docker/prompters/050_notifier.js b/cyphernodeconf_docker/prompters/200_notifier.js similarity index 95% rename from cyphernodeconf_docker/prompters/050_notifier.js rename to cyphernodeconf_docker/prompters/200_notifier.js index 383754747..2ada2a0df 100644 --- a/cyphernodeconf_docker/prompters/050_notifier.js +++ b/cyphernodeconf_docker/prompters/200_notifier.js @@ -11,7 +11,7 @@ const prefix = function() { }; const featureCondition = function(props) { - return true; //props.features && props.features.indexOf( 'telegram' ) != -1; + return props.features && props.features.indexOf( 'telegram' ) != -1; }; module.exports = { From f2d7fe5014c985167b4aa10a28d8baab26386d3f Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Sun, 21 Nov 2021 12:56:48 -0500 Subject: [PATCH 10/25] minor fix --- cyphernodeconf_docker/schema/config-v0.2.5.json | 1 - dist/setup.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cyphernodeconf_docker/schema/config-v0.2.5.json b/cyphernodeconf_docker/schema/config-v0.2.5.json index e75b3cb99..637d2dd22 100644 --- a/cyphernodeconf_docker/schema/config-v0.2.5.json +++ b/cyphernodeconf_docker/schema/config-v0.2.5.json @@ -738,7 +738,6 @@ "telegram_bot_url": { "$id": "#/properties/telegram_bot_url", "type": "string", - "pattern": "string", "title": "The Telegram bot URL", "default": "https://api.telegram.org/bot", "examples": [ diff --git a/dist/setup.sh b/dist/setup.sh index 252bd2ae4..94d136456 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -836,7 +836,7 @@ install_apps() { fi if [[ $FEATURE_TELEGRAM == true ]]; then - step " enabled Telegram - Manual configuration needed before first time use (Bot and Group creation, API key) - see notifier_docker/script/sample-env.properties" + step " enabled Telegram - Manual configuration needed before first time use (Bot and Group creation, API key) - see doc/TELEGRAM.md" else step " disabled Telegram" fi From ff55bd4e1cce139cadd4f82c71baf745d7ef0f3c Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Mon, 22 Nov 2021 09:05:33 -0500 Subject: [PATCH 11/25] added comment + modified trace --- notifier_docker/script/requesthandler.sh | 4 ++-- proxy_docker/app/tests/test-telegram.sh | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index cfb0b26df..10f23b465 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -14,9 +14,9 @@ main() { local url if [ "${FEATURE_TELEGRAM}" = "true" ]; then - trace "[notifier] FEATURE_TELEGRAM is ENABLED" + trace "[main] FEATURE_TELEGRAM is ENABLED" else - trace "[notifier] FEATURE_TELEGRAM is DISABLED" + trace "[main] FEATURE_TELEGRAM is DISABLED" fi # Messages should have this form: diff --git a/proxy_docker/app/tests/test-telegram.sh b/proxy_docker/app/tests/test-telegram.sh index 150bec030..f0bb54225 100755 --- a/proxy_docker/app/tests/test-telegram.sh +++ b/proxy_docker/app/tests/test-telegram.sh @@ -1,5 +1,7 @@ #!/bin/sh +# Tests the notify_telegram (in notify.sh) function by calling it directly - not going through the proxy, there is no endpoint. + cd .. . ./notify.sh From c4dd86b7e0b2d30d43214fec884025e006d01181 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Thu, 6 Jan 2022 15:14:32 -0500 Subject: [PATCH 12/25] fix filename conflict after merge --- .../prompters/300_notifier.js | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 cyphernodeconf_docker/prompters/300_notifier.js diff --git a/cyphernodeconf_docker/prompters/300_notifier.js b/cyphernodeconf_docker/prompters/300_notifier.js new file mode 100644 index 000000000..2ada2a0df --- /dev/null +++ b/cyphernodeconf_docker/prompters/300_notifier.js @@ -0,0 +1,57 @@ +const chalk = require('chalk'); + +const name = 'notifier'; + +const capitalise = function( txt ) { + return txt.charAt(0).toUpperCase() + txt.substr(1); +}; + +const prefix = function() { + return chalk.green(capitalise(name)+': '); +}; + +const featureCondition = function(props) { + return props.features && props.features.indexOf( 'telegram' ) != -1; +}; + +module.exports = { + name: function() { + return name; + }, + prompts: function( utils ) { + return [ + { + when: featureCondition, + type: 'input', + name: 'telegram_bot_url', + default: utils.getDefault( 'telegram_bot_url' ), + message: prefix()+'The Telegram bot URL.'+utils.getHelp('telegram_bot_url'), + filter: utils.trimFilter, + validate: utils.notEmptyValidator + }, + { + when: featureCondition, + type: 'input', + name: 'telegram_api_key', + default: utils.getDefault( 'telegram_api_key' ), + message: prefix()+'The Telegram API key.'+utils.getHelp('telegram_api_key'), + filter: utils.trimFilter, + validate: utils.notEmptyValidator + }, + { + when: featureCondition, + type: 'input', + name: 'telegram_chat_id', + default: utils.getDefault( 'telegram_chat_id' ), + message: prefix()+'The Telegram chat id.'+utils.getHelp('telegram_chat_id'), + filter: utils.trimFilter, + validate: function( chat_id ) { + return utils.notEmptyValidator( chat_id ) && !isNaN( parseInt(chat_id) ) + } + } + ]; + }, + templates: function( props ) { + return [ 'notifier.env' ]; + } +}; From b41c840329598661f57cef32e182717b96590b85 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Sat, 8 Jan 2022 14:58:08 -0500 Subject: [PATCH 13/25] Removed notifier datapath and added dist/.env --- .gitignore | 1 + cyphernodeconf_docker/help.json | 4 +- cyphernodeconf_docker/lib/app.js | 1 - .../prompters/200_notifier.js | 57 --------------- .../prompters/999_installer.js | 38 ---------- .../schema/config-v0.2.5.json | 69 +------------------ .../schema/config-v0.2.6.json | 51 +++++++++++++- .../templates/installer/config.sh | 1 - .../installer/docker/docker-compose.yaml | 2 +- .../templates/installer/start.sh | 1 - .../templates/installer/stop.sh | 1 - dist/setup.sh | 18 ++--- 12 files changed, 61 insertions(+), 183 deletions(-) delete mode 100644 cyphernodeconf_docker/prompters/200_notifier.js diff --git a/.gitignore b/.gitignore index d8a7c692f..aafeefbbc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist/** !dist/setup.sh !dist/sr.sh +!dist/.env diff --git a/cyphernodeconf_docker/help.json b/cyphernodeconf_docker/help.json index ff2bca1d6..ec52dc5f4 100644 --- a/cyphernodeconf_docker/help.json +++ b/cyphernodeconf_docker/help.json @@ -49,10 +49,8 @@ "installer_cleanup": "Do you want to remove this configurator Docker image after installation? This would free about 150MB of disk space.", "docker_mode": "Cyphernode Docker services can be run using Docker Swarm (https://docs.docker.com/engine/swarm/) or docker-compose (https://docs.docker.com/compose/overview/). Both will work, some users prefer one to another depending on deployment types, scalability, current framework, etc.", "telegram": "Would you like to enable Telegram notifications - Some manual steps need to be carried once before first use. See /notifier_docker/sample-config.sh", - "notifier_datapath": "The Notifier's files will be stored in a container's mounted directory. Please provide the local mounted path to that directory. If running on OSX, check mountable directories in Docker's File Sharing configs.", - "notifier_datapath_custom": "Provide the full path name where the Notifier's files will be saved.", "telegram_bot_url": "Provide Telegram URL to use for API calls. If you don't host a Telegram server, the default URL should work. Make sure your network rules let those outbound calls go through. There are no inbound (webhooks) calls for now", "telegram_api_key": "Provide Telegram API key. Get your Telegram API Key by chating with the @BotFather. More info can be found here: https://core.telegram.org/bots", - "telegram_chat_id": "Provide Telegram chat id (an integer). Manual step are required: Add your Bot to a Telegram group you created and then get updates to get the chat.ID in order to send messages to this group afterwards", + "telegram_chat_id": "Provide Telegram chat id (an integer). Manual steps are required: Add your Bot to a Telegram group you created and then get updates to get the chat.ID in order to send messages to this group afterwards", "__default__": "" } diff --git a/cyphernodeconf_docker/lib/app.js b/cyphernodeconf_docker/lib/app.js index 2ed8b326e..f322084df 100644 --- a/cyphernodeconf_docker/lib/app.js +++ b/cyphernodeconf_docker/lib/app.js @@ -369,7 +369,6 @@ module.exports = class App { 'bitcoin_datapath', 'lightning_datapath', 'otsclient_datapath', - 'notifier_datapath' ]; for( let pathProp of pathProps ) { diff --git a/cyphernodeconf_docker/prompters/200_notifier.js b/cyphernodeconf_docker/prompters/200_notifier.js deleted file mode 100644 index 2ada2a0df..000000000 --- a/cyphernodeconf_docker/prompters/200_notifier.js +++ /dev/null @@ -1,57 +0,0 @@ -const chalk = require('chalk'); - -const name = 'notifier'; - -const capitalise = function( txt ) { - return txt.charAt(0).toUpperCase() + txt.substr(1); -}; - -const prefix = function() { - return chalk.green(capitalise(name)+': '); -}; - -const featureCondition = function(props) { - return props.features && props.features.indexOf( 'telegram' ) != -1; -}; - -module.exports = { - name: function() { - return name; - }, - prompts: function( utils ) { - return [ - { - when: featureCondition, - type: 'input', - name: 'telegram_bot_url', - default: utils.getDefault( 'telegram_bot_url' ), - message: prefix()+'The Telegram bot URL.'+utils.getHelp('telegram_bot_url'), - filter: utils.trimFilter, - validate: utils.notEmptyValidator - }, - { - when: featureCondition, - type: 'input', - name: 'telegram_api_key', - default: utils.getDefault( 'telegram_api_key' ), - message: prefix()+'The Telegram API key.'+utils.getHelp('telegram_api_key'), - filter: utils.trimFilter, - validate: utils.notEmptyValidator - }, - { - when: featureCondition, - type: 'input', - name: 'telegram_chat_id', - default: utils.getDefault( 'telegram_chat_id' ), - message: prefix()+'The Telegram chat id.'+utils.getHelp('telegram_chat_id'), - filter: utils.trimFilter, - validate: function( chat_id ) { - return utils.notEmptyValidator( chat_id ) && !isNaN( parseInt(chat_id) ) - } - } - ]; - }, - templates: function( props ) { - return [ 'notifier.env' ]; - } -}; diff --git a/cyphernodeconf_docker/prompters/999_installer.js b/cyphernodeconf_docker/prompters/999_installer.js index e2a13a3e9..1301cff43 100644 --- a/cyphernodeconf_docker/prompters/999_installer.js +++ b/cyphernodeconf_docker/prompters/999_installer.js @@ -372,44 +372,6 @@ module.exports = { validate: utils.pathValidator, message: prefix()+'Where is your otsclient data?'+utils.getHelp('otsclient_datapath_custom'), }, - { - when: function(props) { return true }, - type: 'list', - name: 'notifier_datapath', - default: utils.getDefault( 'notifier_datapath' ), - choices: [ - { - name: utils.setupDir()+"/cyphernode/notifier", - value: utils.setupDir()+"/cyphernode/notifier" - }, - { - name: utils.defaultDataDirBase()+"/cyphernode/notifier", - value: utils.defaultDataDirBase()+"/cyphernode/notifier" - }, - { - name: utils.defaultDataDirBase()+"/.cyphernode/notifier", - value: utils.defaultDataDirBase()+"/.cyphernode/notifier" - }, - { - name: utils.defaultDataDirBase()+"/notifier", - value: utils.defaultDataDirBase()+"/notifier" - }, - { - name: "Custom path", - value: "_custom" - } - ], - message: prefix()+'Where do you want to store your Notifier data?'+utils.getHelp('notifier_datapath'), - }, - { - when: function(props) { return props.notifier_datapath === '_custom' }, - type: 'input', - name: 'notifier_datapath_custom', - default: utils.getDefault( 'notifier_datapath_custom' ), - filter: utils.trimFilter, - validate: utils.pathValidator, - message: prefix()+'Where is your Notifier data?'+utils.getHelp('notifier_datapath_custom'), - }, { type: 'confirm', name: 'gatekeeper_expose', diff --git a/cyphernodeconf_docker/schema/config-v0.2.5.json b/cyphernodeconf_docker/schema/config-v0.2.5.json index 637d2dd22..4810ac5e4 100644 --- a/cyphernodeconf_docker/schema/config-v0.2.5.json +++ b/cyphernodeconf_docker/schema/config-v0.2.5.json @@ -30,7 +30,6 @@ "gatekeeper_clientkeyspassword", "gatekeeper_datapath", "gatekeeper_port", - "notifier_datapath", "proxy_datapath", "logs_datapath", "traefik_datapath", @@ -147,29 +146,8 @@ "otsclient_datapath" ] } - }, - { - "if": { - "properties": { - "features": { - "contains": { - "enum": [ - "telegram" - ] - } - } - } - }, - "then": { - "required": [ - "telegram_bot_url", - "telegram_api_key", - "telegram_chat_id" - ] - } } ], - "properties": { "schema_version": { "type": "string", @@ -209,8 +187,7 @@ "lightning", "otsclient", "batcher", - "specter", - "telegram" + "specter" ], "title": "The feature", "default": "", @@ -219,8 +196,7 @@ "lightning", "otsclient", "batcher", - "specter", - "telegram" + "specter" ] } }, @@ -447,22 +423,6 @@ "/tmp/cyphernode/proxy" ] }, - "notifier_datapath": { - "$id": "#/properties/notifier_datapath", - "type": "string", - "title": "Notifier datapath", - "examples": [ - "/tmp/cyphernode/notifier" - ] - }, - "notifier_datapath_custom": { - "$id": "#/properties/notifier_datapath_custom", - "type": "string", - "title": "Notifier custom datapath", - "examples": [ - "/tmp/cyphernode/notifier" - ] - }, "otsclient_datapath": { "$id": "#/properties/otsclient_datapath", "type": "string", @@ -734,31 +694,6 @@ "00ff00", "00ffff" ] - }, - "telegram_bot_url": { - "$id": "#/properties/telegram_bot_url", - "type": "string", - "title": "The Telegram bot URL", - "default": "https://api.telegram.org/bot", - "examples": [ - "https://api.telegram.org/bot" - ] - }, - "telegram_api_key": { - "$id": "#/properties/telegram_api_key", - "type": "string", - "title": "The Telegram bot API key", - "examples": [ - "2014591315:AAGAE9cZp6Of60ljpFC3VpSwi0yLyu5V2Go" - ] - }, - "telegram_chat_id": { - "$id": "#/properties/telegram_chat_id", - "type": "integer", - "title": "The Telegram chat id", - "examples": [ - "-658390821" - ] } } } diff --git a/cyphernodeconf_docker/schema/config-v0.2.6.json b/cyphernodeconf_docker/schema/config-v0.2.6.json index 3fdb34cc0..88fe5f8e3 100644 --- a/cyphernodeconf_docker/schema/config-v0.2.6.json +++ b/cyphernodeconf_docker/schema/config-v0.2.6.json @@ -148,6 +148,26 @@ "otsclient_datapath" ] } + }, + { + "if": { + "properties": { + "features": { + "contains": { + "enum": [ + "telegram" + ] + } + } + } + }, + "then": { + "required": [ + "telegram_bot_url", + "telegram_api_key", + "telegram_chat_id" + ] + } } ], "properties": { @@ -189,7 +209,8 @@ "lightning", "otsclient", "batcher", - "specter" + "specter", + "telegram" ], "title": "The feature", "default": "", @@ -198,7 +219,8 @@ "lightning", "otsclient", "batcher", - "specter" + "specter", + "telegram" ] } }, @@ -721,6 +743,31 @@ "00ff00", "00ffff" ] + }, + "telegram_bot_url": { + "$id": "#/properties/telegram_bot_url", + "type": "string", + "title": "The Telegram bot URL", + "default": "https://api.telegram.org/bot", + "examples": [ + "https://api.telegram.org/bot" + ] + }, + "telegram_api_key": { + "$id": "#/properties/telegram_api_key", + "type": "string", + "title": "The Telegram bot API key", + "examples": [ + "2014591315:AAGAE9cZp6Of60ljpFC3VpSwi0yLyu5V2Go" + ] + }, + "telegram_chat_id": { + "$id": "#/properties/telegram_chat_id", + "type": "integer", + "title": "The Telegram chat id", + "examples": [ + "-658390821" + ] } } } diff --git a/cyphernodeconf_docker/templates/installer/config.sh b/cyphernodeconf_docker/templates/installer/config.sh index c9cdf33de..5325b005e 100644 --- a/cyphernodeconf_docker/templates/installer/config.sh +++ b/cyphernodeconf_docker/templates/installer/config.sh @@ -22,7 +22,6 @@ TOR_TRAEFIK=<%= (torifyables && torifyables.indexOf('tor_traefik') !== -1)?'true TOR_BITCOIN=<%= (torifyables && torifyables.indexOf('tor_bitcoin') !== -1)?'true':'false' %> TOR_LIGHTNING=<%= (torifyables && torifyables.indexOf('tor_lightning') !== -1)?'true':'false' %> <% } %> -NOTIFIER_DATAPATH=<%= notifier_datapath %> DOCKER_MODE=<%= docker_mode %> RUN_AS_USER=<%= run_as_different_user?username:'' %> CLEANUP=<%= installer_cleanup?'true':'false' %> diff --git a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml index 303f4675c..e85899b4c 100644 --- a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml +++ b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml @@ -305,7 +305,7 @@ services: image: cyphernode/notifier:<%= notifier_version %> command: $USER ./startnotifier.sh env_file: - - <%= notifier_datapath %>/notifier.env + - ./.env/notifier.env volumes: - "<%= logs_datapath %>:/cnlogs" networks: diff --git a/cyphernodeconf_docker/templates/installer/start.sh b/cyphernodeconf_docker/templates/installer/start.sh index c082e0bb3..647cab43f 100644 --- a/cyphernodeconf_docker/templates/installer/start.sh +++ b/cyphernodeconf_docker/templates/installer/start.sh @@ -27,7 +27,6 @@ start_apps() { export TOR_DATAPATH export LIGHTNING_DATAPATH export BITCOIN_DATAPATH - export NOTIFIER_DATAPATH export LOGS_DATAPATH export APP_SCRIPT_PATH export APP_ID diff --git a/cyphernodeconf_docker/templates/installer/stop.sh b/cyphernodeconf_docker/templates/installer/stop.sh index 860d25f96..6096e5760 100644 --- a/cyphernodeconf_docker/templates/installer/stop.sh +++ b/cyphernodeconf_docker/templates/installer/stop.sh @@ -31,7 +31,6 @@ stop_apps() { export TOR_DATAPATH export LIGHTNING_DATAPATH export BITCOIN_DATAPATH - export NOTIFIER_DATAPATH export APP_SCRIPT_PATH export APP_ID export DOCKER_MODE diff --git a/dist/setup.sh b/dist/setup.sh index df8812510..e4312f419 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -127,7 +127,7 @@ sudo_if_required() { } modify_permissions() { - local directories=("$current_path/apps" "$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$OTSCLIENT_DATAPATH" "$POSTGRES_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH" "$NOTIFIER_DATAPATH") + local directories=("$current_path/apps" "$current_path/.env" "$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$OTSCLIENT_DATAPATH" "$POSTGRES_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH") for d in "${directories[@]}" do if [[ -e $d ]]; then @@ -139,7 +139,7 @@ modify_permissions() { } modify_owner() { - local directories=("$current_path/apps" "$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$OTSCLIENT_DATAPATH" "$POSTGRES_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH" "$NOTIFIER_DATAPATH") + local directories=("$current_path/apps" "$current_path/.env" "$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$OTSCLIENT_DATAPATH" "$POSTGRES_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH") local user=$(id -u $RUN_AS_USER):$(id -g $RUN_AS_USER) for d in "${directories[@]}" do @@ -479,13 +479,7 @@ install_docker() { copy_file $cyphernodeconf_filepath/postgres/pgpass $PROXY_DATAPATH/pgpass 1 $SUDO_REQUIRED sudo_if_required chmod 0600 $PROXY_DATAPATH/pgpass - if [ ! -d $NOTIFIER_DATAPATH ]; then - step " create $NOTIFIER_DATAPATH" - sudo_if_required mkdir -p $NOTIFIER_DATAPATH - next - fi - - copy_file $cyphernodeconf_filepath/notifier/notifier.env $NOTIFIER_DATAPATH/notifier.env 1 $SUDO_REQUIRED + copy_file $cyphernodeconf_filepath/notifier/notifier.env $current_path/.env/notifier.env 1 $SUDO_REQUIRED if [[ $BITCOIN_INTERNAL == true ]]; then if [ ! -d $BITCOIN_DATAPATH ]; then @@ -677,7 +671,7 @@ install_docker() { check_directory_owner() { # if one directory does not have access rights for $RUN_AS_USER, we echo 1, else we echo 0 - local directories=("$current_path/apps" "$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$POSTGRES_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH" "$NOTIFIER_DATAPATH") + local directories=("$current_path/apps" "$current_path/.env" "$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$POSTGRES_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH") local status=0 for d in "${directories[@]}" do @@ -781,7 +775,7 @@ sanity_checks_pre_install() { if [[ $sudo_reason == 'directories' ]]; then echo " or check your data volumes if they have the right owner." echo " The owner of the following folders should be '$RUN_AS_USER':" - local directories=("$current_path/apps" "$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$POSTGRES_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH" "$NOTIFIER_DATAPATH") + local directories=("$current_path/apps" "$current_path/.env" "$BITCOIN_DATAPATH" "$LIGHTNING_DATAPATH" "$PROXY_DATAPATH" "$GATEKEEPER_DATAPATH" "$POSTGRES_DATAPATH" "$LOGS_DATAPATH" "$TRAEFIK_DATAPATH" "$TOR_DATAPATH") local status=0 for d in "${directories[@]}" do @@ -853,8 +847,10 @@ install_apps() { if [[ $FEATURE_TELEGRAM == true ]]; then step " enabled Telegram - Manual configuration needed before first time use (Bot and Group creation, API key) - see doc/TELEGRAM.md" + next else step " disabled Telegram" + next fi } From 29a75515284c0b166a5f921b104e407aad6a5ec5 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Sat, 8 Jan 2022 15:00:53 -0500 Subject: [PATCH 14/25] extra-comma removed --- cyphernodeconf_docker/lib/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cyphernodeconf_docker/lib/app.js b/cyphernodeconf_docker/lib/app.js index f322084df..a2840ec42 100644 --- a/cyphernodeconf_docker/lib/app.js +++ b/cyphernodeconf_docker/lib/app.js @@ -368,7 +368,7 @@ module.exports = class App { 'proxy_datapath', 'bitcoin_datapath', 'lightning_datapath', - 'otsclient_datapath', + 'otsclient_datapath' ]; for( let pathProp of pathProps ) { From 201b4984540be83d9d6a00bed066926ee0514343 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Fri, 15 Apr 2022 15:02:33 -0400 Subject: [PATCH 15/25] Added TG config script --- cyphernodeconf_docker/help.json | 3 - cyphernodeconf_docker/lib/app.js | 7 +- .../prompters/300_notifier.js | 32 +--- .../prompters/999_installer.js | 4 +- .../schema/config-v0.2.6.json | 45 ------ .../installer/docker/docker-compose.yaml | 5 +- .../templates/installer/run-tgsetup.sh | 9 ++ .../templates/installer/testfeatures.sh | 3 +- .../templates/installer/tgsetup.sh | 151 ++++++++++++++++++ .../templates/notifier/notifier.env | 4 +- dist/setup.sh | 14 ++ notifier_docker/Dockerfile | 2 +- notifier_docker/script/requesthandler.sh | 24 ++- notifier_docker/script/sql.sh | 32 ++++ notifier_docker/script/startnotifier.sh | 6 + 15 files changed, 244 insertions(+), 97 deletions(-) create mode 100644 cyphernodeconf_docker/templates/installer/run-tgsetup.sh create mode 100755 cyphernodeconf_docker/templates/installer/tgsetup.sh create mode 100644 notifier_docker/script/sql.sh diff --git a/cyphernodeconf_docker/help.json b/cyphernodeconf_docker/help.json index ec52dc5f4..9898f3a9e 100644 --- a/cyphernodeconf_docker/help.json +++ b/cyphernodeconf_docker/help.json @@ -49,8 +49,5 @@ "installer_cleanup": "Do you want to remove this configurator Docker image after installation? This would free about 150MB of disk space.", "docker_mode": "Cyphernode Docker services can be run using Docker Swarm (https://docs.docker.com/engine/swarm/) or docker-compose (https://docs.docker.com/compose/overview/). Both will work, some users prefer one to another depending on deployment types, scalability, current framework, etc.", "telegram": "Would you like to enable Telegram notifications - Some manual steps need to be carried once before first use. See /notifier_docker/sample-config.sh", - "telegram_bot_url": "Provide Telegram URL to use for API calls. If you don't host a Telegram server, the default URL should work. Make sure your network rules let those outbound calls go through. There are no inbound (webhooks) calls for now", - "telegram_api_key": "Provide Telegram API key. Get your Telegram API Key by chating with the @BotFather. More info can be found here: https://core.telegram.org/bots", - "telegram_chat_id": "Provide Telegram chat id (an integer). Manual steps are required: Add your Bot to a Telegram group you created and then get updates to get the chat.ID in order to send messages to this group afterwards", "__default__": "" } diff --git a/cyphernodeconf_docker/lib/app.js b/cyphernodeconf_docker/lib/app.js index a2840ec42..cbc85da4a 100644 --- a/cyphernodeconf_docker/lib/app.js +++ b/cyphernodeconf_docker/lib/app.js @@ -564,12 +564,7 @@ module.exports = class App { }, telegram: { networks: ['cyphernodenet'], - docker: "cypernode/notifier", - extra: { - bot_url: this.config.data.telegram_bot_url, - api_key: this.config.data.telegram_api_key, - chat_id: this.config.data.telegram_chat_id - } + docker: "cypernode/notifier" } } diff --git a/cyphernodeconf_docker/prompters/300_notifier.js b/cyphernodeconf_docker/prompters/300_notifier.js index 2ada2a0df..d1176a210 100644 --- a/cyphernodeconf_docker/prompters/300_notifier.js +++ b/cyphernodeconf_docker/prompters/300_notifier.js @@ -19,37 +19,7 @@ module.exports = { return name; }, prompts: function( utils ) { - return [ - { - when: featureCondition, - type: 'input', - name: 'telegram_bot_url', - default: utils.getDefault( 'telegram_bot_url' ), - message: prefix()+'The Telegram bot URL.'+utils.getHelp('telegram_bot_url'), - filter: utils.trimFilter, - validate: utils.notEmptyValidator - }, - { - when: featureCondition, - type: 'input', - name: 'telegram_api_key', - default: utils.getDefault( 'telegram_api_key' ), - message: prefix()+'The Telegram API key.'+utils.getHelp('telegram_api_key'), - filter: utils.trimFilter, - validate: utils.notEmptyValidator - }, - { - when: featureCondition, - type: 'input', - name: 'telegram_chat_id', - default: utils.getDefault( 'telegram_chat_id' ), - message: prefix()+'The Telegram chat id.'+utils.getHelp('telegram_chat_id'), - filter: utils.trimFilter, - validate: function( chat_id ) { - return utils.notEmptyValidator( chat_id ) && !isNaN( parseInt(chat_id) ) - } - } - ]; + return []; }, templates: function( props ) { return [ 'notifier.env' ]; diff --git a/cyphernodeconf_docker/prompters/999_installer.js b/cyphernodeconf_docker/prompters/999_installer.js index 1301cff43..10083eec6 100644 --- a/cyphernodeconf_docker/prompters/999_installer.js +++ b/cyphernodeconf_docker/prompters/999_installer.js @@ -416,8 +416,8 @@ module.exports = { }, templates: function( props ) { if( props.installer_mode === 'docker' ) { - return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh', path.join('docker', 'docker-compose.yaml')]; + return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh', 'tgsetup.sh', 'run-tgsetup.sh', path.join('docker', 'docker-compose.yaml')]; } - return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh']; + return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh', 'tgsetup.sh', 'run-tgsetup.sh']; } }; diff --git a/cyphernodeconf_docker/schema/config-v0.2.6.json b/cyphernodeconf_docker/schema/config-v0.2.6.json index 88fe5f8e3..828e13c8a 100644 --- a/cyphernodeconf_docker/schema/config-v0.2.6.json +++ b/cyphernodeconf_docker/schema/config-v0.2.6.json @@ -148,26 +148,6 @@ "otsclient_datapath" ] } - }, - { - "if": { - "properties": { - "features": { - "contains": { - "enum": [ - "telegram" - ] - } - } - } - }, - "then": { - "required": [ - "telegram_bot_url", - "telegram_api_key", - "telegram_chat_id" - ] - } } ], "properties": { @@ -743,31 +723,6 @@ "00ff00", "00ffff" ] - }, - "telegram_bot_url": { - "$id": "#/properties/telegram_bot_url", - "type": "string", - "title": "The Telegram bot URL", - "default": "https://api.telegram.org/bot", - "examples": [ - "https://api.telegram.org/bot" - ] - }, - "telegram_api_key": { - "$id": "#/properties/telegram_api_key", - "type": "string", - "title": "The Telegram bot API key", - "examples": [ - "2014591315:AAGAE9cZp6Of60ljpFC3VpSwi0yLyu5V2Go" - ] - }, - "telegram_chat_id": { - "$id": "#/properties/telegram_chat_id", - "type": "integer", - "title": "The Telegram chat id", - "examples": [ - "-658390821" - ] } } } diff --git a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml index dad4561d6..2e4404930 100644 --- a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml +++ b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml @@ -304,14 +304,17 @@ services: image: cyphernode/notifier:<%= notifier_version %> command: $USER ./startnotifier.sh env_file: - - ./.env/notifier.env + - .env/notifier.env volumes: - "<%= logs_datapath %>:/cnlogs" + - "<%= proxy_datapath %>:/proxy/db" + - container_monitor:/container_monitor networks: - cyphernodenet - cyphernodeappsnet depends_on: - broker + - postgres <% if ( docker_mode === 'swarm' ) { %> deploy: replicas: 1 diff --git a/cyphernodeconf_docker/templates/installer/run-tgsetup.sh b/cyphernodeconf_docker/templates/installer/run-tgsetup.sh new file mode 100644 index 000000000..30f0e5596 --- /dev/null +++ b/cyphernodeconf_docker/templates/installer/run-tgsetup.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +current_path="$(cd "$(dirname "$0")" >/dev/null && pwd)" + +docker run --rm -it -v $current_path/tgsetup.sh:/tgsetup.sh \ +-v $current_path:/dist \ +-e PGPASSFILE=/dist/cyphernode/proxy/pgpass \ +--network cyphernodenet eclipse-mosquitto:<%= mosquitto_version %> /tgsetup.sh + diff --git a/cyphernodeconf_docker/templates/installer/testfeatures.sh b/cyphernodeconf_docker/templates/installer/testfeatures.sh index 6303c2f25..d48b1db71 100644 --- a/cyphernodeconf_docker/templates/installer/testfeatures.sh +++ b/cyphernodeconf_docker/templates/installer/testfeatures.sh @@ -131,6 +131,7 @@ checknotifiertelegram() { [ "${returncode}" -ne "0" ] && return 115 http_code=$(echo "${response}" | jq -r ".http_code") [ "${http_code}" -ge "400" ] && return 118 + [ "${http_code}" -eq "0" ] && return 119 echo -e "\e[1;36mNotifier Telegram rocks!" > /dev/console @@ -322,7 +323,7 @@ if [ "${returncode}" -ne "0" ]; then workingproxy="false" fi else - echo -e "\e[1;36mCyphernode seems to be correctly deployed. Let's run more thourough tests..." > /dev/console + echo -e "\e[1;36mCyphernode seems to be correctly deployed. Let's run more thorough tests..." > /dev/console fi # Let's now check each feature fonctionality... diff --git a/cyphernodeconf_docker/templates/installer/tgsetup.sh b/cyphernodeconf_docker/templates/installer/tgsetup.sh new file mode 100755 index 000000000..b1efe26da --- /dev/null +++ b/cyphernodeconf_docker/templates/installer/tgsetup.sh @@ -0,0 +1,151 @@ +#!/bin/sh + +# Cyphernode Telegram configuration +# +# +echo "Telegram setup. Installing components..." +apk add --update --no-cache curl jq postgresql > /dev/null + +sql() { + local select_id=${2} + local response + local inserted_id + + echo "[sql] psql -qAtX -h postgres -U cyphernode -c \"${1}\"" + response=$(psql -qAtX -h postgres -U cyphernode -c "${1}") + returncode=$? + echo ${returncode} + + if [ -n "${select_id}" ]; then + if [ "${returncode}" -eq "0" ]; then + inserted_id=$(echo "${response}" | cut -d ' ' -f1) + else + echo "[sql] psql -qAtX -h postgres -U cyphernode -c \"${select_id}\"" + inserted_id=$(psql -qAtX -h postgres -U cyphernode -c "${select_id}") + returncode=$? + echo ${returncode} + fi + echo -n "${inserted_id}" + else + echo -n "${response}" + fi + + return ${returncode} +} + +# Ping the database an make sure it's UP +echo "Testing database before starting the configuration" + +ping -c 1 postgres 2>&1 > /dev/null +rc=$? + +if [ $rc != 0 ]; then + echo "Database is not up. Make sure Cyphernode is running before setting up Telegram" + exit +else + echo "Database is alive" +fi + +while true; do + read -p "Do you wish to configure Telegram for Cyphernode? [yn] " -n 1 -r + + case $REPLY in + [Yy]* ) break;; + [Nn]* ) echo ""; echo "Got it! You can always come back later"; exit;; + * ) echo "Please answer yes or no.";; + esac +done + +# Set the base Telegram URL in DB +echo "Adding the Telegram base URL in database config table cyphernode_props" + +TG_BASE_URL="https://api.telegram.org/bot" +sql "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_base_url', '$TG_BASE_URL') \ + ON CONFLICT (category, property) DO NOTHING" + +echo "" +echo "Please go into your Telegram App and start chatting with the @BotFather" +echo "" +echo "==> (Step 1) Enter @Botfather in the search tab and choose this bot" +echo "==> Note, official Telegram bots have a blue checkmark beside their name" +echo "==> (Step 2) Click “Start” to activate BotFather bot. In response, you receive a list of commands to manage bots" +echo "==> (Step 3) Choose or type the /newbot command and send it" +echo "==> @BotFather replies: Alright, a new bot. How are we going to call it? Please choose a name for your bot" +echo "==> (Step 4) Choose a name for your bot. And choose a username for your bot — the bot can be found by its username in searches. The username must be unique and end with the word 'bot'" +echo "==> After you choose a suitable name for your bot — the bot is created. You will receive a message with a link to your bot t.me/" +echo "==> Cyphernode needs the generated token to access the API: Copy the line below following the message 'Use this token to access the HTTP API' " + +while true; do + # 46 characters 1234567890:ABCrWd1mHlWzGM-2ovbxRnOF_g3V2-csY4E + # matching '^[0-9]{10}:.{35}$' + read -p "Enter the token here: " -n 46 -r + + if [[ $REPLY =~ ^[0-9]{10}:.{35}$ ]]; then + # Token is good - continue + break + else + echo "" + echo "Oooops, it doesn't seem to be a valid token." + echo "The token should be a string with this format 1234567890:ABCrWd1mHlWzGM-2ovbxRnOF_g3V2-csY4E." + echo "Please enter the token again - 10 digits:35 characters" + fi +done + +# Now let's ping Telegram while we ask the user to type a message in Telegram + +echo "Telegram Setup will now try to obtain the chat ID from the Telgram server." +echo "To make this happen, please go into the Telegram App and send a message to the new bot" +echo "Click on the link in the @BotFather's answer : Congratulations on your new bot. You will find it at t.me/your-new-bot." + +# +# The server will return something like below after the user sends a message +# '{"ok":true,"result":[{"update_id":846048856, +# "message":{"message_id":1,"from":{"id":6666666666,"is_bot":false,"first_name":"Phil","last_name":"","username":"phil","language_code":"en"},"chat":{"id":6666666666,"first_name":"Phil","last_name":"","username":"phil","type":"private"},"date":1649860823,"text":"/start","entities":[{"offset":0,"length":6,"type":"bot_command"}]}},{"update_id":666048857, +# "message":{"message_id":2,"from":{"id":6666666666,"is_bot":false,"first_name":"Phil","last_name":"","username":"phil","language_code":"en"},"chat":{"id":6666666666,"first_name":"Phil","last_name":"","username":"phil","type":"private"},"date":1649860826,"text":"hello"}}]}' +# + +while true; do + echo "Trying to contact Telegram server..." + httpStatusCode=$(curl -o /dev/null -s -w '%{http_code}' $TG_BASE_URL$REPLY/getUpdates) + + if [[ $httpStatusCode == 200 ]]; then + TG_API_KEY=$REPLY + sql "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_api_key', '$TG_API_KEY') \ + ON CONFLICT (category, property) DO UPDATE SET value='$TG_API_KEY'" + + loop=1 + while [ $loop -le 10 ]; do + response=$(curl -s $TG_BASE_URL$TG_API_KEY/getUpdates) + isOk=$(echo $response | jq '.ok') + if [ "$isOk" = "true" ]; then + # get the chat id from the last message + TG_CHAT_ID=$(echo $response | jq '.result[-1].message.chat.id') + + if [[ -z $TG_CHAT_ID || "$TG_CHAT_ID" == "null" ]]; then + echo "[$loop] Received positive answer from Telegram without a chat id - Waiting for YOU to send a message in the chat..." + sleep 10 + loop=$(( $loop + 1 )) + else + # Save the TG_CHAT_ID + today=`date -u` + sql "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_chat_id', '$TG_CHAT_ID') \ + ON CONFLICT (category, property) DO UPDATE SET value=$TG_CHAT_ID" + + echo "Sending message to Telegram [$today]" + echo "curl -X POST $TG_BASE_URL$TG_API_KEY/sendMessage?chat_id=$TG_CHAT_ID" + + curl -X POST "$TG_BASE_URL$TG_API_KEY/sendMessage?chat_id=$TG_CHAT_ID" -H "Content-Type: application/json" -d "{\"text\":\"Hello from Cyphernode [$today] - setup is complete\"}" + + echo "" + echo "Ok. Done." + exit + fi + else + echo "Server returned an error [$response] - exiting"; exit + fi + done + echo "No message found. Please go into the Telegram App and send a message to the new bot - exiting"; exit + else + echo "Server returned a HTTP error code [$httpStatusCode] - exiting"; break + fi +done diff --git a/cyphernodeconf_docker/templates/notifier/notifier.env b/cyphernodeconf_docker/templates/notifier/notifier.env index 5eb75d6b5..1101aa4a7 100644 --- a/cyphernodeconf_docker/templates/notifier/notifier.env +++ b/cyphernodeconf_docker/templates/notifier/notifier.env @@ -6,7 +6,5 @@ TOR_PORT=9050 <% if ( features.indexOf('telegram') !== -1 ) { %> FEATURE_TELEGRAM=true -TELEGRAM_BOT_URL=<%= telegram_bot_url %> -TELEGRAM_API_KEY=<%= telegram_api_key %> -TELEGRAM_CHAT_ID=<%= telegram_chat_id %> <% } %> +PGPASSFILE=/proxy/db/pgpass diff --git a/dist/setup.sh b/dist/setup.sh index 6f91f6cb0..6d0e5d849 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -650,6 +650,8 @@ install_docker() { copy_file $cyphernodeconf_filepath/installer/start.sh $current_path/start.sh 0 copy_file $cyphernodeconf_filepath/installer/stop.sh $current_path/stop.sh 0 copy_file $cyphernodeconf_filepath/installer/testdeployment.sh $current_path/testdeployment.sh 0 + copy_file $cyphernodeconf_filepath/installer/tgsetup.sh $current_path/tgsetup.sh 0 + copy_file $cyphernodeconf_filepath/installer/run-tgsetup.sh $current_path/run-tgsetup.sh 0 if [[ ! -x $current_path/start.sh ]]; then step " make start.sh executable" @@ -674,6 +676,18 @@ install_docker() { try chmod +x $current_path/testdeployment.sh next fi + + if [[ ! -x $current_path/tgsetup.sh ]]; then + step " make tgsetup.sh executable" + try chmod +x $current_path/tgsetup.sh + next + fi + + if [[ ! -x $current_path/run-tgsetup.sh ]]; then + step " make run-tgsetup.sh executable" + try chmod +x $current_path/run-tgsetup.sh + next + fi } check_directory_owner() { diff --git a/notifier_docker/Dockerfile b/notifier_docker/Dockerfile index 2b858a8cd..76cb08b2a 100644 --- a/notifier_docker/Dockerfile +++ b/notifier_docker/Dockerfile @@ -2,7 +2,7 @@ FROM eclipse-mosquitto:1.6-openssl ENV HOME /notifier -RUN apk --no-cache --update add jq curl su-exec +RUN apk --no-cache --update add jq curl su-exec postgresql WORKDIR ${HOME} diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index c005fc447..ef68890d2 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -3,6 +3,7 @@ . ./trace.sh . ./web.sh . ./response.sh +. ./sql.sh main() { trace "Entering main()..." @@ -14,9 +15,24 @@ main() { local url if [ "${FEATURE_TELEGRAM}" = "true" ]; then - trace "[main] FEATURE_TELEGRAM is ENABLED" + trace "[main] FEATURE_TELEGRAM is ENABLED" + + trace "[main] Looking up TG_BOT_URL in database" + TG_BOT_URL=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_base_url'") + returncode=$? + trace_rc ${returncode} + + trace "[main] Looking up TG_API_KEY in database" + TG_API_KEY=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_api_key'") + returncode=$? + trace_rc ${returncode} + + trace "[main] Looking up TG_CHAT_ID in database" + TG_CHAT_ID=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_chat_id'") + returncode=$? + trace_rc ${returncode} else - trace "[main] FEATURE_TELEGRAM is DISABLED" + trace "[main] FEATURE_TELEGRAM is DISABLED" fi # Messages should have this form: @@ -41,7 +57,7 @@ main() { # local body=$(echo "{\"text\":\"Hello world in Telegram at `date -u +"%FT%H%MZ"`\"}" | base64) # response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}") if [ "${FEATURE_TELEGRAM}" = "true" ]; then - url=$(echo ${TELEGRAM_BOT_URL}${TELEGRAM_API_KEY}/sendMessage?chat_id=${TELEGRAM_CHAT_ID}) + url=$(echo ${TG_BOT_URL}${TG_API_KEY}/sendMessage?chat_id=${TG_CHAT_ID}) trace "[main] telegram-url=${url}" msg=$(echo ${msg} | jq --arg url ${url} '. += {"url":$url}' ) @@ -55,7 +71,7 @@ main() { ;; sendToTelegramNoop) if [ "${FEATURE_TELEGRAM}" = "true" ]; then - url=$(echo ${TELEGRAM_BOT_URL}${TELEGRAM_API_KEY}/getMe) + url=$(echo ${TG_BOT_URL}${TG_API_KEY}/getMe) trace "[main] telegram-url=${url}" msg=$(echo ${msg} | jq --arg url ${url} '. += {"url":$url}' ) diff --git a/notifier_docker/script/sql.sh b/notifier_docker/script/sql.sh new file mode 100644 index 000000000..3e2c3efdc --- /dev/null +++ b/notifier_docker/script/sql.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +. ./trace.sh + +sql() { + trace "Entering sql()..." + + local select_id=${2} + local response + local inserted_id + + trace "[sql] psql -qAtX -h postgres -U cyphernode -c \"${1}\"" + response=$(psql -qAtX -h postgres -U cyphernode -c "${1}") + returncode=$? + trace_rc ${returncode} + + if [ -n "${select_id}" ]; then + if [ "${returncode}" -eq "0" ]; then + inserted_id=$(echo "${response}" | cut -d ' ' -f1) + else + trace "[sql] psql -qAtX -h postgres -U cyphernode -c \"${select_id}\"" + inserted_id=$(psql -qAtX -h postgres -U cyphernode -c "${select_id}") + returncode=$? + trace_rc ${returncode} + fi + echo -n "${inserted_id}" + else + echo -n "${response}" + fi + + return ${returncode} +} diff --git a/notifier_docker/script/startnotifier.sh b/notifier_docker/script/startnotifier.sh index 842070004..4781261a4 100644 --- a/notifier_docker/script/startnotifier.sh +++ b/notifier_docker/script/startnotifier.sh @@ -3,4 +3,10 @@ trace "Starting mosquitto and subscribing to the notifier topic..." +if [ "${FEATURE_TELEGRAM}" = "true" ]; then + trace "[startnotifier] Waiting for PostgreSQL to be ready..." + while [ ! -f "/container_monitor/postgres_ready" ]; do trace "[startnotifier] PostgreSQL not ready" ; sleep 10 ; done + trace "[startnotifier] PostgreSQL ready!" +fi + exec sh -c 'mosquitto_sub -h broker -t notifier | ./requesthandler.sh' From 62d6cf3858175363db978f3853f5dcd6cff04048 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Tue, 3 May 2022 09:10:00 -0400 Subject: [PATCH 16/25] Reload configs at the end of TG setup via MQTT --- .../templates/installer/tgsetup.sh | 11 ++-- notifier_docker/script/requesthandler.sh | 62 +++++++++++++------ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/cyphernodeconf_docker/templates/installer/tgsetup.sh b/cyphernodeconf_docker/templates/installer/tgsetup.sh index b1efe26da..986e1d245 100755 --- a/cyphernodeconf_docker/templates/installer/tgsetup.sh +++ b/cyphernodeconf_docker/templates/installer/tgsetup.sh @@ -131,12 +131,15 @@ while true; do sql "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_chat_id', '$TG_CHAT_ID') \ ON CONFLICT (category, property) DO UPDATE SET value=$TG_CHAT_ID" - echo "Sending message to Telegram [$today]" - echo "curl -X POST $TG_BASE_URL$TG_API_KEY/sendMessage?chat_id=$TG_CHAT_ID" - - curl -X POST "$TG_BASE_URL$TG_API_KEY/sendMessage?chat_id=$TG_CHAT_ID" -H "Content-Type: application/json" -d "{\"text\":\"Hello from Cyphernode [$today] - setup is complete\"}" + echo "" + echo "Reloading notifier configs" + response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"reloadConfig\",\"tor\":false}") echo "" + echo "Sending message to Telegram [$today]" + body=$(echo "{\"text\":\"Hello from Cyphernode 2[$today] - setup is complete\"}" | base64 | tr -d '\n') + response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}") + echo "Ok. Done." exit fi diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index ef68890d2..525b53707 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -14,26 +14,11 @@ main() { local response_topic local url - if [ "${FEATURE_TELEGRAM}" = "true" ]; then - trace "[main] FEATURE_TELEGRAM is ENABLED" - - trace "[main] Looking up TG_BOT_URL in database" - TG_BOT_URL=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_base_url'") - returncode=$? - trace_rc ${returncode} - - trace "[main] Looking up TG_API_KEY in database" - TG_API_KEY=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_api_key'") - returncode=$? - trace_rc ${returncode} + TG_BOT_URL="" + TG_API_KEY="" + TG_CHAT_ID="" - trace "[main] Looking up TG_CHAT_ID in database" - TG_CHAT_ID=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_chat_id'") - returncode=$? - trace_rc ${returncode} - else - trace "[main] FEATURE_TELEGRAM is DISABLED" - fi + loadConfig # Messages should have this form: # {"response-topic":"response/5541","cmd":"web","url":"2557df870b9a:1111/callback1conf","body":"eyJpZCI6IjUxIiwiYWRkc...dCI6MTUxNzYwMH0K"} @@ -83,11 +68,50 @@ main() { trace "[main] Telegram is NOT enabled - message not sent" fi ;; + reloadConfig) + trace "[main] Reloading configs Now" + response="{\"return_code\":\"$(loadConfig)\"}" + trace "[main] response=${response}" + publish_response "${response}" "${response_topic}" ${?} + trace "[main] Reloading configs - Done" + ;; esac trace "[main] msg processed" done } +loadConfig(){ + if [ "${FEATURE_TELEGRAM}" = "true" ]; then + trace "[loadConfig] FEATURE_TELEGRAM is ENABLED" + + trace "[loadConfig] Looking up TG_BOT_URL in database" + TG_BOT_URL=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_base_url'") + returncode=$? + trace "[loadConfig] TG_BOT_URL [${TG_BOT_URL}]" + trace_rc ${returncode} + [ "${returncode}" -ne "0" ] && echo 10 + + trace "[loadConfig] Looking up TG_API_KEY in database" + TG_API_KEY=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_api_key'") + returncode=$? + trace "[loadConfig] TG_API_KEY [${TG_API_KEY}]" + trace_rc ${returncode} + [ "${returncode}" -ne "0" ] && echo 20 + + trace "[loadConfig] Looking up TG_CHAT_ID in database" + TG_CHAT_ID=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_chat_id'") + returncode=$? + trace "[loadConfig] TG_CHAT_ID [${TG_CHAT_ID}]" + trace_rc ${returncode} + [ "${returncode}" -ne "0" ] && echo 30 + else + trace "[loadConfig] FEATURE_TELEGRAM is DISABLED" + fi + + echo "0" +} + + main returncode=$? trace "[requesthandler] exiting" From 0b172922dc9a701c2b1c91c741f604ec3aad1073 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Tue, 3 May 2022 15:34:22 -0400 Subject: [PATCH 17/25] moved setup scripts in notifier --- .../templates/installer/run-tgsetup.sh | 9 ---- dist/setup.sh | 14 ----- doc/TELEGRAM.md | 53 +++++++++++++++++-- notifier_docker/script/start-tg-setup.sh | 2 + .../script}/tgsetup.sh | 5 +- 5 files changed, 53 insertions(+), 30 deletions(-) delete mode 100644 cyphernodeconf_docker/templates/installer/run-tgsetup.sh create mode 100755 notifier_docker/script/start-tg-setup.sh rename {cyphernodeconf_docker/templates/installer => notifier_docker/script}/tgsetup.sh (97%) diff --git a/cyphernodeconf_docker/templates/installer/run-tgsetup.sh b/cyphernodeconf_docker/templates/installer/run-tgsetup.sh deleted file mode 100644 index 30f0e5596..000000000 --- a/cyphernodeconf_docker/templates/installer/run-tgsetup.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -current_path="$(cd "$(dirname "$0")" >/dev/null && pwd)" - -docker run --rm -it -v $current_path/tgsetup.sh:/tgsetup.sh \ --v $current_path:/dist \ --e PGPASSFILE=/dist/cyphernode/proxy/pgpass \ ---network cyphernodenet eclipse-mosquitto:<%= mosquitto_version %> /tgsetup.sh - diff --git a/dist/setup.sh b/dist/setup.sh index 6d0e5d849..6f91f6cb0 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -650,8 +650,6 @@ install_docker() { copy_file $cyphernodeconf_filepath/installer/start.sh $current_path/start.sh 0 copy_file $cyphernodeconf_filepath/installer/stop.sh $current_path/stop.sh 0 copy_file $cyphernodeconf_filepath/installer/testdeployment.sh $current_path/testdeployment.sh 0 - copy_file $cyphernodeconf_filepath/installer/tgsetup.sh $current_path/tgsetup.sh 0 - copy_file $cyphernodeconf_filepath/installer/run-tgsetup.sh $current_path/run-tgsetup.sh 0 if [[ ! -x $current_path/start.sh ]]; then step " make start.sh executable" @@ -676,18 +674,6 @@ install_docker() { try chmod +x $current_path/testdeployment.sh next fi - - if [[ ! -x $current_path/tgsetup.sh ]]; then - step " make tgsetup.sh executable" - try chmod +x $current_path/tgsetup.sh - next - fi - - if [[ ! -x $current_path/run-tgsetup.sh ]]; then - step " make run-tgsetup.sh executable" - try chmod +x $current_path/run-tgsetup.sh - next - fi } check_directory_owner() { diff --git a/doc/TELEGRAM.md b/doc/TELEGRAM.md index d2fb77867..af5a51498 100644 --- a/doc/TELEGRAM.md +++ b/doc/TELEGRAM.md @@ -1,7 +1,54 @@ -# Telegram integration in Cyphernode. Please enjoy responsibly +# Telegram integration in Cyphernode. -Get your Telegram API Key by chating with the @BotFather -Details here https://core.telegram.org/bots +Build and setup Cyphernode - Choose to enable Telegram. The first time you run Cyphernode, you will get an error concerning Telegram beacause Telegram has to be setup with the next few steps. + +START CYPHERNODE running /dist/start.sh + +In directory cyphernode/notifier_docker/scripts, you will find the script start-tg-setup.sh to start the Telegram setup. It runs inside the notifier container with this command : + docker exec -it $(docker ps -q -f "name=cyphernode_notifier") ./tgsetup.sh + +Follow the steps of the installer - example output follows: + +notifier_docker/script % ./start-tg-setup.sh +Testing database before starting the configuration +Database is alive +Do you wish to configure Telegram for Cyphernode? [yn] yAdding the Telegram base URL in database config table cyphernode_props +[sql] psql -qAtX -h postgres -U cyphernode -c "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_base_url', 'https://api.telegram.org/bot') ON CONFLICT (category, property) DO NOTHING" +0 + +Please go into your Telegram App and start chatting with the @BotFather + +==> (Step 1) Enter @Botfather in the search tab and choose this bot +==> Note, official Telegram bots have a blue checkmark beside their name +==> (Step 2) Click “Start” to activate BotFather bot. In response, you receive a list of commands to manage bots +==> (Step 3) Choose or type the /newbot command and send it +==> @BotFather replies: Alright, a new bot. How are we going to call it? Please choose a name for your bot +==> (Step 4) Choose a name for your bot. And choose a username for your bot — the bot can be found by its username in searches. The username must be unique and end with the word 'bot' +==> After you choose a suitable name for your bot — the bot is created. You will receive a message with a link to your bot t.me/ +==> Cyphernode needs the generated token to access the API: Copy the line below following the message 'Use this token to access the HTTP API' +Enter the token here: 5172851233:AAHkpd4T1ILyhXyqDelNnOTgFE4hl-AQSVMTelegram Setup will now try to obtain the chat ID from the Telgram server. +To make this happen, please go into the Telegram App and send a message to the new bot +Click on the link in the @BotFather's answer : Congratulations on your new bot. You will find it at t.me/your-new-bot. +Trying to contact Telegram server... +[sql] psql -qAtX -h postgres -U cyphernode -c "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_api_key', '3172855133:AAHkpd4T1ILyhXyqDelNnOTgFE4hl-AQSVM') ON CONFLICT (category, property) DO UPDATE SET value='5182851733:AAHkpd4T1ILyhXyqDelNnOTgFE4hl-AQSVM'" +0 +[sql] psql -qAtX -h postgres -U cyphernode -c "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_chat_id', '1649436203') ON CONFLICT (category, property) DO UPDATE SET value=1609936104" +0 + +Reloading configs + +Sending message to Telegram [Tue May 3 16:29:03 UTC 2022] +Ok. Done. + + + + + + + + + +How it works : calling Telegram API example : diff --git a/notifier_docker/script/start-tg-setup.sh b/notifier_docker/script/start-tg-setup.sh new file mode 100755 index 000000000..674a2ff02 --- /dev/null +++ b/notifier_docker/script/start-tg-setup.sh @@ -0,0 +1,2 @@ +docker exec -it $(docker ps -q -f "name=cyphernode_notifier") ./tgsetup.sh + diff --git a/cyphernodeconf_docker/templates/installer/tgsetup.sh b/notifier_docker/script/tgsetup.sh similarity index 97% rename from cyphernodeconf_docker/templates/installer/tgsetup.sh rename to notifier_docker/script/tgsetup.sh index 986e1d245..1f723e150 100755 --- a/cyphernodeconf_docker/templates/installer/tgsetup.sh +++ b/notifier_docker/script/tgsetup.sh @@ -3,9 +3,6 @@ # Cyphernode Telegram configuration # # -echo "Telegram setup. Installing components..." -apk add --update --no-cache curl jq postgresql > /dev/null - sql() { local select_id=${2} local response @@ -132,7 +129,7 @@ while true; do ON CONFLICT (category, property) DO UPDATE SET value=$TG_CHAT_ID" echo "" - echo "Reloading notifier configs" + echo "Reloading configs" response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"reloadConfig\",\"tor\":false}") echo "" From 2f0ccbb851211f09a194a2859cf24c5a8cf60247 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Tue, 3 May 2022 15:52:16 -0400 Subject: [PATCH 18/25] moved ssetup in notifier --- cyphernodeconf_docker/prompters/999_installer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cyphernodeconf_docker/prompters/999_installer.js b/cyphernodeconf_docker/prompters/999_installer.js index 10083eec6..1301cff43 100644 --- a/cyphernodeconf_docker/prompters/999_installer.js +++ b/cyphernodeconf_docker/prompters/999_installer.js @@ -416,8 +416,8 @@ module.exports = { }, templates: function( props ) { if( props.installer_mode === 'docker' ) { - return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh', 'tgsetup.sh', 'run-tgsetup.sh', path.join('docker', 'docker-compose.yaml')]; + return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh', path.join('docker', 'docker-compose.yaml')]; } - return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh', 'tgsetup.sh', 'run-tgsetup.sh']; + return ['config.sh','start.sh', 'stop.sh', 'testfeatures.sh', 'testdeployment.sh']; } }; From 5e45952fe97a33e59e888a22eb8cfc1f7909beb1 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Tue, 3 May 2022 16:16:58 -0400 Subject: [PATCH 19/25] fix a merge fu --- dist/setup.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dist/setup.sh b/dist/setup.sh index 8ae6701be..734cbb2b1 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -493,9 +493,6 @@ install_docker() { copy_file $cyphernodeconf_filepath/otsclient/otsclient.env $current_path/.env/otsclient.env 1 $SUDO_REQUIRED copy_file $cyphernodeconf_filepath/proxycron/proxycron.env $current_path/.env/proxycron.env 1 $SUDO_REQUIRED - - copy_file $cyphernodeconf_filepath/notifier/notifier.env $current_path/.env/notifier.env 1 $SUDO_REQUIRED - if [[ $BITCOIN_INTERNAL == true ]]; then if [ ! -d $BITCOIN_DATAPATH ]; then step " create $BITCOIN_DATAPATH" From fa4bf60e758fdf8f1f8be5f86aed1d03f8d82fae Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Tue, 3 May 2022 17:10:49 -0400 Subject: [PATCH 20/25] Test TG only once --- cyphernodeconf_docker/templates/installer/testfeatures.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cyphernodeconf_docker/templates/installer/testfeatures.sh b/cyphernodeconf_docker/templates/installer/testfeatures.sh index d48b1db71..f741f5c33 100644 --- a/cyphernodeconf_docker/templates/installer/testfeatures.sh +++ b/cyphernodeconf_docker/templates/installer/testfeatures.sh @@ -430,13 +430,13 @@ result="${result}$(feature_status ${returncode} 'Notifier error!')}" result="${result},{\"coreFeature\":true, \"name\":\"notifier telegram\",\"working\":" status=$(echo "{${containers}}" | jq ".containers[] | select(.name == \"notifier\") | .active") if [[ "${workingproxy}" = "true" && "${status}" = "true" ]]; then - timeout_feature checknotifiertelegram + checknotifiertelegram returncode=$? else returncode=1 fi finalreturncode=$((${returncode} | ${finalreturncode})) -result="${result}$(feature_status ${returncode} 'Notifier Telegram error!')}" +result="${result}$(feature_status ${returncode} 'Notifier Telegram error! - Please run Telegram setup - See doc/TELEGRAM.md')}" <% } %> ############################# From b94e8840f1e4eb1149e2935a1be74c6db0946253 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Tue, 3 May 2022 17:12:28 -0400 Subject: [PATCH 21/25] new doc for setting up TG --- doc/TELEGRAM.md | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/doc/TELEGRAM.md b/doc/TELEGRAM.md index af5a51498..68c76ccc9 100644 --- a/doc/TELEGRAM.md +++ b/doc/TELEGRAM.md @@ -2,38 +2,51 @@ Build and setup Cyphernode - Choose to enable Telegram. The first time you run Cyphernode, you will get an error concerning Telegram beacause Telegram has to be setup with the next few steps. -START CYPHERNODE running /dist/start.sh +==> START CYPHERNODE running /dist/start.sh In directory cyphernode/notifier_docker/scripts, you will find the script start-tg-setup.sh to start the Telegram setup. It runs inside the notifier container with this command : docker exec -it $(docker ps -q -f "name=cyphernode_notifier") ./tgsetup.sh Follow the steps of the installer - example output follows: -notifier_docker/script % ./start-tg-setup.sh +In directory notifier_docker/script, run ** ./start-tg-setup.sh ** + Testing database before starting the configuration Database is alive -Do you wish to configure Telegram for Cyphernode? [yn] yAdding the Telegram base URL in database config table cyphernode_props -[sql] psql -qAtX -h postgres -U cyphernode -c "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_base_url', 'https://api.telegram.org/bot') ON CONFLICT (category, property) DO NOTHING" -0 + +Do you wish to configure Telegram for Cyphernode? [yn] yA + +dding the Telegram base URL in database config table cyphernode_props +[sql] psql -qAtX -h postgres -U cyphernode -c "INSERT INTO ...." + Please go into your Telegram App and start chatting with the @BotFather ==> (Step 1) Enter @Botfather in the search tab and choose this bot + ==> Note, official Telegram bots have a blue checkmark beside their name + ==> (Step 2) Click “Start” to activate BotFather bot. In response, you receive a list of commands to manage bots + ==> (Step 3) Choose or type the /newbot command and send it + ==> @BotFather replies: Alright, a new bot. How are we going to call it? Please choose a name for your bot + ==> (Step 4) Choose a name for your bot. And choose a username for your bot — the bot can be found by its username in searches. The username must be unique and end with the word 'bot' + ==> After you choose a suitable name for your bot — the bot is created. You will receive a message with a link to your bot t.me/ + ==> Cyphernode needs the generated token to access the API: Copy the line below following the message 'Use this token to access the HTTP API' -Enter the token here: 5172851233:AAHkpd4T1ILyhXyqDelNnOTgFE4hl-AQSVMTelegram Setup will now try to obtain the chat ID from the Telgram server. + +Enter the token here: 5172851233:AAHkpd4T1ILyhXyqDelNnOTgFE4hl-AQSVM + +Telegram Setup will now try to obtain the chat ID from the Telgram server. + To make this happen, please go into the Telegram App and send a message to the new bot + Click on the link in the @BotFather's answer : Congratulations on your new bot. You will find it at t.me/your-new-bot. + Trying to contact Telegram server... -[sql] psql -qAtX -h postgres -U cyphernode -c "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_api_key', '3172855133:AAHkpd4T1ILyhXyqDelNnOTgFE4hl-AQSVM') ON CONFLICT (category, property) DO UPDATE SET value='5182851733:AAHkpd4T1ILyhXyqDelNnOTgFE4hl-AQSVM'" -0 -[sql] psql -qAtX -h postgres -U cyphernode -c "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_chat_id', '1649436203') ON CONFLICT (category, property) DO UPDATE SET value=1609936104" -0 Reloading configs @@ -42,12 +55,7 @@ Ok. Done. - - - - - - +=============================================================== How it works : calling Telegram API From d0799cf98429ae2ad69c1f2aa4ccb6e94ef0a7d0 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Wed, 4 May 2022 11:26:15 -0400 Subject: [PATCH 22/25] wait loop able creation + readLoop in notifier --- .../installer/docker/docker-compose.yaml | 2 +- doc/TELEGRAM.md | 10 +++--- notifier_docker/script/requesthandler.sh | 33 +++++++++++++------ notifier_docker/script/sql.sh | 19 +++++++++++ proxy_docker/app/script/requesthandler.sh | 2 ++ proxy_docker/app/script/startproxy.sh | 1 + 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml index 02ac88527..afabd10ee 100644 --- a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml +++ b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml @@ -276,7 +276,7 @@ services: - .env/notifier.env volumes: - "<%= logs_datapath %>:/cnlogs" - - "<%= proxy_datapath %>:/proxy/db" + - "<%= proxy_datapath %>/pgpass:/proxy/db/pgpass" - container_monitor:/container_monitor networks: - cyphernodenet diff --git a/doc/TELEGRAM.md b/doc/TELEGRAM.md index 68c76ccc9..c1ecfabce 100644 --- a/doc/TELEGRAM.md +++ b/doc/TELEGRAM.md @@ -1,11 +1,13 @@ # Telegram integration in Cyphernode. -Build and setup Cyphernode - Choose to enable Telegram. The first time you run Cyphernode, you will get an error concerning Telegram beacause Telegram has to be setup with the next few steps. +The first time you run Cyphernode, you will get an error concerning Telegram beacause Telegram has to be setup with the next few steps. Go to [STEP 1] -==> START CYPHERNODE running /dist/start.sh +Build and setup Cyphernode - Choose to enable Telegram. -In directory cyphernode/notifier_docker/scripts, you will find the script start-tg-setup.sh to start the Telegram setup. It runs inside the notifier container with this command : - docker exec -it $(docker ps -q -f "name=cyphernode_notifier") ./tgsetup.sh +==> START CYPHERNODE by running /dist/start.sh + +[STEP 1]: In directory cyphernode/notifier_docker/script, you will find the script `start-tg-setup.sh` to start the Telegram setup. It runs inside the notifier container with this command : + `docker exec -it $(docker ps -q -f "name=cyphernode_notifier") ./tgsetup.sh` Follow the steps of the installer - example output follows: diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index 525b53707..3b86d39d1 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -5,20 +5,26 @@ . ./response.sh . ./sql.sh + main() { trace "Entering main()..." + while true; do + loadConfig + + readLoop + done + +} + +readLoop(){ local msg local cmd local response local response_topic local url - TG_BOT_URL="" - TG_API_KEY="" - TG_CHAT_ID="" - - loadConfig + trace "[readLoop] Starting" # Messages should have this form: # {"response-topic":"response/5541","cmd":"web","url":"2557df870b9a:1111/callback1conf","body":"eyJpZCI6IjUxIiwiYWRkc...dCI6MTUxNzYwMH0K"} @@ -70,10 +76,13 @@ main() { ;; reloadConfig) trace "[main] Reloading configs Now" - response="{\"return_code\":\"$(loadConfig)\"}" + response="{\"return_code\":\"(loadConfig)\"}" trace "[main] response=${response}" publish_response "${response}" "${response_topic}" ${?} trace "[main] Reloading configs - Done" + + # restart read loop + break ;; esac trace "[main] msg processed" @@ -84,26 +93,31 @@ loadConfig(){ if [ "${FEATURE_TELEGRAM}" = "true" ]; then trace "[loadConfig] FEATURE_TELEGRAM is ENABLED" + # wait for table to exist in DB - for clean install + waitfortable "cyphernode_props" + trace "[loadConfig] Looking up TG_BOT_URL in database" + TG_BOT_URL=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_base_url'") returncode=$? trace "[loadConfig] TG_BOT_URL [${TG_BOT_URL}]" trace_rc ${returncode} - [ "${returncode}" -ne "0" ] && echo 10 + + [ "${returncode}" -ne "0" ] && return 10 trace "[loadConfig] Looking up TG_API_KEY in database" TG_API_KEY=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_api_key'") returncode=$? trace "[loadConfig] TG_API_KEY [${TG_API_KEY}]" trace_rc ${returncode} - [ "${returncode}" -ne "0" ] && echo 20 + [ "${returncode}" -ne "0" ] && return 20 trace "[loadConfig] Looking up TG_CHAT_ID in database" TG_CHAT_ID=$(sql "SELECT value FROM cyphernode_props WHERE category='notifier' AND property='tg_chat_id'") returncode=$? trace "[loadConfig] TG_CHAT_ID [${TG_CHAT_ID}]" trace_rc ${returncode} - [ "${returncode}" -ne "0" ] && echo 30 + [ "${returncode}" -ne "0" ] && return 30 else trace "[loadConfig] FEATURE_TELEGRAM is DISABLED" fi @@ -111,7 +125,6 @@ loadConfig(){ echo "0" } - main returncode=$? trace "[requesthandler] exiting" diff --git a/notifier_docker/script/sql.sh b/notifier_docker/script/sql.sh index 3e2c3efdc..bee2e6dcf 100644 --- a/notifier_docker/script/sql.sh +++ b/notifier_docker/script/sql.sh @@ -30,3 +30,22 @@ sql() { return ${returncode} } + +waitfortable(){ + TABLE_NAME=$1 + + trace "Entering waitfortable [$TABLE_NAME]" + + while true; do + + exists=$(psql -qAtX -h postgres -U cyphernode -c "SELECT EXISTS (SELECT FROM pg_tables WHERE schemaname='public' and tablename='$TABLE_NAME')") + + if [ "${exists}" = "t" ]; then + trace "Table found [$TABLE_NAME] - Exiting" + break + fi + + trace "wainting for table [$TABLE_NAME] to exist" + sleep 5 + done +} diff --git a/proxy_docker/app/script/requesthandler.sh b/proxy_docker/app/script/requesthandler.sh index dd2200b38..5d89021ec 100644 --- a/proxy_docker/app/script/requesthandler.sh +++ b/proxy_docker/app/script/requesthandler.sh @@ -1,5 +1,7 @@ #!/bin/sh # + +. ./db/config.sh . ./sendtobitcoinnode.sh . ./callbacks_job.sh . ./watchrequest.sh diff --git a/proxy_docker/app/script/startproxy.sh b/proxy_docker/app/script/startproxy.sh index 5aeb6097f..793ceb344 100644 --- a/proxy_docker/app/script/startproxy.sh +++ b/proxy_docker/app/script/startproxy.sh @@ -95,6 +95,7 @@ chmod 0600 $DB_FILE createCurlConfig ${WATCHER_BTC_NODE_RPC_CFG} ${WATCHER_BTC_NODE_RPC_USER} createCurlConfig ${SPENDER_BTC_NODE_RPC_CFG} ${SPENDER_BTC_NODE_RPC_USER} +. ${DB_PATH}/config.sh if [ "${FEATURE_LIGHTNING}" = "true" ]; then ./waitanyinvoice.sh & fi From f6459a33e5f73e986eb348219c7461734fbf6cea Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Thu, 12 May 2022 15:18:28 -0400 Subject: [PATCH 23/25] tor config --- cyphernodeconf_docker/lib/app.js | 5 ++++- cyphernodeconf_docker/prompters/040_tor.js | 1 + cyphernodeconf_docker/schema/config-v0.2.6.json | 6 ++++-- .../templates/installer/config.sh | 1 + .../templates/installer/testdeployment.sh | 1 + .../templates/installer/testfeatures.sh | 15 +++++++++++++-- .../templates/notifier/notifier.env | 4 ++++ cyphernodeconf_docker/torifyables.json | 4 ++++ notifier_docker/script/requesthandler.sh | 4 ++++ notifier_docker/script/tgsetup.sh | 14 +++++++++++--- proxy_docker/app/script/notify.sh | 14 +++++++++----- proxy_docker/app/tests/test-telegram.sh | 2 +- 12 files changed, 57 insertions(+), 14 deletions(-) diff --git a/cyphernodeconf_docker/lib/app.js b/cyphernodeconf_docker/lib/app.js index cbc85da4a..e3847d479 100644 --- a/cyphernodeconf_docker/lib/app.js +++ b/cyphernodeconf_docker/lib/app.js @@ -564,7 +564,10 @@ module.exports = class App { }, telegram: { networks: ['cyphernodenet'], - docker: "cypernode/notifier" + docker: "cypernode/notifier", + extra:{ + torified: this.torifyables.find(data => data.value === 'tor_telegram').checked, + } } } diff --git a/cyphernodeconf_docker/prompters/040_tor.js b/cyphernodeconf_docker/prompters/040_tor.js index 871be6c10..a65783770 100644 --- a/cyphernodeconf_docker/prompters/040_tor.js +++ b/cyphernodeconf_docker/prompters/040_tor.js @@ -66,6 +66,7 @@ module.exports = { // - OTS Callbacks (webhooks) // - Address Watches Callbacks (webhooks) // - TXID Watches Callbacks (webhooks) +// - Telegram // Certain services can also use clearnet. What do you want to allow to use clearnet? // - Bitcoin Node diff --git a/cyphernodeconf_docker/schema/config-v0.2.6.json b/cyphernodeconf_docker/schema/config-v0.2.6.json index 828e13c8a..7d27b4377 100644 --- a/cyphernodeconf_docker/schema/config-v0.2.6.json +++ b/cyphernodeconf_docker/schema/config-v0.2.6.json @@ -219,7 +219,8 @@ "tor_otsoperations", "tor_otswebhooks", "tor_addrwatcheswebhooks", - "tor_txidwatcheswebhooks" + "tor_txidwatcheswebhooks", + "tor_telegram" ], "title": "The Torified feature", "default": "", @@ -230,7 +231,8 @@ "tor_otsoperations", "tor_otswebhooks", "tor_addrwatcheswebhooks", - "tor_txidwatcheswebhooks" + "tor_txidwatcheswebhooks", + "tor_telegram" ] } }, diff --git a/cyphernodeconf_docker/templates/installer/config.sh b/cyphernodeconf_docker/templates/installer/config.sh index 5325b005e..26f0abfea 100644 --- a/cyphernodeconf_docker/templates/installer/config.sh +++ b/cyphernodeconf_docker/templates/installer/config.sh @@ -21,6 +21,7 @@ TOR_TXID_WATCH_WEBHOOKS=<%= (torifyables && torifyables.indexOf('tor_txidwatches TOR_TRAEFIK=<%= (torifyables && torifyables.indexOf('tor_traefik') !== -1)?'true':'false' %> TOR_BITCOIN=<%= (torifyables && torifyables.indexOf('tor_bitcoin') !== -1)?'true':'false' %> TOR_LIGHTNING=<%= (torifyables && torifyables.indexOf('tor_lightning') !== -1)?'true':'false' %> +TOR_TELEGRAM=<%= (torifyables && torifyables.indexOf('tor_telegram') !== -1)?'true':'false' %> <% } %> DOCKER_MODE=<%= docker_mode %> RUN_AS_USER=<%= run_as_different_user?username:'' %> diff --git a/cyphernodeconf_docker/templates/installer/testdeployment.sh b/cyphernodeconf_docker/templates/installer/testdeployment.sh index 60755d217..1f938a946 100644 --- a/cyphernodeconf_docker/templates/installer/testdeployment.sh +++ b/cyphernodeconf_docker/templates/installer/testdeployment.sh @@ -56,6 +56,7 @@ export USER=$(id -u <%= default_username %>):$(id -g <%= default_username %>) # Will test if Cyphernode is fully up and running... docker run --rm -it -v $current_path/testfeatures.sh:/testfeatures.sh \ -v <%= gatekeeper_datapath %>:/gatekeeper \ +-v ${current_path}/.cyphernodeconf/installer/config.sh:/config.sh \ -v $current_path:/dist \ -v cyphernode_container_monitor:/container_monitor:ro \ --network cyphernodenet eclipse-mosquitto:<%= mosquitto_version %> /testfeatures.sh diff --git a/cyphernodeconf_docker/templates/installer/testfeatures.sh b/cyphernodeconf_docker/templates/installer/testfeatures.sh index f741f5c33..d8e75c968 100644 --- a/cyphernodeconf_docker/templates/installer/testfeatures.sh +++ b/cyphernodeconf_docker/templates/installer/testfeatures.sh @@ -4,6 +4,8 @@ apk add --update --no-cache openssl curl jq coreutils postgresql > /dev/null . /gatekeeper/keys.properties +. ./config.sh + checkgatekeeper() { echo -e "\r\n\e[1;36mTesting Gatekeeper...\e[0;32m" > /dev/console @@ -125,8 +127,17 @@ checknotifiertelegram() { echo -en "\r\n\e[1;36mTesting Notifier Telegram... " > /dev/console local response local returncode - - response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramNoop\"}") + local msg + + echo "TOR [$TOR_TELEGRAM]" + + if [ "$TOR_TELEGRAM" = "true" ]; then + msg="{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramNoop\",\"tor\":true}" + else + msg="{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramNoop\"}" + fi + + response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "$msg") returncode=$? [ "${returncode}" -ne "0" ] && return 115 http_code=$(echo "${response}" | jq -r ".http_code") diff --git a/cyphernodeconf_docker/templates/notifier/notifier.env b/cyphernodeconf_docker/templates/notifier/notifier.env index 1101aa4a7..160e122ef 100644 --- a/cyphernodeconf_docker/templates/notifier/notifier.env +++ b/cyphernodeconf_docker/templates/notifier/notifier.env @@ -6,5 +6,9 @@ TOR_PORT=9050 <% if ( features.indexOf('telegram') !== -1 ) { %> FEATURE_TELEGRAM=true +<% if ( features.indexOf('tor') !== -1 && torifyables && torifyables.indexOf('tor_telegram') !== -1 ) { %> +TOR_TELEGRAM=true <% } %> +<% } %> + PGPASSFILE=/proxy/db/pgpass diff --git a/cyphernodeconf_docker/torifyables.json b/cyphernodeconf_docker/torifyables.json index 87c201270..51c861baa 100644 --- a/cyphernodeconf_docker/torifyables.json +++ b/cyphernodeconf_docker/torifyables.json @@ -26,5 +26,9 @@ { "name": "TXID Watches Callbacks (webhooks)", "value": "tor_txidwatcheswebhooks" + }, + { + "name": "Telegram", + "value": "tor_telegram" } ] diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index 3b86d39d1..e8635db4f 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -93,6 +93,10 @@ loadConfig(){ if [ "${FEATURE_TELEGRAM}" = "true" ]; then trace "[loadConfig] FEATURE_TELEGRAM is ENABLED" + if [ "${TOR_TELEGRAM}" = "true" ]; then + trace "[loadConfig] Telegram will be used with tor" + fi + # wait for table to exist in DB - for clean install waitfortable "cyphernode_props" diff --git a/notifier_docker/script/tgsetup.sh b/notifier_docker/script/tgsetup.sh index 1f723e150..8d31fa256 100755 --- a/notifier_docker/script/tgsetup.sh +++ b/notifier_docker/script/tgsetup.sh @@ -43,6 +43,8 @@ else echo "Database is alive" fi +echo "Using tor [$TOR_TELEGRAM]" + while true; do read -p "Do you wish to configure Telegram for Cyphernode? [yn] " -n 1 -r @@ -130,13 +132,19 @@ while true; do echo "" echo "Reloading configs" - response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"reloadConfig\",\"tor\":false}") + + response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"reloadConfig\"}") echo "" echo "Sending message to Telegram [$today]" - body=$(echo "{\"text\":\"Hello from Cyphernode 2[$today] - setup is complete\"}" | base64 | tr -d '\n') - response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}") + if [ "${TOR_TELEGRAM}" = "true" ]; then + body=$(echo "{\"text\":\"Hello from Cyphernode [$today] using tor - setup is complete\"}" | base64 | tr -d '\n') + response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\",\"tor\":true}") + else + body=$(echo "{\"text\":\"Hello from Cyphernode [$today] using clearnet - setup is complete\"}" | base64 | tr -d '\n') + response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}") + fi echo "Ok. Done." exit fi diff --git a/proxy_docker/app/script/notify.sh b/proxy_docker/app/script/notify.sh index 099fedc1e..8148e2bf6 100644 --- a/proxy_docker/app/script/notify.sh +++ b/proxy_docker/app/script/notify.sh @@ -52,13 +52,13 @@ notify_web() { } # -# call notify_telegram "JSON data". See https://core.telegram.org/bots/api#sendmessage -# ex in shell script: notify_telegram "{\"text\":\"Unit testing notify_telegram at `date -u +"%FT%H%MZ"`\"}" +# call notify_telegram "text to send". See https://core.telegram.org/bots/api#sendmessage +# ex in shell script: notify_telegram "Unit testing notify_telegram at `date -u +"%FT%H%MZ"`" # notify_telegram() { trace "Entering notify_telegram()..." - local body=$(echo "${1}" | base64 | tr -d '\n') + local body=$(echo {\"text\":\"$1\"} | base64 | tr -d '\n') local returncode local response @@ -66,8 +66,12 @@ notify_telegram() { local curl_code local msg - msg="{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}" - + if [ "$TOR_TELEGRAM" = "true" ]; then + msg="{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\",\"tor\":true}" + else + msg="{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}" + fi + # We use the pid as the response-topic, so there's no conflict in responses. trace "[notify_telegram] mosquitto_rr -h broker -W 21 -t notifier -e \"response/$$\" -m \"${msg}\"" response=$(mosquitto_rr -h broker -W 21 -t notifier -e "response/$$" -m ${msg}) diff --git a/proxy_docker/app/tests/test-telegram.sh b/proxy_docker/app/tests/test-telegram.sh index f0bb54225..6405a0e0f 100755 --- a/proxy_docker/app/tests/test-telegram.sh +++ b/proxy_docker/app/tests/test-telegram.sh @@ -7,7 +7,7 @@ cd .. echo "Calling notify_telegram..." -notify_telegram "{\"text\":\"Unit testing notify_telegram at `date -u +"%FT%H%MZ"`\"}" +notify_telegram "Unit testing notify_telegram at `date -u +"%FT%H%MZ"`" echo "Done..." From 7dffd37b8a069f9c5acac95b90f049b7ec9377a2 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Thu, 12 May 2022 18:04:31 -0400 Subject: [PATCH 24/25] Hooked up TG setup in start.sh --- .../templates/installer/testdeployment.sh | 5 +++++ .../templates/installer/testfeatures.sh | 12 +++++++----- notifier_docker/script/tgsetup.sh | 7 ------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cyphernodeconf_docker/templates/installer/testdeployment.sh b/cyphernodeconf_docker/templates/installer/testdeployment.sh index 1f938a946..dd52235e3 100644 --- a/cyphernodeconf_docker/templates/installer/testdeployment.sh +++ b/cyphernodeconf_docker/templates/installer/testdeployment.sh @@ -84,6 +84,11 @@ if [ "$EXIT_STATUS" -ne "0" ]; then exit 1 fi +if [ "$RUN_TELEGRAM_SETUP" -ne "0" ]; then + printf "\r\n\e[1;32mStarting Telegram setup\e[0m\n" + ../notifier_docker/script/start-tg-setup.sh +fi + printf "\r\n\033[0;92mDepending on your current location and DNS settings, point your favorite browser to one of the following URLs to access Cyphernode's status page:\r\n" printf "\r\n" printf "\033[0;95m<% cns.forEach(cn => { %><%= ('https://' + cn + ':' + traefik_https_port + '/welcome\\r\\n') %><% }) %>\033[0m\r\n" diff --git a/cyphernodeconf_docker/templates/installer/testfeatures.sh b/cyphernodeconf_docker/templates/installer/testfeatures.sh index d8e75c968..e2f9335b5 100644 --- a/cyphernodeconf_docker/templates/installer/testfeatures.sh +++ b/cyphernodeconf_docker/templates/installer/testfeatures.sh @@ -129,8 +129,6 @@ checknotifiertelegram() { local returncode local msg - echo "TOR [$TOR_TELEGRAM]" - if [ "$TOR_TELEGRAM" = "true" ]; then msg="{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramNoop\",\"tor\":true}" else @@ -139,10 +137,10 @@ checknotifiertelegram() { response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "$msg") returncode=$? - [ "${returncode}" -ne "0" ] && return 115 + [ "${returncode}" -ne "0" ] && echo -e "\e[1;31mNotifier Telegram needs to be configured" > /dev/console && return 115 http_code=$(echo "${response}" | jq -r ".http_code") - [ "${http_code}" -ge "400" ] && return 118 - [ "${http_code}" -eq "0" ] && return 119 + [ "${http_code}" -ge "400" ] && echo -e "\e[1;31mNotifier Telegram needs to be configured" > /dev/console && return 118 + [ "${http_code}" -eq "0" ] && echo -e "\e[1;31mNotifier Telegram needs to be configured" > /dev/console && return 119 echo -e "\e[1;36mNotifier Telegram rocks!" > /dev/console @@ -317,6 +315,7 @@ feature_status() { # Let's first see if everything is up. echo "EXIT_STATUS=1" > /dist/exitStatus.sh +RUN_TELEGRAM_SETUP=0 ############################# # Ping containers and PROXY # @@ -443,6 +442,8 @@ status=$(echo "{${containers}}" | jq ".containers[] | select(.name == \"notifier if [[ "${workingproxy}" = "true" && "${status}" = "true" ]]; then checknotifiertelegram returncode=$? + # Non critical error - run telegram setup at the end + [ "${returncode}" -ne "0" ] && RUN_TELEGRAM_SETUP=1 && returncode=0 else returncode=1 fi @@ -545,6 +546,7 @@ result="{${result}]}" echo "${result}" > /gatekeeper/installation.json echo "EXIT_STATUS=${finalreturncode}" > /dist/exitStatus.sh +echo "RUN_TELEGRAM_SETUP=$RUN_TELEGRAM_SETUP" >> /dist/exitStatus.sh <% if (features.indexOf('tor') !== -1 && torifyables && torifyables.indexOf('tor_traefik') !== -1) { %> echo "TOR_TRAEFIK_HOSTNAME=$(cat /dist/.cyphernodeconf/tor/traefik/hidden_service/hostname)" >> /dist/exitStatus.sh diff --git a/notifier_docker/script/tgsetup.sh b/notifier_docker/script/tgsetup.sh index 8d31fa256..972bc68fa 100755 --- a/notifier_docker/script/tgsetup.sh +++ b/notifier_docker/script/tgsetup.sh @@ -8,23 +8,16 @@ sql() { local response local inserted_id - echo "[sql] psql -qAtX -h postgres -U cyphernode -c \"${1}\"" response=$(psql -qAtX -h postgres -U cyphernode -c "${1}") returncode=$? - echo ${returncode} if [ -n "${select_id}" ]; then if [ "${returncode}" -eq "0" ]; then inserted_id=$(echo "${response}" | cut -d ' ' -f1) else - echo "[sql] psql -qAtX -h postgres -U cyphernode -c \"${select_id}\"" inserted_id=$(psql -qAtX -h postgres -U cyphernode -c "${select_id}") returncode=$? - echo ${returncode} fi - echo -n "${inserted_id}" - else - echo -n "${response}" fi return ${returncode} From 165b0c87a72e48cbf589b8f6e9cbecbfce0484b2 Mon Sep 17 00:00:00 2001 From: Philippe Lamy Date: Fri, 13 May 2022 13:33:22 -0400 Subject: [PATCH 25/25] TG setup with a nicer look - added colors --- notifier_docker/script/colors.sh | 74 ++++++++++++++++ notifier_docker/script/requesthandler.sh | 4 +- notifier_docker/script/startnotifier.sh | 9 ++ notifier_docker/script/tgsetup.sh | 102 +++++++++++++---------- 4 files changed, 143 insertions(+), 46 deletions(-) create mode 100644 notifier_docker/script/colors.sh diff --git a/notifier_docker/script/colors.sh b/notifier_docker/script/colors.sh new file mode 100644 index 000000000..883d58eeb --- /dev/null +++ b/notifier_docker/script/colors.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# Reset +Color_Off="\033[0m" # Text Reset + +# Regular Colors +Black="\033[0;30m" # Black +Red="\033[0;31m" # Red +Green="\033[0;32m" # Green +Yellow="\033[0;33m" # Yellow +Blue="\033[0;34m" # Blue +Purple="\033[0;35m" # Purple +Cyan="\033[0;36m" # Cyan +White="\033[0;37m" # White + +# Bold +BBlack="\033[1;30m" # Black +BRed="\033[1;31m" # Red +BGreen="\033[1;32m" # Green +BYellow="\033[1;33m" # Yellow +BBlue="\033[1;34m" # Blue +BPurple="\033[1;35m" # Purple +BCyan="\033[1;36m" # Cyan +BWhite="\033[1;37m" # White + +# Underline +UBlack="\033[4;30m" # Black +URed="\033[4;31m" # Red +UGreen="\033[4;32m" # Green +UYellow="\033[4;33m" # Yellow +UBlue="\033[4;34m" # Blue +UPurple="\033[4;35m" # Purple +UCyan="\033[4;36m" # Cyan +UWhite="\033[4;37m" # White + +# Background +On_Black="\033[40m" # Black +On_Red="\033[41m" # Red +On_Green="\033[42m" # Green +On_Yellow="\033[43m" # Yellow +On_Blue="\033[44m" # Blue +On_Purple="\033[45m" # Purple +On_Cyan="\033[46m" # Cyan +On_White="\033[47m" # White + +# High Intensty +IBlack="\033[0;90m" # Black +IRed="\033[0;91m" # Red +IGreen="\033[0;92m" # Green +IYellow="\033[0;93m" # Yellow +IBlue="\033[0;94m" # Blue +IPurple="\033[0;95m" # Purple +ICyan="\033[0;96m" # Cyan +IWhite="\033[0;97m" # White + +# Bold High Intensty +BIBlack="\033[1;90m" # Black +BIRed="\033[1;91m" # Red +BIGreen="\033[1;92m" # Green +BIYellow="\033[1;93m" # Yellow +BIBlue="\033[1;94m" # Blue +BIPurple="\033[1;95m" # Purple +BICyan="\033[1;96m" # Cyan +BIWhite="\033[1;97m" # White + +# High Intensty backgrounds +On_IBlack="\033[0;100m" # Black +On_IRed="\033[0;101m" # Red +On_IGreen="\033[0;102m" # Green +On_IYellow="\033[0;103m" # Yellow +On_IBlue="\033[0;104m" # Blue +On_IPurple="\033[10;95m" # Purple +On_ICyan="\033[0;106m" # Cyan +On_IWhite="\033[0;107m" # White diff --git a/notifier_docker/script/requesthandler.sh b/notifier_docker/script/requesthandler.sh index e8635db4f..45cebbc33 100644 --- a/notifier_docker/script/requesthandler.sh +++ b/notifier_docker/script/requesthandler.sh @@ -87,6 +87,8 @@ readLoop(){ esac trace "[main] msg processed" done + + trace "[readLoop] Exiting read loop" } loadConfig(){ @@ -125,8 +127,6 @@ loadConfig(){ else trace "[loadConfig] FEATURE_TELEGRAM is DISABLED" fi - - echo "0" } main diff --git a/notifier_docker/script/startnotifier.sh b/notifier_docker/script/startnotifier.sh index 4781261a4..e5a5198cc 100644 --- a/notifier_docker/script/startnotifier.sh +++ b/notifier_docker/script/startnotifier.sh @@ -1,6 +1,12 @@ #!/bin/sh . ./trace.sh +wait_for_broker() { + trace "[startnotifier-wait_for_broker] Waiting for broker to be ready" + + while true ; do ping -c 1 broker ; [ "$?" -eq "0" ] && break ; sleep 5; done +} + trace "Starting mosquitto and subscribing to the notifier topic..." if [ "${FEATURE_TELEGRAM}" = "true" ]; then @@ -9,4 +15,7 @@ if [ "${FEATURE_TELEGRAM}" = "true" ]; then trace "[startnotifier] PostgreSQL ready!" fi +# Wait for broker to be ready +wait_for_broker + exec sh -c 'mosquitto_sub -h broker -t notifier | ./requesthandler.sh' diff --git a/notifier_docker/script/tgsetup.sh b/notifier_docker/script/tgsetup.sh index 972bc68fa..8ce594dae 100755 --- a/notifier_docker/script/tgsetup.sh +++ b/notifier_docker/script/tgsetup.sh @@ -1,5 +1,7 @@ #!/bin/sh +. ./colors.sh + # Cyphernode Telegram configuration # # @@ -13,7 +15,7 @@ sql() { if [ -n "${select_id}" ]; then if [ "${returncode}" -eq "0" ]; then - inserted_id=$(echo "${response}" | cut -d ' ' -f1) + inserted_id=$(echo -e "${response}" | cut -d ' ' -f1) else inserted_id=$(psql -qAtX -h postgres -U cyphernode -c "${select_id}") returncode=$? @@ -24,70 +26,80 @@ sql() { } # Ping the database an make sure it's UP -echo "Testing database before starting the configuration" +echo -e "\r\n$BIBlue"; echo -e "[TG Setup] Testing database before starting the configuration" ping -c 1 postgres 2>&1 > /dev/null rc=$? if [ $rc != 0 ]; then - echo "Database is not up. Make sure Cyphernode is running before setting up Telegram" - exit + echo -e "\r\n$BIRed"; echo -e "[TG Setup] Database is not up. Make sure Cyphernode is running before setting up Telegram. Exiting\r\n" + exit 1 else - echo "Database is alive" + echo -e "\r\n$Green"; echo -e "[TG Setup] Database is alive" fi -echo "Using tor [$TOR_TELEGRAM]" +if [ -n "$TOR_TELEGRAM" ] && [ "$TOR_TELEGRAM" = "1" ]; then + echo -e "[TG Setup] Sending Telegram messages usging tor\r\n" +else + echo -e "[TG Setup] Sending Telegram messages usging clearnet\r\n" +fi while true; do - read -p "Do you wish to configure Telegram for Cyphernode? [yn] " -n 1 -r + echo -e "\r\n$Green"; + read -p "[TG Setup] Do you wish to configure Telegram for Cyphernode? [yn] " -n 1 -r case $REPLY in [Yy]* ) break;; - [Nn]* ) echo ""; echo "Got it! You can always come back later"; exit;; - * ) echo "Please answer yes or no.";; + [Nn]* ) echo -e "\r\n[TG Setup] Got it! You can always come back later"; exit;; + * ) echo -e "Please answer yes or no.";; esac done # Set the base Telegram URL in DB -echo "Adding the Telegram base URL in database config table cyphernode_props" +echo -e $Blue; echo -e "\r\n[TG Setup] Adding the Telegram base URL in database config table cyphernode_props\r\n" TG_BASE_URL="https://api.telegram.org/bot" sql "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_base_url', '$TG_BASE_URL') \ ON CONFLICT (category, property) DO NOTHING" -echo "" -echo "Please go into your Telegram App and start chatting with the @BotFather" -echo "" -echo "==> (Step 1) Enter @Botfather in the search tab and choose this bot" -echo "==> Note, official Telegram bots have a blue checkmark beside their name" -echo "==> (Step 2) Click “Start” to activate BotFather bot. In response, you receive a list of commands to manage bots" -echo "==> (Step 3) Choose or type the /newbot command and send it" -echo "==> @BotFather replies: Alright, a new bot. How are we going to call it? Please choose a name for your bot" -echo "==> (Step 4) Choose a name for your bot. And choose a username for your bot — the bot can be found by its username in searches. The username must be unique and end with the word 'bot'" -echo "==> After you choose a suitable name for your bot — the bot is created. You will receive a message with a link to your bot t.me/" -echo "==> Cyphernode needs the generated token to access the API: Copy the line below following the message 'Use this token to access the HTTP API' " +echo -e "" +echo -e "[TG Setup] Please go into your Telegram App and start chatting with the @BotFather\r\n" +echo -e "\r\n$Blue"; +echo -e "==> (Step 1) Enter @Botfather in the search tab and choose this bot" +echo -e "==> Note, official Telegram bots have a blue checkmark beside their name" +echo -e "==> (Step 2) Click “Start” to activate BotFather bot. In response, you receive a list of commands to manage bots" +echo -e "==> (Step 3) Choose or type the /newbot command and send it" +echo -e "==> @BotFather replies: Alright, a new bot. How are we going to call it? Please choose a name for your bot" +echo -e "==> (Step 4) Choose a name for your bot. And choose a username for your bot — the bot can be found by its username in searches. The username must be unique and end with the word 'bot'" +echo -e "==> After you choose a suitable name for your bot — the bot is created. You will receive a message with a link to your bot t.me/" +echo -e "==> Cyphernode needs the generated token to access the API: Copy the line below following the message 'Use this token to access the HTTP API' " +echo -e "\r\n\r\n" while true; do + echo -e "\r\n$Green"; + # 46 characters 1234567890:ABCrWd1mHlWzGM-2ovbxRnOF_g3V2-csY4E # matching '^[0-9]{10}:.{35}$' - read -p "Enter the token here: " -n 46 -r + read -p "[TG Setup] Enter the token here: " -n 46 -r - if [[ $REPLY =~ ^[0-9]{10}:.{35}$ ]]; then + if [[ ${#REPLY} -gt 0 ]] && [[ $REPLY =~ ^[0-9]{10}:.{35}$ ]]; then # Token is good - continue break else - echo "" - echo "Oooops, it doesn't seem to be a valid token." - echo "The token should be a string with this format 1234567890:ABCrWd1mHlWzGM-2ovbxRnOF_g3V2-csY4E." - echo "Please enter the token again - 10 digits:35 characters" + echo -e "$BIRed" + echo -e "[TG Setup] Oooops, it doesn't seem to be a valid token." + echo -e "[TG Setup] The token should be a string with this format 1234567890:ABCrWd1mHlWzGM-2ovbxRnOF_g3V2-csY4E." + echo -e "[TG Setup] Please enter the token again - 10 digits:35 characters" fi done # Now let's ping Telegram while we ask the user to type a message in Telegram -echo "Telegram Setup will now try to obtain the chat ID from the Telgram server." -echo "To make this happen, please go into the Telegram App and send a message to the new bot" -echo "Click on the link in the @BotFather's answer : Congratulations on your new bot. You will find it at t.me/your-new-bot." +echo -e "\r\n$Green"; +echo -e "\r\n[TG Setup] Telegram Setup will now try to obtain the chat ID from the Telgram server.\r\n" + +echo -e "To make this happen, please go into the Telegram App and send a message to the new bot" +echo -e "Click on the link in the @BotFather's answer : Congratulations on your new bot. You will find it at t.me/your-new-bot." # # The server will return something like below after the user sends a message @@ -97,7 +109,7 @@ echo "Click on the link in the @BotFather's answer : Congratulations on your new # while true; do - echo "Trying to contact Telegram server..." + echo -e "Trying to contact Telegram server..." httpStatusCode=$(curl -o /dev/null -s -w '%{http_code}' $TG_BASE_URL$REPLY/getUpdates) if [[ $httpStatusCode == 200 ]]; then @@ -108,13 +120,13 @@ while true; do loop=1 while [ $loop -le 10 ]; do response=$(curl -s $TG_BASE_URL$TG_API_KEY/getUpdates) - isOk=$(echo $response | jq '.ok') + isOk=$(echo -e $response | jq '.ok') if [ "$isOk" = "true" ]; then # get the chat id from the last message - TG_CHAT_ID=$(echo $response | jq '.result[-1].message.chat.id') + TG_CHAT_ID=$(echo -e $response | jq '.result[-1].message.chat.id') if [[ -z $TG_CHAT_ID || "$TG_CHAT_ID" == "null" ]]; then - echo "[$loop] Received positive answer from Telegram without a chat id - Waiting for YOU to send a message in the chat..." + echo -e $Yellow; echo -e "[$loop] [TG Setup] Received positive answer from Telegram without a chat id - Waiting for$IRed YOU$Yellow to send a message in the chat..." sleep 10 loop=$(( $loop + 1 )) else @@ -123,30 +135,32 @@ while true; do sql "INSERT INTO cyphernode_props (category, property, value) VALUES ('notifier', 'tg_chat_id', '$TG_CHAT_ID') \ ON CONFLICT (category, property) DO UPDATE SET value=$TG_CHAT_ID" - echo "" - echo "Reloading configs" + echo -e "$Green" + echo -e "[TG Setup] Reloading configs\r\n" response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"reloadConfig\"}") - echo "" - echo "Sending message to Telegram [$today]" + echo -e "" + echo -e "[TG Setup] Sending message to Telegram [$today]" if [ "${TOR_TELEGRAM}" = "true" ]; then - body=$(echo "{\"text\":\"Hello from Cyphernode [$today] using tor - setup is complete\"}" | base64 | tr -d '\n') + body=$(echo -e "{\"text\":\"Hello from Cyphernode [$today] using tor - setup is complete\"}" | base64 | tr -d '\n') response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\",\"tor\":true}") else - body=$(echo "{\"text\":\"Hello from Cyphernode [$today] using clearnet - setup is complete\"}" | base64 | tr -d '\n') + body=$(echo -e "{\"text\":\"Hello from Cyphernode [$today] using clearnet - setup is complete\"}" | base64 | tr -d '\n') response=$(mosquitto_rr -h broker -W 15 -t notifier -e "response/$$" -m "{\"response-topic\":\"response/$$\",\"cmd\":\"sendToTelegramGroup\",\"body\":\"${body}\"}") fi - echo "Ok. Done." + + echo -e "$BBlue" + echo -e "\r\n[TG Setup] Ok. Done." exit fi else - echo "Server returned an error [$response] - exiting"; exit + echo -e "\r\n[TG Setup] Server returned an error [$response] - exiting"; exit fi done - echo "No message found. Please go into the Telegram App and send a message to the new bot - exiting"; exit + echo -e "\r\n[TG Setup] No message found. Please go into the Telegram App and send a message to the new bot - exiting"; exit else - echo "Server returned a HTTP error code [$httpStatusCode] - exiting"; break + echo -e "\r\n[TG Setup] Server returned a HTTP error code [$httpStatusCode] - exiting"; break fi done