README update and added more variables

This commit is contained in:
Joan
2023-08-04 10:25:20 +02:00
parent b575930118
commit 3ff1bf3481
5 changed files with 40 additions and 18 deletions

View File

@@ -5,5 +5,7 @@ MYSQL_DATABASE=telemovris
MYSQL_USER=telemovris MYSQL_USER=telemovris
MYSQL_PASSWORD=abcd1234 MYSQL_PASSWORD=abcd1234
MYSQL_HOST="telemovris_db" MYSQL_HOST="telemovris_db"
REQUEST_URL="telemovris_web" REQUEST_URL="http://telemovris_web:8000/getmessage"
REQUEST_PORT=8000 #use docker internal port, not the exposed one REQUEST_PATH="getmessage"
RING_WAIT_TIME=25
MAX_CALL_DURATION=30

View File

@@ -12,4 +12,8 @@ You're now all set up.
## Run ## Run
Execute `docker-compose up -d` Execute `docker-compose up -d`
The app will query the `REQUEST_URL` variable you set in `.env` file every 5 minutes and load the returned json that should contain the variables `user`, `message` and `audio`, being the user variable the Telegram username (without @), the message the text you want to send to the user, and audio 0 or 1, depending if you want to just send the text or the text and the audio through a call.
The `docker-compose.yml` includes a database service (with adminer so you can manage it) and a web service, the web exposes the next call in the `/getmessage` path (the entry will be marked as done in the database when queried) that returns the json of the next call. It also exposes `/sendmessage`, expecting HTTP GET parameters `user`, `message` and `audio`, this will insert a row in the database that will then be queried by the other path. This three services are not needed for the app to work but are meant to be an example on how to use it.

View File

@@ -12,7 +12,8 @@ services:
- API_ID=${API_ID} - API_ID=${API_ID}
- API_HASH=${API_HASH} - API_HASH=${API_HASH}
- REQUEST_URL=${REQUEST_URL} - REQUEST_URL=${REQUEST_URL}
- REQUEST_PORT=${REQUEST_PORT} - RING_WAIT_TIME=${RING_WAIT_TIME}
- MAX_CALL_DURATION=${MAX_CALL_DURATION}
telemovris_db: telemovris_db:
image: mysql:8 image: mysql:8

View File

@@ -28,28 +28,36 @@ 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)
request_url = os.environ.get("REQUEST_URL") REQUEST_URL = os.environ.get("REQUEST_URL")
request_port = os.environ.get("REQUEST_PORT")
def get_audio_duration(location: str) -> float: RING_WAIT_TIME = os.environ.get("RING_WAIT_TIME")
args = ("ffprobe", "-show_entries", "format=duration", "-i", location) MAX_CALL_DURATION = os.environ.get("MAX_CALL_DURATION")
def get_audio_duration(audio_name):
logging.info(f"Getting audio duration for {audio_name}")
args = ("ffprobe", "-show_entries", "format=duration", "-i", f"/data/audio/{audio_name}.wav")
popen = subprocess.Popen(args, stdout=subprocess.PIPE) popen = subprocess.Popen(args, stdout=subprocess.PIPE)
popen.wait() popen.wait()
output = popen.stdout.read() output = popen.stdout.read()
r = re.findall(r'(?<=duration=)(.*)(?=\\n\[/F)', str(output)) r = re.findall(r'(?<=duration=)(.*)(?=\\n\[/F)', str(output))
return float(r[0]) return float(r[0])
def convert_audio_to_raw(audio_name):
args = ("ffmpeg", "-i", f"/data/audio/{audio_name}.wav", "-f", "s16le", "-ac", "1", "-ar", "48000", "-acodec", "pcm_s16le", f"/data/audio/{audio_name}.raw")
popen = subprocess.Popen(args, stdout=subprocess.PIPE)
popen.wait()
def generate_audio(message_text): def generate_audio(message_text):
audio_name = md5(message_text.encode('utf-8')).hexdigest() audio_name = md5(message_text.encode('utf-8')).hexdigest()
if not os.path.isfile(f"/data/audio/{audio_name}.raw"): if not os.path.isfile(f"/data/audio/{audio_name}.raw"):
logging.info(f"Audio {audio_name} not found, generating") logging.info(f"Audio {audio_name} not found, generating")
tts = gTTS(text=message_text, lang="es") tts = gTTS(text=message_text, lang="es")
tts.save(f"/data/audio/{audio_name}.wav") 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") convert_audio_to_raw(audio_name)
else: else:
logging.info(f"Audio {audio_name} found") logging.info(f"Audio {audio_name} found")
return audio_name, get_audio_duration(f"/data/audio/{audio_name}.wav") return audio_name, get_audio_duration(audio_name)
async def main(user, message_text, audio): async def main(user, message_text, audio):
async with client: async with client:
@@ -76,8 +84,8 @@ async def main(user, message_text, audio):
t2 = time.perf_counter() t2 = time.perf_counter()
await asyncio.sleep(1) await asyncio.sleep(1)
try: 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) > min(30, RING_WAIT_TIME)) or call.ctrl.call_duration > MAX_CALL_DURATION:
if call.ctrl.call_duration > audio_duration or call_has_ended or (call.state == CallState.WAITING and int(t2-t1) > 25): logging.info("Finishing call because of duration")
await call.discard_call() await call.discard_call()
break break
except: except:
@@ -87,12 +95,12 @@ while True:
time.sleep(5) time.sleep(5)
try: try:
logging.info("Checking for new messages...") logging.info("Checking for new messages...")
response = requests.get(f"http://{request_url}:{request_port}/getmessage") response = requests.get(REQUEST_URL)
if response.content != '': if response.content != '':
response_json = json.loads(response.content) response_json = json.loads(response.content)
user = response_json[1] user = response_json["user"]
message = response_json[2] message = response_json["message"]
audio = response_json[3] audio = response_json["audio"]
logging.info(f"Calling {user}") logging.info(f"Calling {user}")
loop.run_until_complete(main(f"@{user}", message, audio)) loop.run_until_complete(main(f"@{user}", message, audio))
logging.info("Call finished") logging.info("Call finished")

View File

@@ -57,8 +57,15 @@ def getmessage():
rec = query_messages() rec = query_messages()
try: try:
update_message(rec[0][0]) id = rec[0][0]
return json.dumps(rec[0]) user = rec[0][1]
message = rec[0][2]
audio = rec[0][3]
update_message(id)
response = {"user": user,
"message": message,
"audio": audio}
return json.dumps(response)
except Exception as e: except Exception as e:
logging.info(f"Error: {e}") logging.info(f"Error: {e}")
return '' return ''