11
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"jx3_richang":{
|
||||||
|
"url":"https://www.jx3api.com/data/active/calendar",
|
||||||
|
"method":"GET",
|
||||||
|
"description":"获取剑网三日常任务",
|
||||||
|
"params":{
|
||||||
|
"server": "眉间雪",
|
||||||
|
"num": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+132
-54
@@ -1,25 +1,68 @@
|
|||||||
# core/request.py
|
# core/request.py
|
||||||
import requests
|
import aiohttp
|
||||||
import json
|
import json
|
||||||
|
from aiohttp import ClientTimeout
|
||||||
from astrbot.api import logger
|
from astrbot.api import logger
|
||||||
|
|
||||||
def api_data_post(api_url, json_data=None, outdata=None):
|
class APIClient:
|
||||||
"""
|
"""
|
||||||
获取数据的POST请求函数
|
API客户端类,封装GET和POST请求功能
|
||||||
|
|
||||||
Args:
|
|
||||||
api_url: API地址
|
|
||||||
json_data: POST请求的JSON数据
|
|
||||||
outdata: 返回数据中要提取的字段
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
成功时返回outdata字段的数据,失败返回None
|
|
||||||
"""
|
"""
|
||||||
try:
|
|
||||||
response = requests.post(api_url, json=json_data, timeout=10, verify=False)
|
def __init__(self, base_timeout=10, ssl_verify=False):
|
||||||
response.raise_for_status()
|
"""
|
||||||
data = response.json()
|
初始化APIClient
|
||||||
|
|
||||||
|
Args:
|
||||||
|
base_timeout: 默认超时时间(秒)
|
||||||
|
ssl_verify: SSL证书验证开关
|
||||||
|
"""
|
||||||
|
self.base_timeout = base_timeout
|
||||||
|
self.ssl_verify = ssl_verify
|
||||||
|
|
||||||
|
async def _make_request(self, method, url, **kwargs):
|
||||||
|
"""
|
||||||
|
内部请求方法,处理通用请求逻辑
|
||||||
|
|
||||||
|
Args:
|
||||||
|
method: 请求方法 ('GET', 'POST')
|
||||||
|
url: 请求URL
|
||||||
|
**kwargs: 其他请求参数
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
成功时返回解析后的数据,失败返回None
|
||||||
|
"""
|
||||||
|
timeout = ClientTimeout(total=self.base_timeout)
|
||||||
|
|
||||||
|
try:
|
||||||
|
async with aiohttp.ClientSession(timeout=timeout) as session:
|
||||||
|
async with session.request(method, url, ssl=self.ssl_verify, **kwargs) as response:
|
||||||
|
response.raise_for_status()
|
||||||
|
data = await response.json()
|
||||||
|
|
||||||
|
# 检查API响应状态
|
||||||
|
return self._check_response_data(data)
|
||||||
|
|
||||||
|
except aiohttp.ClientError as e:
|
||||||
|
logger.error(f"请求出错: {e}")
|
||||||
|
return None
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
logger.error(f"JSON解析错误: {e}")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"未知错误: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _check_response_data(self, data):
|
||||||
|
"""
|
||||||
|
检查API响应数据的通用逻辑
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data: API返回的数据
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
检查通过返回数据,否则返回None
|
||||||
|
"""
|
||||||
# 检查是否有code字段
|
# 检查是否有code字段
|
||||||
if 'code' in data:
|
if 'code' in data:
|
||||||
# 有code字段时,检查是否成功
|
# 有code字段时,检查是否成功
|
||||||
@@ -32,53 +75,88 @@ def api_data_post(api_url, json_data=None, outdata=None):
|
|||||||
logger.error("API返回空数据")
|
logger.error("API返回空数据")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
async def post(self, api_url, json_data=None, outdata=None):
|
||||||
|
"""
|
||||||
|
POST请求方法
|
||||||
|
|
||||||
|
Args:
|
||||||
|
api_url: API地址
|
||||||
|
json_data: POST请求的JSON数据
|
||||||
|
outdata: 返回数据中要提取的字段
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
成功时返回outdata字段的数据,失败返回None
|
||||||
|
"""
|
||||||
|
data = await self._make_request('POST', api_url, json=json_data)
|
||||||
|
|
||||||
|
if data is None:
|
||||||
|
return None
|
||||||
|
|
||||||
if outdata is None or outdata == "":
|
if outdata is None or outdata == "":
|
||||||
return data
|
return data
|
||||||
return data.get(outdata, {})
|
return data.get(outdata, {})
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
|
||||||
logger.error(f"请求出错: {e}")
|
|
||||||
return None
|
|
||||||
except json.JSONDecodeError as e:
|
|
||||||
logger.error(f"JSON解析错误: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def api_data_get(api_url,params=None,outdata=None):
|
async def get(self, api_url, params=None, outdata=None):
|
||||||
"""
|
"""
|
||||||
获取数据的GET请求函数
|
GET请求方法
|
||||||
|
|
||||||
Args:
|
|
||||||
api_url: API地址
|
|
||||||
|
|
||||||
params: 其他查询参数
|
Args:
|
||||||
|
api_url: API地址
|
||||||
Returns:
|
params: 其他查询参数
|
||||||
成功时返回outdata字段的数据,失败返回None
|
outdata: 返回数据中要提取的字段
|
||||||
"""
|
|
||||||
try:
|
|
||||||
response = requests.get(api_url, params, timeout=10, verify=False)
|
|
||||||
response.raise_for_status()
|
|
||||||
data = response.json()
|
|
||||||
|
|
||||||
# 检查是否有code字段
|
Returns:
|
||||||
if 'code' in data:
|
成功时返回outdata字段的数据,失败返回None
|
||||||
# 有code字段时,检查是否成功
|
"""
|
||||||
if data.get('code') not in [200, "0", 0]:
|
data = await self._make_request('GET', api_url, params=params)
|
||||||
logger.error(f"API返回错误:{data.get('code', '未知状态')} {data.get('msg', '未知错误')}")
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
# 无code字段时,检查数据是否为空
|
|
||||||
if not data:
|
|
||||||
logger.error("API返回空数据")
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
if data is None:
|
||||||
|
return None
|
||||||
|
|
||||||
if outdata is None or outdata == "":
|
if outdata is None or outdata == "":
|
||||||
return data
|
return data
|
||||||
return data.get(outdata, {})
|
return data.get(outdata, {})
|
||||||
|
|
||||||
|
async def request(self, api_config, outdata=None):
|
||||||
|
"""
|
||||||
|
通用请求方法,根据api_config中的method选择GET或POST
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
Args:
|
||||||
logger.error(f"请求出错: {e}")
|
api_config: 包含url, method, params/json等信息的字典
|
||||||
return None
|
outdata: 返回数据中要提取的字段
|
||||||
except json.JSONDecodeError as e:
|
|
||||||
logger.error(f"JSON解析错误: {e}")
|
Returns:
|
||||||
return None
|
成功时返回outdata字段的数据,失败返回None
|
||||||
|
"""
|
||||||
|
if 'url' not in api_config or 'method' not in api_config:
|
||||||
|
logger.error("api_config必须包含url和method字段")
|
||||||
|
return None
|
||||||
|
data = await self._make_request(api_config['method'], api_config['url'], api_config['params'])
|
||||||
|
|
||||||
|
if data is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if outdata is None or outdata == "":
|
||||||
|
return data
|
||||||
|
return data.get(outdata, {})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 保持原有函数接口的兼容性(可选)
|
||||||
|
async def api_data_post(api_url, json_data=None, outdata=None):
|
||||||
|
"""兼容原有函数的POST请求"""
|
||||||
|
client = APIClient()
|
||||||
|
return await client.post(api_url, json_data, outdata)
|
||||||
|
|
||||||
|
async def api_data_get(api_url, params=None, outdata=None):
|
||||||
|
"""兼容原有函数的GET请求"""
|
||||||
|
client = APIClient()
|
||||||
|
return await client.get(api_url, params, outdata)
|
||||||
@@ -1,29 +1,45 @@
|
|||||||
import urllib3
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from astrbot.api.event import filter, AstrMessageEvent, MessageEventResult
|
from astrbot.api.event import filter, AstrMessageEvent, MessageEventResult
|
||||||
from astrbot.api.star import Context, Star, register
|
from astrbot.api.star import Context, Star, register, StarTools
|
||||||
from astrbot.api import logger
|
from astrbot.api import logger
|
||||||
from astrbot.api import AstrBotConfig
|
from astrbot.api import AstrBotConfig
|
||||||
|
|
||||||
from .core.load_template import load_template
|
from .core.load_template import load_template
|
||||||
from .core.jx3_data import jx3_data_jiaoyihang,jx3_data_wujia
|
from .core.jx3_data import jx3_data_jiaoyihang,jx3_data_wujia
|
||||||
from .core.api_data import api_data_get, api_data_post
|
from .core.api_data import APIClient,api_data_get, api_data_post
|
||||||
from .core.sql_data import sql_data_searchdata,sql_data_select
|
from .core.sql_data import sql_data_searchdata,sql_data_select
|
||||||
|
|
||||||
# 禁用 SSL 警告
|
|
||||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
||||||
|
|
||||||
|
@register("astrbot_plugin_jx3api",
|
||||||
@register("jx3api", "fxdyz", "通过接口调用剑网三API接口获取游戏数据", "1.0.0")
|
"fxdyz",
|
||||||
|
"通过接口调用剑网三API接口获取游戏数据",
|
||||||
|
"1.0.0",
|
||||||
|
"https://github.com/qsc20001102/astrbot_plugin_jx3api.git"
|
||||||
|
)
|
||||||
class Jx3ApiPlugin(Star):
|
class Jx3ApiPlugin(Star):
|
||||||
def __init__(self, context: Context, config: AstrBotConfig):
|
def __init__(self, context: Context, config: AstrBotConfig):
|
||||||
super().__init__(context)
|
super().__init__(context)
|
||||||
|
#获取配置
|
||||||
self.conf = config
|
self.conf = config
|
||||||
print(self.conf)
|
# 本地数据存储路径
|
||||||
|
self.local_data_dir = StarTools.get_data_dir("astrbot_plugin_jx3api")
|
||||||
|
# api数据文件
|
||||||
|
self.api_file = Path(__file__).parent / "api_config.json"
|
||||||
|
logger.info("jx3api插件初始化完成")
|
||||||
|
|
||||||
async def initialize(self):
|
async def initialize(self):
|
||||||
"""可选择实现异步的插件初始化方法,当实例化该插件类之后会自动调用该方法。"""
|
"""可选择实现异步的插件初始化方法,当实例化该插件类之后会自动调用该方法。"""
|
||||||
|
#创建类实例
|
||||||
|
self.api_data = APIClient()
|
||||||
|
logger.info("jx3api插件创建实例完成")
|
||||||
|
|
||||||
|
async def message_str(self, event: AstrMessageEvent):
|
||||||
|
"""可选择实现异步的消息预处理方法,在消息分发到具体命令前会调用该方法。"""
|
||||||
|
# 预处理消息内容
|
||||||
|
message_str = event.message_str.strip()
|
||||||
|
return message_str.split()
|
||||||
|
|
||||||
@filter.command("剑三日常")
|
@filter.command("剑三日常")
|
||||||
async def jx3_richang(self, event: AstrMessageEvent):
|
async def jx3_richang(self, event: AstrMessageEvent):
|
||||||
@@ -32,25 +48,23 @@ class Jx3ApiPlugin(Star):
|
|||||||
custom_url = "https://www.jx3api.com/data/active/calendar"
|
custom_url = "https://www.jx3api.com/data/active/calendar"
|
||||||
# 接口参数
|
# 接口参数
|
||||||
params = {
|
params = {
|
||||||
"server": "眉间雪", # 默认服务器
|
"server": "眉间雪", # 服务器
|
||||||
"num": 0 # 默认当天
|
"num": 0 # 当天
|
||||||
}
|
}
|
||||||
|
|
||||||
# 获取消息内容
|
# 获取消息内容
|
||||||
message_str = event.message_str.strip()
|
parts = await self.message_str(event)
|
||||||
parts = message_str.split()
|
|
||||||
# 解析消息内容
|
# 解析消息内容
|
||||||
if len(parts) > 1:
|
if len(parts) > 1:
|
||||||
params["server"] = parts[1] # 第二个参数为服务器
|
params["server"] = parts[1]
|
||||||
|
|
||||||
if len(parts) > 2:
|
if len(parts) > 2:
|
||||||
try:
|
try:
|
||||||
params["num"] = int(parts[2]) # 第三个参数为日期偏移
|
params["num"] = int(parts[2])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
params["num"] = 0 # 参数为日期偏移
|
params["num"] = 0
|
||||||
|
|
||||||
# 获取数据
|
# 获取数据
|
||||||
data = api_data_get(custom_url, params,"data")
|
data = await self.api_data.request(self.api_file['jx3_richang'], params,"data")
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
yield event.plain_result("获取获取接口信息失败,请稍后再试")
|
yield event.plain_result("获取获取接口信息失败,请稍后再试")
|
||||||
|
|||||||
Reference in New Issue
Block a user