bot_messages.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. from flask import current_app
  2. from ownchatbot.db import get_db, is_cool
  3. from ownchatbot.owncast_com import send_chat, send_private_chat
  4. from ownchatbot.reward_handlers import run_script, add_to_queue, add_to_vote, add_to_goal, was_goal_reached, goal_reached, is_reward_active, check_vote, all_active_goals, goal_left, was_milestone_reached, save_alerts
  5. from ownchatbot.user_handlers import spend_points, get_users_points, refund_points, get_all_users_with_user_id
  6. import os
  7. def porps(points): # Pluralize points based on the number of points
  8. if points == 1:
  9. num = 'point'
  10. else:
  11. num = 'points'
  12. return f'{points} {num}'
  13. def mas(time_diff): # Convert time difference decimal number to minutes and seconds
  14. minutes = int(time_diff)
  15. seconds = (time_diff - minutes) * 60
  16. seconds = round(seconds)
  17. if minutes > 1:
  18. mnum = 'minutes'
  19. else:
  20. mnum = 'minute'
  21. if seconds > 1:
  22. snum = 'seconds'
  23. else:
  24. snum = 'second'
  25. if minutes == 0:
  26. return f'{seconds} {snum}'
  27. else:
  28. return f'{minutes} {mnum} and {seconds} {snum}'
  29. def do_reward(message, user_id): # Parse the chat command
  30. db = get_db()
  31. for user in get_all_users_with_user_id(db, user_id):
  32. username = user[1]
  33. prefix = current_app.config['PREFIX']
  34. alerts_dict = current_app.config['ALERTS']
  35. split_message = message[1:].split(maxsplit=1)
  36. reward = split_message[0]
  37. if len(split_message) == 1: # If it's a goal contribution, split the command and the contribution
  38. contribution = None
  39. else:
  40. contribution = split_message[1]
  41. if reward not in current_app.config['REWARDS']: # Check if it's a command or a reward
  42. send_private_chat(user_id, f'{username}, \"{prefix}{reward}\" is not a chat command or a reward. Check your spelling?')
  43. return
  44. if not is_reward_active(reward): # If reward isn't active, say so
  45. send_chat(f'Sorry, {username}. \"{prefix}{reward}\" is not currently an active reward.')
  46. return
  47. reward_type = current_app.config['REWARDS'][reward]['type']
  48. points = get_users_points(db, user_id)
  49. if reward_type == 'goal': # If it's a goal contribution, do the thing
  50. if not contribution:
  51. send_private_chat(user_id, f'{username}, you didn\'t tell me how many points you want to contribute.')
  52. return
  53. if goal_reached(db, reward):
  54. send_private_chat(user_id, f'{username}, we already completed this goal.')
  55. return
  56. if int(contribution) > goal_left(db, reward): # If they're contributing more than they need to
  57. current_app.logger.info(f'{username} contributed more than what was needed to reach the target.')
  58. contribution = goal_left(db, reward) # only spend what is needed to reach the goal.
  59. if int(contribution) > points:
  60. send_private_chat(user_id, f'{username}, you don\'t have that many points.')
  61. elif int(contribution) < 0:
  62. send_private_chat(user_id, f'{username}, you can\'t contribute negative points.')
  63. elif int(contribution) == 0:
  64. send_private_chat(user_id, f'{username}, you can\'t contribute zero points.')
  65. elif add_to_goal(db, user_id, reward, int(contribution)):
  66. send_chat(f'{username} contributed {porps(contribution)} to the \"{prefix}{reward}\" goal.')
  67. wmr = was_milestone_reached(db, reward)
  68. if was_goal_reached(db, reward): # Was a goal reached?
  69. alerts_dict['g_name'] = username
  70. alerts_dict['g_reward'] = reward
  71. save_alerts(alerts_dict)
  72. send_chat(f'\"{prefix}{reward}\" target reached! 🎉')
  73. else: # If goal wasn't reached, was a milestone passed?
  74. if wmr:
  75. alerts_dict['m_name'] = username
  76. alerts_dict['m_reward'] = wmr
  77. save_alerts(alerts_dict)
  78. send_chat(f'{wmr} milestone reached!')
  79. else:
  80. send_private_chat(user_id, f'Couldn\'t contribute to the \"{prefix}{reward}\" goal for {username}, for some highly technical reason.')
  81. return
  82. price = current_app.config['REWARDS'][reward]['price'] # Do they have enough points?
  83. if not points or points < price:
  84. send_private_chat(user_id, f'{username}, you don\'t have enough points for \"{prefix}{reward}\".')
  85. return
  86. if reward_type == 'vote': # If it's a vote, do the thing
  87. if check_vote(db, reward, user_id): # See if viewer already voted
  88. send_private_chat(user_id, f'{username}, you already voted for \"{prefix}{reward}\".')
  89. else:
  90. if add_to_vote(db, reward, user_id) and spend_points(db, user_id, price):
  91. send_chat(f'{username} voted for \"{prefix}{reward}\" for {porps(price)}.')
  92. else:
  93. send_private_chat(user_id, f'Couldn\'t vote for \"{prefix}{reward}\" for {username}, for some highly technical reason.')
  94. elif reward_type == 'redeem': # If it's a redeem, do the thing
  95. if is_cool(reward)[0]: # Is there an active cool down?
  96. if (add_to_queue(db, user_id, reward) and
  97. spend_points(db, user_id, price)):
  98. send_chat(f'{username} redeemed \"{prefix}{reward}\" for {porps(price)}.')
  99. else:
  100. send_private_chat(user_id, f'Couldn\'t redeem \"{prefix}{reward}\"for {username}, for some highly technical reason.')
  101. else:
  102. hot_time = is_cool(reward)[1]
  103. send_chat(f'\"{prefix}{reward}\" has {mas(hot_time)} left to cool down.')
  104. elif reward_type == 'special': # If it's a special, do the thing
  105. if is_cool(reward)[0]: # Is there an active cool down?
  106. script_cmd = current_app.config['REWARDS'][reward]['cmd']
  107. script_ran = run_script(reward, script_cmd)
  108. used_points = spend_points(db, user_id, price)
  109. if (script_ran and used_points):
  110. send_chat(f'{username} redeemed \'{prefix}{reward}\' for {porps(price)}.')
  111. else:
  112. if refund_points(db, user_id, price):
  113. send_private_chat(user_id, f'Couldn\'t redeem \"{prefix}{reward}\"for {username}, for some highly technical reason.')
  114. else:
  115. hot_time = is_cool(reward)[1]
  116. send_chat(f'\"{prefix}{reward}\" has {mas(hot_time)} left to cool down.')
  117. else: # If we can't find the reward, say so
  118. send_private_chat(user_id, f'\"{prefix}{reward}\", {username}? No such reward.')
  119. def help_message(user_id):
  120. prefix = current_app.config['PREFIX']
  121. kofi_settings = current_app.config['KOFI_SETTINGS']
  122. kofi_integration = current_app.config['KOFI_INTEGRATION']
  123. message = f'You get {current_app.config["POINTS_AWARD"]} points for every {current_app.config["POINTS_INTERVAL"]} minutes you\'re in chat.<br> \
  124. You can see your points, the rewards queue, and other helpful information by clicking on the \"Points Rewards\" button.<br><br> \
  125. <b><u>Chat commands:</u></b><br> \
  126. <b>{prefix}help</b> to see this help message.<br> \
  127. <b>{prefix}points</b> to see your points.<br> \
  128. <b>{prefix}rewards</b> to see a list of currently active rewards.'
  129. if kofi_integration:
  130. message = f'{message}<br><br>\
  131. <b><u>Kofi is enabled!</b></u><br>\
  132. Authenticate with Owncast, and enter your email address into the Stream Rewards Info page to get Kofi perks.'
  133. if kofi_settings['donations']:
  134. if kofi_settings["donation_points"] == 1:
  135. d_points_label = 'point'
  136. else:
  137. d_points_label = 'points'
  138. if kofi_settings["sub_points"] == 1:
  139. s_points_label = 'point'
  140. else:
  141. s_points_label = 'points'
  142. message = f'{message}<br>\
  143. You\'ll recieve {kofi_settings["donation_points"]} {d_points_label} for every dollar you donate on Kofi'
  144. if kofi_settings['subs']:
  145. message = f'{message}, and {kofi_settings["sub_points"]} {s_points_label} every month for subscribing to my Kofi page.'
  146. else:
  147. message = f'{message}.'
  148. send_private_chat(user_id, message)
  149. def save_announce(announce_dict): # Write rewards to announce.py
  150. announce_file = os.path.join(current_app.instance_path, 'announce.py')
  151. new_announce = f"ANNOUNCEMENTS = {announce_dict['ANNOUNCEMENTS']} # List of announcements\n\n\
  152. ANNOUNCE_ENABLE = {announce_dict['ANNOUNCE_ENABLE']} # Enable announcements\n\
  153. ANNOUNCE_INTERVAL = {announce_dict['ANNOUNCE_INTERVAL']} # How long, in minutes, between points announcements"
  154. try:
  155. with open(announce_file, 'w') as f:
  156. f.write(new_announce)
  157. f.close()
  158. except Exception as saerror:
  159. current_app.logger.error(f'Couldn\'t save announce.py: {saerror.args[0]}')
  160. return False
  161. current_app.config.from_pyfile('announce.py', silent=True)
  162. return True