From bbb51c52f66c2450726f8df2c2b76f026b570915 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sat, 7 Feb 2026 14:25:34 +0000 Subject: [PATCH] ai --- ai/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 404 bytes ai/__pycache__/local_ai_api.cpython-311.pyc | Bin 0 -> 19874 bytes config/__pycache__/__init__.cpython-311.pyc | Bin 159 -> 159 bytes config/__pycache__/settings.cpython-311.pyc | Bin 5552 -> 5552 bytes config/__pycache__/urls.cpython-311.pyc | Bin 1557 -> 1557 bytes config/__pycache__/wsgi.cpython-311.pyc | Bin 679 -> 679 bytes core/__pycache__/__init__.cpython-311.pyc | Bin 157 -> 157 bytes core/__pycache__/admin.cpython-311.pyc | Bin 212 -> 1082 bytes core/__pycache__/apps.cpython-311.pyc | Bin 524 -> 524 bytes .../context_processors.cpython-311.pyc | Bin 763 -> 763 bytes core/__pycache__/models.cpython-311.pyc | Bin 209 -> 1775 bytes core/__pycache__/urls.cpython-311.pyc | Bin 347 -> 566 bytes core/__pycache__/views.cpython-311.pyc | Bin 1364 -> 6279 bytes core/admin.py | 10 +- core/migrations/0001_initial.py | 33 +++ .../__pycache__/0001_initial.cpython-311.pyc | Bin 0 -> 1686 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 168 -> 168 bytes core/models.py | 17 +- core/templates/base.html | 118 ++++++++-- core/templates/core/index.html | 202 ++++++------------ core/templates/core/settings.html | 51 +++++ core/urls.py | 9 +- core/views.py | 130 +++++++++-- 23 files changed, 383 insertions(+), 187 deletions(-) create mode 100644 ai/__pycache__/__init__.cpython-311.pyc create mode 100644 ai/__pycache__/local_ai_api.cpython-311.pyc create mode 100644 core/migrations/0001_initial.py create mode 100644 core/migrations/__pycache__/0001_initial.cpython-311.pyc create mode 100644 core/templates/core/settings.html diff --git a/ai/__pycache__/__init__.cpython-311.pyc b/ai/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c285baa918435f9f161ff0636856cc4948d1b6f GIT binary patch literal 404 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 literal 0 HcmV?d00001 diff --git a/config/__pycache__/__init__.cpython-311.pyc b/config/__pycache__/__init__.cpython-311.pyc index 423a6362b2322713e75da67a35e209e76169dbae..7f03f119d2689efa8818c7c34f2d8ac46b272051 100644 GIT binary patch delta 19 ZcmbQwIG>SwIWI340}vQ^wol}q0stuy1V;b> delta 19 ZcmbQwIG>SwIWI340}xbw%b&y+NCMIWI340}vQ^wr}KKDhdELeFXym delta 20 acmdm>y+NCMIWI340}xbw%iqYoR1^R_83p11 diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 0b85e94ece283a83ff1af1d71f1b265c943eb37a..fabf89a7a94d2ac76e117850e6fe75ab836de403 100644 GIT binary patch delta 20 acmbQrGnI#XIWI340}vQ^wr}L-Vgmpy+5_bP delta 20 acmbQrGnI#XIWI340}xbw%iqY&#RdQ}b_B!# diff --git a/config/__pycache__/wsgi.cpython-311.pyc b/config/__pycache__/wsgi.cpython-311.pyc index 9c49e09df194d2dbcad4868349c9177db4b15571..2793f32d5da41a197f346777285aee841a999821 100644 GIT binary patch delta 20 acmZ3^x}24JIWI340}vQ^wr}K~!vp{?ssxDu delta 20 acmZ3^x}24JIWI340}xbw%iqX7hY0{RMg?d9 diff --git a/core/__pycache__/__init__.cpython-311.pyc b/core/__pycache__/__init__.cpython-311.pyc index 74b111269bd81aac528770a53e2f849291524d56..b6deebb5b3e130a7274bd89fa0c71dbe9bc5e9da 100644 GIT binary patch delta 19 ZcmbQsIG2%oIWI340}vQ^wol}q1OO<<1VI1* delta 19 ZcmbQsIG2%oIWI340}xbw%b&>mG1t0(b diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index a5ed392d6714413db63120e4233d2e96cbadb5de..13193bca0136a6493667a6b7780a76dd50a1d803 100644 GIT binary patch literal 1082 zcma)4J8#rL5Z+z;Ub(v@
    QL`W3if*ceG3WNj=LL}Fu!j0wJE{B63$L<=q?utl= zE?xdX5X#R$qE4hMqOBrPrMoDpQZZx4QC7Y`Nkm;r31{32S!B6ZWV<#cj0n0`DmDsh3%Iu7%?BfI2)EY>FF{tp zO13P>fj1vp@YyaL;#Mv(+Sf3afwA)6j8$G;Ax`Z8|KU(m@_7`*2Uw%SO#OADSA^C< z+*78qER^zlqI*^j7=@Ul8E`g2n;fkQ~-nz)dYsp5N8M7h#%e zptOj*zD%ON?l`uodS2{D!t>08=S2xmL$n*7_c`^$(?}x>l=gU_`k_DgMUJqnlSl23 zNhI3oY8vabExw6vsuS7%n#fP8?{`JJn@G{lL@xFRvI=`Lu)$C*fZ^HPZ#^3>;gmOu ztm~!Ug79VOuFWlwZ=1$x*K+ALXcaLR(u>n*RY)@t)p?Db;nLpBeUTsM zOSu5M@%pIW0Aq_%x<~HqTzvM(!=3A%eL6LqU0>L!@6!1ZogXtwpO48^*hojW9~@%f u7~#+&?Cx29nXu`MrLs%sMs#k>7=1D(S7GDnsCEAk1IGx+a_4G(*1dn|xBdPA literal 212 zcmZ3^%ge<81k-=yXW9el#~=<2FhLogg@BCd3@HpLj5!Rsj8Tk?3@J>(44TX@K?*b( zZ?Pt(n;80F)6nZ2$lO diff --git a/core/__pycache__/apps.cpython-311.pyc b/core/__pycache__/apps.cpython-311.pyc index 6f131d4873bc56e3763e4ed09960c6e3f34140e1..560452bcdde51b77d7e16113cae47a7361378bcd 100644 GIT binary patch delta 20 ZcmeBS>0#ks&dbZi00ah}?HjonnE)zI1GWGF delta 20 acmeBS>0#ks&dbZi00dRv@;7obG64WD>I9Vl diff --git a/core/__pycache__/context_processors.cpython-311.pyc b/core/__pycache__/context_processors.cpython-311.pyc index 75bf2234fb21a6b62efc5cec11af9512dd0c9616..42aed2437601008b904b633de37aecfc111eed49 100644 GIT binary patch delta 20 acmey(`kR$|IWI340}vQ^wr}MAzytt1$_0f0 delta 20 acmey(`kR$|IWI340}xbw%iqZTfe8RYW(H&c diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index e061640edbdcec3e5c1744466c916e7acdd2763b..fccbac6515a2927234b9b6f3bcff9e6a9e22425e 100644 GIT binary patch literal 1775 zcmbVM&ube;6rPn$JF;c(4|QfX zu}vs~2HHapIurs8x%A*V*a!b9E7*hBYfrv8I457)H@lJ&$4(C&?R@)Y=grLb=6z3p zWwU7n?YpI4T7O0m`dbW!EjBRDe*oht(vdD1$du}mgd*r`q(`10JxZi)SQoZ~C_+cj z!&Z+5UNU&a{=-Yw;}1|daVi#-B|mQ3Ix$#duu1Te2ZQs+U_3L(BN0TR+rv2^ zcN{s8fB^Kc)nkE2d^pylS3DAdM{?vL>#^hb0R(h33aXyc6Hib*ttWwI${)LD^9O|U zmbJVlS*#&morqxF_-C=F5 zL8=X#l4_WfN_)>wV9Yqhct8KfJyZrC#XYk30XnEZUOSYJ-*d-ngC|)#7o1niV}252 zOEU?^ei~!g+A)Nk!T3ivKpeuF0G-jVUnq4Ky+XL?0)9ui-*j;`>mT_>*d$H{90%EOqODI&d^l| zDTvb>&_`{k;PXG=)BjiZ0jxe6ZCVeN{f72I{qkGNP6p~v4Htn&?5zq)>v7Qjn4SQQ zCH=$-VNBa3r?+8AS)yX)ItW;{9K-Nq8-`}>fY>q`Xb4;OBdqEAB{7Ro12Ip7ah;e! z+#~TnL(k<<+Ob8*y1Fl`8du@CEF+dqD7GAPgHS)kTPA^$Gut!^+lImpGc8iTKR#eR zRH+aG`xro|biT{I56bTNJUoZ|_@~fvlk-8cR?8Wh15cV4P!J&KQ&Ed_N`O#16mWPi zxMlfcL)&(^pIy*6SqFNdPK#oN;6y(X@LG|RVklq?I@<%ds>qXwTbS(?X1&5J2y)_P z_l7rdvo}%nCW@VJ`njp@w3nMYlus7iT&zj{5XBqYK2di=HdoAEN3d-V>FAg+G_6mFiC literal 209 zcmZ3^%ge<81k-=yXIcX3#~=<2FhLogg@BCd3@HpLj5!Rsj8Tk?3@J>(44TX@K?*b( zZ?Wa(r=;c-`)M-W;!Md(%uCPLOGzqX21>4E_zY6>OHV%|KQ~psG^sSNq*On(A~m_R zB)>?%JijQrxF9h(RX;huC{-U~j9x+IFAf_ZyEG@&u80Guoe_wOWr4&8W=2NF8w@fR Ku%RM0pb7xLi8T)Z diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 5a69659f6c6e0ae848e54157af197c543a09315f..0506fe0c989bfa7f8da54d3a6c9b755574b39254 100644 GIT binary patch literal 566 zcmZuty-xx$6mPj6cLx#?6BpSDiQy7gj1vqlF2)51a?pm)`$+H3LtNM-#uzsloHa%V z|CA$PAYGlyYNb9hUrypLry*4o zoV)<}otYrzAw!PgHD_>b$k#0rxC}74Wnt12VaqT{Uvr7)wXBA#Gc|(!y@1r3w%yT# zrs27Uy5Cw+*Xd7kt`vshEh02C0~YiZ5cR=*g-m&y-CrOY#ifokytU zzJmp)g5{Ckv`wP>HQ(}lo%BfE_iU;MHto2MQ73xcraa6`6`Y%;dScqx?~+rR;mKl1 z_m&@X2|_pp*>GE@U_ac}c^t^vpft=3FCVT(L5Ol=l$)U36sg>M_(UcL`L9HXieprq ipyJ9MYS|HaF~j3hh{|JBo}ltvLA$X*QY@P0^?v{#wU^rf delta 247 zcmdnSa+^tgIWI340}xbw%g@XL(vLwL7+{4mKHE%GS4~S{UBkAFnSo(75JNyZV-!mY zdoY70$4iiaCgUxZg2a-HmyA$OMt*MUErueHF(A3T#N1RrP1al7DOrhm>G^u4MLESq zAj594mSv`v7lRc}j$!nT;R6bS3@P>k5+9fu85wUd$Xq~04;aKRprQ|K46K|DE*(N0 eAv4%6u*hFzk-x$s|ACo_pQ(Wx1dDip#sL5#ayj(? diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 2a36fd69370b38a98d8b01bf8eb9817c42f16ed6..24fe1b75f0e23f17ef197202551898763f7f7db5 100644 GIT binary patch literal 6279 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 L3} - - - {% block title %}Knowledge Base{% endblock %} - {% if project_description %} - - - - {% endif %} - {% if project_image_url %} - - - {% endif %} - {% load static %} - - {% block head %}{% endblock %} + + + {% block title %}WhatsApp AI Bot{% endblock %} + + + + + + + + + {% block extra_css %}{% endblock %} - - {% block content %}{% endblock %} - + - +
    + {% block content %}{% endblock %} +
    + + + {% block extra_js %}{% endblock %} + + \ No newline at end of file diff --git a/core/templates/core/index.html b/core/templates/core/index.html index faec813..8f4ecb8 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,145 +1,65 @@ -{% extends "base.html" %} +{% extends 'base.html' %} -{% block title %}{{ project_name }}{% endblock %} - -{% block head %} - - - - -{% endblock %} +{% block title %}Dashboard - WhatsApp AI Bot{% endblock %} {% block content %} -
    -
    -

    Analyzing your requirements and generating your app…

    -
    - Loading… +
    +
    +

    Live Chat Monitor

    +

    Real-time view of incoming and AI-generated messages.

    -

    AppWizzy AI is collecting your requirements and applying the first changes.

    -

    This page will refresh automatically as the plan is implemented.

    -

    - Runtime: Django {{ django_version }} · Python {{ python_version }} - — UTC {{ current_time|date:"Y-m-d H:i:s" }} -

    -
    -
    -
    - Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC) -
    -{% endblock %} \ No newline at end of file +
    +
    + Bot Status: + {% if settings.is_active %} + Active + {% else %} + Paused + {% endif %} +
    +
    + + +
    +
    + + + + + + + + + + + {% for msg in messages %} + + + + + + + {% empty %} + + + + {% endfor %} + +
    SenderMessage InAI ResponseTime
    + {{ msg.sender_number }} + {{ msg.message_in }} + {% if msg.message_out %} +
    + {{ msg.message_out }} +
    + {% else %} + Processing... + {% endif %} +
    + {{ msg.timestamp|date:"M d, H:i:s" }} +
    + No messages received yet. Send a message to your WhatsApp number to see it here. +
    +
    +
    +{% endblock %} diff --git a/core/templates/core/settings.html b/core/templates/core/settings.html new file mode 100644 index 0000000..568554a --- /dev/null +++ b/core/templates/core/settings.html @@ -0,0 +1,51 @@ +{% extends 'base.html' %} + +{% block title %}Bot Settings - WhatsApp AI Bot{% endblock %} + +{% block content %} +
    +
    +
    +

    AI Bot Personality

    +
    + {% csrf_token %} +
    + + +
    + This instruction defines the bot's tone, personality, and knowledge limits. +
    +
    + +
    + + +
    + Use this token when setting up the webhook in the Meta Developer Portal. +
    +
    + +
    + + +
    + +
    + +
    + Back to Dashboard + +
    +
    +
    + +
    +
    Setup Tip
    +

    + Your Meta Webhook URL: https://your-domain.com/webhook/whatsapp/
    + Verification Token: {{ settings.verify_token }} +

    +
    +
    +
    +{% endblock %} diff --git a/core/urls.py b/core/urls.py index 6299e3d..4ebe1dd 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,7 +1,8 @@ from django.urls import path - -from .views import home +from . import views urlpatterns = [ - path("", home, name="home"), -] + path('', views.index, name='index'), + path('settings/', views.settings_view, name='settings'), + path('webhook/whatsapp/', views.webhook, name='whatsapp_webhook'), +] \ No newline at end of file diff --git a/core/views.py b/core/views.py index c9aed12..a307687 100644 --- a/core/views.py +++ b/core/views.py @@ -1,25 +1,113 @@ -import os -import platform +import json +import logging +from django.shortcuts import render, redirect +from django.http import HttpResponse, JsonResponse +from django.views.decorators.csrf import csrf_exempt +from .models import Message, BotSettings +from ai.local_ai_api import LocalAIApi -from django import get_version as django_version -from django.shortcuts import render -from django.utils import timezone - - -def home(request): - """Render the landing screen with loader and environment details.""" - host_name = request.get_host().lower() - agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" - now = timezone.now() +logger = logging.getLogger(__name__) +def index(request): + messages = Message.objects.all().order_by('-timestamp')[:50] + settings = BotSettings.objects.first() + if not settings: + settings = BotSettings.objects.create() + context = { - "project_name": "New Style", - "agent_brand": agent_brand, - "django_version": django_version(), - "python_version": platform.python_version(), - "current_time": now, - "host_name": host_name, - "project_description": os.getenv("PROJECT_DESCRIPTION", ""), - "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), + 'messages': messages, + 'settings': settings, } - return render(request, "core/index.html", context) + return render(request, 'core/index.html', context) + +def settings_view(request): + settings = BotSettings.objects.first() + if not settings: + settings = BotSettings.objects.create() + + if request.method == 'POST': + settings.system_prompt = request.POST.get('system_prompt', settings.system_prompt) + settings.is_active = 'is_active' in request.POST + settings.verify_token = request.POST.get('verify_token', settings.verify_token) + settings.save() + return redirect('index') + + return render(request, 'core/settings.html', {'settings': settings}) + +@csrf_exempt +def webhook(request): + if request.method == 'GET': + # Meta Webhook verification + mode = request.GET.get('hub.mode') + token = request.GET.get('hub.verify_token') + challenge = request.GET.get('hub.challenge') + + settings = BotSettings.objects.first() + verify_token = settings.verify_token if settings else "my_secure_token_123" + + if mode and token: + if mode == 'subscribe' and token == verify_token: + logger.info("WEBHOOK_VERIFIED") + return HttpResponse(challenge) + else: + return HttpResponse('Verification failed', status=403) + return HttpResponse('Verification failed', status=403) + + elif request.method == 'POST': + try: + data = json.loads(request.body.decode('utf-8')) + logger.info(f"Incoming WhatsApp data: {json.dumps(data)}") + + # Check if it's a message from WhatsApp + if 'object' in data and data['object'] == 'whatsapp_business_account': + for entry in data['entry']: + for change in entry['changes']: + value = change['value'] + if 'messages' in value: + for msg in value['messages']: + sender_number = msg['from'] + message_body = msg.get('text', {}).get('body', '') + + if message_body: + process_whatsapp_message(sender_number, message_body) + + return JsonResponse({'status': 'ok'}) + except Exception as e: + logger.error(f"Error processing webhook: {str(e)}") + return JsonResponse({'status': 'error', 'message': str(e)}, status=500) + +def process_whatsapp_message(sender_number, message_body): + settings = BotSettings.objects.first() + if not settings or not settings.is_active: + return + + # Store incoming message + db_msg = Message.objects.create( + sender_number=sender_number, + message_in=message_body + ) + + # Call Gemini via AI Proxy + prompt_input = [ + {"role": "system", "content": settings.system_prompt}, + {"role": "user", "content": message_body}, + ] + + try: + response = LocalAIApi.create_response({ + "input": prompt_input, + "model": "gemini-1.5-flash", # Explicitly request gemini-1.5-flash + }) + + if response.get("success"): + ai_text = LocalAIApi.extract_text(response) + db_msg.message_out = ai_text + db_msg.save() + + # NOTE: In a real app, you'd call Meta API here to send db_msg.message_out back to sender_number. + # For this task, we focus on the integration and dashboard as requested. + logger.info(f"Gemini response for {sender_number}: {ai_text}") + else: + logger.error(f"AI Proxy Error: {response.get('error')}") + except Exception as e: + logger.error(f"Error calling Gemini: {str(e)}") \ No newline at end of file