🔀 Merge pull request #536

完善飞书相关文档和部分事件Model
This commit is contained in:
Mix 2021-09-25 10:04:35 +08:00 committed by GitHub
commit 049d14295e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 516 additions and 12 deletions

View File

@ -11,7 +11,7 @@ pip install nonebot-adapter-feishu
## 创建应用与启用应用“机器人”能力
::: tip
此部分可参考[飞书开放平台-快速开发机器人-创建应用](https://open.feishu.cn/document/home/develop-a-bot-in-5-minutes/create-an-app)部分文档。
此部分可参考[飞书开放平台-快速开发机器人-创建应用](https://open.feishu.cn/document/home/develop-a-bot-in-5-minutes/create-an-app)部分文档。
:::
@ -44,7 +44,7 @@ pip install nonebot-adapter-feishu
## 在 NoneBot 配置中添加相应配置
`.env` 文件中添加以下部分
`.env` 文件中添加以下配置
```
APP_ID=<yourAppId>
@ -52,6 +52,51 @@ APP_SECRET=<yourAppSecret>
VERIFICATION_TOKEN=<yourVerificationToken>
```
复制所创建应用**“凭证和基础信息”**中的**App ID**与**App Secret**及**“事件订阅”**中的**Verification Token**,替换上面相应的配置的值。
复制所创建应用**“凭证和基础信息”**中的 **App ID****App Secret****“事件订阅”** 中的 **Verification Token** ,替换上面相应的配置的值。
此外,对于飞书平台的事件订阅加密机制,飞书适配器也提供 `ENCRYPT_KEY` 配置项。
```
ENCRYPT_KEY=<yourEncryptKey>
```
当此项不为空时,飞书适配器会认为用户启用了加密机制,并对事件上报中的密文进行解密。
对于[Lark(飞书平台海外版)](https://www.larksuite.com) 的用户,飞书适配器也提供**实验性**支持,仅需要在配置文件中添加 `IS_LARK=true` 即可。
```
IS_LARK=true
```
## 注册飞书适配器
`bot.py` 中添加:
```python
from nonebot.adapters.feishu import Bot as FeishuBot
driver.register_adapter("feishu", FeishuBot)
```
## 编写一个适用于飞书适配器的插件并加载
插件代码范例:
```python
from nonebot.plugin import on_command
from nonebot.typing import T_State
from nonebot.adapters.feishu import Bot as FeishuBot, MessageEvent
helper = on_command("say")
@helper.handle()
async def feishu_helper(bot: FeishuBot, event: MessageEvent, state: T_State):
message = event.get_message()
await helper.finish(message, at_sender=True)
```
以上代码注册了一个对飞书平台适用的`say`指令,并会提取`/say`之后的内容发送到事件所对应的群或私聊。
大功告成!现在可以试试向机器人发送类似`/say Hello, Feishu!`的消息进行测试了。
大功告成!现在可以试试向机器人发送消息进行测试了。

View File

@ -18,6 +18,8 @@ class EventHeader(BaseModel):
token: str
app_id: str
tenant_key: str
resource_id: Optional[str]
user_list: Optional[List[dict]]
class Event(BaseEvent):
@ -27,8 +29,9 @@ class Event(BaseEvent):
.. _飞书文档:
https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-list
"""
__event__ = ""
schema_: str = Field("", alias='schema')
schema_: str = Field("", alias="schema")
header: EventHeader
event: Any
@ -136,8 +139,10 @@ class EventMessage(BaseModel):
@root_validator(pre=True)
def parse_message(cls, values: dict):
values["content"] = MessageDeserializer(
values["message_type"], json.loads(values["content"]),
values.get("mentions")).deserialize()
values["message_type"],
json.loads(values["content"]),
values.get("mentions"),
).deserialize()
return values
@ -187,7 +192,8 @@ class MessageEvent(Event):
return (
f"{self.event.message.message_id} from {self.get_user_id()}"
f"@[{self.event.message.chat_type}:{self.event.message.chat_id}]"
f" {self.get_message()}")
f" {self.get_message()}"
)
@overrides(Event)
def get_message(self) -> Message:
@ -395,6 +401,460 @@ class GroupMemberUserDeletedEvent(NoticeEvent):
event: GroupMemberUserDeletedEventDetail
class AvatarInfo(BaseModel):
avatar_72: str
avatar_240: str
avatar_640: str
avatar_origin: str
class UserStatus(BaseModel):
is_frozen: bool
is_resigned: bool
is_activated: bool
class UserOrder(BaseModel):
department_id: str
user_order: int
department_order: int
class UserCustomAttrValue(BaseModel):
text: str
url: str
pc_url: str
class UserCustomAttr(BaseModel):
type: str
id: str
value: UserCustomAttrValue
class ContactUser(BaseModel):
open_id: str
user_id: str
name: str
en_name: str
email: str
mobile: str
gender: int
avatar: AvatarInfo
status: UserStatus
department_ids: Optional[List[str]]
leader_user_id: str
city: str
country: str
work_station: str
join_time: int
employee_no: str
employee_type: int
orders: Optional[List[UserOrder]]
custom_attrs: List[UserCustomAttr]
class OldContactUser(BaseModel):
department_ids: List[str]
open_id: str
class ContactUserUpdatedEventDetail(BaseModel):
object: ContactUser
old_object: ContactUser
class ContactUserUpdatedEvent(NoticeEvent):
__event__ = "contact.user.updated_v3"
event: ContactUserUpdatedEventDetail
class ContactUserDeletedEventDetail(NoticeEvent):
object: ContactUser
old_object: OldContactUser
class ContactUserDeletedEvent(NoticeEvent):
__event__ = "contact.user.deleted_v3"
event: ContactUserDeletedEventDetail
class ContactUserCreatedEventDetail(BaseModel):
object: ContactUser
class ContactUserCreatedEvent(NoticeEvent):
__event__ = "contact.user.created_v3"
event: ContactUserCreatedEventDetail
class ContactDepartmentStatus(BaseModel):
is_deleted: bool
class ContactDepartment(BaseModel):
name: str
parent_department_id: str
department_id: str
open_department_id: str
leader_user_id: str
chat_id: str
order: int
status: ContactDepartmentStatus
class ContactDepartmentUpdatedEventDetail(BaseModel):
object: ContactDepartment
old_object: ContactDepartment
class ContactDepartmentUpdatedEvent(NoticeEvent):
__event__ = "contact.department.updated_v3"
event: ContactDepartmentUpdatedEventDetail
class OldContactDepartment(BaseModel):
status: ContactDepartmentStatus
open_department_id: str
class ContactDepartmentDeletedEventDetail(NoticeEvent):
object: ContactDepartment
old_object: OldContactDepartment
class ContactDepartmentDeletedEvent(NoticeEvent):
__event__ = "contact.department.deleted_v3"
event: ContactDepartmentDeletedEventDetail
class ContactDepartmentCreatedEventDetail(BaseModel):
object: ContactDepartment
class ContactDepartmentCreatedEvent(NoticeEvent):
__event__ = "contact.department.created_v3"
event: ContactDepartmentCreatedEventDetail
class CalendarAclScope(BaseModel):
type: str
user_id: str
class CalendarAclCreatedEventDetail(BaseModel):
acl_id: str
role: str
scope: CalendarAclScope
class CalendarAclCreatedEvent(NoticeEvent):
__event__ = "calendar.calendar.acl.created_v4"
event: CalendarAclCreatedEventDetail
class CalendarAclDeletedEventDetail(BaseModel):
acl_id: str
role: str
scope: CalendarAclScope
class CalendarAclDeletedEvent(NoticeEvent):
__event__ = "calendar.calendar.acl.deleted_v4"
event: CalendarAclDeletedEventDetail
class CalendarChangedEvent(NoticeEvent):
__event__ = "calendar.calendar.changed_v4"
event: dict
class CalendarEventChangedEventDetail(BaseModel):
calendar_id: str
class CalendarEventChangedEvent(NoticeEvent):
__event__ = "calendar.calendar.event.changed_v4"
event: CalendarEventChangedEventDetail
class DriveFileReadEventDetail(BaseModel):
file_token: str
file_type: str
operator_id_list: List[UserId]
class DriveFileReadEvent(NoticeEvent):
__event__ = "drive.file.read_v1"
event: DriveFileReadEventDetail
class DriveFileTitleUpdatedEventDetail(BaseModel):
file_token: str
file_type: str
operator_id: UserId
class DriveFileTitleUpdatedEvent(NoticeEvent):
__event__ = "drive.file.title_updated_v1"
event: DriveFileTitleUpdatedEventDetail
class DriveFilePermissionMemberAddedEventDetail(BaseModel):
chat_list: List[str]
file_token: str
file_type: str
operator_id: UserId
user_list: List[UserId]
class DriveFilePermissionMemberAddedEvent(NoticeEvent):
__event__ = "drive.file.permission_member_added_v1"
event: DriveFilePermissionMemberAddedEventDetail
class DriveFilePermissionMemberRemovedEventDetail(BaseModel):
chat_list: List[str]
file_token: str
file_type: str
operator_id: UserId
user_list: List[UserId]
class DriveFilePermissionMemberRemovedEvent(NoticeEvent):
__event__ = "drive.file.permission_member_removed_v1"
event: DriveFilePermissionMemberRemovedEventDetail
class DriveFileTrashedEventDetail(BaseModel):
file_token: str
file_type: str
operator_id: UserId
class DriveFileTrashedEvent(NoticeEvent):
__event__ = "drive.file.trashed_v1"
event: DriveFileTrashedEventDetail
class DriveFileDeletedEventDetail(BaseModel):
file_token: str
file_type: str
operator_id: UserId
class DriveFileDeletedEvent(NoticeEvent):
__event__ = "drive.file.deleted_v1"
event: DriveFileDeletedEventDetail
class DriveFileEditedEventDetail(BaseModel):
file_token: str
file_type: str
operator_id_list: List[UserId]
subscriber_id_list: List[UserId]
class DriveFileEditedEvent(NoticeEvent):
__event__ = "drive.file.edit_v1"
event: DriveFileEditedEventDetail
class MeetingRoomCreatedEventDetail(BaseModel):
room_id: str
room_name: str
class MeetingRoomCreatedEvent(NoticeEvent):
__event__ = "meeting_room.meeting_room.created_v1"
event: MeetingRoomCreatedEventDetail
class MeetingRoomUpdatedEventDetail(BaseModel):
room_id: str
room_name: str
class MeetingRoomUpdatedEvent(NoticeEvent):
__event__ = "meeting_room.meeting_room.updated_v1"
event: MeetingRoomUpdatedEventDetail
class MeetingRoomDeletedEventDetail(BaseModel):
room_id: str
room_name: str
class MeetingRoomDeletedEvent(NoticeEvent):
__event__ = "meeting_room.meeting_room.deleted_v1"
event: MeetingRoomDeletedEventDetail
class MeetingRoomStatusChangedEventDetail(BaseModel):
room_id: str
room_name: str
class MeetingRoomStatusChangedEvent(NoticeEvent):
__event__ = "meeting_room.meeting_room.status_changed_v1"
event: MeetingRoomStatusChangedEventDetail
class MeetingUser(BaseModel):
id: UserId
user_role: Optional[int]
user_type: Optional[int]
class Meeting(BaseModel):
id: str
topic: str
meeting_no: str
start_time: Optional[str]
end_time: Optional[str]
host_user: Optional[MeetingUser]
owner: MeetingUser
class VCMeetingStartedEventDetail(BaseModel):
meeting: Meeting
operator: MeetingUser
class VCMeetingStartedEvent(NoticeEvent):
__event__ = "vc.meeting.meeting_started_v1"
event: VCMeetingStartedEventDetail
class VCMeetingEndedEventDetail(BaseModel):
meeting: Meeting
operator: MeetingUser
class VCMeetingEndedEvent(NoticeEvent):
__event__ = "vc.meeting.meeting_ended_v1"
event: VCMeetingEndedEventDetail
class VCMeetingJoinedEventDetail(BaseModel):
meeting: Meeting
operator: MeetingUser
class VCMeetingJoinedEvent(NoticeEvent):
__event__ = "vc.meeting.join_meeting_v1"
event: VCMeetingJoinedEventDetail
class VCMeetingLeftEventDetail(BaseModel):
meeting: Meeting
operator: MeetingUser
leave_reason: int
class VCMeetingLeftEvent(NoticeEvent):
__event__ = "vc.meeting.leave_meeting_v1"
event: VCMeetingLeftEventDetail
class VCMeetingRecordingStartedEventDetail(BaseModel):
meeting: Meeting
operator: MeetingUser
class VCMeetingRecordingStartedEvent(NoticeEvent):
__event__ = "vc.meeting.recording_started_v1"
event: VCMeetingRecordingStartedEventDetail
class VCMeetingRecordingEndedEventDetail(BaseModel):
meeting: Meeting
operator: MeetingUser
class VCMeetingRecordingEndedEvent(NoticeEvent):
__event__ = "vc.meeting.recording_ended_v1"
event: VCMeetingRecordingEndedEventDetail
class VCMeetingRecordingReadyEventDetail(BaseModel):
meeting: Meeting
url: str
duration: str
class VCMeetingRecordingReadyEvent(NoticeEvent):
__event__ = "vc.meeting.recording_ready_v1"
event: VCMeetingRecordingReadyEventDetail
class VCMeetingShareStartedEventDetail(BaseModel):
meeting: Meeting
operator: MeetingUser
class VCMeetingShareStartedEvent(NoticeEvent):
__event__ = "vc.meeting.share_started_v1"
event: VCMeetingShareStartedEventDetail
class VCMeetingShareEndedEventDetail(BaseModel):
meeting: Meeting
operator: MeetingUser
class VCMeetingShareEndedEvent(NoticeEvent):
__event__ = "vc.meeting.share_ended_v1"
event: VCMeetingShareEndedEventDetail
class AttendanceUserFlowCreatedEventDetail(BaseModel):
bssid: str
check_time: str
comment: str
employee_id: str
employee_no: str
is_field: bool
is_wifi: bool
latitude: float
location_name: str
longitude: float
photo_urls: Optional[List[str]]
record_id: str
ssid: str
type: int
class AttendanceUserFlowCreatedEvent(NoticeEvent):
__event__ = "attendance.user_flow.created_v1"
event: AttendanceUserFlowCreatedEventDetail
class AttendanceUserTaskStatusDiff(BaseModel):
before_status: str
before_supplement: str
current_status: str
current_supplement: str
index: int
work_type: str
class AttendanceUserTaskUpdatedEventDetail(BaseModel):
date: int
employee_id: str
employee_no: str
group_id: str
shift_id: str
status_changes: List[AttendanceUserTaskStatusDiff]
task_id: str
time_zone: str
class AttendanceUserTaskUpdatedEvent(NoticeEvent):
__event__ = "attendance.user_task.updated_v1"
event: AttendanceUserTaskUpdatedEventDetail
_t = StringTrie(separator=".")
# define `model` first to avoid globals changing while `for`

View File

@ -1,12 +1,11 @@
from nonebot.adapters.feishu.event import MessageEvent
from nonebot.rule import to_me
from nonebot.plugin import on_command
from nonebot.adapters.feishu import Bot as FeishuBot, MessageSegment, MessageEvent
from nonebot.typing import T_State
from nonebot.adapters.feishu import Bot as FeishuBot, MessageEvent
helper = on_command("say")
@helper.handle()
async def feishu_helper(bot: FeishuBot, event: MessageEvent):
async def feishu_helper(bot: FeishuBot, event: MessageEvent, state: T_State):
message = event.get_message()
await helper.finish(message, at_sender=True)