242 lines
9.1 KiB
Python
242 lines
9.1 KiB
Python
# See readme.md for instructions on running this code.
|
|
|
|
from typing import Any, Dict, List
|
|
|
|
import requests
|
|
|
|
from zulip_bots.lib import BotHandler
|
|
|
|
|
|
class BaremetricsHandler:
|
|
def initialize(self, bot_handler: BotHandler) -> None:
|
|
self.config_info = bot_handler.get_config_info('baremetrics')
|
|
self.api_key = self.config_info['api_key']
|
|
|
|
self.auth_header = {
|
|
'Authorization': 'Bearer ' + self.api_key
|
|
}
|
|
|
|
self.commands = ['help',
|
|
'list-commands',
|
|
'account-info',
|
|
'list-sources',
|
|
'list-plans <source_id>',
|
|
'list-customers <source_id>',
|
|
'list-subscriptions <source_id>',
|
|
'create-plan <source_id> <oid> <name> <currency> <amount> <interval> <interval_count>']
|
|
|
|
self.descriptions = ['Display bot info', 'Display the list of available commands', 'Display the account info',
|
|
'List the sources', 'List the plans for the source', 'List the customers in the source',
|
|
'List the subscriptions in the source', 'Create a plan in the given source']
|
|
|
|
self.check_api_key(bot_handler)
|
|
|
|
def check_api_key(self, bot_handler: BotHandler) -> None:
|
|
url = "https://api.baremetrics.com/v1/account"
|
|
test_query_response = requests.get(url, headers=self.auth_header)
|
|
test_query_data = test_query_response.json()
|
|
|
|
try:
|
|
if test_query_data['error'] == "Unauthorized. Token not found (001)":
|
|
bot_handler.quit('API Key not valid. Please see doc.md to find out how to get it.')
|
|
except KeyError:
|
|
pass
|
|
|
|
def usage(self) -> str:
|
|
return '''
|
|
This bot gives updates about customer behavior, financial performance, and analytics
|
|
for an organization using the Baremetrics Api.\n
|
|
Enter `list-commands` to show the list of available commands.
|
|
Version 1.0
|
|
'''
|
|
|
|
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
|
content = message['content'].strip().split()
|
|
|
|
if content == []:
|
|
bot_handler.send_reply(message, 'No Command Specified')
|
|
return
|
|
|
|
content[0] = content[0].lower()
|
|
|
|
if content == ['help']:
|
|
bot_handler.send_reply(message, self.usage())
|
|
return
|
|
|
|
if content == ['list-commands']:
|
|
response = '**Available Commands:** \n'
|
|
for command, description in zip(self.commands, self.descriptions):
|
|
response += ' - {} : {}\n'.format(command, description)
|
|
|
|
bot_handler.send_reply(message, response)
|
|
return
|
|
|
|
response = self.generate_response(content)
|
|
bot_handler.send_reply(message, response)
|
|
|
|
def generate_response(self, commands: List[str]) -> str:
|
|
try:
|
|
instruction = commands[0]
|
|
|
|
if instruction == 'account-info':
|
|
return self.get_account_info()
|
|
|
|
if instruction == 'list-sources':
|
|
return self.get_sources()
|
|
|
|
try:
|
|
if instruction == 'list-plans':
|
|
return self.get_plans(commands[1])
|
|
|
|
if instruction == 'list-customers':
|
|
return self.get_customers(commands[1])
|
|
|
|
if instruction == 'list-subscriptions':
|
|
return self.get_subscriptions(commands[1])
|
|
|
|
if instruction == 'create-plan':
|
|
if len(commands) == 8:
|
|
return self.create_plan(commands[1:])
|
|
else:
|
|
return 'Invalid number of arguments.'
|
|
|
|
except IndexError:
|
|
return 'Missing Params.'
|
|
except KeyError:
|
|
return 'Invalid Response From API.'
|
|
|
|
return 'Invalid Command.'
|
|
|
|
def get_account_info(self) -> str:
|
|
url = "https://api.baremetrics.com/v1/account"
|
|
account_response = requests.get(url, headers=self.auth_header)
|
|
|
|
account_data = account_response.json()
|
|
account_data = account_data['account']
|
|
|
|
template = ['**Your account information:**',
|
|
'Id: {id}',
|
|
'Company: {company}',
|
|
'Default Currency: {currency}']
|
|
|
|
return "\n".join(template).format(currency=account_data['default_currency']['name'],
|
|
**account_data)
|
|
|
|
def get_sources(self) -> str:
|
|
url = 'https://api.baremetrics.com/v1/sources'
|
|
sources_response = requests.get(url, headers=self.auth_header)
|
|
|
|
sources_data = sources_response.json()
|
|
sources_data = sources_data['sources']
|
|
|
|
response = '**Listing sources:** \n'
|
|
for index, source in enumerate(sources_data):
|
|
response += ('{_count}.ID: {id}\n'
|
|
'Provider: {provider}\n'
|
|
'Provider ID: {provider_id}\n\n').format(_count=index + 1, **source)
|
|
|
|
return response
|
|
|
|
def get_plans(self, source_id: str) -> str:
|
|
url = 'https://api.baremetrics.com/v1/{}/plans'.format(source_id)
|
|
plans_response = requests.get(url, headers=self.auth_header)
|
|
|
|
plans_data = plans_response.json()
|
|
plans_data = plans_data['plans']
|
|
|
|
template = '\n'.join(['{_count}.Name: {name}',
|
|
'Active: {active}',
|
|
'Interval: {interval}',
|
|
'Interval Count: {interval_count}',
|
|
'Amounts:'])
|
|
response = ['**Listing plans:**']
|
|
for index, plan in enumerate(plans_data):
|
|
response += (
|
|
[template.format(_count=index + 1, **plan)]
|
|
+ [
|
|
' - {amount} {currency}'.format(**amount)
|
|
for amount in plan['amounts']
|
|
]
|
|
+ ['']
|
|
)
|
|
|
|
return '\n'.join(response)
|
|
|
|
def get_customers(self, source_id: str) -> str:
|
|
url = 'https://api.baremetrics.com/v1/{}/customers'.format(source_id)
|
|
customers_response = requests.get(url, headers=self.auth_header)
|
|
|
|
customers_data = customers_response.json()
|
|
customers_data = customers_data['customers']
|
|
|
|
# FIXME BUG here? mismatch of name and display name?
|
|
template = '\n'.join(['{_count}.Name: {display_name}',
|
|
'Display Name: {name}',
|
|
'OID: {oid}',
|
|
'Active: {is_active}',
|
|
'Email: {email}',
|
|
'Notes: {notes}',
|
|
'Current Plans:'])
|
|
response = ['**Listing customers:**']
|
|
for index, customer in enumerate(customers_data):
|
|
response += (
|
|
[template.format(_count=index + 1, **customer)]
|
|
+ [' - {name}'.format(**plan) for plan in customer['current_plans']]
|
|
+ ['']
|
|
)
|
|
|
|
return '\n'.join(response)
|
|
|
|
def get_subscriptions(self, source_id: str) -> str:
|
|
url = 'https://api.baremetrics.com/v1/{}/subscriptions'.format(source_id)
|
|
subscriptions_response = requests.get(url, headers=self.auth_header)
|
|
|
|
subscriptions_data = subscriptions_response.json()
|
|
subscriptions_data = subscriptions_data['subscriptions']
|
|
|
|
template = '\n'.join(['{_count}.Customer Name: {name}',
|
|
'Customer Display Name: {display_name}',
|
|
'Customer OID: {oid}',
|
|
'Customer Email: {email}',
|
|
'Active: {_active}',
|
|
'Plan Name: {_plan_name}',
|
|
'Plan Amounts:'])
|
|
response = ['**Listing subscriptions:**']
|
|
for index, subscription in enumerate(subscriptions_data):
|
|
response += (
|
|
[
|
|
template.format(
|
|
_count=index + 1,
|
|
_active=subscription['active'],
|
|
_plan_name=subscription['plan']['name'],
|
|
**subscription['customer']
|
|
)
|
|
]
|
|
+ [
|
|
' - {amount} {symbol}'.format(**amount)
|
|
for amount in subscription['plan']['amounts']
|
|
]
|
|
+ ['']
|
|
)
|
|
|
|
return '\n'.join(response)
|
|
|
|
def create_plan(self, parameters: List[str]) -> str:
|
|
data_header = {
|
|
'oid': parameters[1],
|
|
'name': parameters[2],
|
|
'currency': parameters[3],
|
|
'amount': int(parameters[4]),
|
|
'interval': parameters[5],
|
|
'interval_count': int(parameters[6])
|
|
} # type: Any
|
|
|
|
url = 'https://api.baremetrics.com/v1/{}/plans'.format(parameters[0])
|
|
create_plan_response = requests.post(url, data=data_header, headers=self.auth_header)
|
|
if 'error' not in create_plan_response.json():
|
|
return 'Plan Created.'
|
|
else:
|
|
return 'Invalid Arguments Error.'
|
|
|
|
handler_class = BaremetricsHandler
|