|
| 1 | +# Leetcode Daily Question Telegram Bot |
| 2 | + |
| 3 | +> Fetch question of today from Leetcode's GraphQL API and send it to Telegram channel. |
| 4 | +
|
| 5 | +## Development Notes |
| 6 | + |
| 7 | +### Tech Stack |
| 8 | +* Python 3 |
| 9 | +* [Serverless@2.63.0](https://www.npmjs.com/package/serverless) |
| 10 | +* AWS Lambda |
| 11 | +* AWS CloudFormation - Used by Serverless when doing deployment |
| 12 | +* AWS CloudWatch - Automatically Setup by Serverless when doing deployment |
| 13 | +* AWS S3 - Used by Serverless when doing deployment |
| 14 | + |
| 15 | +> **Note:** |
| 16 | +> Both Lambda, CloudWatch, and CloudFormation has free tier provided. However for AWS S3, it has only has free tier for limited time. |
| 17 | +> |
| 18 | +> To check the tier limit, head to [https://aws.amazon.com/free/](https://aws.amazon.com/free/). It is recommended to setup a billing alert by following the documentation on [https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/tracking-free-tier-usage.html](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/tracking-free-tier-usage.html). |
| 19 | +
|
| 20 | +### Development Setup |
| 21 | + |
| 22 | +#### Prerequisites |
| 23 | +* Node.js 14 installed |
| 24 | +* Python 3 installed |
| 25 | +* `virtualenv` installed |
| 26 | + |
| 27 | +#### Prepare `serverless` environment |
| 28 | + |
| 29 | +##### NPM |
| 30 | + |
| 31 | +```bash |
| 32 | +npm install serverless@2.63.0 --global |
| 33 | +npm install |
| 34 | +``` |
| 35 | + |
| 36 | +##### Yarn |
| 37 | + |
| 38 | +```bash |
| 39 | +yarn global add serverless@2.63.0 |
| 40 | +yarn |
| 41 | +``` |
| 42 | + |
| 43 | +#### Setup Python Virtual Environments |
| 44 | + |
| 45 | +```bash |
| 46 | +# Create a new virtual environment |
| 47 | +virtualenv venv --python=python3 |
| 48 | + |
| 49 | +# Activate virtual environment created |
| 50 | +. venv/bin/activate |
| 51 | + |
| 52 | +# Install dependencies listed in requirements.txt |
| 53 | +pip install -r requirements.txt |
| 54 | +``` |
| 55 | + |
| 56 | +#### Setup Bot to send message |
| 57 | + |
| 58 | +Save a copy of `.env` and name it as `.env.local`, place your Telegram bot token and Telegram Chat ID in the configuration file. |
| 59 | + |
| 60 | +> **Note:** |
| 61 | +> Environment variables are used instead of `ConfigParser` provided by Python since [by default AWS Lambda will encrypt environment variables using KMS](https://docs.aws.amazon.com/whitepapers/latest/kms-best-practices/encrypting-lambda-environment-variables.html), and we don't want to store tokens using plain text. |
| 62 | +
|
| 63 | +##### 1. How to get a Telegram bot token |
| 64 | + |
| 65 | +1. In Telegram, search for the user `@BotFather`. |
| 66 | +2. Use the command `\newbot` and choose a name and username for your bot. |
| 67 | +3. `@BotFather` will return you the token of the bot created. Remember to keep it safe! |
| 68 | + |
| 69 | +##### 2. How to get a Telegram chat ID |
| 70 | + |
| 71 | +1. Send a `/start` command to the telegram bot created in the previous step |
| 72 | +2. Visit `https://api.telegram.org/bot<BOT_TOKEN>/getUpdates` |
| 73 | +3. Look at the API response, `result[0]['message']['chat']['id']` should contains ID of the chat. Remember to copy the `-` prefix if exists. |
| 74 | + |
| 75 | +##### 3. Test if Bot token and Chat ID is correct or not |
| 76 | + |
| 77 | +Open Terminal, run the following command. You will need to replace `<BOT_TOKEN>` and `<CHAT_ID>` with the one you get in previous steps. |
| 78 | + |
| 79 | +```bash |
| 80 | +curl -X POST "https://api.telegram.org/bot<BOT_TOKEN>/sendMessage" -d "chat_id=<CHAT_ID>&text=Hello World" |
| 81 | +``` |
| 82 | + |
| 83 | +#### Deployment |
| 84 | + |
| 85 | +##### Create named AWS profile (for first time deployment) |
| 86 | + |
| 87 | +1. Create new user on AWS, with "Programmatic access" |
| 88 | +2. Assign permission to user by "Attaching existing policies directly" |
| 89 | + * In the official Serverless blog, they have introduced [serverless-policy generator](https://github.com/dancrumb/generator-serverless-policy) to help you generate IAM policies. |
| 90 | +3. Configure new AWS credientials to use newly created user |
| 91 | + ```bash |
| 92 | + aws configure --profile <PROFILE_NAME> |
| 93 | + ``` |
| 94 | + |
| 95 | +##### Deploy to Lambda |
| 96 | + |
| 97 | +```bash |
| 98 | +# Load environment variables |
| 99 | +. load-environment-variables.sh |
| 100 | +
|
| 101 | +# Deploy to AWS Lambda using serverless cli |
| 102 | +serverless deploy --aws-profile <PROFILE_NAME> |
| 103 | +``` |
| 104 | + |
| 105 | +#### Settings |
| 106 | + |
| 107 | +##### Add / Edit bot messages |
| 108 | +All messages are stored in `app/messages.txt`, and will be randomly picked when handler is triggered. To update the message sets, simply edit and save the file. Re-deployment is needed for changes to take effect. |
| 109 | + |
| 110 | +##### Add / Edit stickers |
| 111 | +All sticker IDs are stored in `app/stickers.txt`, and will be randomly picked when handler is triggered. To update the sticker sets, you will need to get the sticker ID by sending stickers to the created bot. Visit `https://api.telegram.org/bot<BOT_TOKEN>/getUpdates`, stickers ID can be found in the API reponse node `result[n]['message']['sticker']['file_id']`. Re-deployment is needed for changes to take effect. |
| 112 | + |
| 113 | +##### Edit bot schedule |
| 114 | + |
| 115 | +Open `serverless.yml`, edit `functions['cron']['schedule']`. Syntax reference: [https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-expressions.html](https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-expressions.html) |
| 116 | + |
| 117 | +#### Test |
| 118 | + |
| 119 | +##### Testing the handler |
| 120 | + |
| 121 | +Run the following command inside virtual environment: |
| 122 | +```bash |
| 123 | +# Load environment variables |
| 124 | +. load-environment-variables.sh |
| 125 | +
|
| 126 | +# Execute handler |
| 127 | +serverless invoke local -f cron |
| 128 | +``` |
| 129 | + |
| 130 | +#### Others |
| 131 | + |
| 132 | +##### Delete deployed Lambda function |
| 133 | + |
| 134 | +```bash |
| 135 | +serverless remove --aws-profile <PROFILE_NAME> |
| 136 | +``` |
0 commit comments