webhooks.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. from flask import Flask, request, json, Blueprint, current_app, render_template, jsonify, request, g
  2. from ownchatbot.db import get_db
  3. from ownchatbot.owncast_com import send_chat, send_private_chat
  4. from ownchatbot.user_handlers import add_user_to_points, change_name, get_users_points, remove_duplicates, get_email_code, set_email_code
  5. from ownchatbot.bot_messages import do_reward, help_message
  6. from ownchatbot.reward_handlers import all_active_goals, all_active_votes, all_active_rewards
  7. from ownchatbot.kofi_handlers import accept_donation
  8. import json
  9. import random
  10. ocb = Blueprint('webhooks', __name__)
  11. def format(rawjson): # Make data legible
  12. formatted_data = json.dumps(rawjson, indent=4)
  13. return formatted_data
  14. @ocb.route('/kofiHook', methods=["POST"])
  15. def kofiHook():
  16. current_app.logger.info(f'----------------------------------------------------------------------------')
  17. current_app.logger.info(f'Kofi request')
  18. if request.content_type == 'application/x-www-form-urlencoded':
  19. raw_data = request.form.get('data') # Get the kofi data
  20. if raw_data:
  21. raw_data = json.loads(raw_data)
  22. is_authed = raw_data['verification_token']
  23. if is_authed == current_app.config['KOFI_TOKEN']:
  24. type = raw_data['type']
  25. is_public = raw_data['is_public']
  26. if is_public:
  27. from_name = raw_data['from_name']
  28. new_sub = raw_data['is_first_subscription_payment']
  29. message = raw_data['message']
  30. shop_items = raw_data['shop_items']
  31. name = raw_data['from_name']
  32. email = raw_data['email']
  33. amount = raw_data['amount']
  34. sub_payment = raw_data['is_subscription_payment']
  35. first_sub = raw_data['is_first_subscription_payment']
  36. tier_name = raw_data['tier_name']
  37. if type == 'Shop Order':
  38. current_app.logger.info(f'\n{name} purchased {format(shop_items)}\nMessage: {message}\n')
  39. if type == 'Donation':
  40. donation_info = [is_public, name, email, amount, message]
  41. tip_points = current_app.config['KOFI_SETTINGS']['tip_points']
  42. accept_donation(donation_info, tip_points)
  43. if type == 'Subscription':
  44. if first_sub:
  45. if tier_name:
  46. current_app.logger.info(f'\n{name} <{email}> subscribed as a {tier_name} tier member.')
  47. else:
  48. current_app.logger.info(f'\n{name} <{email}> subscribed.')
  49. else:
  50. if tier_name:
  51. current_app.logger.info(f'\n{name} <{email}> renewed their {tier_name} tier membership.')
  52. else:
  53. current_app.logger.info(f'\n{name} <{email}> renewed their membership.')
  54. return jsonify({'status': 'success'}), 200
  55. else:
  56. current_app.logger.info(f'Token invalid. Rejecting.')
  57. return jsonify({'status': 'unauthorized'}), 401
  58. @ocb.route('/chatHook', methods=['POST'])
  59. def chat_hook():
  60. prefix = current_app.config['PREFIX']
  61. data = request.json
  62. db = get_db()
  63. if data['type'] in ['CHAT', 'NAME_CHANGED', 'USER_JOINED']: # Check if the viewer is in the chatbot database
  64. user_id = data['eventData']['user']['id']
  65. authed = data['eventData']['user']['authenticated']
  66. display_name = data['eventData']['user']['displayName']
  67. if add_user_to_points(db, user_id, display_name, authed):
  68. current_app.logger.debug(f'Added/updated {user_id} database.')
  69. if data['type'] == 'USER_JOINED': # Do username house cleaning when a viewer joins
  70. if data['eventData']['user']['authenticated']:
  71. remove_duplicates(db, user_id, display_name)
  72. elif data['type'] == 'NAME_CHANGE':
  73. user_id = data['eventData']['user']['id']
  74. new_name = data['eventData']['newName']
  75. change_name(db, user_id, new_name)
  76. if data['eventData']['user']['authenticated']:
  77. remove_duplicates(db, user_id, new_name)
  78. elif data['type'] == 'CHAT': # If a chat message, sort out what command it is
  79. user_id = data['eventData']['user']['id']
  80. display_name = data['eventData']['user']['displayName']
  81. current_app.logger.debug(f'Chat message from {display_name}:')
  82. current_app.logger.debug(f'{data["eventData"]["rawBody"]}')
  83. lowercase_msg = data['eventData']['rawBody'].lower() # Convert body to lower case to match reward case
  84. if lowercase_msg.startswith(f'{prefix}help'): # Send the help message
  85. help_message(user_id)
  86. elif lowercase_msg.startswith(f'{prefix}points'): # Get the viewer's current points
  87. points = get_users_points(db, user_id)
  88. if points is None:
  89. send_private_chat(user_id, f'{display_name}, couldn\'t get your points, for some highly technical reason.')
  90. else:
  91. send_private_chat(user_id, f'{display_name}, you have {points} points.')
  92. elif lowercase_msg.startswith(f'{prefix}reg_mail'): # Generate a code to verify users account for email registration
  93. mail_reg_code = get_email_code(db, user_id)
  94. if mail_reg_code: # If the viewer already has a code waiting
  95. send_private_chat(user_id, f'{display_name}, your code is {mail_reg_code}. Enter it into the form, with your email address, to enable Kofi perks!')
  96. else: # if not
  97. mail_reg_code = random.randint(100000, 999999)
  98. if set_email_code(db, user_id, mail_reg_code):
  99. send_private_chat(user_id, f'{display_name}, your code is {mail_reg_code}. Enter it into the form on the , with your email address, to enable Kofi perks!')
  100. elif lowercase_msg.startswith(f'{prefix}rewards'): # Send rewards list
  101. if current_app.config['REWARDS']:
  102. rewards_msg = f'Currently active rewards:'
  103. for reward, details in current_app.config['REWARDS'].items():
  104. if details.get('categories'):
  105. if not (set(details['categories']) & set(current_app.config['ACTIVE_CAT'])): # If there are no common categories, continue
  106. continue
  107. if 'type' in details and details['type'] == 'goal':
  108. rewards_msg = f'{rewards_msg}<br>* {prefix}{reward} goal at {details["target"]} contributed points.'
  109. else:
  110. rewards_msg = f'{rewards_msg}<br>* {prefix}{reward} for {details["price"]} points.'
  111. if 'info' in details:
  112. rewards_msg = f'{rewards_msg}<br>{details["info"]}'
  113. else:
  114. rewards_msg = f'{rewards_msg}'
  115. else:
  116. rewards_msg = 'There are currently no active rewards.'
  117. send_private_chat(user_id, rewards_msg)
  118. elif lowercase_msg.startswith(f'{prefix}'): # Send to handle rewards
  119. do_reward(lowercase_msg, user_id)
  120. return data
  121. @ocb.route('/goals', methods=['GET']) # Route for goals overlay
  122. def goals():
  123. db = get_db()
  124. return render_template('goals.html',
  125. goals=all_active_goals(db),
  126. rewards=all_active_rewards())
  127. @ocb.route('/votes', methods=['GET']) # Route for votes overlay
  128. def votes():
  129. db = get_db()
  130. return render_template('votes.html',
  131. votes=all_active_votes(db))