bugfix
This commit is contained in:
parent
0e5bfc492d
commit
10af1ca2ad
16
config/tenants.json
Normal file
16
config/tenants.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"org_id":"org_demo",
|
||||||
|
"platform":"feishu",
|
||||||
|
"app_id":"cli_xxx",
|
||||||
|
"app_secret":"xxx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"org_id":"org_demo2",
|
||||||
|
"platform":"wecom",
|
||||||
|
"corp_id":"wwxxx",
|
||||||
|
"agent_id":"1000002",
|
||||||
|
"secret":"xxx"
|
||||||
|
}
|
||||||
|
]
|
||||||
8
im_platform/adapters/base.py
Normal file
8
im_platform/adapters/base.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
class BaseAdapter:
|
||||||
|
|
||||||
|
def __init__(self, tenant):
|
||||||
|
self.tenant = tenant
|
||||||
|
|
||||||
|
async def send_text(self, user, text):
|
||||||
|
raise NotImplementedError()
|
||||||
19
im_platform/adapters/feishu.py
Normal file
19
im_platform/adapters/feishu.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
import aiohttp
|
||||||
|
from im_platform.adapters.base import BaseAdapter
|
||||||
|
|
||||||
|
class FeishuAdapter(BaseAdapter):
|
||||||
|
|
||||||
|
async def send_text(self, user, text):
|
||||||
|
|
||||||
|
url = "https://open.feishu.cn/open-apis/im/v1/messages"
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"receive_id": user,
|
||||||
|
"msg_type": "text",
|
||||||
|
"content": {"text": text}
|
||||||
|
}
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.post(url, json=payload) as r:
|
||||||
|
return await r.text()
|
||||||
20
im_platform/adapters/wecom.py
Normal file
20
im_platform/adapters/wecom.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
import aiohttp
|
||||||
|
from im_platform.adapters.base import BaseAdapter
|
||||||
|
|
||||||
|
class WeComAdapter(BaseAdapter):
|
||||||
|
|
||||||
|
async def send_text(self, user, text):
|
||||||
|
|
||||||
|
url = "https://qyapi.weixin.qq.com/cgi-bin/message/send"
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"touser": user,
|
||||||
|
"msgtype": "text",
|
||||||
|
"agentid": self.tenant["agent_id"],
|
||||||
|
"text": {"content": text}
|
||||||
|
}
|
||||||
|
|
||||||
|
async with aiohttp.ClientSession() as s:
|
||||||
|
async with s.post(url, json=payload) as r:
|
||||||
|
return await r.text()
|
||||||
17
im_platform/api/webhooks.py
Normal file
17
im_platform/api/webhooks.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
from aiohttp import web
|
||||||
|
|
||||||
|
async def feishu_webhook(request):
|
||||||
|
|
||||||
|
data = await request.json()
|
||||||
|
print("feishu event", data)
|
||||||
|
|
||||||
|
return web.json_response({"ok": True})
|
||||||
|
|
||||||
|
|
||||||
|
async def wecom_webhook(request):
|
||||||
|
|
||||||
|
data = await request.json()
|
||||||
|
print("wecom event", data)
|
||||||
|
|
||||||
|
return web.json_response({"ok": True})
|
||||||
24
im_platform/core/tenant_manager.py
Normal file
24
im_platform/core/tenant_manager.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
TENANT_CACHE = {}
|
||||||
|
|
||||||
|
async def load_tenants():
|
||||||
|
global TENANT_CACHE
|
||||||
|
p = Path(__file__).resolve().parent.parent / "config" / "tenants.json"
|
||||||
|
if p.exists():
|
||||||
|
TENANT_CACHE = json.loads(p.read_text())
|
||||||
|
return TENANT_CACHE
|
||||||
|
|
||||||
|
def get_tenant_by_org(org_id):
|
||||||
|
for t in TENANT_CACHE:
|
||||||
|
if t["org_id"] == org_id:
|
||||||
|
return t
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_tenant_by_platform(platform, key):
|
||||||
|
for t in TENANT_CACHE:
|
||||||
|
if t["platform"] == platform and (t.get("app_id")==key or t.get("corp_id")==key):
|
||||||
|
return t
|
||||||
|
return None
|
||||||
17
im_platform/core/token_cache.py
Normal file
17
im_platform/core/token_cache.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
import asyncio
|
||||||
|
import time
|
||||||
|
|
||||||
|
CACHE = {}
|
||||||
|
|
||||||
|
async def get_token(key):
|
||||||
|
v = CACHE.get(key)
|
||||||
|
if not v:
|
||||||
|
return None
|
||||||
|
token, expire = v
|
||||||
|
if expire < time.time():
|
||||||
|
return None
|
||||||
|
return token
|
||||||
|
|
||||||
|
async def set_token(key, token, ttl):
|
||||||
|
CACHE[key] = (token, time.time() + ttl - 60)
|
||||||
63
im_platform/models/im_tenant.json
Normal file
63
im_platform/models/im_tenant.json
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "im_tenant",
|
||||||
|
"title": "IM\u79df\u6237",
|
||||||
|
"primary": "id",
|
||||||
|
"catelog": "relation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "org_id",
|
||||||
|
"title": "\u7ec4\u7ec7ID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "platform",
|
||||||
|
"title": "\u5e73\u53f0",
|
||||||
|
"type": "str",
|
||||||
|
"length": 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "app_id",
|
||||||
|
"title": "APPID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 64
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "app_secret",
|
||||||
|
"title": "APPSECRET",
|
||||||
|
"type": "str",
|
||||||
|
"length": 128
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "corp_id",
|
||||||
|
"title": "\u4f01\u4e1aID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 64
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "agent_id",
|
||||||
|
"title": "AgentID",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "idx_org",
|
||||||
|
"idxtype": "index",
|
||||||
|
"idxfields": [
|
||||||
|
"org_id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
16
im_platform/server.py
Normal file
16
im_platform/server.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
from aiohttp import web
|
||||||
|
from im_platform.api.webhooks import feishu_webhook, wecom_webhook
|
||||||
|
|
||||||
|
async def init_app():
|
||||||
|
app = web.Application()
|
||||||
|
|
||||||
|
app.router.add_post("/webhook/feishu", feishu_webhook)
|
||||||
|
app.router.add_post("/webhook/wecom", wecom_webhook)
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import asyncio
|
||||||
|
app = asyncio.run(init_app())
|
||||||
|
web.run_app(app, port=8080)
|
||||||
13
im_platform/workers/event_worker.py
Normal file
13
im_platform/workers/event_worker.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
QUEUE = asyncio.Queue()
|
||||||
|
|
||||||
|
async def push_event(event):
|
||||||
|
await QUEUE.put(event)
|
||||||
|
|
||||||
|
async def worker():
|
||||||
|
|
||||||
|
while True:
|
||||||
|
event = await QUEUE.get()
|
||||||
|
print("process event", event)
|
||||||
9
pyproject.toml
Normal file
9
pyproject.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
[project]
|
||||||
|
name = "im_platform"
|
||||||
|
version = "1.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"ahserver",
|
||||||
|
"cryptography",
|
||||||
|
"redis"
|
||||||
|
]
|
||||||
Loading…
x
Reference in New Issue
Block a user