Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sendToTelegram in proxy and notifier #232

Open
wants to merge 30 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
21db2fd
Added sendToTelegram in proxy and notifier
phillamy Nov 4, 2021
54d53dc
Removed test keys
phillamy Nov 4, 2021
90ce08a
Added Telegram feature in setup + test on CN start
phillamy Nov 10, 2021
fdcd7ef
undo change
phillamy Nov 10, 2021
4ad3840
undo change
phillamy Nov 10, 2021
9a155b9
removed empty line
phillamy Nov 10, 2021
d3f11d9
move test in tests directory
phillamy Nov 15, 2021
6ce3bd5
Added TG config to setup
phillamy Nov 21, 2021
66b6788
renamed prompter file notifier
phillamy Nov 21, 2021
f2d7fe5
minor fix
phillamy Nov 21, 2021
ff55bd4
added comment + modified trace
phillamy Nov 22, 2021
5ae063c
Merge remote-tracking branch 'upstream/dev' into features/telegram
phillamy Jan 6, 2022
c4dd86b
fix filename conflict after merge
phillamy Jan 6, 2022
b41c840
Removed notifier datapath and added dist/.env
phillamy Jan 8, 2022
29a7551
extra-comma removed
phillamy Jan 8, 2022
1830eed
Merge remote-tracking branch 'upstream/dev' into features/telegram
phillamy Apr 12, 2022
201b498
Added TG config script
phillamy Apr 15, 2022
62d6cf3
Reload configs at the end of TG setup via MQTT
phillamy May 3, 2022
0b17292
moved setup scripts in notifier
phillamy May 3, 2022
fd07ba8
Merge remote-tracking branch 'upstream/dev' into features/telegram
phillamy May 3, 2022
2f0ccbb
moved ssetup in notifier
phillamy May 3, 2022
5e45952
fix a merge fu
phillamy May 3, 2022
fa4bf60
Test TG only once
phillamy May 3, 2022
b94e884
new doc for setting up TG
phillamy May 3, 2022
f414868
Merge branch 'features/telegram' of github.com:phillamy/cyphernode in…
phillamy May 3, 2022
d0799cf
wait loop able creation + readLoop in notifier
phillamy May 4, 2022
d7ae529
Merge remote-tracking branch 'upstream/dev' into features/telegram
phillamy May 12, 2022
f6459a3
tor config
phillamy May 12, 2022
7dffd37
Hooked up TG setup in start.sh
phillamy May 12, 2022
165b0c8
TG setup with a nicer look - added colors
phillamy May 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
.vscode
dist/**
!dist/setup.sh
!dist/sr.sh
!dist/sr.sh
4 changes: 4 additions & 0 deletions cyphernodeconf_docker/features.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@
{
"name": "Specter Cypherapp",
"value": "specter"
},
{
"name": "Telegram notifications",
"value": "telegram"
}
]
1 change: 1 addition & 0 deletions cyphernodeconf_docker/help.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@
"installer_mode": "Only one <font underline='true'>installation mode</font> is supported, right now: <font color='#0000ff'>local docker (self-hosted)</font>. Choose wisely ;-)",
"installer_cleanup": "Do you want to <font underline='true'>remove</font> this configurator Docker image after installation? This would free about 150MB of disk space.",
"docker_mode": "Cyphernode Docker services can be run using <font underline='true'>Docker Swarm</font> (https://docs.docker.com/engine/swarm/) or <font underline='true'>docker-compose</font> (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__": ""
}
7 changes: 7 additions & 0 deletions cyphernodeconf_docker/lib/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,13 @@ module.exports = class App {
clearnet: !this.isChecked('features', 'tor') || this.isChecked('clearnet', 'clearnet_lightning'),
tor_hostname: this.sessionData.tor_lightning_hostname
}
},
telegram: {
networks: ['cyphernodenet'],
docker: "cypernode/notifier",
extra:{
torified: this.torifyables.find(data => data.value === 'tor_telegram').checked,
}
}
}

Expand Down
1 change: 1 addition & 0 deletions cyphernodeconf_docker/prompters/040_tor.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions cyphernodeconf_docker/prompters/300_notifier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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 [];
},
templates: function( props ) {
return [ 'notifier.env' ];
}
};
12 changes: 8 additions & 4 deletions cyphernodeconf_docker/schema/config-v0.2.6.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@
"lightning",
"otsclient",
"batcher",
"specter"
"specter",
"telegram"
],
"title": "The feature",
"default": "",
Expand All @@ -198,7 +199,8 @@
"lightning",
"otsclient",
"batcher",
"specter"
"specter",
"telegram"
]
}
},
Expand All @@ -217,7 +219,8 @@
"tor_otsoperations",
"tor_otswebhooks",
"tor_addrwatcheswebhooks",
"tor_txidwatcheswebhooks"
"tor_txidwatcheswebhooks",
"tor_telegram"
],
"title": "The Torified feature",
"default": "",
Expand All @@ -228,7 +231,8 @@
"tor_otsoperations",
"tor_otswebhooks",
"tor_addrwatcheswebhooks",
"tor_txidwatcheswebhooks"
"tor_txidwatcheswebhooks",
"tor_telegram"
]
}
},
Expand Down
2 changes: 2 additions & 0 deletions cyphernodeconf_docker/templates/installer/config.sh
Original file line number Diff line number Diff line change
@@ -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' %>
Expand All @@ -20,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:'' %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,11 +280,14 @@ services:
- .env/notifier.env
volumes:
- "<%= logs_datapath %>:/cnlogs"
- "<%= proxy_datapath %>/pgpass:/proxy/db/pgpass"
- container_monitor:/container_monitor
networks:
- cyphernodenet
- cyphernodeappsnet
depends_on:
- broker
- postgres
<% if ( docker_mode === 'swarm' ) { %>
deploy:
replicas: 1
Expand Down
6 changes: 6 additions & 0 deletions cyphernodeconf_docker/templates/installer/testdeployment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -83,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"
Expand Down
49 changes: 48 additions & 1 deletion cyphernodeconf_docker/templates/installer/testfeatures.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -121,6 +123,30 @@ checknotifier() {
return 0
}

checknotifiertelegram() {
echo -en "\r\n\e[1;36mTesting Notifier Telegram... " > /dev/console
local response
local returncode
local msg

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" ] && 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" ] && 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

return 0
}

checkots() {
echo -en "\r\n\e[1;36mTesting OTSclient... " > /dev/console
local rc
Expand Down Expand Up @@ -289,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 #
Expand All @@ -306,7 +333,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...
Expand Down Expand Up @@ -405,6 +432,25 @@ 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
checknotifiertelegram
returncode=$?
# Non critical error - run telegram setup at the end
[ "${returncode}" -ne "0" ] && RUN_TELEGRAM_SETUP=1 && returncode=0
else
returncode=1
fi
finalreturncode=$((${returncode} | ${finalreturncode}))
result="${result}$(feature_status ${returncode} 'Notifier Telegram error! - Please run Telegram setup - See doc/TELEGRAM.md')}"
<% } %>

#############################
# PYCOIN #
#############################
Expand Down Expand Up @@ -500,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
Expand Down
9 changes: 9 additions & 0 deletions cyphernodeconf_docker/templates/notifier/notifier.env
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@ TRACING=1
TOR_HOST=tor
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
4 changes: 4 additions & 0 deletions cyphernodeconf_docker/torifyables.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,9 @@
{
"name": "TXID Watches Callbacks (webhooks)",
"value": "tor_txidwatcheswebhooks"
},
{
"name": "Telegram",
"value": "tor_telegram"
}
]
10 changes: 9 additions & 1 deletion dist/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +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


if [[ $BITCOIN_INTERNAL == true ]]; then
if [ ! -d $BITCOIN_DATAPATH ]; then
step " create $BITCOIN_DATAPATH"
Expand Down Expand Up @@ -856,6 +855,15 @@ 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 doc/TELEGRAM.md"
next
else
step " disabled Telegram"
next
fi

}

install() {
Expand Down
91 changes: 91 additions & 0 deletions doc/TELEGRAM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Telegram integration in Cyphernode.

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]

Build and setup Cyphernode - Choose to enable Telegram.

==> 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:

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] 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/<bot_username>

==> 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-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...

Reloading configs

Sending message to Telegram [Tue May 3 16:29:03 UTC 2022]
Ok. Done.



===============================================================
How it works :

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"}'
Loading