This is a Telegram bot implementation for checking the validity of VAT numbers in VIES (VAT Information Exchange System).
You can submit a VAT number that will be checked in VIES. If the number is valid, the bot will tell you exactly that. If the number is not valid, the bot will store the number and check it periodically until it becomes valid. The bot will notify you when that happens.
You can do the same manually here: https://ec.europa.eu/taxation_customs/vies
Code is TypeScript/Node.js that is intended to be deployed on Azure Functions. Database is CosmosDB which is also deployed on Azure (and is accessed through MongoDB APIs). Telegraf is a framework of choice for handling Telegram bot interactions.
- Serverless: I didn't want to pay for the hosting (serverless is basically free for small workloads) and also wanted to try, well, serverless.
- Azure: because I already have an account and have a bit of familiarity with the ecosystem.
- Typescript/Node.js: quick feedback loop for hacking/exploring solutions, can be deployed on Azure.
- CosmosDB / MongoDB: provided by Azure, low effort deployment and usage in the context of Node.js (especially for such a simple use case).
- Telegram: I use it a lot so wanted to explore implementing bots. Simple solution for providing UI and notifications.
- Telegraf: simple intuitive API.
There are 4 functions:
-
TgBotApi: HTTP Trigger that sets up Telegram webhooks and command handlers upon initialization. Webhook invocations will trigger command handlers which then delegate execution to a different HTTP Trigger: HttpApi.
-
HttpApi: HTTP Trigger that can perform various actions with VAT numbers. This function can store VAT numbers in the MongoDB database and validate them against VIES API.
-
TimerTrigger: Timer Trigger that checks all pending VAT numbers once an hour and notifies Telegram users when those numbers become valid. If TimerTrigger encounters unrecoverable error, it will put the VAT number in question into a separate DB collection (
VatRequestErrors
) which you can use to investigate the source of the issue and maybe re-register the VAT number for monitoring after the issue was resolved. -
HttpAdminApi: HTTP Trigger that you can use to manually re-register VAT numbers that encountered unrecoverable errors during validation process.
You can't run this as is.
- Use VS Code with Azure Tools extension.
- Create a Telegram bot. Put it's access token into settings file (see step 6).
- Go to Azure > Databases pane and create new "MongoDB" database (in Azure it's Azure Cosmos DB for MongoDB API). Put the connection string into settings file (see step 6).
- Since Telegram can only invoke webhooks for publicly available URLs, you'll need something like localtunnel or ngrok to setup a proxy that will redirect traffic to your app running on
localhost
. Put the proxy URL into settings file (see step 6). - Go to Azure > Functions pane, click on Local Project's initialize button.
- Go to Run and Debug pane and try to run the project. Follow the steps to connect your project to your Azure Account.
- Modify
local.settings.json
at the root of the repo. It should contain following settings:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsStorage": "YOUR_AUTOGENERATED_AZURE_CONNECTION_STRING",
"MONGODB_CONNECTION_STRING": "YOUR_MONGODB_CONNECTION_STRING",
"TG_BOT_TOKEN": "YOUR_TELEGRAM_BOT_TOKEN",
"TG_BOT_API_URL": "LOCAL_TUNNEL_OR_NGROK_OR_WHATEVER_BASE_URL/api/TgBotApi",
"TG_BOT_API_TOKEN": "", // not required for local deployment
"HTTP_API_URL": "http://localhost:7071/api/HttpApi",
"HTTP_API_TOKEN": "", // not required for local deployment
"VIES_URL": "https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl",
"MAX_PENDING_VAT_NUMBERS_PER_USER": 10,
"VAT_NUMBER_EXPIRATION_DAYS": 90
}
}
- You can now run your functions locally (either through
npm run
or through the VS Code's Run and Debug pane). - You can also deploy your functions to Azure using Azure > Functions pane.
- After you've deployed your functions, you can now update Azure > Functions > {Your Project} > Application Settings to contain the same settings that you added to
local.settings.json
:MONGODB_CONNECTION_STRING
andTG_BOT_TOKEN
will be the same.TG_BOT_API_URL
is the URL of TgBotApi function (withoutcode
param).TG_BOT_API_TOKEN
is the auth code of TgBotApi function.HTTP_API_URL
is the URL of HttpApi function (withoutcode
param).HTTP_API_TOKEN
is the auth code of HttpApi function.- Note that you can retrieve the URL with code by selecting "Copy Function URL" in the context menu of a specific deployed function (e.g.
https://{your-project-name}.azurewebsites.net/api/httpapi?code={http-api-function-auth-code}
). MAX_PENDING_APP_NUMBERS_PER_USER
should be self-explanatory.VAT_NUMBER_EXPIRATION_DAYS
defines a period after which VAT number should stop being monitored (to handle the case when it never becomes valid).
You need to create .env.test
file first so configuration can be initialized properly. You can just duplicate .env.example
in this case.
You can run unit tests with npm run test
.
Tests are written with mocha, chai and sinon.
Tests are located in the Admin Portal repo and are supposed to be executed against the backend running in E2E mode.
E2E mode is just an express server reusing the same handlers that are used in Azure Functions APIs + a little extra helpers.
You need to create .env.e2e
file first so configuration can be initialized properly. You can just duplicate .env.example
in this case.
You can run backend in E2E mode with npm run start:e2e
.
When you register an entity in EU, chances are that you need to be registered in VIES as well. It can take some time during which you'll probably get bored manually entering your VAT number and seeing that it's not yet valid. This bot is aimed to automate VAT number validation for you.
You need to verify that some other entity has a valid VAT number for transactions within EU.
Simple admin portal app that will allow you to resolve errors more conveniently than calling the admin API by hand: https://github.com/megafinz/ViesVatCheckerBotAdminPortal.