Added db and web. Modified things. A lot.
This commit is contained in:
@@ -1,2 +1,9 @@
|
|||||||
API_ID=123456
|
API_ID=123456
|
||||||
API_HASH="123456789abcdef"
|
API_HASH="123456789abcdef"
|
||||||
|
MYSQL_ROOT_PASSWORD=1234abcd
|
||||||
|
MYSQL_DATABASE=telemovris
|
||||||
|
MYSQL_USER=telemovris
|
||||||
|
MYSQL_PASSWORD=abcd1234
|
||||||
|
MYSQL_HOST="telemovris_db"
|
||||||
|
REQUEST_URL="telemovris_web"
|
||||||
|
REQUEST_PORT=8000 #use docker internal port, not the exposed one
|
||||||
@@ -11,3 +11,37 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- API_ID=${API_ID}
|
- API_ID=${API_ID}
|
||||||
- API_HASH=${API_HASH}
|
- API_HASH=${API_HASH}
|
||||||
|
- REQUEST_URL=${REQUEST_URL}
|
||||||
|
- REQUEST_PORT=${REQUEST_PORT}
|
||||||
|
|
||||||
|
telemovris_db:
|
||||||
|
image: mysql:8
|
||||||
|
container_name: telemovris_db
|
||||||
|
volumes:
|
||||||
|
- ./db:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||||
|
- MYSQL_USER=${MYSQL_USER}
|
||||||
|
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
telemovris_adminer:
|
||||||
|
image: adminer
|
||||||
|
container_name: telemovris_adminer
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 8558:8080
|
||||||
|
|
||||||
|
telemovris_web:
|
||||||
|
build: telemovris_web
|
||||||
|
image: telemovris_web:latest
|
||||||
|
container_name: telemovris_web
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 8777:8000
|
||||||
|
environment:
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE}
|
||||||
|
- MYSQL_USER=${MYSQL_USER}
|
||||||
|
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
|
||||||
|
- MYSQL_HOST=${MYSQL_HOST}
|
||||||
@@ -4,8 +4,11 @@ RUN apt update
|
|||||||
RUN apt install ffmpeg make cmake gcc g++ python3-dev gcc g++ openssl libssl-dev libopus0 libopus-dev -y
|
RUN apt install ffmpeg make cmake gcc g++ python3-dev gcc g++ openssl libssl-dev libopus0 libopus-dev -y
|
||||||
RUN mkdir /app
|
RUN mkdir /app
|
||||||
ADD requirements.txt /app
|
ADD requirements.txt /app
|
||||||
ADD *.py /app/
|
|
||||||
RUN pip install -r /app/requirements.txt
|
RUN pip install -r /app/requirements.txt
|
||||||
|
#ADD tgvoip_pyrogram /install/tgvoip_pyrogram
|
||||||
|
#WORKDIR /install/tgvoip_pyrogram
|
||||||
|
#RUN python3 setup.py install
|
||||||
|
ADD *.py /app/
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ TgCrypto==1.2.5
|
|||||||
pytgvoip==0.0.7.1
|
pytgvoip==0.0.7.1
|
||||||
pytgvoip-pyrogram==0.0.11
|
pytgvoip-pyrogram==0.0.11
|
||||||
gTTS==2.3.2
|
gTTS==2.3.2
|
||||||
|
mysql-connector-python==8.0.32
|
||||||
@@ -1,12 +1,23 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import pyrogram
|
import pyrogram
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from gtts import gTTS
|
from gtts import gTTS
|
||||||
from tgvoip import VoIPServerConfig
|
from tgvoip import VoIPServerConfig, CallState
|
||||||
from tgvoip_pyrogram import VoIPFileStreamService
|
from tgvoip_pyrogram import VoIPFileStreamService
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
client = pyrogram.Client(os.environ.get('SESSION_NAME', '/data/telemovris'),
|
client = pyrogram.Client(os.environ.get('SESSION_NAME', '/data/telemovris'),
|
||||||
api_hash=os.environ.get('API_HASH'),
|
api_hash=os.environ.get('API_HASH'),
|
||||||
@@ -17,29 +28,73 @@ VoIPServerConfig.set_bitrate_config(80000, 100000, 60000, 5000, 5000)
|
|||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
voip_service = VoIPFileStreamService(client, receive_calls=False)
|
voip_service = VoIPFileStreamService(client, receive_calls=False)
|
||||||
|
|
||||||
@client.on_message(pyrogram.filters.command('callme'))
|
request_url = os.environ.get("REQUEST_URL")
|
||||||
async def callme(cl, message: pyrogram.types.Message):
|
request_port = os.environ.get("REQUEST_PORT")
|
||||||
|
|
||||||
|
def get_audio_duration(location: str) -> float:
|
||||||
|
args = ("ffprobe", "-show_entries", "format=duration", "-i", location)
|
||||||
|
popen = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||||
|
popen.wait()
|
||||||
|
output = popen.stdout.read()
|
||||||
|
r = re.findall(r'(?<=duration=)(.*)(?=\\n\[/F)', str(output))
|
||||||
|
return float(r[0])
|
||||||
|
|
||||||
|
def generate_audio(message_text):
|
||||||
|
audio_name = md5(message_text.encode('utf-8')).hexdigest()
|
||||||
|
if not os.path.isfile(f"/data/audio/{audio_name}.raw"):
|
||||||
|
logging.info(f"Audio {audio_name} not found, generating")
|
||||||
|
tts = gTTS(text=message_text, lang="es")
|
||||||
|
tts.save(f"/data/audio/{audio_name}.wav")
|
||||||
|
os.system(f"ffmpeg -i /data/audio/{audio_name}.wav -f s16le -ac 1 -ar 48000 -acodec pcm_s16le /data/audio/{audio_name}.raw")
|
||||||
|
else:
|
||||||
|
logging.info(f"Audio {audio_name} found")
|
||||||
|
|
||||||
|
return audio_name, get_audio_duration(f"/data/audio/{audio_name}.wav")
|
||||||
|
|
||||||
|
async def main(user, message_text, audio):
|
||||||
|
async with client:
|
||||||
|
audio_name, audio_duration = generate_audio(message_text)
|
||||||
|
|
||||||
|
logging.info(f"Calling {user}")
|
||||||
|
call = await voip_service.start_call(user)
|
||||||
|
await client.send_message(user, message_text)
|
||||||
|
if audio:
|
||||||
|
call.play(f"/data/audio/{audio_name}.raw")
|
||||||
|
call_has_ended = False
|
||||||
|
|
||||||
|
@call.on_call_state_changed
|
||||||
|
def state_changed(call, state):
|
||||||
|
print(f'State changed: {state}')
|
||||||
|
|
||||||
|
@call.on_call_ended
|
||||||
|
async def call_ended(call):
|
||||||
|
global call_has_ended
|
||||||
|
call_has_ended = True
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
while True:
|
||||||
|
t2 = time.perf_counter()
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
try:
|
||||||
|
logging.info(call.ctrl.call_duration)
|
||||||
|
if call.ctrl.call_duration > audio_duration or call_has_ended or (call.state == CallState.WAITING and int(t2-t1) > 25):
|
||||||
|
await call.discard_call()
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
break
|
||||||
|
|
||||||
|
while True:
|
||||||
|
time.sleep(5)
|
||||||
try:
|
try:
|
||||||
message_text = message.text.split('/callme ')[1]
|
logging.info("Checking for new messages...")
|
||||||
audio_name = md5(message_text.encode('utf-8')).hexdigest()
|
response = requests.get(f"http://{request_url}:{request_port}/getmessage")
|
||||||
|
if response.content != '':
|
||||||
if not os.path.isfile(f"/data/audio/{audio_name}.raw"):
|
response_json = json.loads(response.content)
|
||||||
tts = gTTS(text=message_text, lang="es")
|
user = response_json[1]
|
||||||
tts.save(f"/data/audio/{audio_name}.wav")
|
message = response_json[2]
|
||||||
os.system(f"ffmpeg -i /data/audio/{audio_name}.wav -f s16le -ac 1 -ar 48000 -acodec pcm_s16le /data/audio/{audio_name}.raw")
|
audio = response_json[3]
|
||||||
|
logging.info(f"Calling {user}")
|
||||||
await client.send_message(message.from_user.id, f"Llamando con el texto: {message_text}")
|
loop.run_until_complete(main(f"@{user}", message, audio))
|
||||||
call = await voip_service.start_call(message.from_user.id)
|
logging.info("Call finished")
|
||||||
call.play(f"/data/audio/{audio_name}.raw")
|
except Exception as e:
|
||||||
#call.set_output_file(f'/data/audio/{audio_name}_output.raw')
|
logging.info(f"Error: {e}")
|
||||||
except:
|
|
||||||
await client.send_message(message.from_user.id, 'No se ha detectado ningún texto después del comando')
|
|
||||||
|
|
||||||
async def main():
|
|
||||||
await client.start()
|
|
||||||
print(await client.export_session_string())
|
|
||||||
await pyrogram.idle()
|
|
||||||
|
|
||||||
loop.run_until_complete(main())
|
|
||||||
|
|
||||||
|
|
||||||
17
telemovris_web/Dockerfile
Normal file
17
telemovris_web/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
FROM python:3.9
|
||||||
|
|
||||||
|
RUN mkdir /app
|
||||||
|
ADD requirements.txt /app
|
||||||
|
RUN pip install -r /app/requirements.txt
|
||||||
|
ADD *.py /app/
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV FLASK_APP app.py
|
||||||
|
ENV FLASK_ENV development
|
||||||
|
ENV FLASK_RUN_PORT 8000
|
||||||
|
ENV FLASK_RUN_HOST 0.0.0.0
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["flask", "run"]
|
||||||
80
telemovris_web/app.py
Normal file
80
telemovris_web/app.py
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import os
|
||||||
|
from flask import Flask, request
|
||||||
|
import mysql.connector
|
||||||
|
import logging
|
||||||
|
import json
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def connect_db():
|
||||||
|
db = mysql.connector.connect(
|
||||||
|
host = os.environ.get("MYSQL_HOST"),
|
||||||
|
user = os.environ.get("MYSQL_USER"),
|
||||||
|
password = os.environ.get("MYSQL_PASSWORD"),
|
||||||
|
database = os.environ.get("MYSQL_DATABASE")
|
||||||
|
)
|
||||||
|
return db
|
||||||
|
|
||||||
|
def populate_db():
|
||||||
|
con = connect_db()
|
||||||
|
cur = con.cursor(prepared=True)
|
||||||
|
cur.execute('CREATE TABLE IF NOT EXISTS messages (id INT AUTO_INCREMENT PRIMARY KEY, user VARCHAR(255), message VARCHAR(255), audio BOOLEAN, processed BOOLEAN)')
|
||||||
|
con.commit()
|
||||||
|
con.close()
|
||||||
|
|
||||||
|
def query_messages():
|
||||||
|
con = connect_db()
|
||||||
|
cur = con.cursor(prepared=True)
|
||||||
|
cur.execute('SELECT id, user, message, audio FROM messages WHERE processed IS false LIMIT 1')
|
||||||
|
ret = cur.fetchall()
|
||||||
|
con.close()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def insert_message(user, message, audio):
|
||||||
|
con = connect_db()
|
||||||
|
cur = con.cursor(prepared=True)
|
||||||
|
params = (user, message, audio)
|
||||||
|
cur.execute('INSERT INTO messages (user, message, audio, processed) VALUES (%s, %s, %s, 0)', params)
|
||||||
|
con.commit()
|
||||||
|
con.close()
|
||||||
|
|
||||||
|
def update_message(id):
|
||||||
|
con = connect_db()
|
||||||
|
cur = con.cursor(prepared=True)
|
||||||
|
cur.execute(f'UPDATE messages SET processed = true WHERE id = {id}')
|
||||||
|
con.commit()
|
||||||
|
con.close()
|
||||||
|
|
||||||
|
server = Flask(__name__)
|
||||||
|
|
||||||
|
@server.route('/getmessage')
|
||||||
|
def getmessage():
|
||||||
|
rec = query_messages()
|
||||||
|
|
||||||
|
try:
|
||||||
|
update_message(rec[0][0])
|
||||||
|
return json.dumps(rec[0])
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(f"Error: {e}")
|
||||||
|
return ''
|
||||||
|
|
||||||
|
@server.route('/sendmessage', methods=['GET'])
|
||||||
|
def sendmessage():
|
||||||
|
user = request.args.get('user')
|
||||||
|
message = request.args.get('message')
|
||||||
|
audio = request.args.get('audio')
|
||||||
|
|
||||||
|
try:
|
||||||
|
insert_message(user, message, audio)
|
||||||
|
return f"Inserted {user} - {message} - {audio}"
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(f"Error: {e}")
|
||||||
|
return ''
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
server.run()
|
||||||
2
telemovris_web/requirements.txt
Normal file
2
telemovris_web/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Flask==2.0.1
|
||||||
|
mysql-connector-python==8.0.32
|
||||||
Reference in New Issue
Block a user