In this article, we will learn how to use the Njalla API from a Python script, so we will be able to automate many administrative tasks.
The first step will be to create an access token from the web interface:
We add a new access:
We indicate the name and restrict access by IP address:
To consult the token, we access the new entry:
Now we can access it from our Python code. In my case, it is a script that will check if there is enough balance to renew services in the next 15 days. Otherwise, it will send a notification via Telegram:
#!/usr/local/bin/python3.8
# https://njal.la/api/
import requests
import time
njalla_tokens = {
"ID1": "TOKEN1",
"ID2": "TOKEN2"
}
def njalla(method, token, **params):
url = 'https://njal.la/api/1/'
#print('token: %s' % token)
headers = {
'Authorization': 'Njalla ' + token
}
response = requests.post(url, json={
'method': method,
'params': params
}, headers=headers).json()
if 'result' not in response:
raise Exception('API Error', response)
return response['result']
for key, value in njalla_tokens.items():
print('')
print('======= Checking account: %s =======' % key)
#print('value: %s' % value)
token = value
domains_raw_data = njalla('list-domains', token)
domains_data = [*domains_raw_data.values()][0]
servers_raw_data = njalla('list-servers', token)
servers_data = [*servers_raw_data.values()][0]
balance = njalla('get-balance', token)['balance']
all_items = domains_data + servers_data
sorted_items = sorted(all_items, key=lambda k: k['expiry'])
print('------ Initial balance: %i -------' % balance)
last_renew = 'NONE'
for item in sorted_items:
print('Name: %s' % item['name'])
print('Expiry: %s' % item['expiry'])
if "id" in item:
cost = 45
else:
cost = 15
print('Cost: %i' % cost)
balance = balance - cost
if balance < 0:
# check if renewal covers 15 days
# 15 days threshold: 1296000s
time_treshold = 1296000
# If first item couldnt be renewed check if it expires in the next 15 days
print('')
if last_renew == 'NONE':
last_renew = item['expiry']
print('')
print('>> Current balance cant covers first pay but it expires: %s' % last_renew)
else:
print('>> Current balance covers to: %s' % last_renew)
last_renew_timestamp = time.strptime(last_renew, "%Y-%m-%dT%H:%M:%SZ")
last_renew_timestamp = time.mktime(last_renew_timestamp)
last_renew_timestamp_human = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(last_renew_timestamp))
current_timestamp = int(time.time())
current_timestamp_human = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(current_timestamp))
#print('current_timestamp: %i -- %s' % (current_timestamp, current_timestamp_human))
#print('last_renew_timestamp: %i -- %s' % (last_renew_timestamp, last_renew_timestamp_human))
margin = last_renew_timestamp - current_timestamp
#print('margin: %i' % margin)
#print('time_treshold: %i' % time_treshold)
if margin < time_treshold:
print('>> SENDING TELEGRAM')
apiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
chatId = "YYYYYY"
url = "https://api.telegram.org/bot{}/sendMessage".format(apiKey)
msg = 'Insufficient Njal.la: ' + key + ' balance to renew 15 day services'
data = {"chat_id":chatId,"text":msg}
r = requests.post(url,json=data)
break
last_renew = item['expiry']
print('------ Balance: %i -------' % balance)
NOTE: As we can see, the prices are hardcoded, which can be problematic if the rates change. Ideally, we should be able to check the price of each service before deducting the balance amount, but I have not found a way to do it.
We assign the necessary permissions to the script:
We run it and we will get an output similar to the following:
In this case, there is no product that expires in the next 15 days and cannot be renewed, so it does not send the notification via Telegram.