o
    Gh '                  
   @   s.  d dl mZmZmZ d dlmZ d dlZd dlZd dlZd dl	m	Z	m
Z
 d dlmZ d dl
Zd dlZd dlZd dlZeeZeddZedd	ed
deddedddejjdZeddeddeddedddZejedZdZdZdZdZdZdZ i Z!i Z"de#fd d!Z$d"e%de&fd#d$Z'd%e&d&e&de(fd'd(Z)d)e&d*e&d+e&fd,d-Z*d.e&d)e&d&e&d+e&fd/d0Z+ej,d1d2gd3d4d5 Z-ze.d6 e'd7Ze'd8Ze'd9Ze'd:Ze.d; W n e/y Z0 ze.d<e0  W Y dZ0[0ndZ0[0ww ed=kre.d> e.d? ej1d@dAdB dS dS )C    )Flaskrequestjsonify)genaiN)datetimetime)ZoneInfoGEMINI_API_KEYz'AIzaSyBn1Xami_b7fgIyRm_rpAuMzwA-xiRlf7QDB_HOSTz119.205.233.11DB_USERchanggiDB_PASSWORD
vkdnjgus13DB_NAME	versatileutf8mb4)hostuserpassworddatabasecharsetcursorclassNAVER_ACCESS_TOKEN_HABBY0kOxJovvQaqwH2zJpfaQNAVER_ACCESS_TOKEN_GRANCEEDBpJzdvb3RzeO3o5rJaMk!NAVER_ACCESS_TOKEN_GRANCEED_TOOLSr3jxwzxFSQOzWzeg61EjNAVER_ACCESS_TOKEN_YONEX_DAEGUlfZAFRz8SvmZmxynNjJshabbygranceedgranceed_toolszyonex-daegu)api_key d      returnc                  C   s   t td} |  }|  }|  }t }|dv s||v r0||v r.td|	| d dS tddd|  koAtdddk n  pWtddd|  koUtd	d
d
kS   S )Nz
Asia/Seoul)      u   [INFO] 오늘은 공휴일(u$   )이므로 24시간 운영합니다.Tr   r*         ;   )
r   nowr   dateweekdayr   holidaysKRprintget)r.   todaywdtkr_holidays r9   7/var/www/html/chatbot_naver/habby_granceed_ai_chabot.pyis_allowed_now_kst;   s   ( r;   	prompt_idc                 C   s  zzTt jd
i tddi}| :}|d| f | }|rE|drEtd|  d |d W  d    W W z|  W S    Y S W d    n1 sOw   Y  W n t	yq } ztd|  d|  W Y d }~nd }~ww W z|  W d	S    Y d	S z|  W w    Y w )Nconnect_timeoutr)   z3SELECT prompt_text FROM ai_prompt_table WHERE id=%sprompt_textz[INFO] prompt id=u    로드 성공u&   [WARN] 프롬프트 로드 오류 (id=z): uT   {"block": true, "response": "(챗봇) 내부 오류로 응답할 수 없습니다."}r9   )
pymysqlconnect	DB_CONFIGcursorexecutefetchoner4   r3   close	Exception)r<   conncurrower9   r9   r:   load_prompt_from_dbK   s>   
	 
rK   system_instructionuser_messagec              
   C   s   d|  d| }z*t jjddd|igdgddid	}t|dd
p"d
 }|s-dddW S t|W S  tyP } ztd|  dddW  Y d}~S d}~ww )u?   시간제한 없이 Gemini API의 응답을 기다리는 함수u   [시스템 명령어]
u   

---

[사용자 질문]
zmodels/gemini-2.5-flashr   text)rolepartsresponse_mime_typezapplication/json)modelcontentsconfigr%   Fu6   (챗봇) AI가 답변을 생성하지 못했습니다.)blockresponseu.   [오류] Gemini API 호출 중 오류 발생: u3   (챗봇) AI 엔진에 오류가 발생했습니다.N)	clientmodelsgenerate_contentgetattrstripjsonloadsrF   r3   )rL   rM   combined_messageresprN   rJ   r9   r9   r:   call_gemini_with_long_wait`   s(   r`   user_idmessage_textaccess_tokenc              
   C   s   d}|dd}d| d|id}zt j|||dd}|  td	|  d
 W dS  t jjyb } z-td|  |jdurLtd|jj d|jj  ntd W Y d}~dS W Y d}~dS d}~ww )uP   네이버 Send API를 호출하여 사용자에게 메시지를 전송합니다.z*https://gw.talk.naver.com/chatbot/v1/eventzapplication/json;charset=UTF-8)AuthorizationzContent-TypesendrN   )eventr   textContent
   )headersr\   timeoutu^   [INFO] 네이버 Send API를 통해 성공적으로 메시지를 보냈습니다. (사용자: )u*   [FATAL] 네이버 Send API 호출 실패: Nu          ㄴ 응답 코드: u   , 응답 내용: u          ㄴ 응답 없음)	requestspostraise_for_statusr3   
exceptionsRequestExceptionrV   status_coderN   )ra   rb   rc   naver_api_endpointri   payloadrV   rJ   r9   r9   r:   send_message_to_naverz   s*   
rt   system_promptc                 C   sj   t d| d| d t| |}|r/|dr/|d }t d|dd  d t||| dS t d	 dS )
u\   백그라운드 스레드에서 AI 호출 및 네이버로 답변 전송을 처리합니다.u1   [INFO] 백그라운드 작업 시작 (사용자: u   , 메시지: 'z')rV   u?   [INFO] AI 답변 생성 완료. 네이버로 전송합니다: 'N2   z...'u\   [WARN] AI가 유효한 답변을 생성하지 못하여 메시지를 보내지 않습니다.)r3   r`   r4   rt   )ru   ra   rM   rc   
reply_dict
reply_textr9   r9   r:   process_message_in_background   s   
ry   z/webhook/<bot_name>POST)methodsc                 C   s6  t d|  dt  d tjpi }t sdS |di ddp"d }|ddp,d}|r1|s3dS t	 }|t
v rTt
| \}}|| d	k rT||krTt d
|  dS ||ft
|< ttttd}|| t}t| }	t d|  d|	 d |	st d|  d dS tjt||||	fd}
d|
_|
  t d dS )Nz'
[INFO] -------- Request received for 'z' at z	 --------)r%      rg   rN   r%   r   rh   u<   [WARN] 중복 요청(메아리) 감지됨. 무시합니다: r    u   [DEBUG] 봇 'u%   '에 대해 로드된 Access Token: ''z	[FATAL] 'u?   '에 해당하는 Access Token이 설정되지 않았습니다.)targetargsTuP   [INFO] 메시지 수신 확인. 백그라운드에서 처리를 시작합니다.)r3   r   r.   r   r\   r;   r4   r[   timerr   last_message_cachesystem_prompt_habbysystem_prompt_granceedsystem_prompt_granceed_toolssystem_prompt_yonex_daeguNAVER_ACCESS_TOKENS	threadingThreadry   daemonstart)bot_namedatarM   ra   r.   	last_timelast_msgpromptscurrent_system_promptcurrent_access_tokenbackground_taskr9   r9   r:   webhook   s@   



r   uN   [INFO] 앱 시작... 데이터베이스에서 프롬프트를 로드합니다.   r)   r*      uD   [INFO] 프롬프트 로드 완료. 챗봇 서버를 시작합니다.u0   [FATAL] 앱 시작 중 심각한 오류 발생: __main__ux   
[WARNING] Flask 개발용 서버로 실행 중입니다. 성능 저하 및 응답 누락이 발생할 수 있습니다.uD   [RECOMMEND] 운영 환경에서는 Gunicorn을 사용해 주세요.
z0.0.0.0i  )r   port)2flaskr   r   r   googler   osr\   r?   r   r   zoneinfor   r   r1   r   rl   __name__appgetenvAPI_KEYcursors
DictCursorrA   r   ClientrW   r   r   r   r   MAX_MESSAGE_LENGTHMAX_USER_QUERIESuser_query_countr   boolr;   intstrrK   dictr`   rt   ry   router   r3   rF   rJ   runr9   r9   r9   r:   <module>   sr    







!
/
