===== Feishu-side configuration =====
APP_ID = os.environ["FEISHU_APP_ID"]
APP_SECRET = os.environ["FEISHU_APP_SECRET"]
===== LLM side: via the unified gateway =====
llm = OpenAI(
api_key=os.environ["THISTOKEN_API_KEY"],
base_url="https://api.thistoken.ai/v1", # Key point: unified gateway entry
)
def ask_llm(question: str) -> str:
resp = llm.chat.completions.create(
model="gpt-4o-mini", # To switch models, just change this line
messages=[
{"role": "system", "content": "你是群里的技术助手,回答简洁准确。"},
{"role": "user", "content": question},
],
)
return resp.choices[0].message.content
def do_reply(client: lark.Client, data: P2ImMessageReceiveV1):
msg = data.event.message
if msg.message_type != "text":
return
import json
text = json.loads(msg.content).get("text", "").strip()
if not text:
return
answer = ask_llm(text)
req = ReplyMessageRequest.builder() \
.message_id(msg.message_id) \
.request_body(ReplyMessageRequestBody.builder()
.content(json.dumps({"text": answer}))
.msg_type("text")
.build()) \
.build()
client.im.v1.message.reply(req)
def main():
client = lark.Client.builder() \
.app_id(APP_ID).app_secret(APP_SECRET).build()
handler = lark.EventDispatcherHandler.builder("", "") \
.register_p2_im_message_receive_v1(
lambda _, data: do_reply(client, data)) \
.build()
ws_client = lark.ws.Client(APP_ID, APP_SECRET,
event_handler=handler,
log_level=lark.LogLevel.INFO)
ws_client.start()
if __name__ == "__main__":
main()
Set environment variables before running:
export FEISHU_APP_ID=你的AppID
export FEISHU_APP_SECRET=你的AppSecret
export THISTOKEN_API_KEY=你的Key
python bot.py
Then @mention the bot in the test group and ask "Explain what WebSocket is in one sentence"—it will reply within seconds. At this point, the minimal loop is complete.
## A Few Pitfalls I Hit in Practice
- **Never hardcode keys in your code.** Use environment variables or a config center—build this habit from your very first line of code.
- **Long connection mode reconnects automatically after network outages**, but if your server drops connections frequently, check the heartbeat logs before blaming your code.
- **In group chats, only messages that @mention the bot trigger events.** If nothing happens, first confirm you @mentioned it rather than sending a regular message.
- **The model name must match the gateway's supported list.** You can view available models in the ThisToken.AI console; an incorrect model name will throw an error immediately.
## Where the Saved Time Goes
The first time I manually integrated a model provider's official SDK, I spent an entire afternoon just handling auth signatures and error codes; this time, switching to a unified gateway, the integration took about two hours—half of which was spent configuring Feishu permissions. More importantly, there are ongoing benefits:
- **Zero-cost model switching**: To compare different models' performance in group chat scenarios, just change one string—no need to go through registration, top-ups, and documentation again.
- **Key management in one place**: Small teams' worst nightmare is keys scattered across five or six scripts. With a gateway, one key manages all models.
- **Centralized billing**: All API usage is visible in a single dashboard—no more digging through five platforms at month-end reconciliation.
For independent developers, this means turning an idea into something usable in a single evening; for a team of three to five, it means no one has to be designated to grind through the differences between various SDK docs. The hours you save are the truly scarce resource in projects like these.
The registration link is here: https://api.thistoken.ai/register — once you have your key, the code above will run as-is.
---
Ready to try it yourself? Sign up at https://api.thistoken.ai/register to get your API key and start building.Ready to try Token.AI?
Create a project-level API Key, enable channels in the console, and configure routing, budgets, and audit logs.
注册 ThisToken.AI 并获取 API Key