diff --git a/README.md b/README.md
index ca85ef8..b734981 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,10 @@
-# Tesla Inventory Auto-Buyer Bot πΉπ·
+# Tesla Inventory Bot (No Docker)
-This is an automated Telegram bot that monitors [Tesla TΓΌrkiye's inventory page](https://www.tesla.com/tr_TR/inventory/new/my?arrangeby=plh&zip=&range=0) and sends real-time alerts when new cars appear. It includes price, VIN, color info, and an inline "HEMEN SΔ°PARΔ°Ε VER" button.
+This Telegram bot monitors Tesla TΓΌrkiye inventory and notifies you of new cars.
-## π¦ Features
+## Setup
-- π Detects all new inventory vehicles (Model Y)
-- π¬ Sends Telegram messages (with order button)
-- πΌοΈ Includes exterior/interior color & price
-- π§ Avoids duplicates using VIN tracking
-- π
Cronjob support (run every X minutes)
-- π³ Docker-based installation
-- π Menu-based installer script
+1. Run `install.sh`.
+2. Follow prompts to install Python, pip, and configure Telegram.
+3. Use menu options to run manually or set up a cronjob.
----
-
-## π Installation (Recommended via `install.sh`)
-
-> This method clones the repo, builds Docker, prompts for Telegram info, and lets you configure a cronjob.
-
-### 1. Download and run:
-
-```bash
-git clone https://git.bitmaster.cc/BitMaster/tesla-bot.git
-cd tesla-bot
-chmod +x install.sh
-./install.sh
-```
-
-β
curl One-liner
-```bash
-bash <(curl -sSL https://git.bitmaster.cc/BitMaster/tesla-bot/raw/branch/main/install.sh)
-```
-
-β
wget One-liner
-```bash
-bash <(wget -qO- https://git.bitmaster.cc/BitMaster/tesla-bot/raw/branch/main/install.sh)
-```
\ No newline at end of file
diff --git a/bot.py b/bot.py
index 9be07b2..89cc1bf 100644
--- a/bot.py
+++ b/bot.py
@@ -7,111 +7,88 @@ import os
import requests
TELEGRAM_TOKEN = "your_token_here"
-CHAT_ID = "your_chat_id_here"
-TESLA_URL = "https://www.tesla.com/tr_TR/inventory/new/my?arrangeby=plh&zip=&range=0"
-SEEN_VINS_FILE = "seen_vins.txt"
+CHAT_ID = "your_chat_id_here"
+TESLA_URL = "https://www.tesla.com/tr_TR/inventory/new/my?arrangeby=plh&zip=&range=0"
+SEEN_VINS_FILE= "seen_vins.txt"
-def detect_chat_id(token):
- try:
- resp = requests.get(f"https://api.telegram.org/bot{token}/getUpdates")
- data = resp.json()
- if not data.get("ok"):
- return None
- for update in reversed(data.get("result", [])):
- chat = update.get("message", {}).get("chat", {})
- chat_id = chat.get("id")
- if chat_id:
- return chat_id
- except Exception as e:
- print(f"Chat ID detection failed: {e}")
- return None
-
-scraper = cloudscraper.create_scraper(browser={'browser': 'chrome', 'platform': 'windows'}, delay=5)
+scraper = cloudscraper.create_scraper(
+ browser={'browser': 'chrome', 'platform': 'windows'},
+ delay=5
+)
HEADERS = {
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/114.0.0.0 Safari/537.36",
+ "User-Agent": (
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
+ "Chrome/114.0.0.0 Safari/537.36"
+ ),
"Accept-Language": "tr-TR,tr;q=0.9",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9",
"Referer": "https://www.tesla.com/"
}
-def notify_telegram_with_button(message, button_text, button_url):
+def notify_telegram_with_button(msg, btn_text, btn_url):
payload = {
"chat_id": CHAT_ID,
- "text": message,
+ "text": msg,
"parse_mode": "HTML",
"reply_markup": json.dumps({
- "inline_keyboard": [[{
- "text": button_text,
- "url": button_url
- }]]
+ "inline_keyboard": [[{"text": btn_text, "url": btn_url}]]
})
}
- requests.post(f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage", data=payload)
+ requests.post(
+ f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage",
+ data=payload,
+ headers=HEADERS,
+ timeout=30
+ )
def load_seen_vins():
if not os.path.exists(SEEN_VINS_FILE):
return set()
- with open(SEEN_VINS_FILE, "r") as f:
- return set(line.strip() for line in f.readlines())
+ return set(open(SEEN_VINS_FILE).read().splitlines())
def save_seen_vins(vins):
with open(SEEN_VINS_FILE, "w") as f:
- f.writelines(f"{vin}\n" for vin in vins)
+ f.write("\n".join(vins))
def get_page(url):
time.sleep(random.uniform(10, 60))
try:
- return scraper.get(url, headers=HEADERS, timeout=30)
+ return scraper.get(url, headers=HEADERS, timeout=60)
except Exception as e:
print("Request failed:", e)
+ notify_telegram_with_button(f"β οΈ Failed to fetch Tesla page: {e}", "Retry", TESLA_URL)
return None
def check_inventory():
resp = get_page(TESLA_URL)
- if resp is None:
- notify_telegram_with_button("β οΈ Bot failed to get Tesla page (no response).", "Retry", TESLA_URL)
- return
-
- if resp.status_code in (403, 429) or "captcha" in resp.text.lower():
- notify_telegram_with_button(f"β οΈ Tesla bot likely detected. Status: {resp.status_code}", "Open Tesla", TESLA_URL)
+ if not resp or resp.status_code in (403,429) or "captcha" in resp.text.lower():
+ notify_telegram_with_button(f"β οΈ Bot likely detected. Status: {getattr(resp,'status_code','N/A')}", "Open Tesla", TESLA_URL)
return
try:
- page_text = resp.text
- json_data_match = re.search(r'\"results\"\s*:\s*(\[\{.*?\}\])', page_text, re.DOTALL)
- if not json_data_match:
- raise Exception("Could not find inventory JSON")
-
- cars = json.loads(json_data_match.group(1))
- seen_vins = load_seen_vins()
- new_seen = seen_vins.copy()
-
+ m = re.search(r'"results"\s*:\s*(\[\{.*?\}\])', resp.text, re.DOTALL)
+ cars = json.loads(m.group(1)) if m else []
+ seen = load_seen_vins()
for car in cars:
vin = car.get("vin")
- if not vin or vin in seen_vins:
- continue
-
- price = car.get("price", "N/A")
- ext_color = car.get("paint", {}).get("value", "N/A")
- int_color = car.get("interior", {}).get("value", "N/A")
- order_link = f"https://www.tesla.com/tr_TR/my/order/{vin}"
-
- message = (
- f"π¨ YENΔ° ARAΓ GELDΔ°!\n"
- f"π° Fiyat: {price:,} TL\n"
- f"π¨ DΔ±Ε Renk: {ext_color.upper()}\n"
- f"πͺ Δ°Γ§ Renk: {int_color.upper()}\n"
- f"π VIN: {vin}"
- )
-
- notify_telegram_with_button(message, "π HEMEN SΔ°PARΔ°Ε VER", order_link)
- new_seen.add(vin)
-
- save_seen_vins(new_seen)
-
+ if not vin or vin in seen: continue
+ price = car.get("price","N/A")
+ ext = car.get("paint",{}).get("value","N/A").upper()
+ inn = car.get("interior",{}).get("value","N/A").upper()
+ link= f"https://www.tesla.com/tr_TR/my/order/{vin}"
+ msg = (f"π¨ NEW CAR!\n"
+ f"π° Price: {price:,} TL\n"
+ f"π¨ Exterior: {ext}\n"
+ f"πͺ Interior: {inn}\n"
+ f"π VIN: {vin}")
+ notify_telegram_with_button(msg,"π ORDER NOW",link)
+ seen.add(vin)
+ save_seen_vins(seen)
except Exception as e:
- print("Error parsing inventory:", e)
- notify_telegram_with_button("β Bot error during parsing.", "Retry", TESLA_URL)
+ print("Parsing error:",e)
+ notify_telegram_with_button("β Parsing error occurred.","Retry",TESLA_URL)
-check_inventory()
+if __name__=="__main__":
+ check_inventory()
diff --git a/install.sh b/install.sh
index 5a9c823..d2ad181 100644
--- a/install.sh
+++ b/install.sh
@@ -29,7 +29,6 @@ function check_requirements() {
PYTHON_OK=true
else
echo -e "${RED}Missing${NC}"
- PYTHON_OK=false
fi
echo -n "π¦ pip3: "
@@ -38,20 +37,18 @@ function check_requirements() {
PIP_OK=true
else
echo -e "${RED}Missing${NC}"
- PIP_OK=false
fi
echo -n "π Project folder '$CLONE_DIR': "
if [ -d "$CLONE_DIR" ]; then
- echo -e "${YELLOW}Exists${NC}"
+ echo -e "${GREEN}Exists${NC}"
else
echo -e "${RED}Not present${NC}"
fi
if [ "$PYTHON_OK" = false ]; then
- echo -e "${YELLOW}β Python3 is required. Do you want to install it now? [Y/n]${NC}"
- read -rp "> " confirm
- confirm="${confirm,,}"
+ echo -e "${YELLOW}β Python3 is required. Install now? [Y/n]${NC}"
+ read -rp "> " confirm; confirm="${confirm,,}"
if [[ "$confirm" =~ ^(y|yes| )?$ ]]; then
sudo apt update && sudo apt install -y python3
else
@@ -60,9 +57,8 @@ function check_requirements() {
fi
if [ "$PIP_OK" = false ]; then
- echo -e "${YELLOW}β pip3 is required. Do you want to install it now? [Y/n]${NC}"
- read -rp "> " confirm
- confirm="${confirm,,}"
+ echo -e "${YELLOW}β pip3 is required. Install now? [Y/n]${NC}"
+ read -rp "> " confirm; confirm="${confirm,,}"
if [[ "$confirm" =~ ^(y|yes| )?$ ]]; then
sudo apt update && sudo apt install -y python3-pip
else
@@ -74,8 +70,8 @@ function check_requirements() {
function clone_and_setup() {
echo -e "${GREEN}π₯ Cloning repo...${NC}"
rm -rf "$CLONE_DIR"
- git clone "$REPO_URL" "$CLONE_DIR"
- cd "$CLONE_DIR" || exit 1
+ git clone "$REPO_URL" "$CLONE_DIR" || { echo -e "${RED}β git clone failed${NC}"; return; }
+ cd "$CLONE_DIR"
echo -e "${GREEN}π¦ Installing Python dependencies...${NC}"
pip3 install -r requirements.txt
@@ -83,33 +79,37 @@ function clone_and_setup() {
echo -e "${YELLOW}π¨ Enter your Telegram bot token:${NC}"
read -rp "π TELEGRAM_TOKEN: " token
- echo -e "${YELLOW}π€ Auto detecting the Telegram chat-ID...${NC}"
- auto_chat_id=$(curl -s "https://api.telegram.org/bot$token/getUpdates" | grep -oE '"id":[0-9-]+' | head -n1 | cut -d: -f2)
+ echo -e "${YELLOW}π€ Auto-detecting your Telegram chat ID...${NC}"
+ auto_chat_id=$(python3 - < /dev/null
- echo -e "${GREEN}β
Test message sent. Check your Telegram!${NC}"
+ curl -s -X POST "https://api.telegram.org/bot$token/sendMessage" -d chat_id="$chat_id" -d text="β
Tesla bot installed and ready!" -d parse_mode="HTML"
+ echo -e "${GREEN}β
Test message sent!${NC}"
cd ..
read -rp "$(echo -e "${GREEN}π Press Enter to return to the main menu...${NC}")"
@@ -117,12 +117,12 @@ function clone_and_setup() {
function run_bot_now() {
if [ ! -f "$CLONE_DIR/bot.py" ]; then
- echo -e "${RED}β Bot not installed. Please run option 1 first.${NC}"
+ echo -e "${RED}β Bot not installed. Run option 1 first.${NC}"
else
echo -e "${YELLOW}βοΈ Running bot.py...${NC}"
python3 "$CLONE_DIR/bot.py"
fi
- read -rp "$(echo -e "${GREEN}π Press Enter to return to the main menu...${NC}")"
+ read -rp "$(echo -e "${GREEN}π Press Enter to return...${NC}")"
}
function setup_cronjob() {
@@ -130,43 +130,37 @@ function setup_cronjob() {
if [ ! -d "$CLONE_DIR" ]; then
echo -e "${RED}β Bot not installed. Run option 1 first.${NC}"
else
- echo -e "${YELLOW}β± How often should the bot run? (in minutes, 1-60)${NC}"
- read -rp "Interval: " interval
+ read -rp "β± Run interval in minutes (1β60): " interval
if ! [[ "$interval" =~ ^[0-9]+$ ]] || [ "$interval" -lt 1 ] || [ "$interval" -gt 60 ]; then
- echo -e "${RED}β Invalid input. Must be between 1 and 60.${NC}"
+ echo -e "${RED}β Invalid interval.${NC}"
else
- (crontab -l 2>/dev/null | grep -v "$CRON_NAME"; echo "*/$interval * * * * cd $(pwd)/$CLONE_DIR && python3 bot.py >> cron.log 2>&1") | crontab -
- echo -e "${GREEN}β
Cronjob installed to run every $interval minute(s).${NC}"
+ (crontab -l 2>/dev/null | grep -v "$CRON_NAME"; echo "*/$interval * * * * cd $(pwd)/$CLONE_DIR && python3 bot.py >> cron.log 2>&1") | crontab -
+ echo -e "${GREEN}β
Cronjob set for every $interval min.${NC}"
fi
fi
- read -rp "$(echo -e "${GREEN}π Press Enter to return to the main menu...${NC}")"
+ read -rp "$(echo -e "${GREEN}π Press Enter to return...${NC}")"
}
function remove_cronjob() {
- echo -e "${YELLOW}Removing bot cronjob...${NC}"
- crontab -l 2>/dev/null | grep -v "$CRON_NAME" | crontab -
+ crontab -l | grep -v "$CRON_NAME" | crontab -
echo -e "${GREEN}β
Cronjob removed.${NC}"
- read -rp "$(echo -e "${GREEN}π Press Enter to return to the main menu...${NC}")"
+ read -rp "$(echo -e "${GREEN}π Press Enter to return...${NC}")"
}
while true; do
- clear
- banner
- check_requirements
+ clear; banner; check_requirements
echo -e "${YELLOW}1. Install bot and configure"
echo -e "2. Run bot manually now"
- echo -e "3. Setup new cronjob (every X min)"
+ echo -e "3. Setup new cronjob"
echo -e "4. Remove existing cronjob"
echo -e "5. Exit${NC}"
- echo ""
read -rp "$(echo -e "${YELLOW}π Choose [1-5]: ${NC}")" choice
-
case $choice in
1) clone_and_setup ;;
- 2) run_bot_now ;;
- 3) setup_cronjob ;;
- 4) remove_cronjob ;;
+ 2) run_bot_now ;;
+ 3) setup_cronjob ;;
+ 4) remove_cronjob ;;
5) echo -e "${RED}β Exiting...${NC}"; exit 0 ;;
*) echo -e "${RED}β Invalid option.${NC}"; sleep 1 ;;
esac
-done
\ No newline at end of file
+done
diff --git a/requirements.txt b/requirements.txt
index 1b44c54..f7b8e8f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,2 @@
requests
-
cloudscraper