feat: create telegraph account

- feat: create and store the telegraph token locally
 - check and use if there exist token in json
- feat: auto generate telegraph token for cohere.py and answer_it
- fix: optional delete other answer_it message and only leave a telegraph link messsage for clean view

Co-Authored-By: yihong <zouzou0208@gmail.com>
This commit is contained in:
Alter-xyz 2024-06-23 09:14:19 -04:00
parent bfad22ffaf
commit e2ffd7fa57
4 changed files with 114 additions and 44 deletions

1
.gitignore vendored
View File

@ -169,3 +169,4 @@ nohup.out
*.pdf *.pdf
.pdm-python .pdm-python
*.wav *.wav
telegraph_token.json

View File

@ -206,6 +206,57 @@ import markdown # pip install Markdown
from bs4 import BeautifulSoup # pip install beautifulsoup4 from bs4 import BeautifulSoup # pip install beautifulsoup4
def create_ph_account(short_name: str, author_name: str, author_url: str = None) -> str:
"""
Creates a new account on the Telegra.ph platform.
If an account already exists (stored in a local JSON file), returns the existing access token.
Otherwise, creates a new account and stores the information locally.
Sample request
https://api.telegra.ph/editAccountInfo?access_token=d3b25feccb89e508a9114afb82aa421fe2a9712b963b387cc5ad71e58722&short_name=Sandbox&author_name=Anonymous
Args:
short_name (str): The short name of the account.
author_name (str): The name of the author.
author_url (str, optional): The URL of the author's profile. Defaults to None.
Returns:
str: The access token for the account.
Raises:
requests.RequestException: If the API request fails.
json.JSONDecodeError: If the API response is not valid JSON.
KeyError: If the API response does not contain the expected data.
"""
TELEGRAPH_API_URL = "https://api.telegra.ph/createAccount"
# Try to load existing account information
try:
with open("telegraph_token.json", "r") as f:
account = json.load(f)
return account["result"]["access_token"]
except FileNotFoundError:
# If no existing account, create a new one
data = {
"short_name": short_name,
"author_name": author_name,
}
if author_url:
data["author_url"] = author_url
# Make API request
response = requests.post(TELEGRAPH_API_URL, data=data)
response.raise_for_status() # Raises an HTTPError for bad responses
account = response.json()
access_token = account["result"]["access_token"]
# Store the new account information
with open("telegraph_token.json", "w") as f:
json.dump(account, f)
return access_token
class TelegraphAPI: class TelegraphAPI:
def __init__(self, access_token): def __init__(self, access_token):
self.access_token = access_token self.access_token = access_token
@ -457,4 +508,5 @@ __all__ = [
"enrich_text_with_urls", "enrich_text_with_urls",
"image_to_data_uri", "image_to_data_uri",
"TelegraphAPI", "TelegraphAPI",
"create_ph_account",
] ]

View File

@ -21,6 +21,11 @@ COHERE_MODEL = "command-r-plus"
TELEGRA_PH_TOKEN = environ.get("TELEGRA_PH_TOKEN") TELEGRA_PH_TOKEN = environ.get("TELEGRA_PH_TOKEN")
if TELEGRA_PH_TOKEN: if TELEGRA_PH_TOKEN:
ph = TelegraphAPI(TELEGRA_PH_TOKEN) ph = TelegraphAPI(TELEGRA_PH_TOKEN)
else:
TELEGRA_PH_TOKEN = create_ph_account(
short_name="cohere", author_name="A Telegram Bot"
)
ph = TelegraphAPI(TELEGRA_PH_TOKEN)
if COHERE_API_KEY: if COHERE_API_KEY:
co = cohere.Client(api_key=COHERE_API_KEY) co = cohere.Client(api_key=COHERE_API_KEY)
@ -219,22 +224,15 @@ def cohere_handler(message: Message, bot: TeleBot) -> None:
if COHERE_API_KEY: if COHERE_API_KEY:
if not TELEGRA_PH_TOKEN:
def register(bot: TeleBot) -> None: def register(bot: TeleBot) -> None:
bot.register_message_handler( bot.register_message_handler(
cohere_handler_direct, commands=["cohere"], pass_bot=True cohere_handler_direct, commands=["cohere_no_ph"], pass_bot=True
) )
bot.register_message_handler( bot.register_message_handler(
cohere_handler_direct, regexp="^cohere:", pass_bot=True cohere_handler_direct, regexp="^cohere_no_ph:", pass_bot=True
) )
else:
def register(bot: TeleBot) -> None: def register(bot: TeleBot) -> None:
bot.register_message_handler( bot.register_message_handler(cohere_handler, commands=["cohere"], pass_bot=True)
cohere_handler, commands=["cohere"], pass_bot=True bot.register_message_handler(cohere_handler, regexp="^cohere:", pass_bot=True)
)
bot.register_message_handler(
cohere_handler, regexp="^cohere:", pass_bot=True
)

View File

@ -5,6 +5,7 @@ from telebot.types import Message
from expiringdict import ExpiringDict from expiringdict import ExpiringDict
from os import environ from os import environ
import time import time
import datetime
from openai import OpenAI from openai import OpenAI
import google.generativeai as genai import google.generativeai as genai
@ -22,7 +23,14 @@ import cohere
COHERE_API_KEY = environ.get("COHERE_API_KEY") COHERE_API_KEY = environ.get("COHERE_API_KEY")
TELEGRA_PH_TOKEN = environ.get("TELEGRA_PH_TOKEN") TELEGRA_PH_TOKEN = environ.get("TELEGRA_PH_TOKEN")
if COHERE_API_KEY:
co = cohere.Client(api_key=COHERE_API_KEY) co = cohere.Client(api_key=COHERE_API_KEY)
if TELEGRA_PH_TOKEN:
ph = TelegraphAPI(TELEGRA_PH_TOKEN)
else:
TELEGRA_PH_TOKEN = create_ph_account(
short_name="Answer it", author_name="A Telegram Bot"
)
ph = TelegraphAPI(TELEGRA_PH_TOKEN) ph = TelegraphAPI(TELEGRA_PH_TOKEN)
COHERE_MODEL = "command-r-plus" COHERE_MODEL = "command-r-plus"
@ -196,10 +204,7 @@ def answer_it_handler(message: Message, bot: TeleBot):
pass pass
##### Answer ##### ##### Answer #####
if TELEGRA_PH_TOKEN:
final_answer(latest_message, bot, full, chat_id_list) final_answer(latest_message, bot, full, chat_id_list)
else:
pass
def cohere_answer(latest_message: Message, bot: TeleBot, full, m): def cohere_answer(latest_message: Message, bot: TeleBot, full, m):
@ -210,45 +215,60 @@ def cohere_answer(latest_message: Message, bot: TeleBot, full, m):
player_message = [{"role": "User", "message": m}] player_message = [{"role": "User", "message": m}]
try: try:
r = co.chat_stream( stream = co.chat_stream(
model=COHERE_MODEL, model=COHERE_MODEL,
message=m, message=m,
temperature=0.4, temperature=0.3,
chat_history=player_message, chat_history=player_message,
prompt_truncation="AUTO", prompt_truncation="AUTO",
connectors=[{"id": "web-search"}], connectors=[{"id": "web-search"}],
citation_quality="fast", citation_quality="accurate",
preamble=f"You are Command R+, a large language model trained to have polite, helpful, inclusive conversations with people. The current time in Tornoto is {datetime.datetime.now(datetime.timezone.utc).astimezone().strftime('%Y-%m-%d %H:%M:%S')}, in Los Angeles is {datetime.datetime.now(datetime.timezone.utc).astimezone().astimezone(datetime.timezone(datetime.timedelta(hours=-7))).strftime('%Y-%m-%d %H:%M:%S')}, and in China is {datetime.datetime.now(datetime.timezone.utc).astimezone(datetime.timezone(datetime.timedelta(hours=8))).strftime('%Y-%m-%d %H:%M:%S')}.",
) )
s = "" s = ""
source = "" source = ""
start = time.time() start = time.time()
for event in r: for event in stream:
if event.event_type == "text-generation": if event.event_type == "stream-start":
s += event.text.encode("utf-8").decode("utf-8") bot_reply_markdown(reply_id, who, "Thinking...", bot)
if time.time() - start > 1.2: elif event.event_type == "search-queries-generation":
start = time.time() bot_reply_markdown(reply_id, who, "Searching online...", bot)
bot_reply_markdown(reply_id, who, s, bot, split_text=False)
elif event.event_type == "search-results": elif event.event_type == "search-results":
bot_reply_markdown(reply_id, who, "Reading...", bot)
for doc in event.documents: for doc in event.documents:
source += f"\n[{doc['title']}]({doc['url']})" source += f"\n{doc['title']}\n{doc['url']}\n"
elif event.event_type == "text-generation":
s += event.text.encode("utf-8").decode("utf-8")
if time.time() - start > 0.4:
start = time.time()
bot_reply_markdown(
reply_id,
who,
f"\nStill thinking{len(s)}...",
bot,
split_text=True,
)
elif event.event_type == "stream-end": elif event.event_type == "stream-end":
break break
content = (
s
+ "\n------\n------\n"
+ source
+ f"\n------\n------\nLast Update{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
)
# maybe not complete
# maybe the same message
try: try:
bot_reply_markdown(reply_id, who, s, bot) bot_reply_markdown(reply_id, who, s, bot, split_text=True)
except: except:
pass pass
except Exception as e: except Exception as e:
print(e) print(e)
bot_reply_markdown(reply_id, who, "Answer wrong", bot) bot_reply_markdown(reply_id, who, "Answer wrong", bot)
player_message.clear()
content = s + "\n------\n" + source return full, reply_id.message_id
full += f"\n---\n{who}:\n{content}" full += f"\n---\n{who}:\n{content}"
chat_id = reply_id.chat.id return full, reply_id.message_id
return full, chat_id
def final_answer(latest_message: Message, bot: TeleBot, full, list): def final_answer(latest_message: Message, bot: TeleBot, full, list):
@ -258,9 +278,8 @@ def final_answer(latest_message: Message, bot: TeleBot, full, list):
ph_s = ph.create_page_md(title="Answer it", markdown_text=full) ph_s = ph.create_page_md(title="Answer it", markdown_text=full)
bot_reply_markdown(reply_id, who, f"[View]({ph_s})", bot) bot_reply_markdown(reply_id, who, f"[View]({ph_s})", bot)
# delete the chat message, only leave a telegra.ph link # delete the chat message, only leave a telegra.ph link
# for i in list: # for i in list:
# bot.delete_message(chat_id=chat_id, message_id=i) # bot.delete_message(latest_message.chat.id, i)
if GOOGLE_GEMINI_KEY and CHATGPT_API_KEY: if GOOGLE_GEMINI_KEY and CHATGPT_API_KEY: