Mikrotik: update WiFi PSK with randomly generated password and send it in telegram

Recently I upgraded my home WiFi with mikrotik cAP ac, the main reason to do it was an intention to configure guest WiFi with transparent traffic routing via TOR. Since I have intention to share guest password freely, I needed a way to change it from time to time. Firstly I wanted to make a telegram bot which would change wifi password via api call, but later I learned that it may be done with ugly scripting language which device supports.
More than that it has HTTP client, so I can change password by schedule and send it in telegram.

Here is the pre-requisites:
First, you should register the new bot with help of BotFather and get bot token, it looks like 110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw
Second, you need to get your chat id with bot. I got it by sending a message to newly registered bot and fetching an update with curl:

$ curl 'https://api.telegram.org/bot110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw/getUpdates'|jq '.result[].message.chat.id'

(chat id looks like 76615696).

The next thing to do is to create some sort of function to send message to telegram, it may be created with CLI or in WebFig -> System -> Scripts. Name tg_send, policy: read, write, policy, test

:local BotToken "110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw";
:local ChatID "76615696";
:local ParseMode "html";
:local DisableWebPagePreview True;
:local SendText $MessageText;
:local tgUrl "https://api.telegram.org/bot$BotToken/sendMessage?chat_id=$ChatID&text=$SendText&parse_mode=$ParseMode&disable_web_page_preview=$DisableWebPagePreview";
/tool fetch http-method=get url=$tgUrl keep-result=no;

It’s important to replace BotToken and ChatID with your own token and id.

Previous script allows to make notification when password changed, the next one do the trick. Name: change_guest_pw, policy: read, write, policy, test, password.

:local ProfileName guest
:local DeviceName [/system identity get name];
:local PW ([:pick ([/certificate scep-server otp generate minutes-valid=0 as-value]->"password") 0 10])
:interface wireless security-profiles set $ProfileName wpa2-pre-shared-key="$PW";
:local MessageText "\F0\9F\94\91 <b>$DeviceName:</b> new guest pw: <code>$PW</code>";
:local SendTelegramMessage [:parse [/system script get tg_send source]]; 
$SendTelegramMessage MessageText=$MessageText;

Here is important to replace ProfileName with your own security profile which is ‘guest‘ in my case.
After that change_guest_pw can be scheduled to be executed regularly.


One of the first thing which I noticed when I got the new access point was useless hardware button which just switched off all LEDs. It’s possible to use it as a trigger for script execution.
Cli commands:

/system routerboard mode-button
set enabled=yes on-event=change_guest_pw

make it change WiFI password as well or it may be configured in WebFig -> System -> RouterBoard -> Mode Button