mirror of
http://shenjack.top:5100/shenjack/icalingua-python-bot.git
synced 2024-11-23 12:41:05 +08:00
p1
This commit is contained in:
parent
a606db5cb0
commit
ca9033a23f
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@ env*
|
||||||
|
|
||||||
config.toml
|
config.toml
|
||||||
|
|
||||||
|
.idea
|
||||||
*.pyc
|
*.pyc
|
||||||
*__pycache__/
|
*__pycache__/
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use serde_json::{json, Value as JsonValue};
|
||||||
use crate::data_struct::tailchat::{ConverseId, GroupId, MessageId, UserId};
|
use crate::data_struct::tailchat::{ConverseId, GroupId, MessageId, UserId};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct ReciveMessage {
|
pub struct ReceiveMessage {
|
||||||
/// 消息ID
|
/// 消息ID
|
||||||
#[serde(rename = "_id")]
|
#[serde(rename = "_id")]
|
||||||
pub msg_id: MessageId,
|
pub msg_id: MessageId,
|
||||||
|
@ -27,7 +27,7 @@ pub struct ReciveMessage {
|
||||||
pub has_recall: bool,
|
pub has_recall: bool,
|
||||||
/// 暂时懒得解析这玩意
|
/// 暂时懒得解析这玩意
|
||||||
/// 准确来说是不确定内容, 毕竟没细看 API
|
/// 准确来说是不确定内容, 毕竟没细看 API
|
||||||
pub meta: JsonValue,
|
pub meta: Option<JsonValue>,
|
||||||
/// 也懒得解析这玩意
|
/// 也懒得解析这玩意
|
||||||
pub reactions: Vec<JsonValue>,
|
pub reactions: Vec<JsonValue>,
|
||||||
/// 创建时间
|
/// 创建时间
|
||||||
|
@ -38,8 +38,14 @@ pub struct ReciveMessage {
|
||||||
pub updated_at: String,
|
pub updated_at: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReciveMessage {
|
impl ReceiveMessage {
|
||||||
pub fn is_reply(&self) -> bool { self.meta.get("reply").is_some() }
|
pub fn is_reply(&self) -> bool {
|
||||||
|
if let Some(meta) = &self.meta {
|
||||||
|
meta.get("reply").is_some()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 创建一个对这条消息的回复
|
/// 创建一个对这条消息的回复
|
||||||
pub fn as_reply(&self) -> SendingMessage {
|
pub fn as_reply(&self) -> SendingMessage {
|
||||||
|
@ -62,7 +68,7 @@ impl ReciveMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ReciveMessage {
|
impl Display for ReceiveMessage {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
// msgid|groupid-converseid|senderid|content
|
// msgid|groupid-converseid|senderid|content
|
||||||
write!(
|
write!(
|
||||||
|
@ -90,6 +96,8 @@ pub struct SendingMessage {
|
||||||
/// 消息内容
|
/// 消息内容
|
||||||
///
|
///
|
||||||
/// 其实还有个 plain, 就是不知道干啥的
|
/// 其实还有个 plain, 就是不知道干啥的
|
||||||
|
///
|
||||||
|
/// [img height=1329 width=1918]{BACKEND}/static/files/6602e20d7b8d10675758e36b/8db505b87bdf9fb309467abcec4d8e2a.png[/img]
|
||||||
pub content: String,
|
pub content: String,
|
||||||
/// 会话ID
|
/// 会话ID
|
||||||
#[serde(rename = "converseId")]
|
#[serde(rename = "converseId")]
|
||||||
|
@ -99,6 +107,9 @@ pub struct SendingMessage {
|
||||||
pub group_id: Option<GroupId>,
|
pub group_id: Option<GroupId>,
|
||||||
/// 消息的元数据
|
/// 消息的元数据
|
||||||
pub meta: Option<ReplyMeta>,
|
pub meta: Option<ReplyMeta>,
|
||||||
|
/// 额外携带的文件
|
||||||
|
#[serde(skip)]
|
||||||
|
pub file: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SendingMessage {
|
impl SendingMessage {
|
||||||
|
@ -113,6 +124,7 @@ impl SendingMessage {
|
||||||
converse_id,
|
converse_id,
|
||||||
group_id,
|
group_id,
|
||||||
meta,
|
meta,
|
||||||
|
file: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn new_without_meta(
|
pub fn new_without_meta(
|
||||||
|
@ -125,8 +137,13 @@ impl SendingMessage {
|
||||||
converse_id,
|
converse_id,
|
||||||
group_id,
|
group_id,
|
||||||
meta: None,
|
meta: None,
|
||||||
|
file: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn contain_file(&self) -> bool { self.file.is_some() }
|
||||||
|
|
||||||
|
pub fn add_img(&mut self, file: Vec<u8>, ) { self.file = Some(file); }
|
||||||
|
|
||||||
pub fn as_value(&self) -> JsonValue { serde_json::to_value(self).unwrap() }
|
pub fn as_value(&self) -> JsonValue { serde_json::to_value(self).unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +160,7 @@ pub struct ReplyMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReplyMeta {
|
impl ReplyMeta {
|
||||||
pub fn from_recive_message(msg: &ReciveMessage) -> Self {
|
pub fn from_recive_message(msg: &ReceiveMessage) -> Self {
|
||||||
Self {
|
Self {
|
||||||
mentions: vec![msg.sender_id.clone()],
|
mentions: vec![msg.sender_id.clone()],
|
||||||
reply_id: msg.msg_id.clone(),
|
reply_id: msg.msg_id.clone(),
|
||||||
|
|
|
@ -33,32 +33,18 @@ pub struct UpdateDMConverse {
|
||||||
pub updated_at: String,
|
pub updated_at: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
pub type Writeable<T> = Arc<RwLock<T>>;
|
pub type Writeable<T> = Arc<RwLock<T>>;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BotStatus {
|
pub struct BotStatus {
|
||||||
user_id: Writeable<UserId>,
|
user_id: UserId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BotStatus {
|
impl BotStatus {
|
||||||
pub fn new(user_id: UserId) -> Self {
|
pub fn new(user_id: UserId) -> Self { Self { user_id } }
|
||||||
Self {
|
|
||||||
user_id: Arc::new(RwLock::new(user_id)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_user_id(&self) -> UserId { self.user_id.read().await.clone() }
|
pub fn get_user_id(&self) -> UserId { self.user_id.clone() }
|
||||||
|
|
||||||
pub fn block_get_user_id(&self) -> UserId {
|
|
||||||
tokio::task::block_in_place(|| {
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
||||||
rt.block_on(self.get_user_id())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn set_user_id(&self, user_id: UserId) {
|
|
||||||
self.user_id.write().await.clone_from(&user_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub async fn add_message(payload: Payload, client: Client) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("add_message {}", message.to_string().cyan());
|
event!(Level::INFO, "add_message {}", message.to_string().cyan());
|
||||||
// 就在这里处理掉最基本的消息
|
// 就在这里处理掉最基本的消息
|
||||||
// 之后的处理交给插件
|
// 之后的处理交给插件
|
||||||
if !message.is_from_self() && !message.is_reply() {
|
if !message.is_from_self() && !message.is_reply() {
|
||||||
|
@ -68,7 +68,7 @@ pub async fn delete_message(payload: Payload, client: Client) {
|
||||||
// 消息 id
|
// 消息 id
|
||||||
if let Some(value) = values.first() {
|
if let Some(value) = values.first() {
|
||||||
if let Some(msg_id) = value.as_str() {
|
if let Some(msg_id) = value.as_str() {
|
||||||
info!("delete_message {}", msg_id.to_string().yellow());
|
event!(Level::INFO, "delete_message {}", msg_id.to_string().yellow());
|
||||||
|
|
||||||
py::call::ica_delete_message_py(msg_id.to_string(), &client).await;
|
py::call::ica_delete_message_py(msg_id.to_string(), &client).await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
pub const ICA_VERSION: &str = "1.6.0";
|
pub const ICA_VERSION: &str = "1.6.0";
|
||||||
pub const TAILCHAT_VERSION: &str = "1.1.0";
|
pub const TAILCHAT_VERSION: &str = "1.1.0";
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
macro_rules! async_callback_with_state {
|
macro_rules! async_callback_with_state {
|
||||||
($f:expr, $state:expr) => {{
|
($f:expr, $state:expr) => {{
|
||||||
use futures_util::FutureExt;
|
use futures_util::FutureExt;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use rust_socketio::asynchronous::Client;
|
use rust_socketio::asynchronous::Client;
|
||||||
use tracing::{info, warn};
|
use tracing::{event, info, warn, Level};
|
||||||
|
|
||||||
|
use crate::data_struct::tailchat::status::BotStatus;
|
||||||
use crate::data_struct::{ica, tailchat};
|
use crate::data_struct::{ica, tailchat};
|
||||||
use crate::error::PyPluginError;
|
use crate::error::PyPluginError;
|
||||||
use crate::py::{class, PyPlugin, PyStatus};
|
use crate::py::{class, PyPlugin, PyStatus};
|
||||||
|
@ -106,7 +108,7 @@ macro_rules! call_py_func {
|
||||||
$func_name.to_string(),
|
$func_name.to_string(),
|
||||||
$plugin_path.to_string_lossy().to_string(),
|
$plugin_path.to_string_lossy().to_string(),
|
||||||
);
|
);
|
||||||
warn!("failed to call function<{}>: {:?}", $func_name, e);
|
event!(Level::WARN, "failed to call function<{}>: {:?}", $func_name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -126,20 +128,6 @@ pub async fn ica_new_message_py(message: &ica::messages::NewMessage, client: &Cl
|
||||||
let args = (msg, client);
|
let args = (msg, client);
|
||||||
// 甚至实际上压根不需要await这个spawn, 直接让他自己跑就好了(离谱)
|
// 甚至实际上压根不需要await这个spawn, 直接让他自己跑就好了(离谱)
|
||||||
call_py_func!(args, plugin, path, ICA_NEW_MESSAGE_FUNC, client);
|
call_py_func!(args, plugin, path, ICA_NEW_MESSAGE_FUNC, client);
|
||||||
// tokio::spawn(async move {
|
|
||||||
// Python::with_gil(|py| {
|
|
||||||
// if let Ok(py_func) = get_func(plugin.py_module.bind(py), ICA_NEW_MESSAGE_FUNC) {
|
|
||||||
// if let Err(e) = py_func.call1(args) {
|
|
||||||
// let e = PyPluginError::FuncCallError(
|
|
||||||
// e,
|
|
||||||
// ICA_NEW_MESSAGE_FUNC.to_string(),
|
|
||||||
// path.to_string_lossy().to_string(),
|
|
||||||
// );
|
|
||||||
// warn!("failed to call function<{}>: {:?}", ICA_NEW_MESSAGE_FUNC, e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,29 +140,19 @@ pub async fn ica_delete_message_py(msg_id: ica::MessageId, client: &Client) {
|
||||||
let client = class::ica::IcaClientPy::new(client);
|
let client = class::ica::IcaClientPy::new(client);
|
||||||
let args = (msg_id.clone(), client);
|
let args = (msg_id.clone(), client);
|
||||||
call_py_func!(args, plugin, path, ICA_DELETE_MESSAGE_FUNC, client);
|
call_py_func!(args, plugin, path, ICA_DELETE_MESSAGE_FUNC, client);
|
||||||
// tokio::spawn(async move {
|
|
||||||
// Python::with_gil(|py| {
|
|
||||||
// if let Ok(py_func) = get_func(plugin.py_module.bind(py), ICA_DELETE_MESSAGE_FUNC) {
|
|
||||||
// if let Err(e) = py_func.call1(args) {
|
|
||||||
// let e = PyPluginError::FuncCallError(
|
|
||||||
// e,
|
|
||||||
// ICA_DELETE_MESSAGE_FUNC.to_string(),
|
|
||||||
// path.to_string_lossy().to_string(),
|
|
||||||
// );
|
|
||||||
// warn!("failed to call function<{}>: {:?}", ICA_DELETE_MESSAGE_FUNC, e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn tailchat_new_message_py(message: &tailchat::messages::ReciveMessage, client: &Client) {
|
pub async fn tailchat_new_message_py(
|
||||||
|
message: &tailchat::messages::ReceiveMessage,
|
||||||
|
client: &Client,
|
||||||
|
status: Arc<BotStatus>,
|
||||||
|
) {
|
||||||
verify_plugins();
|
verify_plugins();
|
||||||
|
|
||||||
let plugins = PyStatus::get_files();
|
let plugins = PyStatus::get_files();
|
||||||
for (path, plugin) in plugins.iter() {
|
for (path, plugin) in plugins.iter() {
|
||||||
let msg = class::tailchat::TailchatReciveMessagePy::from_recive_message(message);
|
let msg = class::tailchat::TailchatReceiveMessagePy::from_recive_message(message);
|
||||||
let client = class::tailchat::TailchatClientPy::new(client);
|
let client = class::tailchat::TailchatClientPy::new(client);
|
||||||
let args = (msg, client);
|
let args = (msg, client);
|
||||||
call_py_func!(args, plugin, path, TAILCHAT_NEW_MESSAGE_FUNC, client);
|
call_py_func!(args, plugin, path, TAILCHAT_NEW_MESSAGE_FUNC, client);
|
||||||
|
|
|
@ -3,7 +3,7 @@ use pyo3::prelude::*;
|
||||||
use rust_socketio::asynchronous::Client;
|
use rust_socketio::asynchronous::Client;
|
||||||
use tracing::{debug, info, warn};
|
use tracing::{debug, info, warn};
|
||||||
|
|
||||||
use crate::data_struct::tailchat::messages::{ReciveMessage, SendingMessage};
|
use crate::data_struct::tailchat::messages::{ReceiveMessage, SendingMessage};
|
||||||
use crate::data_struct::tailchat::{ConverseId, GroupId, MessageId, UserId};
|
use crate::data_struct::tailchat::{ConverseId, GroupId, MessageId, UserId};
|
||||||
use crate::tailchat::client::send_message;
|
use crate::tailchat::client::send_message;
|
||||||
|
|
||||||
|
@ -27,13 +27,13 @@ impl TailchatClientPy {
|
||||||
pub struct TailchatStatusPy {}
|
pub struct TailchatStatusPy {}
|
||||||
|
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
#[pyo3(name = "TailchatReciveMessage")]
|
#[pyo3(name = "TailchatReceiveMessage")]
|
||||||
pub struct TailchatReciveMessagePy {
|
pub struct TailchatReceiveMessagePy {
|
||||||
pub message: ReciveMessage,
|
pub message: ReceiveMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TailchatReciveMessagePy {
|
impl TailchatReceiveMessagePy {
|
||||||
pub fn from_recive_message(msg: &ReciveMessage) -> Self {
|
pub fn from_recive_message(msg: &ReceiveMessage) -> Self {
|
||||||
Self {
|
Self {
|
||||||
message: msg.clone(),
|
message: msg.clone(),
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ impl TailchatClientPy {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl TailchatReciveMessagePy {
|
impl TailchatReceiveMessagePy {
|
||||||
#[getter]
|
#[getter]
|
||||||
pub fn get_is_reply(&self) -> bool { self.message.is_reply() }
|
pub fn get_is_reply(&self) -> bool { self.message.is_reply() }
|
||||||
#[getter]
|
#[getter]
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use md5::{Digest, Md5};
|
use md5::{Digest, Md5};
|
||||||
use reqwest::ClientBuilder as reqwest_ClientBuilder;
|
use reqwest::ClientBuilder as reqwest_ClientBuilder;
|
||||||
|
@ -11,9 +13,9 @@ use serde_json::{json, Value};
|
||||||
use tracing::{event, span, Level};
|
use tracing::{event, span, Level};
|
||||||
|
|
||||||
use crate::config::TailchatConfig;
|
use crate::config::TailchatConfig;
|
||||||
use crate::data_struct::tailchat::status::LoginData;
|
use crate::data_struct::tailchat::status::{BotStatus, LoginData};
|
||||||
use crate::error::{ClientResult, TailchatError};
|
use crate::error::{ClientResult, TailchatError};
|
||||||
use crate::StopGetter;
|
use crate::{async_callback_with_state, StopGetter};
|
||||||
|
|
||||||
pub async fn start_tailchat(
|
pub async fn start_tailchat(
|
||||||
config: TailchatConfig,
|
config: TailchatConfig,
|
||||||
|
@ -60,11 +62,17 @@ pub async fn start_tailchat(
|
||||||
Err(e) => return Err(TailchatError::LoginFailed(e.to_string())),
|
Err(e) => return Err(TailchatError::LoginFailed(e.to_string())),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let sharded_status = BotStatus::new(status.user_id.clone());
|
||||||
|
let sharded_status = Arc::new(sharded_status);
|
||||||
|
|
||||||
let socket = ClientBuilder::new(config.host)
|
let socket = ClientBuilder::new(config.host)
|
||||||
.auth(json!({"token": status.jwt.clone()}))
|
.auth(json!({"token": status.jwt.clone()}))
|
||||||
.transport_type(TransportType::Websocket)
|
.transport_type(TransportType::Websocket)
|
||||||
.on_any(async_any_callback!(events::any_event))
|
.on_any(async_any_callback!(events::any_event))
|
||||||
.on("notify:chat.message.add", async_callback!(events::on_message))
|
.on(
|
||||||
|
"notify:chat.message.add",
|
||||||
|
async_callback_with_state!(events::on_message, sharded_status.clone()),
|
||||||
|
)
|
||||||
.on("notify:chat.message.delete", async_callback!(events::on_msg_delete))
|
.on("notify:chat.message.delete", async_callback!(events::on_msg_delete))
|
||||||
.on(
|
.on(
|
||||||
"notify:chat.converse.updateDMConverse",
|
"notify:chat.converse.updateDMConverse",
|
||||||
|
|
|
@ -8,6 +8,10 @@ use serde_json::{json, Value};
|
||||||
use tracing::{debug, info, warn};
|
use tracing::{debug, info, warn};
|
||||||
|
|
||||||
pub async fn send_message(client: &Client, message: &SendingMessage) -> bool {
|
pub async fn send_message(client: &Client, message: &SendingMessage) -> bool {
|
||||||
|
if message.contain_file() {
|
||||||
|
// 处理文件
|
||||||
|
|
||||||
|
}
|
||||||
let value: Value = message.as_value();
|
let value: Value = message.as_value();
|
||||||
match client.emit("chat.message.sendMessage", value).await {
|
match client.emit("chat.message.sendMessage", value).await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use rust_socketio::asynchronous::Client;
|
use rust_socketio::asynchronous::Client;
|
||||||
use rust_socketio::{Event, Payload};
|
use rust_socketio::{Event, Payload};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::data_struct::tailchat::messages::ReciveMessage;
|
use crate::data_struct::tailchat::messages::ReceiveMessage;
|
||||||
use crate::data_struct::tailchat::status::UpdateDMConverse;
|
use crate::data_struct::tailchat::status::{BotStatus, UpdateDMConverse};
|
||||||
use crate::tailchat::client::{emit_join_room, send_message};
|
use crate::tailchat::client::{emit_join_room, send_message};
|
||||||
|
|
||||||
/// 所有
|
/// 所有
|
||||||
|
@ -60,10 +62,10 @@ pub async fn any_event(event: Event, payload: Payload, _client: Client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::collapsible_if)]
|
#[allow(clippy::collapsible_if)]
|
||||||
pub async fn on_message(payload: Payload, client: Client) {
|
pub async fn on_message(payload: Payload, client: Client, status: Arc<BotStatus>) {
|
||||||
if let Payload::Text(values) = payload {
|
if let Payload::Text(values) = payload {
|
||||||
if let Some(value) = values.first() {
|
if let Some(value) = values.first() {
|
||||||
let message: ReciveMessage = match serde_json::from_value(value.clone()) {
|
let message: ReceiveMessage = match serde_json::from_value(value.clone()) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
info!("tailchat_msg {}", value.to_string().red());
|
info!("tailchat_msg {}", value.to_string().red());
|
||||||
|
@ -83,7 +85,7 @@ pub async fn on_message(payload: Payload, client: Client) {
|
||||||
send_message(&client, &reply).await;
|
send_message(&client, &reply).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::py::call::tailchat_new_message_py(&message, &client).await;
|
crate::py::call::tailchat_new_message_py(&message, &client, status.clone()).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
news.md
11
news.md
|
@ -1,5 +1,16 @@
|
||||||
# 更新日志
|
# 更新日志
|
||||||
|
|
||||||
|
## 0.6.8
|
||||||
|
|
||||||
|
- 修复了一堆拼写错误
|
||||||
|
- 太难绷了
|
||||||
|
- `TailchatReciveMessagePy` -> `TailchatReceiveMessagePy`
|
||||||
|
- `ReciveMessage` -> `ReceiveMessage`
|
||||||
|
- `ReceiveMessage::meta`
|
||||||
|
- 从 `JsonValue` 改成 `Option<JsonValue>`
|
||||||
|
- 用来解决发图片的时候没有 `meta` 字段的问题
|
||||||
|
- 去除了
|
||||||
|
|
||||||
## 0.6.7
|
## 0.6.7
|
||||||
|
|
||||||
游学回来啦
|
游学回来啦
|
||||||
|
|
Loading…
Reference in New Issue
Block a user