Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
Merge pull request #31 from jimmygchen/add-telegram-support
Browse files Browse the repository at this point in the history
added telegram integration
  • Loading branch information
jimmygchen authored Dec 31, 2022
2 parents 55bcb7a + 9511142 commit d8766e9
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 21 deletions.
5 changes: 4 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ BEACON_API_LIST=<beacon_node_api_url>
TWILIO_ACCOUNT_SID=<twilio_account_sid>
TWILIO_AUTH_TOKEN=<twilio_auth_token>
SMS_FROM=<sms_sender_number>
SMS_TO=<sms_recipient_number>
SMS_TO=<sms_recipient_number>
TELEGRAM_BOT_API_URL=https://api.telegram.org/bot
TELEGRAM_BOT_TOKEN=<>
TELEGRAM_CHAT_ID=<>
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Please see additional alert types that are being considered in [issue list](http

## Notification channels

Currently only **SMS** notification is supported - This is the original idea that started this project, to be notified without installing a mobile app and without needing Internet access.
Currently, **SMS** and **Telegram** notifications are supported - This is the original idea that started this project, to be notified without installing a mobile app and without needing Internet access.

However, additional notification channels are being considered and may be implemented depending on demand. See issue list [here](https://github.com/jchen86/staker-notifier/issues?q=is%3Aissue+is%3Aopen+label%3A%22notification+channel%22)

Expand Down Expand Up @@ -58,6 +58,8 @@ However, additional notification channels are being considered and may be implem
| SMS_FROM | 'From' number from step 1. |
| SMS_TO | 'To' number from step 1. |
| BALANCE_REDUCED_NOTIFY_INTERVAL_EPOCHS | Optional. Number of epochs before resending alert. Default: 20. |
| TELEGRAM_BOT_TOKEN | You need to create a new bot in Telegram. |
| TELEGRAM_CHAT_ID | You need to create a new chat and invite the bot to it. |


4. Run one of the following commands:
Expand Down
2 changes: 1 addition & 1 deletion src/alerts/validator-balance-reduced-alert.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const validatorBalanceReducedAlert = (notifier, alertConfig) => {
}

} else {
logger.info(`All ${validators.length} valiators balances are healthy.`)
logger.info(`All ${validators.length} validators balances are healthy.`)
}
}
}
Expand Down
33 changes: 19 additions & 14 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@ import dotenv from 'dotenv';
dotenv.config();

const config = {
beaconAPIs: process.env.BEACON_API_LIST,
sms: {
accountSid: process.env.TWILIO_ACCOUNT_SID,
authToken: process.env.TWILIO_AUTH_TOKEN,
from: process.env.SMS_FROM,
to: process.env.SMS_TO
},
pubkeys: process.env.VALIDATOR_PUBKEYS.split(','),
alerts: {
validatorBalanceReduced: {
minEpochsToTrigger: 3,
notifyIntervalEpochs: process.env.BALANCE_REDUCED_NOTIFY_INTERVAL_EPOCHS || 20
beaconAPIs: process.env.BEACON_API_LIST,
sms: {
accountSid: process.env.TWILIO_ACCOUNT_SID,
authToken: process.env.TWILIO_AUTH_TOKEN,
from: process.env.SMS_FROM,
to: process.env.SMS_TO
},
telegram: {
botURL: process.env.TELEGRAM_BOT_API_URL,
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatID: process.env.TELEGRAM_CHAT_ID
},
pubkeys: process.env.VALIDATOR_PUBKEYS.split(','),
alerts: {
validatorBalanceReduced: {
minEpochsToTrigger: 3,
notifyIntervalEpochs: process.env.BALANCE_REDUCED_NOTIFY_INTERVAL_EPOCHS || 20
}
}
}
}

export { config };
export {config};
16 changes: 12 additions & 4 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import { ValidatorPollingService } from './validator-polling-service.js';
import { SMSNotifier } from './notifiers/index.js';
import { SMSNotifier, TelegramNotifier } from './notifiers/index.js';
import { config } from './config.js';
import { BeaconAPIClient } from './beacon-api-client.js';
import { validatorBalanceReducedAlert, validatorStatusChangedAlert } from './alerts/index.js';
import { logger } from './logger.js';

const smsNotifer = new SMSNotifier(config.sms)
const notifiers = [];
if (config.sms.accountSid) notifiers.push(new SMSNotifier(config.sms));
if (config.telegram.chatID) notifiers.push(new TelegramNotifier(config.telegram));

if (notifiers.length === 0) {
throw new Error('Missing notifier config, check your .env file!');
}
const beaconApiClient = new BeaconAPIClient(config.beaconAPIs);
const validatorPollingService = new ValidatorPollingService(beaconApiClient);

validatorPollingService.addValidators(config.pubkeys);
validatorPollingService.addListener(validatorBalanceReducedAlert(smsNotifer, config.alerts.validatorBalanceReduced));
validatorPollingService.addListener(validatorStatusChangedAlert(smsNotifer));
notifiers.forEach((notifier) => {
validatorPollingService.addListener(validatorBalanceReducedAlert(notifier, config.alerts.validatorBalanceReduced));
validatorPollingService.addListener(validatorStatusChangedAlert(notifier));
});
validatorPollingService.start()
.catch((err) => {
logger.error(`Error polling validators from Beacon API ${config.beaconAPIs}: `, err);
Expand Down
1 change: 1 addition & 0 deletions src/notifiers/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './sms-notifier.js';
export * from './telegram-notifier.js';
19 changes: 19 additions & 0 deletions src/notifiers/telegram-notifier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {logger} from '../logger.js';
import {TelegramBotApiClient} from '../telegram-bot-api-client.js';

class TelegramNotifier {
constructor(config) {
this.chatID = config.chatID;
this.client = new TelegramBotApiClient(config.botURL, config.botToken);
}

notify(message) {
logger.info(`Sending telegram message to chat_id[${this.chatID}] via bot: ${message}`);
this.client.sendMessage(this.chatID, message)
.then(r => logger.info("Message sent to " + this.chatID))
.catch(err => logger.error('Error sending a message', err));
}

}

export {TelegramNotifier};
29 changes: 29 additions & 0 deletions src/telegram-bot-api-client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import axios from 'axios';
import {logger} from './logger.js';

class TelegramBotApiClient {
constructor(botAPI, botToken) {
this.botAPI = botAPI;
this.botToken = botToken;
this.http = axios.create({
baseURL: this.botAPI + this.botToken
})
}

async sendMessage(chatID, message) {
const body = {
chat_id: chatID,
text: message
}

try {
await this.http.post('/sendMessage', body);
} catch (err) {
logger.error(`Request to sendMessage failed with error`, err);
throw err
}
}

}

export {TelegramBotApiClient};

0 comments on commit d8766e9

Please sign in to comment.