mirror of
http://shenjack.top:5100/shenjack/icalingua-python-bot.git
synced 2024-11-23 12:41:05 +08:00
进度是真tm快啊
This commit is contained in:
parent
5a07286d2d
commit
ff255426f6
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -659,7 +659,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ica-rs"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.22.1",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "ica-rs"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -188,9 +188,9 @@ class TailchatReciveMessage:
|
|||
@property
|
||||
def sender_id(self) -> TailchatType.UserId:
|
||||
...
|
||||
@property
|
||||
def is_from_self(self) -> bool:
|
||||
...
|
||||
# @property
|
||||
# def is_from_self(self) -> bool:
|
||||
# ...
|
||||
@property
|
||||
def is_reply(self) -> bool:
|
||||
...
|
||||
|
@ -202,11 +202,41 @@ class TailchatReciveMessage:
|
|||
...
|
||||
|
||||
|
||||
class TailchatSendingMessage:
|
||||
"""
|
||||
Tailchat 将要发送的信息
|
||||
"""
|
||||
@property
|
||||
def content(self) -> str:
|
||||
...
|
||||
@content.setter
|
||||
def content(self, value: str) -> None:
|
||||
...
|
||||
def with_content(self, content: str) -> "TailchatSendingMessage":
|
||||
"""
|
||||
为了链式调用, 返回自身
|
||||
"""
|
||||
self.content = content
|
||||
return self
|
||||
# def set_img(self, file: bytes, file_type: str, as_sticker: bool):
|
||||
# """
|
||||
# 设置消息的图片
|
||||
# @param file: 图片文件 (实际上是 vec<u8>)
|
||||
# @param file_type: 图片类型 (MIME) (image/png; image/jpeg)
|
||||
# @param as_sticker: 是否作为贴纸发送
|
||||
# """
|
||||
|
||||
|
||||
class TailchatClient:
|
||||
"""
|
||||
Tailchat 的客户端
|
||||
"""
|
||||
def send_message(self, message: TailchatSendingMessage) -> bool:
|
||||
...
|
||||
def send_and_warn(self, message: TailchatSendingMessage) -> bool:
|
||||
"""发送消息, 并在日志中输出警告信息"""
|
||||
self.warn(message.content)
|
||||
return self.send_message(message)
|
||||
|
||||
def debug(self, message: str) -> None:
|
||||
"""向日志中输出调试信息"""
|
||||
|
@ -235,8 +265,9 @@ on_ica_delete_message = Callable[[IcaType.MessageId, IcaClient], None]
|
|||
# def on_delete_message(msg_id: MessageId, client: IcaClient) -> None:
|
||||
# ...
|
||||
|
||||
# TODO: Tailchat adapter
|
||||
on_tailchat_message = Callable[[], None]
|
||||
on_tailchat_message = Callable[[TailchatClient, TailchatReciveMessage], None]
|
||||
# def on_tailchat_message(client: TailchatClient, msg: TailchatReciveMessage) -> None:
|
||||
# ...
|
||||
|
||||
on_config = Callable[[None], Tuple[str, str]]
|
||||
|
||||
|
|
|
@ -11,3 +11,5 @@ def on_ica_message(msg: IcaNewMessage, client: IcaClient) -> None:
|
|||
if msg.content == "/bot":
|
||||
reply = msg.reply_with(f"ica-async-rs({client.version})-sync-py {client.ica_version}")
|
||||
client.send_message(reply)
|
||||
|
||||
|
||||
|
|
|
@ -3,18 +3,6 @@ use serde_json::{json, Value as JsonValue};
|
|||
|
||||
use crate::data_struct::tailchat::{ConverseId, GroupId, MessageId, UserId};
|
||||
|
||||
/*{'_id': '6606b3075163504389a6fc47',
|
||||
'content': '光速!(',
|
||||
'author': '6602e20d7b8d10675758e36b',
|
||||
'groupId': '6602e331d31fd31b04aa0693',
|
||||
'converseId': '6602f785928c4254f17726b2',
|
||||
'hasRecall': False,
|
||||
'meta': {'mentions': []},
|
||||
'reactions': [],
|
||||
'createdAt': ExtType(code=0, data=b'\x00\x00\x01\x8e\x8a+TJ'),
|
||||
'updatedAt': ExtType(code=0, data=b'\x00\x00\x01\x8e\x8a+TJ'),
|
||||
'__v': 0} */
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ReciveMessage {
|
||||
/// 消息ID
|
||||
|
@ -35,6 +23,7 @@ pub struct ReciveMessage {
|
|||
#[serde(rename = "hasRecall")]
|
||||
pub has_recall: bool,
|
||||
/// 暂时懒得解析这玩意
|
||||
/// 准确来说是不确定内容, 毕竟没细看 API
|
||||
pub meta: JsonValue,
|
||||
/// 也懒得解析这玩意
|
||||
pub reactions: Vec<JsonValue>,
|
||||
|
@ -50,19 +39,46 @@ pub struct ReciveMessage {
|
|||
}
|
||||
|
||||
impl ReciveMessage {
|
||||
pub fn as_reply(&self) -> ReplyMessage {
|
||||
ReplyMessage {
|
||||
content: self.content.clone(),
|
||||
converse_id: self.converse_id.clone(),
|
||||
group_id: self.group_id.clone(),
|
||||
reply_id: self.msg_id.clone(),
|
||||
pub fn is_reply(&self) -> bool { self.meta.get("reply").is_some() }
|
||||
|
||||
/// 创建一个对这条消息的回复
|
||||
pub fn as_reply(&self) -> SendingMessage {
|
||||
SendingMessage::new(
|
||||
"".to_string(),
|
||||
self.converse_id.clone(),
|
||||
self.group_id.clone(),
|
||||
Some(ReplyMeta::from_recive_message(self)),
|
||||
)
|
||||
}
|
||||
|
||||
/// 回复这条消息
|
||||
pub fn reply_with(&self, content: String) -> SendingMessage {
|
||||
SendingMessage::new(
|
||||
content,
|
||||
self.converse_id.clone(),
|
||||
self.group_id.clone(),
|
||||
Some(ReplyMeta::from_recive_message(self)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
/// 将要发送的消息
|
||||
///
|
||||
/// 发送时:
|
||||
/// - `content`: 回复的消息内容
|
||||
/// - `converseId`: 会话ID
|
||||
/// - `groupId`: 服务器ID
|
||||
/// - `meta`: 回复的消息的元数据 ( 可能为空 )
|
||||
/// - `mentions`: 被回复的人的ID (可以是多个)
|
||||
/// - `reply`: 被回复的消息
|
||||
/// - `_id`: 被回复的消息ID
|
||||
/// - `author`: 被回复的消息的发送者ID
|
||||
/// - `content`: 被回复的消息内容
|
||||
pub struct SendingMessage {
|
||||
/// 消息内容
|
||||
///
|
||||
/// 其实还有个 plain, 就是不知道干啥的
|
||||
pub content: String,
|
||||
/// 会话ID
|
||||
#[serde(rename = "converseId")]
|
||||
|
@ -70,11 +86,38 @@ pub struct SendingMessage {
|
|||
/// 服务器ID
|
||||
#[serde(rename = "groupId")]
|
||||
pub group_id: GroupId,
|
||||
/// 消息的元数据
|
||||
pub meta: Option<ReplyMeta>,
|
||||
}
|
||||
|
||||
impl SendingMessage {
|
||||
pub fn new(
|
||||
content: String,
|
||||
converse_id: ConverseId,
|
||||
group_id: GroupId,
|
||||
meta: Option<ReplyMeta>,
|
||||
) -> Self {
|
||||
Self {
|
||||
content,
|
||||
converse_id,
|
||||
group_id,
|
||||
meta,
|
||||
}
|
||||
}
|
||||
pub fn new_without_meta(content: String, converse_id: ConverseId, group_id: GroupId) -> Self {
|
||||
Self {
|
||||
content,
|
||||
converse_id,
|
||||
group_id,
|
||||
meta: None,
|
||||
}
|
||||
}
|
||||
pub fn as_value(&self) -> JsonValue { serde_json::to_value(self).unwrap() }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ReplyMeta {
|
||||
/// 被回复的人的ID (可以是多个?)
|
||||
/// 被回复的人的ID (可以是多个)
|
||||
pub mentions: Vec<UserId>,
|
||||
/// 被回复的消息ID
|
||||
pub reply_id: MessageId,
|
||||
|
@ -84,6 +127,19 @@ pub struct ReplyMeta {
|
|||
pub reply_content: String,
|
||||
}
|
||||
|
||||
impl ReplyMeta {
|
||||
pub fn from_recive_message(msg: &ReciveMessage) -> Self {
|
||||
Self {
|
||||
mentions: vec![msg.sender_id.clone()],
|
||||
reply_id: msg.msg_id.clone(),
|
||||
reply_author: msg.sender_id.clone(),
|
||||
reply_content: msg.content.clone(),
|
||||
}
|
||||
}
|
||||
pub fn add_mention(&mut self, user_id: UserId) { self.mentions.push(user_id); }
|
||||
pub fn replace_content(&mut self, content: String) { self.reply_content = content; }
|
||||
}
|
||||
|
||||
impl Serialize for ReplyMeta {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
|
@ -91,9 +147,9 @@ impl Serialize for ReplyMeta {
|
|||
{
|
||||
let reply = json! {
|
||||
{
|
||||
"replyId": self.reply_id,
|
||||
"replyAuthor": self.reply_author,
|
||||
"replyContent": self.reply_content,
|
||||
"_id": self.reply_id,
|
||||
"author": self.reply_author,
|
||||
"content": self.reply_content,
|
||||
}
|
||||
};
|
||||
let mut map = serde_json::Map::new();
|
||||
|
@ -102,18 +158,3 @@ impl Serialize for ReplyMeta {
|
|||
map.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ReplyMessage {
|
||||
/// 消息内容
|
||||
pub content: String,
|
||||
/// 会话ID
|
||||
#[serde(rename = "converseId")]
|
||||
pub converse_id: ConverseId,
|
||||
/// 服务器ID
|
||||
#[serde(rename = "groupId")]
|
||||
pub group_id: GroupId,
|
||||
/// 回复的消息ID
|
||||
#[serde(rename = "replyId")]
|
||||
pub reply_id: MessageId,
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ pub type MainStatus = status::BotStatus;
|
|||
pub type StopGetter = tokio::sync::oneshot::Receiver<()>;
|
||||
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const ICA_VERSION: &str = "1.4.1";
|
||||
pub const TAILCHAT_VERSION: &str = "0.1.0";
|
||||
pub const ICA_VERSION: &str = "1.5.0";
|
||||
pub const TAILCHAT_VERSION: &str = "0.2.0";
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! wrap_callback {
|
||||
|
|
|
@ -174,8 +174,9 @@ pub async fn tailchat_new_message_py(message: &tailchat::messages::ReciveMessage
|
|||
|
||||
let plugins = PyStatus::get_files();
|
||||
for (path, plugin) in plugins.iter() {
|
||||
// let msg = class::tailchat::
|
||||
let args = ();
|
||||
let msg = class::tailchat::TailchatReciveMessagePy::from_recive_message(&message);
|
||||
let client = class::tailchat::TailchatClientPy::new(client);
|
||||
let args = (msg, client);
|
||||
call_py_func!(args, plugin, path, TAILCHAT_NEW_MESSAGE_FUNC, client);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub mod ica;
|
||||
pub mod tailchat;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use toml::Value as TomlValue;
|
||||
|
|
|
@ -185,10 +185,7 @@ impl IcaClientPy {
|
|||
|
||||
pub fn send_and_warn(&self, message: SendMessagePy) -> bool {
|
||||
warn!(message.msg.content);
|
||||
tokio::task::block_in_place(|| {
|
||||
let rt = Runtime::new().unwrap();
|
||||
rt.block_on(send_message(&self.client, &message.msg))
|
||||
})
|
||||
self.send_message(message)
|
||||
}
|
||||
|
||||
pub fn delete_message(&self, message: DeleteMessagePy) -> bool {
|
||||
|
@ -222,11 +219,9 @@ impl IcaClientPy {
|
|||
pub fn debug(&self, content: String) {
|
||||
debug!("{}", content);
|
||||
}
|
||||
|
||||
pub fn info(&self, content: String) {
|
||||
info!("{}", content);
|
||||
}
|
||||
|
||||
pub fn warn(&self, content: String) {
|
||||
warn!("{}", content);
|
||||
}
|
||||
|
|
116
ica-rs/src/py/class/tailchat.rs
Normal file
116
ica-rs/src/py/class/tailchat.rs
Normal file
|
@ -0,0 +1,116 @@
|
|||
use pyo3::prelude::*;
|
||||
|
||||
use rust_socketio::asynchronous::Client;
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
use crate::data_struct::tailchat::messages::{ReciveMessage, ReplyMeta, SendingMessage};
|
||||
use crate::data_struct::tailchat::{ConverseId, GroupId, MessageId, UserId};
|
||||
use crate::tailchat::client::send_message;
|
||||
|
||||
#[pyclass]
|
||||
#[pyo3(name = "TailchatClient")]
|
||||
pub struct TailchatClientPy {
|
||||
pub client: Client,
|
||||
}
|
||||
|
||||
impl TailchatClientPy {
|
||||
pub fn new(client: &Client) -> Self {
|
||||
Self {
|
||||
client: client.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[pyo3(name = "TailchatStatus")]
|
||||
/// 预留?
|
||||
pub struct TailchatStatusPy {}
|
||||
|
||||
#[pyclass]
|
||||
#[pyo3(name = "TailchatReciveMessage")]
|
||||
pub struct TailchatReciveMessagePy {
|
||||
pub message: ReciveMessage,
|
||||
}
|
||||
|
||||
impl TailchatReciveMessagePy {
|
||||
pub fn from_recive_message(msg: &ReciveMessage) -> Self {
|
||||
Self {
|
||||
message: msg.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[pyclass]
|
||||
#[pyo3(name = "TailchatSendingMessage")]
|
||||
pub struct TailchatSendingMessagePy {
|
||||
pub message: SendingMessage,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl TailchatClientPy {
|
||||
pub fn send_message(&self, message: TailchatSendingMessagePy) -> bool {
|
||||
tokio::task::block_in_place(|| {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(send_message(&self.client, &message.message))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn send_and_warn(&self, message: TailchatSendingMessagePy) -> bool {
|
||||
warn!("{}", message.message.content);
|
||||
self.send_message(message)
|
||||
}
|
||||
|
||||
pub fn debug(&self, content: String) {
|
||||
debug!("{}", content);
|
||||
}
|
||||
pub fn info(&self, content: String) {
|
||||
info!("{}", content);
|
||||
}
|
||||
pub fn warn(&self, content: String) {
|
||||
warn!("{}", content);
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl TailchatReciveMessagePy {
|
||||
#[getter]
|
||||
pub fn get_is_reply(&self) -> bool { self.message.is_reply() }
|
||||
#[getter]
|
||||
pub fn get_msg_id(&self) -> MessageId { self.message.msg_id.clone() }
|
||||
#[getter]
|
||||
pub fn get_content(&self) -> String { self.message.content.clone() }
|
||||
#[getter]
|
||||
pub fn get_sender_id(&self) -> UserId { self.message.sender_id.clone() }
|
||||
#[getter]
|
||||
pub fn get_group_id(&self) -> GroupId { self.message.group_id.clone() }
|
||||
#[getter]
|
||||
pub fn get_converse_id(&self) -> ConverseId { self.message.converse_id.clone() }
|
||||
/// 作为回复
|
||||
pub fn as_reply(&self) -> TailchatSendingMessagePy {
|
||||
TailchatSendingMessagePy {
|
||||
message: self.message.as_reply(),
|
||||
}
|
||||
}
|
||||
pub fn reply_with(&self, content: String) -> TailchatSendingMessagePy {
|
||||
TailchatSendingMessagePy {
|
||||
message: self.message.reply_with(content),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl TailchatSendingMessagePy {
|
||||
#[getter]
|
||||
pub fn get_content(&self) -> String { self.message.content.clone() }
|
||||
#[setter]
|
||||
pub fn set_content(&mut self, content: String) { self.message.content = content; }
|
||||
#[getter]
|
||||
pub fn get_converse_id(&self) -> ConverseId { self.message.converse_id.clone() }
|
||||
#[getter]
|
||||
pub fn get_group_id(&self) -> GroupId { self.message.group_id.clone() }
|
||||
pub fn with_content(&mut self, content: String) -> Self {
|
||||
self.message.content = content;
|
||||
self.clone()
|
||||
}
|
||||
}
|
|
@ -1 +1,22 @@
|
|||
use crate::data_struct::tailchat::messages::SendingMessage;
|
||||
// use crate::data_struct::tailchat::{ConverseId, GroupId, MessageId, UserId};
|
||||
|
||||
use rust_socketio::asynchronous::Client;
|
||||
|
||||
use colored::Colorize;
|
||||
use serde_json::Value;
|
||||
use tracing::{debug, info, span, warn, Level};
|
||||
|
||||
pub async fn send_message(client: &Client, message: &SendingMessage) -> bool {
|
||||
let value: Value = message.as_value();
|
||||
match client.emit("chat.message.sendMessage", value).await {
|
||||
Ok(_) => {
|
||||
debug!("send_message {}", format!("{:#?}", message).cyan());
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("send_message faild:{}", format!("{:#?}", e).red());
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,24 +56,19 @@ pub async fn any_event(event: Event, payload: Payload, _client: Client) {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn on_message(payload: Payload, _client: Client) {
|
||||
match payload {
|
||||
Payload::Text(values) => {
|
||||
pub async fn on_message(payload: Payload, client: Client) {
|
||||
if let Payload::Text(values) = payload {
|
||||
if let Some(value) = values.first() {
|
||||
let message: ReciveMessage = serde_json::from_value(value.clone()).unwrap();
|
||||
info!("收到消息 {:?}", message);
|
||||
crate::py::call::tailchat_new_message_py(&message, &client).await;
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
pub async fn on_msg_delete(payload: Payload, _client: Client) {
|
||||
match payload {
|
||||
Payload::Text(values) => {
|
||||
if let Payload::Text(values) = payload {
|
||||
if let Some(value) = values.first() {
|
||||
info!("删除消息 {}", value.to_string().red());
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user