|
@@ -0,0 +1,660 @@
|
|
|
+import time
|
|
|
+import asyncio
|
|
|
+from telethon import TelegramClient, events
|
|
|
+from telethon.errors.rpcerrorlist import AuthKeyError
|
|
|
+from telethon.sync import TelegramClient as SyncTelegramClient
|
|
|
+import json
|
|
|
+import datetime
|
|
|
+import signal
|
|
|
+import sys
|
|
|
+import math
|
|
|
+import requests
|
|
|
+from telethon.tl.types import MessageEntityTextUrl
|
|
|
+from apscheduler.schedulers.background import BackgroundScheduler
|
|
|
+from telethon.tl.types import PeerUser, PeerChat, PeerChannel
|
|
|
+import os
|
|
|
+import traceback
|
|
|
+import re
|
|
|
+from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
|
|
+import pathlib
|
|
|
+import shutil
|
|
|
+import pandas as pd
|
|
|
+old_print = print
|
|
|
+
|
|
|
+
|
|
|
+def timestamped_print(*args, **kwargs):
|
|
|
+ old_print(datetime.datetime.utcnow().replace(
|
|
|
+ microsecond=0), *args, **kwargs)
|
|
|
+
|
|
|
+
|
|
|
+print = timestamped_print
|
|
|
+print('\n'*5)
|
|
|
+
|
|
|
+def global_exception_hook(exc_type, exc_value, exc_traceback):
|
|
|
+ print(f"Global exception: {exc_type.__name__} - {exc_value}")
|
|
|
+ traceback.print_tb(exc_traceback)
|
|
|
+ raise
|
|
|
+
|
|
|
+def keep_alnum_forgmgn(string):
|
|
|
+ return re.sub(r'[^a-zA-Z0-9\.\s\+\-]', ' ', string)
|
|
|
+
|
|
|
+
|
|
|
+def keep_alnum(string):
|
|
|
+ return re.sub(r'[^a-zA-Z0-9\.\s:+-]', ' ', string)
|
|
|
+
|
|
|
+def term_sig_handler(signum, frame):
|
|
|
+ # save_obj_unraydium_token()
|
|
|
+ print(f'catched singal: {signum}')
|
|
|
+
|
|
|
+ sys.exit()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def global_exception_hook(exc_type, exc_value, exc_traceback):
|
|
|
+ print(f"Global exception: {exc_type.__name__} - {exc_value}")
|
|
|
+ traceback.print_tb(exc_traceback)
|
|
|
+ raise
|
|
|
+
|
|
|
+
|
|
|
+int_pattern = r"^\d+$"
|
|
|
+api_id_gate = 29760088
|
|
|
+api_hash_gate = "7cd2222e0629c770789f9c6cf280d051"
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+GMGN_Alert_Bot_Solana_id = 6917338381
|
|
|
+
|
|
|
+# ID: 7290510619, Name: GMGN Alert Bot - ETH, title: GMGN Alert Bot - ETH,
|
|
|
+# ID: 6917338381, Name: GMGN Alert Bot - Solana, title: GMGN Alert Bot - Solana,
|
|
|
+
|
|
|
+
|
|
|
+feishu_url = 'https://open.feishu.cn/open-apis/bot/v2/hook/a68cffbf-9104-427b-8e25-62dfaf363a47'
|
|
|
+utc_plus_8 = datetime.timezone(datetime.timedelta(hours=8))
|
|
|
+
|
|
|
+
|
|
|
+client_gate = TelegramClient('anon_gate', api_id_gate, api_hash_gate)
|
|
|
+client_gate.start()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+set_has_read_file=set()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+obj_queueing_send_feishu={
|
|
|
+# "feishu_timestamp":{
|
|
|
+# "is_sending":False,
|
|
|
+# "str_tokenaddress":str_tokenaddress,
|
|
|
+# "str_now_price":str_now_price,
|
|
|
+# "number_open":number_open,
|
|
|
+# "number_liq":number_liq,
|
|
|
+# "number_holders":number_holders,
|
|
|
+# "number_top_10_holding":number_top_10_holding,
|
|
|
+# "last_5m_change":last_5m_change,
|
|
|
+# "last_1h_change":last_1h_change,
|
|
|
+# "feishu_timestamp":cur_now_timestamp,
|
|
|
+# }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+async def ready_send_feishu(obj_temp_queueing_send_feishu):
|
|
|
+ global obj_queueing_send_feishu , utc_plus_8
|
|
|
+ cur_now_timestamp = int(time.time()*1000)
|
|
|
+ arr_send_feishu_info = []
|
|
|
+
|
|
|
+ for obj_one_queueing_send_feishu in obj_temp_queueing_send_feishu.values():
|
|
|
+ str_tokenaddress = obj_one_queueing_send_feishu["str_tokenaddress"]
|
|
|
+ feishu_timestamp = obj_one_queueing_send_feishu["feishu_timestamp"]
|
|
|
+
|
|
|
+
|
|
|
+ if obj_one_queueing_send_feishu["is_sending"] == True:
|
|
|
+ if cur_now_timestamp - obj_one_queueing_send_feishu["sending_time"] >=obj_one_queueing_send_feishu["send_counts"]* 15*1000:
|
|
|
+ print(f"feishu_timestamp={feishu_timestamp} str_tokenaddress={str_tokenaddress} is_sending_too_long del")
|
|
|
+ del obj_queueing_send_feishu[feishu_timestamp]
|
|
|
+ else:
|
|
|
+ print(f"feishu_timestamp={feishu_timestamp} str_tokenaddress={str_tokenaddress} is_sending")
|
|
|
+ return True
|
|
|
+
|
|
|
+
|
|
|
+ obj_one_queueing_send_feishu["sending_time"] = cur_now_timestamp
|
|
|
+ obj_one_queueing_send_feishu["send_counts"]+=1
|
|
|
+ obj_one_queueing_send_feishu["is_sending"] = True
|
|
|
+
|
|
|
+
|
|
|
+ # 将时间戳转换为datetime对象,并指定时区 ,转换为ISO 8601格式的时间字符串,包含时区信息
|
|
|
+
|
|
|
+
|
|
|
+ str_iso8601_date = datetime.datetime.fromtimestamp(feishu_timestamp/1000, tz=utc_plus_8).isoformat().split('.')[0]
|
|
|
+ str_now_price = obj_one_queueing_send_feishu["str_now_price"]
|
|
|
+ str_dev_status = obj_one_queueing_send_feishu["str_dev_status"]
|
|
|
+ str_swap_type = obj_one_queueing_send_feishu["str_swap_type"]
|
|
|
+
|
|
|
+ str_swap_token_amount = str(obj_one_queueing_send_feishu["number_swap_token_amount"] )
|
|
|
+ str_swap_sol = str(obj_one_queueing_send_feishu["number_swap_sol"])
|
|
|
+
|
|
|
+ str_dalaoaddress = obj_one_queueing_send_feishu["str_dalaoaddress"]
|
|
|
+ str_last_5m_change = str(obj_one_queueing_send_feishu["last_5m_change"])
|
|
|
+ str_last_1h_change = str(obj_one_queueing_send_feishu["last_1h_change"])
|
|
|
+ str_number_holders = str(obj_one_queueing_send_feishu["number_holders"])
|
|
|
+ str_number_liq_sol = str(obj_one_queueing_send_feishu["number_liq_sol"])
|
|
|
+
|
|
|
+
|
|
|
+ str_number_open = ""
|
|
|
+ if obj_one_queueing_send_feishu["number_open"] >24:
|
|
|
+ str_number_open = str(obj_one_queueing_send_feishu["number_open"]/24) + "d"
|
|
|
+ else:
|
|
|
+ str_number_open = str(obj_one_queueing_send_feishu["number_open"]) + "h"
|
|
|
+
|
|
|
+
|
|
|
+ arr_send_feishu_info.append( {
|
|
|
+ "str_iso8601_date": str_iso8601_date,
|
|
|
+ "str_tokenaddress":str_tokenaddress,
|
|
|
+ "str_dalaoaddress":str_dalaoaddress,
|
|
|
+ "str_dev_status":str_dev_status,
|
|
|
+ "str_swap_type":str_swap_type,
|
|
|
+ "str_number_liq_sol":str_number_liq_sol,
|
|
|
+ "str_swap_token_amount":str_swap_token_amount,
|
|
|
+ "str_swap_sol":str_swap_sol,
|
|
|
+ "str_number_holders":str_number_holders,
|
|
|
+ "str_last_5m_change":str_last_5m_change,
|
|
|
+ "str_last_1h_change":str_last_1h_change,
|
|
|
+ "str_now_price": str_now_price,
|
|
|
+ "str_number_open":str_number_open,
|
|
|
+
|
|
|
+ })
|
|
|
+ # 发给飞书
|
|
|
+ send_feishu(
|
|
|
+ arr_send_feishu_info
|
|
|
+ )
|
|
|
+
|
|
|
+ for obj_one_queueing_send_feishu in obj_temp_queueing_send_feishu.values():
|
|
|
+ str_tokenaddress = obj_one_queueing_send_feishu["str_tokenaddress"]
|
|
|
+ feishu_timestamp = obj_one_queueing_send_feishu["feishu_timestamp"]
|
|
|
+ del obj_queueing_send_feishu[feishu_timestamp]
|
|
|
+
|
|
|
+ return
|
|
|
+
|
|
|
+
|
|
|
+def send_feishu(arr_obj_sendmsg):
|
|
|
+
|
|
|
+ payload_message = {
|
|
|
+ "msg_type": "post",
|
|
|
+ "content": {
|
|
|
+ "post": {
|
|
|
+ "zh_cn": {
|
|
|
+ "title": arr_obj_sendmsg[0]["str_iso8601_date"],
|
|
|
+ "content": [
|
|
|
+
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ headers = {
|
|
|
+ "Content-Type": "application/json; charset=utf-8",
|
|
|
+ }
|
|
|
+ content = []
|
|
|
+ for obj_sendmsg in arr_obj_sendmsg:
|
|
|
+
|
|
|
+ content.append([
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': obj_sendmsg['str_swap_type']
|
|
|
+ } ,
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': ' '+obj_sendmsg['str_tokenaddress']
|
|
|
+ }
|
|
|
+ ])
|
|
|
+ content.append([
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': "dalao: "+ obj_sendmsg['str_dalaoaddress']
|
|
|
+ } ,
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': ' ' + obj_sendmsg['str_swap_token_amount'] + 'token' ,
|
|
|
+ } ,
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': ' ' + obj_sendmsg['str_swap_sol'] +'sol'
|
|
|
+ } ,
|
|
|
+ ])
|
|
|
+
|
|
|
+
|
|
|
+ content.append([
|
|
|
+
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': "liq: " + obj_sendmsg['str_number_liq_sol']
|
|
|
+ } ,
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': ' op:' + obj_sendmsg['str_number_open']
|
|
|
+ }
|
|
|
+ ,
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': ' dev:' + obj_sendmsg['str_dev_status']
|
|
|
+ }
|
|
|
+
|
|
|
+ ])
|
|
|
+
|
|
|
+
|
|
|
+ content.append([
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': "price:" + obj_sendmsg['str_now_price']
|
|
|
+ },
|
|
|
+
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': ' ho:' + obj_sendmsg["str_number_holders"]
|
|
|
+ }
|
|
|
+
|
|
|
+ ])
|
|
|
+
|
|
|
+ content.append([
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': "5m: " + obj_sendmsg['str_last_5m_change'] + "%"
|
|
|
+ },
|
|
|
+
|
|
|
+ {
|
|
|
+ "tag": "text",
|
|
|
+ 'text': ' 1h: ' + obj_sendmsg["str_last_1h_change"] + "%"
|
|
|
+ }
|
|
|
+
|
|
|
+ ])
|
|
|
+
|
|
|
+ content.append([{
|
|
|
+ "tag": "a",
|
|
|
+ "href": "https://gmgn.ai/sol/token/" + obj_sendmsg["str_tokenaddress"],
|
|
|
+ "text": "GMGN " + obj_sendmsg["str_tokenaddress"][-6:]
|
|
|
+ }])
|
|
|
+
|
|
|
+ content.append([{
|
|
|
+ "tag": "text",
|
|
|
+ "text": "*****************"
|
|
|
+ }])
|
|
|
+
|
|
|
+
|
|
|
+ payload_message["content"]["post"]["zh_cn"]["content"] = content
|
|
|
+ payload_message["content"] = json.dumps(payload_message["content"])
|
|
|
+
|
|
|
+ payload_message = json.dumps(payload_message)
|
|
|
+ response = requests.post(
|
|
|
+ url=feishu_url, headers=headers, data=payload_message)
|
|
|
+ # response_json = response.json()
|
|
|
+ # print("response_json=",response_json)
|
|
|
+ return
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+async def ready_send_feishu_timed():
|
|
|
+ global obj_queueing_send_feishu
|
|
|
+
|
|
|
+
|
|
|
+ if len(obj_queueing_send_feishu.keys())==0:
|
|
|
+ return
|
|
|
+
|
|
|
+ arr_feishu_timestamp = (list(obj_queueing_send_feishu.keys()))
|
|
|
+ obj_temp_queueing_send_feishu = {}
|
|
|
+ for feishu_timestamp in arr_feishu_timestamp:
|
|
|
+ obj_temp_queueing_send_feishu[feishu_timestamp] = (obj_queueing_send_feishu[feishu_timestamp])
|
|
|
+
|
|
|
+ handle_res = await ready_send_feishu(obj_temp_queueing_send_feishu=obj_temp_queueing_send_feishu )
|
|
|
+
|
|
|
+
|
|
|
+ return
|
|
|
+
|
|
|
+obj_queueing_tokenaddress={}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+address_pattern = re.compile(r'^[a-zA-Z0-9]+$')
|
|
|
+def check_is_address(string):
|
|
|
+ if address_pattern.match(string):
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ return False
|
|
|
+
|
|
|
+@client_gate.on(events.NewMessage(chats=[GMGN_Alert_Bot_Solana_id ], incoming=True))
|
|
|
+async def handle_incoming_GMGN_bot_NewMessage(event):
|
|
|
+
|
|
|
+ global obj_queueing_tokenaddress
|
|
|
+ event_message = event.message
|
|
|
+ message_text = event.message.message
|
|
|
+ # print("enter handle_incoming_GMGN_bot_NewMessage client_gate.on(events.NewMessage event_message=",event_message)
|
|
|
+ print("enter handle_incoming_GMGN_bot_NewMessage client_gate.on(events.NewMessage message_text=",message_text)
|
|
|
+ # return
|
|
|
+ swap_buttons = event.message.buttons
|
|
|
+ if not swap_buttons:
|
|
|
+ print("GMGN_Alert_Bot_Solana_id not buttons")
|
|
|
+ return
|
|
|
+ swap_buttons = sum(swap_buttons, [])
|
|
|
+ button_chart_line = swap_buttons[0]
|
|
|
+ url_chart_line = button_chart_line.url
|
|
|
+
|
|
|
+ arr_url_chart_line = url_chart_line.split("?wallet=")
|
|
|
+ str_dalaoaddress = arr_url_chart_line[-1]
|
|
|
+ str_tokenaddress = arr_url_chart_line[0].split("/")[-1]
|
|
|
+
|
|
|
+
|
|
|
+ # 🔴4632BM....BMA7Z sell 2.12 SOL WeCat PnL+7.46% on Raydium 🔴🔴🔴🔴
|
|
|
+
|
|
|
+ # [Sell all] Check tx
|
|
|
+ # 🪙Buy: $310.59(2.12 SOL)/ 3.4M
|
|
|
+ # 💲Price/Avg Cost: $0.00009/$0.00008
|
|
|
+ # 🚀Total Profit: 🟢+$21.57(+7.46%)
|
|
|
+
|
|
|
+ # 💎Current Holdings: --
|
|
|
+ # 💰Total buy: $289.02(1.98 SOL)/ 3.4M 1 TXs
|
|
|
+ # 💳Total sell: $310.59(2.12 SOL)/ 3.4M 1 TXs
|
|
|
+ # ⏳SOL Balance: 20.86 SOL
|
|
|
+
|
|
|
+ # $WeCat(WeCat 微猫)
|
|
|
+ # EAMU6WF4SzcWaVEPf6q6YmG7tsaC5jtmjXFWyjorpump
|
|
|
+
|
|
|
+ # 📈 5m | 1h | 6h: 53.95% | 2013.3% | 2013.3%
|
|
|
+ # 🎲 5m TXs/Vol: 855/$136.6K
|
|
|
+ # 💡 MCP: $90.6K
|
|
|
+ # 💧 Liq: 100.71 SOL ($29.4K 🔥99.98%)
|
|
|
+ # 👥 Holder: 466
|
|
|
+ # 🕒 Open: 4min ago
|
|
|
+
|
|
|
+ # ✅NoMint / ✅Blacklist / ✅Burnt
|
|
|
+ # ✅TOP 10: 19.37%<30%
|
|
|
+
|
|
|
+ # ⏳ DEV: 🚨 Sell All
|
|
|
+ # 👨🍳 DEV Burnt烧币: -
|
|
|
+
|
|
|
+ # 🌏 Website | 💊️ Pump
|
|
|
+ # 🌈Push Smart Money Alerts in group? Invite @Alert_GMGNBOT in your group
|
|
|
+
|
|
|
+ # 💎 NEW: 100x MEME & Smart Money Hunter with GMGN.ai
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ str_now_price = None
|
|
|
+ str_swap_type = None
|
|
|
+ last_5m_change = None
|
|
|
+ last_1h_change = None
|
|
|
+ number_open = 0
|
|
|
+ number_liq_sol = 0
|
|
|
+ nomint_flag = False
|
|
|
+ blacklist_flag = False
|
|
|
+ burnt_flag = False
|
|
|
+ number_insiders = 0
|
|
|
+ number_holders = 0
|
|
|
+
|
|
|
+ dev_action = None
|
|
|
+ is_normal = True
|
|
|
+ number_swap_token_amount = 0
|
|
|
+ number_swap_sol = 0
|
|
|
+ str_dev_status = "unknown"
|
|
|
+ top_10_flag = False
|
|
|
+ message_text=message_text.lower()
|
|
|
+ message_text=message_text.strip()
|
|
|
+ arr_total_split_message = re.split('\n+', message_text)
|
|
|
+
|
|
|
+
|
|
|
+ for idx,split_message in enumerate( arr_total_split_message):
|
|
|
+ split_message=split_message.strip()
|
|
|
+ if idx == 0 and "...." in split_message:
|
|
|
+ if "pump" in split_message:
|
|
|
+ print("platform is pump pass")
|
|
|
+ return
|
|
|
+ if "🔴" in split_message:
|
|
|
+ str_swap_type = "sell"
|
|
|
+ elif "🟢" in split_message:
|
|
|
+ str_swap_type = "buy"
|
|
|
+ continue
|
|
|
+ elif "🪙buy:" in split_message :
|
|
|
+
|
|
|
+ # 获取当前 购买/卖出的sol 与 token 数量
|
|
|
+ split_message = keep_alnum_forgmgn(split_message)
|
|
|
+ split_message=split_message.replace("--","0")
|
|
|
+
|
|
|
+ if str_swap_type=="buy":
|
|
|
+ if "sol" not in split_message:
|
|
|
+ print(f"{str_swap_type} no sol amount")
|
|
|
+ return
|
|
|
+ split_message=split_message.strip()
|
|
|
+ split_message=split_message.replace("sol","")
|
|
|
+ split_message = re.sub(r"\s+", " ", split_message)
|
|
|
+
|
|
|
+ arr_split_message = split_message.split(' ')
|
|
|
+ split_message_token_amount = arr_split_message[-1]
|
|
|
+ split_message_sol = arr_split_message[-2]
|
|
|
+ number_swap_sol = float(split_message_sol)
|
|
|
+
|
|
|
+ base_amount = 1
|
|
|
+ if "m" in split_message_token_amount:
|
|
|
+ split_message_token_amount =split_message_token_amount.replace("m","")
|
|
|
+ base_amount = 10**6
|
|
|
+ elif "k" in split_message_token_amount:
|
|
|
+ split_message_token_amount =split_message_token_amount.replace("k","")
|
|
|
+ base_amount = 10**3
|
|
|
+ elif "b" in split_message_token_amount:
|
|
|
+ split_message_token_amount =split_message_token_amount.replace("b","")
|
|
|
+ base_amount = 10**9
|
|
|
+ number_swap_token_amount = int(base_amount * float(split_message_token_amount) )
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ elif "💲price" in split_message :
|
|
|
+ # 获取当前价格
|
|
|
+ split_message=split_message.replace("--","0")
|
|
|
+ split_message=split_message.replace("/"," ")
|
|
|
+ temp_now_price = None
|
|
|
+ if "💲price:" in split_message:
|
|
|
+ temp_now_price = split_message.split(" ")[-1]
|
|
|
+ elif "💲price avg" in split_message:
|
|
|
+ temp_now_price = split_message.split(" ")[-2]
|
|
|
+
|
|
|
+ temp_now_price=temp_now_price.replace("$","")
|
|
|
+ arr_temp_now_price = temp_now_price.split(".")
|
|
|
+ integer_now_price = arr_temp_now_price[0]
|
|
|
+ fractional_now_price = arr_temp_now_price[1]
|
|
|
+ if "{" in fractional_now_price:
|
|
|
+ fractional_now_price = re.sub(r"[{}]", " ", fractional_now_price)
|
|
|
+ arr_fractional_now_price = fractional_now_price.split(" ")
|
|
|
+ fractional_now_price = "0" * (int(arr_fractional_now_price[-2]))+ arr_fractional_now_price[-1]
|
|
|
+ str_now_price = integer_now_price + "." + fractional_now_price
|
|
|
+
|
|
|
+
|
|
|
+ elif "1h" in split_message :
|
|
|
+ # 获取最近时间的价格变化
|
|
|
+ # split_message = re.sub(r"[|%:📈]", "", split_message)
|
|
|
+ # split_message = re.sub(r"\s+", " ", split_message)
|
|
|
+ split_message = keep_alnum_forgmgn(split_message)
|
|
|
+ split_message = re.sub(r"\s+", " ", split_message)
|
|
|
+ split_message=split_message.strip()
|
|
|
+
|
|
|
+ arr_price_change = split_message.split(" ")
|
|
|
+ if len(arr_price_change)==6:
|
|
|
+ last_5m_change = arr_price_change[3]
|
|
|
+ last_1h_change = arr_price_change[4]
|
|
|
+
|
|
|
+ elif "liq:" in split_message:
|
|
|
+ split_message=split_message.replace("sol","")
|
|
|
+ split_message=split_message.replace(",","")
|
|
|
+ split_message = keep_alnum_forgmgn(split_message)
|
|
|
+ split_message=split_message.strip()
|
|
|
+ split_message = re.sub(r"\s+", " ", split_message)
|
|
|
+ arr_split_message = split_message.split(' ')
|
|
|
+ split_message_sol = arr_split_message[1]
|
|
|
+ number_liq_sol = float(split_message_sol)
|
|
|
+
|
|
|
+
|
|
|
+ elif "holder:" in split_message:
|
|
|
+ split_message = keep_alnum_forgmgn(split_message)
|
|
|
+ split_message=split_message.strip()
|
|
|
+ split_message = re.sub(r"\s+", " ", split_message)
|
|
|
+ arr_split_message = split_message.split(' ')
|
|
|
+ number_holders = int(arr_split_message[1])
|
|
|
+
|
|
|
+ elif "open" in split_message:
|
|
|
+ split_message = keep_alnum_forgmgn(split_message)
|
|
|
+ split_message=split_message.strip()
|
|
|
+ split_message = re.sub(r"\s+", " ", split_message)
|
|
|
+ arr_split_message = split_message.split(' ')
|
|
|
+ if "d" in arr_split_message[1]:
|
|
|
+ number_open = int(arr_split_message[1].replace("d","")) *24
|
|
|
+ elif "h" in arr_split_message[1]:
|
|
|
+ number_open = int(arr_split_message[1].replace("h",""))
|
|
|
+ elif "min" in arr_split_message[1]:
|
|
|
+ number_open = round(int(arr_split_message[1].replace("min","")) / 60 , 2 )
|
|
|
+
|
|
|
+ elif "nomint" in split_message:
|
|
|
+ split_message =split_message.replace("✅","yes ")
|
|
|
+ split_message =split_message.replace("❌","no ")
|
|
|
+ split_message =split_message.replace("?","no ")
|
|
|
+ split_message = keep_alnum_forgmgn(split_message)
|
|
|
+ split_message=split_message.strip()
|
|
|
+ split_message = re.sub(r"\s+", " ", split_message)
|
|
|
+ arr_split_message = split_message.split(' ')
|
|
|
+
|
|
|
+ nomint_flag = (arr_split_message[0]=="yes")
|
|
|
+ blacklist_flag = (arr_split_message[2]=="yes")
|
|
|
+ burnt_flag = (arr_split_message[4]=="yes")
|
|
|
+
|
|
|
+ elif "top 10:" in split_message:
|
|
|
+
|
|
|
+ split_message =split_message.replace("✅","yes ")
|
|
|
+ split_message =split_message.replace("❌","no ")
|
|
|
+ split_message =split_message.replace("?","no ")
|
|
|
+ split_message = keep_alnum_forgmgn(split_message)
|
|
|
+
|
|
|
+ split_message=split_message.strip()
|
|
|
+ split_message = re.sub(r"\s+", " ", split_message)
|
|
|
+ arr_split_message = split_message.split(' ')
|
|
|
+ top_10_flag = (arr_split_message[0]=="yes")
|
|
|
+
|
|
|
+
|
|
|
+ elif "⏳ dev:" in split_message:
|
|
|
+ split_message = keep_alnum_forgmgn(split_message)
|
|
|
+ split_message=split_message.replace("--","0")
|
|
|
+ split_message=split_message.strip()
|
|
|
+ if "hold" in split_message:
|
|
|
+ str_dev_status = "hold"
|
|
|
+ elif "sell all" in split_message:
|
|
|
+ str_dev_status = "unhold"
|
|
|
+ elif "buy more" in split_message:
|
|
|
+ str_dev_status = "hold"
|
|
|
+
|
|
|
+ if (nomint_flag and blacklist_flag and burnt_flag ) == False:
|
|
|
+ is_normal = False
|
|
|
+ if number_liq_sol <= 10:
|
|
|
+ # 1 sol = 150 $
|
|
|
+ is_normal =False
|
|
|
+ if top_10_flag == False:
|
|
|
+ is_normal = False
|
|
|
+ if number_holders <= 60 :
|
|
|
+ is_normal =False
|
|
|
+
|
|
|
+ print("info=",{
|
|
|
+ "nomint_flag":nomint_flag,
|
|
|
+ "blacklist_flag":blacklist_flag,
|
|
|
+ "burnt_flag":burnt_flag,
|
|
|
+ "top_10_flag":top_10_flag,
|
|
|
+
|
|
|
+ "str_dev_status":str_dev_status,
|
|
|
+ "str_swap_type":str_swap_type,
|
|
|
+ "str_tokenaddress":str_tokenaddress,
|
|
|
+ "str_dalaoaddress":str_dalaoaddress,
|
|
|
+ "str_swap_type":str_swap_type,
|
|
|
+ "number_swap_sol":number_swap_sol,
|
|
|
+ "number_swap_token_amount":number_swap_token_amount,
|
|
|
+ "str_now_price":str_now_price,
|
|
|
+ "number_open":number_open,
|
|
|
+ "number_liq_sol":number_liq_sol,
|
|
|
+ "number_holders":number_holders,
|
|
|
+ "last_5m_change":last_5m_change,
|
|
|
+ "last_1h_change":last_1h_change,
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+ if is_normal ==False:
|
|
|
+ print(f"{str_tokenaddress} is unnormal")
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ print(f"{str_tokenaddress} is normal")
|
|
|
+
|
|
|
+ global obj_queueing_send_feishu
|
|
|
+
|
|
|
+ cur_now_timestamp = int(time.time()*1000)
|
|
|
+ obj_queueing_send_feishu[cur_now_timestamp] = {
|
|
|
+ "is_sending":False,
|
|
|
+ "send_counts":0,
|
|
|
+ "sending_time":0,
|
|
|
+ "str_dev_status":str_dev_status,
|
|
|
+ "str_tokenaddress":str_tokenaddress,
|
|
|
+ "str_dalaoaddress":str_dalaoaddress,
|
|
|
+ "str_swap_type":str_swap_type,
|
|
|
+ "number_swap_sol":number_swap_sol,
|
|
|
+ "number_swap_token_amount":number_swap_token_amount,
|
|
|
+ "str_now_price":str_now_price,
|
|
|
+ "number_open":number_open,
|
|
|
+ "number_liq_sol":number_liq_sol,
|
|
|
+ "number_holders":number_holders,
|
|
|
+ "last_5m_change":last_5m_change,
|
|
|
+ "last_1h_change":last_1h_change,
|
|
|
+ "feishu_timestamp":cur_now_timestamp,
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return
|
|
|
+
|
|
|
+obj_global_info ={
|
|
|
+ "timedTasks_idx":0
|
|
|
+}
|
|
|
+
|
|
|
+sys.excepthook = global_exception_hook
|
|
|
+signal.signal(signal.SIGTERM, term_sig_handler)
|
|
|
+signal.signal(signal.SIGINT, term_sig_handler)
|
|
|
+print(f"Begin Listening for messages containing in chats ichat names...")
|
|
|
+
|
|
|
+
|
|
|
+async def timedTasks():
|
|
|
+ global obj_global_info
|
|
|
+ obj_global_info["timedTasks_idx"]+=1
|
|
|
+ cur_timedTasks_idx =obj_global_info["timedTasks_idx"]
|
|
|
+ if cur_timedTasks_idx <5:
|
|
|
+ return
|
|
|
+
|
|
|
+ if cur_timedTasks_idx%3609 == 0:
|
|
|
+ obj_global_info["timedTasks_idx"]=10
|
|
|
+
|
|
|
+
|
|
|
+ if cur_timedTasks_idx%15==0:
|
|
|
+ # 15s一次飞书
|
|
|
+ await ready_send_feishu_timed()
|
|
|
+
|
|
|
+ return
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+# scheduler = BackgroundScheduler({'apscheduler.timezone': 'UTC'})
|
|
|
+scheduler = AsyncIOScheduler({'apscheduler.timezone': 'UTC'})
|
|
|
+scheduler.add_job(timedTasks, "interval", seconds=1)
|
|
|
+# scheduler.add_job(func=timedTasks, trigger="cron", seconds=10)
|
|
|
+# '*/1 * * * * *'
|
|
|
+
|
|
|
+scheduler.start()
|
|
|
+client_gate.run_until_disconnected()
|
|
|
+asyncio.get_event_loop().run_forever()
|
|
|
+
|