Prechádzať zdrojové kódy

Got basic account verification for email working. Needs some polishing.

deadtom 3 týždňov pred
rodič
commit
cc67ede724

+ 2 - 2
TODO.md

@@ -1,2 +1,2 @@
-* Set up email form with code entry. Both fields should be required.
-* Get system messages for some bot messages
+* Add flash to mail input form for success or failure
+* Find some way to refresh the page when switching tabs in mgmt panel

+ 3 - 3
ownchatbot/__init__.py

@@ -1,8 +1,8 @@
 import os
 import logging
-from flask import Flask
+from flask import Flask, g
 from ownchatbot.db import get_db
-from ownchatbot.owncast_com import live_now, award_points, send_chat
+from ownchatbot.owncast_com import live_now, award_points, send_system_chat
 from apscheduler.schedulers.background import BackgroundScheduler
 
 current_index = 0
@@ -49,7 +49,7 @@ def create_app(test_config=None):
         if app.config['ANNOUNCE_ENABLE']:  # If announcements are enabled
             global current_index
             message = announcements[current_index]
-            send_chat(message)
+            send_system_chat(message)
             current_index = (current_index + 1) % len(announcements)
         else:
             app.logger.info(f'Not live, so not sending announcement.')

+ 1 - 1
ownchatbot/bot_messages.py

@@ -45,7 +45,7 @@ def do_reward(message, user_id):  # Parse the chat command
         contribution = split_message[1]
 
     if reward not in current_app.config['REWARDS']:  # Check if it's a command or a reward
-        send_private_chat(userId, f'{username}, \"{prefix}{reward}\" is not a chat command or a reward. Check your spelling?')
+        send_private_chat(user_id, f'{username}, \"{prefix}{reward}\" is not a chat command or a reward. Check your spelling?')
         return
     if not is_reward_active(reward):  # If reward isn't active, say so
         send_chat(f'Sorry, {username}. \"{prefix}{reward}\" is not currently an active reward.')

+ 18 - 1
ownchatbot/owncast_com.py

@@ -70,7 +70,7 @@ def send_chat(message):  # Send message to owncast chat
     return response.json()
 
 
-def send_private_chat(user_id, message):  # Check to see who is connected
+def send_private_chat(user_id, message):
     client_id = get_client_id(user_id)
     owncast_url = current_app.config['OWNCAST_URL']
     access_token = current_app.config['ACCESS_TOKEN']
@@ -86,3 +86,20 @@ def send_private_chat(user_id, message):  # Check to see who is connected
         current_app.logger.error(f'Couldn\'t send {message} to Owncast: {response.status_code}.')
         sys.exit()
     response = response.json()
+
+
+def send_system_chat(message):
+    owncast_url = current_app.config['OWNCAST_URL']
+    access_token = current_app.config['ACCESS_TOKEN']
+    url = f'{owncast_url}/api/integrations/chat/system'
+    auth_bearer = f'Bearer {access_token}'
+    headers = {'Authorization': auth_bearer}
+    try:
+        response = requests.post(url, headers=headers, json={'body': message})
+    except requests.exceptions.RequestException as swerror:
+        current_app.logger.error(f'Couldn\'t send {message} to Owncast: {swerror.args[0]}')
+        sys.exit()
+    if response.status_code != 200:
+        current_app.logger.error(f'Couldn\'t send {message} to Owncast: {response.status_code}.')
+        sys.exit()
+    response = response.json()

+ 4 - 2
ownchatbot/templates/userpanel.html

@@ -45,8 +45,10 @@
                     {% endif %}
                     OwnchatBot recognizes your Kofi account by your email address. In order for OwnchatBot to award your tip points, you must enter the email address associated with your Kofi account here.<br><br>
                     <form method="POST" action="/set_viewer_email">
-                        <label for="new_email">Your Kofi email address:</label>
-                        <input type="text" name="new_email" value="{{ user[4] }}" size="40">
+                        <label for="code">Type !reg_mail into the chat, and enter the code it gives you here:</label>
+                        <input type="number" name="code" size="6" required><br>                        
+                        <label for="new_email">Enter the email address associated with your Kofi account:</label>
+                        <input type="text" name="new_email" value="{{ user[4] }}" size="40" required>
                         <input type="hidden" name="instance" value="{{ instance }}">
                         <input type="hidden" name="user_name" value="{{ username }}">
                         <br>Email addresses are <b>ONLY</b> used for Kofi integration. They are not sent to any other individual or company, and will not be used to create or send mailing lists of any kind.<br>

+ 24 - 0
ownchatbot/user_handlers.py

@@ -15,6 +15,17 @@ def get_users_points(db, user_id):  # Look up one user's points by user id
         current_app.logger.error(f'Couldn\'t look up points for {user_id}: {guperror.args[0]}')
 
 
+def get_email_code(db, user_id):  # Get user's reg_code
+    try:
+        cursor = db.execute(
+            "SELECT code FROM points WHERE id = ?",
+            (user_id,)
+        )
+        return cursor.fetchone()[0]
+    except Error as gecerror:
+        current_app.logger.error(f'Couldn\'t look up points for {user_id}: {gecerror.args[0]}')
+
+
 def get_id_by_email(db, email):  # Look up all users' points by username
     try:
         cursor = db.execute(
@@ -75,6 +86,19 @@ def award_chat_points(db, user_id, points):  # Award points to user by user id
         return False
 
 
+def set_email_code(db, user_id, reg_code):  # Award points to user by user id
+    try:
+        db.execute(
+            "UPDATE points SET code = ? WHERE id = ?",
+            (reg_code, user_id,)
+        )
+        db.commit()
+        return True
+    except Error as secerror:
+        current_app.logger.error(f'Couldn\'t set reg code \"{reg_code}\" for {user_id}: {secerror.args[0]}')
+        return False
+
+
 def adjust_points(db, user_id, points):  # For streamer to manually adjust a user's points
     try:
         db.execute(

+ 10 - 4
ownchatbot/web_panels.py

@@ -1,12 +1,13 @@
-from flask import flash, render_template, Blueprint, current_app, redirect, request, url_for, session
+from flask import flash, render_template, Blueprint, current_app, redirect, request, url_for, session, g
 from datetime import timezone
 from ownchatbot.db import get_db, reread_goals, reread_votes, rem_vote, reset_vote, reset_goal, clear_fulfilled_rewards, clear_reward_queue, rem_cool, rem_from_queue
 from ownchatbot.reward_handlers import all_active_votes, all_active_goals, all_active_rewards, get_queue, fulfill_reward, save_rewards, activate_category, deactivate_category, refund_reward, reread_categories, save_config
-from ownchatbot.user_handlers import get_all_users, get_all_users_by_name, refund_points, adjust_points, change_email
+from ownchatbot.user_handlers import get_all_users, get_all_users_by_name, refund_points, adjust_points, change_email, get_email_code
 from ownchatbot.bot_messages import save_announce
 import json
 import emoji
 from ownchatbot.kofi_handlers import save_kofi_settings, kofi_pngs
+import random
 
 ocb = Blueprint('web_panels', __name__)
 
@@ -382,12 +383,17 @@ def add(reward_type):
 @ocb.route('/set_viewer_email', methods=['GET', 'POST'])
 def set_viewer_email():
     db = get_db()
+    mail_reg_code = int(request.form['code'])
     user_id = request.form['user_id']
+    db_mail_reg_code = get_email_code(db, user_id)
     new_email = request.form['new_email']
     instance = request.form['instance']
     user_name = request.form['user_name']
-    if change_email(db, user_id, new_email):
-        current_app.logger.info(f'Changed {user_id}\'s email to {new_email}')
+    if mail_reg_code == db_mail_reg_code:
+        if change_email(db, user_id, new_email):
+            current_app.logger.info(f'Changed {user_id}\'s email to {new_email}')
+    else:
+        current_app.logger.info(f'The code entered, \"{mail_reg_code}\", does not match \"{db_mail_reg_code}\" found in database.')
     return redirect(url_for('web_panels.user_panel', instance=instance, username=user_name))
 
 

+ 12 - 2
ownchatbot/webhooks.py

@@ -1,11 +1,12 @@
-from flask import Flask, request, json, Blueprint, current_app, render_template, jsonify, request
+from flask import Flask, request, json, Blueprint, current_app, render_template, jsonify, request, g
 from ownchatbot.db import get_db
 from ownchatbot.owncast_com import send_chat, send_private_chat
-from ownchatbot.user_handlers import add_user_to_points, change_name, get_users_points, remove_duplicates
+from ownchatbot.user_handlers import add_user_to_points, change_name, get_users_points, remove_duplicates, get_email_code, set_email_code
 from ownchatbot.bot_messages import do_reward, help_message
 from ownchatbot.reward_handlers import all_active_goals, all_active_votes, all_active_rewards
 from ownchatbot.kofi_handlers import accept_donation
 import json
+import random
 
 
 ocb = Blueprint('webhooks', __name__)
@@ -101,6 +102,15 @@ def chat_hook():
                 send_private_chat(user_id, f'{display_name}, couldn\'t get your points, for some highly technical reason.')
             else:
                 send_private_chat(user_id, f'{display_name}, you have {points} points.')
+            
+        elif lowercase_msg.startswith(f'{prefix}reg_mail'):  # Generate a code to verify users account for email registration
+            mail_reg_code = get_email_code(db, user_id)
+            if mail_reg_code:  # If the viewer already has a code waiting
+                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!')
+            else:  # if not
+                mail_reg_code = random.randint(100000, 999999)
+                if set_email_code(db, user_id, mail_reg_code):
+                    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!')
                 
         elif lowercase_msg.startswith(f'{prefix}rewards'):  # Send rewards list
             if current_app.config['REWARDS']: