diff --git a/.env.example b/.env.example index 8a442cc..cd72960 100644 --- a/.env.example +++ b/.env.example @@ -5,5 +5,7 @@ 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 \ No newline at end of file +REQUEST_URL="http://telemovris_web:8000/getmessage" +REQUEST_PATH="getmessage" +RING_WAIT_TIME=25 +MAX_CALL_DURATION=30 \ No newline at end of file diff --git a/README.md b/README.md index 3ae77f7..d38b1e0 100644 --- a/README.md +++ b/README.md @@ -12,4 +12,8 @@ You're now all set up. ## Run -Execute `docker-compose up -d` \ No newline at end of file +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. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 9fef8bd..dfdc076 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,8 @@ services: - API_ID=${API_ID} - API_HASH=${API_HASH} - REQUEST_URL=${REQUEST_URL} - - REQUEST_PORT=${REQUEST_PORT} + - RING_WAIT_TIME=${RING_WAIT_TIME} + - MAX_CALL_DURATION=${MAX_CALL_DURATION} telemovris_db: image: mysql:8 diff --git a/telemovris/telemovris.py b/telemovris/telemovris.py index 2228be3..a06f8fd 100644 --- a/telemovris/telemovris.py +++ b/telemovris/telemovris.py @@ -28,28 +28,36 @@ VoIPServerConfig.set_bitrate_config(80000, 100000, 60000, 5000, 5000) loop = asyncio.get_event_loop() voip_service = VoIPFileStreamService(client, receive_calls=False) -request_url = os.environ.get("REQUEST_URL") -request_port = os.environ.get("REQUEST_PORT") +REQUEST_URL = os.environ.get("REQUEST_URL") -def get_audio_duration(location: str) -> float: - args = ("ffprobe", "-show_entries", "format=duration", "-i", location) +RING_WAIT_TIME = os.environ.get("RING_WAIT_TIME") +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.wait() output = popen.stdout.read() r = re.findall(r'(?<=duration=)(.*)(?=\\n\[/F)', str(output)) 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): 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") + convert_audio_to_raw(audio_name) else: 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 with client: @@ -76,8 +84,8 @@ async def main(user, message_text, audio): 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): + 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: + logging.info("Finishing call because of duration") await call.discard_call() break except: @@ -87,12 +95,12 @@ while True: time.sleep(5) try: logging.info("Checking for new messages...") - response = requests.get(f"http://{request_url}:{request_port}/getmessage") + response = requests.get(REQUEST_URL) if response.content != '': response_json = json.loads(response.content) - user = response_json[1] - message = response_json[2] - audio = response_json[3] + user = response_json["user"] + message = response_json["message"] + audio = response_json["audio"] logging.info(f"Calling {user}") loop.run_until_complete(main(f"@{user}", message, audio)) logging.info("Call finished") diff --git a/telemovris_web/app.py b/telemovris_web/app.py index 8e031b9..54e935e 100644 --- a/telemovris_web/app.py +++ b/telemovris_web/app.py @@ -57,8 +57,15 @@ def getmessage(): rec = query_messages() try: - update_message(rec[0][0]) - return json.dumps(rec[0]) + id = rec[0][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: logging.info(f"Error: {e}") return ''