├── src ├── Data │ ├── GetGroupList.php │ ├── GetGroupMemberList.php │ ├── GetGroupFilesByFolder.php │ ├── GetUnidirectionalFriendList.php │ ├── GetStatus.php │ ├── Post │ │ ├── Notice │ │ │ ├── FriendAddNotice.php │ │ │ ├── FriendRecallNotice.php │ │ │ ├── BaseSubNotice.php │ │ │ ├── ClientStatusNotice.php │ │ │ ├── TitleNotice.php │ │ │ ├── LuckyKingNotice.php │ │ │ ├── OfflineFileNotice.php │ │ │ ├── GroupRecallNotice.php │ │ │ ├── PokeNotice.php │ │ │ ├── GroupCardNotice.php │ │ │ ├── GroupAdminNotice.php │ │ │ ├── GroupUploadNotice.php │ │ │ ├── HonorNotice.php │ │ │ ├── GroupIncreaseNotice.php │ │ │ ├── GroupDecreaseNotice.php │ │ │ ├── EssenceNotice.php │ │ │ ├── BaseNotice.php │ │ │ └── GroupBanNotice.php │ │ ├── MetaEvent │ │ │ ├── GeartbeatMetaEvent.php │ │ │ └── BaseMetaEvent.php │ │ ├── Request │ │ │ ├── BaseRequest.php │ │ │ ├── FriendRequest.php │ │ │ └── GroupRequest.php │ │ ├── Message │ │ │ ├── PrivateMessage.php │ │ │ ├── BaseMessage.php │ │ │ └── GroupMessage.php │ │ └── BasePostMessage.php │ ├── Struct │ │ ├── Enum │ │ │ ├── PostMessageType.php │ │ │ ├── PostRequestType.php │ │ │ ├── PostMetaEventType.php │ │ │ ├── PostType.php │ │ │ ├── PostMessageSubType.php │ │ │ └── PostNoticeType.php │ │ ├── Device.php │ │ ├── Anonymous.php │ │ ├── HonorInfo.php │ │ ├── TalkativeHonorInfo.php │ │ ├── InvitedRequest.php │ │ ├── Folder.php │ │ ├── StatusStatistics.php │ │ ├── File.php │ │ ├── Status.php │ │ ├── JoinRequest.php │ │ └── Sender.php │ ├── GetLoginInfo.php │ ├── GetModelShow.php │ ├── GetImage.php │ ├── GetFriendList.php │ ├── GetOnlineClients.php │ ├── GetGroupAtAllRemain.php │ ├── GetGroupFileSystemInfo.php │ ├── GetGroupNotice.php │ ├── GetEssenceMsgList.php │ ├── GetGroupRootFiles.php │ ├── GetStrangerInfo.php │ ├── GetGroupSystemMsg.php │ ├── GetGroupInfo.php │ ├── GetMsg.php │ ├── GetGroupMemberInfo.php │ ├── GetVersionInfo.php │ ├── CreateData.php │ ├── GetGroupHonorInfo.php │ ├── ArrayData.php │ └── GetGroupMsgHistory.php ├── Exceptions │ ├── ApiHttpException.php │ ├── PostMessageException.php │ └── ApiException.php ├── Apis │ ├── BaseApi.php │ ├── Record.php │ ├── Request.php │ ├── Image.php │ ├── Friend.php │ ├── GroupSetting.php │ ├── Bot.php │ ├── GroupInfo.php │ ├── GroupFile.php │ ├── Cq.php │ ├── GroupAction.php │ └── Message.php ├── Interfaces │ ├── CqCodeInterfaces.php │ └── Arrayable.php ├── CqCode │ ├── RedBag.php │ ├── Face.php │ ├── Tts.php │ ├── Poke.php │ ├── Forward.php │ ├── Xml.php │ ├── Music.php │ ├── At.php │ ├── Json.php │ ├── Gift.php │ ├── Share.php │ ├── Video.php │ ├── Reply.php │ ├── MusicCustom.php │ ├── Record.php │ ├── Image.php │ ├── CardImage.php │ └── BaseCqCode.php ├── Support │ ├── ApiResponse.php │ ├── Str.php │ ├── Handler.php │ └── Utils.php ├── Providers │ └── MessageProvider.php ├── Api.php ├── Middlewares │ └── ResponseMiddleware.php └── Server.php ├── .gitattributes ├── composer.json ├── ide_helper.php ├── README.md └── LICENSE /src/Data/GetGroupList.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function toArray(): array; 15 | } 16 | -------------------------------------------------------------------------------- /src/Data/Post/MetaEvent/GeartbeatMetaEvent.php: -------------------------------------------------------------------------------- 1 | variants = $variants; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Data/Post/Notice/OfflineFileNotice.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public ArrayData $clients; 15 | 16 | public function __construct(array $clients, ...$args) 17 | { 18 | $this->clients = $this->createArrayData($clients, Device::class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Data/Post/MetaEvent/BaseMetaEvent.php: -------------------------------------------------------------------------------- 1 | 收 16 | */ 17 | public function __construct( 18 | public string $title, 19 | ...$args 20 | ) { 21 | } 22 | 23 | public function __toString(): string 24 | { 25 | return $this->get(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Exceptions/ApiException.php: -------------------------------------------------------------------------------- 1 | response; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/CqCode/Face.php: -------------------------------------------------------------------------------- 1 | 收 + 发 18 | */ 19 | public function __construct( 20 | public int $id, 21 | ...$args 22 | ) { 23 | } 24 | 25 | public function __toString(): string 26 | { 27 | return $this->get(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Data/Post/Notice/GroupIncreaseNotice.php: -------------------------------------------------------------------------------- 1 | data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Data/Post/Notice/GroupDecreaseNotice.php: -------------------------------------------------------------------------------- 1 | 发 20 | */ 21 | public function __construct( 22 | public string $text, 23 | ...$args 24 | ) { 25 | } 26 | 27 | public function __toString(): string 28 | { 29 | return $this->get(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Providers/MessageProvider.php: -------------------------------------------------------------------------------- 1 | getContent(); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/CqCode/Poke.php: -------------------------------------------------------------------------------- 1 | 发 20 | */ 21 | public function __construct( 22 | public int $qq, 23 | ...$args 24 | ) { 25 | } 26 | 27 | public function __toString(): string 28 | { 29 | return $this->get(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Data/GetGroupFileSystemInfo.php: -------------------------------------------------------------------------------- 1 | 收 18 | */ 19 | public function __construct( 20 | public string $id, 21 | ...$args 22 | ) { 23 | } 24 | 25 | public function __toString(): string 26 | { 27 | return $this->get(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "itwmw/go-cq-http-sdk", 3 | "description": "go-cqhttp的SDK", 4 | "type": "library", 5 | "license": "Apache-2.0", 6 | "autoload": { 7 | "psr-4": { 8 | "Itwmw\\GoCqHttp\\": "src/" 9 | } 10 | }, 11 | "authors": [ 12 | { 13 | "name": "skip" 14 | } 15 | ], 16 | "require": { 17 | "php": ">=8.0", 18 | "guzzlehttp/guzzle": "^6.5.8|^7.4.5", 19 | "ext-mbstring": "*" 20 | }, 21 | "extra": { 22 | "laravel": { 23 | "providers": [ 24 | "Itwmw\\GoCqHttp\\Providers\\MessageProvider" 25 | ] 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/CqCode/Xml.php: -------------------------------------------------------------------------------- 1 | 收 + 发 16 | * @param int $resid 可能为空, 或空字符串 收 + 发 17 | */ 18 | public function __construct( 19 | public string $data, 20 | public int $resid = 0, 21 | ...$args 22 | ) { 23 | } 24 | 25 | public function __toString(): string 26 | { 27 | return $this->get(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/CqCode/Music.php: -------------------------------------------------------------------------------- 1 | 发 19 | * @param string $id 歌曲 ID 20 | */ 21 | public function __construct( 22 | public string $type, 23 | public string $id, 24 | ...$args 25 | ) { 26 | } 27 | 28 | public function __toString(): string 29 | { 30 | return $this->get(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/CqCode/At.php: -------------------------------------------------------------------------------- 1 | 收 + 发 19 | * @param string $name 当在群中找不到此QQ号的名称时才会生效 20 | */ 21 | public function __construct( 22 | public int|string $qq, 23 | public string $name = '', 24 | ...$args 25 | ) { 26 | } 27 | 28 | public function __toString(): string 29 | { 30 | return $this->get(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Data/GetGroupNotice.php: -------------------------------------------------------------------------------- 1 | 18 | * } $message 公告内容 19 | */ 20 | public function __construct( 21 | public string $notice_id, 22 | public int $sender_id, 23 | public int $publish_time, 24 | public array $message, 25 | ...$args 26 | ) { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/CqCode/Json.php: -------------------------------------------------------------------------------- 1 | 收 + 发 19 | * @param int $resid 默认不填为0, 走小程序通道, 填了走富文本通道发送 收 + 发 20 | */ 21 | public function __construct( 22 | public string $data, 23 | public int $resid = 0, 24 | ...$args 25 | ) { 26 | } 27 | 28 | public function __toString(): string 29 | { 30 | return $this->get(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/CqCode/Gift.php: -------------------------------------------------------------------------------- 1 | 发 21 | * @param int<0, 13> $id 礼物的类型 22 | */ 23 | public function __construct( 24 | public int $qq, 25 | public int $id, 26 | ...$args 27 | ) { 28 | } 29 | 30 | public function __toString(): string 31 | { 32 | return $this->get(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Data/GetEssenceMsgList.php: -------------------------------------------------------------------------------- 1 | |null 文件列表*/ 11 | public ?ArrayData $files; 12 | 13 | /** @var ArrayData|null 文件夹列表 */ 14 | public ?ArrayData $folders; 15 | 16 | /** 17 | * @param array|null $files 文件列表 18 | * @param array|null $folders 文件夹列表 19 | */ 20 | public function __construct( 21 | ?array $files = null, 22 | ?array $folders = null, 23 | ...$args 24 | ) { 25 | $this->files = $files ? $this->createArrayData($files, File::class) : null; 26 | $this->folders = $folders ? $this->createArrayData($folders, Folder::class) : null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Data/Struct/Folder.php: -------------------------------------------------------------------------------- 1 | |null 邀请消息列表 */ 11 | public ?ArrayData $invited_requests; 12 | 13 | /** @var ArrayData|null 进群消息列表 */ 14 | public ?ArrayData $join_requests; 15 | 16 | /** 17 | * @param array|null $invited_requests 邀请消息列表 18 | * @param array|null $join_requests 进群消息列表 19 | */ 20 | public function __construct(?array $invited_requests = null, ?array $join_requests = null, ...$args) 21 | { 22 | $this->invited_requests = $invited_requests ? $this->createArrayData($invited_requests, InvitedRequest::class) : null; 23 | $this->join_requests = $join_requests ? $this->createArrayData($join_requests, JoinRequest::class) : null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Data/Post/Message/PrivateMessage.php: -------------------------------------------------------------------------------- 1 | 收 + 发 21 | * @param string $title 标题 收 + 发 22 | * @param string $content 发送时可选, 内容描述 收 + 发 23 | * @param string $image 发送时可选, 图片 URL 收 + 发 24 | */ 25 | public function __construct( 26 | public string $url, 27 | public string $title, 28 | public string $content = '', 29 | public string $image = '', 30 | ...$args 31 | ) { 32 | } 33 | 34 | public function __toString(): string 35 | { 36 | return $this->get(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/CqCode/Video.php: -------------------------------------------------------------------------------- 1 | 收 + 发 20 | * @param string $cover 视频封面, 支持http, file和base64发送, 格式必须为jpg 21 | * @param int $c 通过网络下载视频时的线程数, 默认单线程. (在资源不支持并发时会自动处理) 22 | * @param string $url 视频Url 23 | */ 24 | public function __construct( 25 | public string $file, 26 | public string $cover = '', 27 | public int $c = 1, 28 | public string $url = '', 29 | ...$args 30 | ) { 31 | } 32 | 33 | public function __toString(): string 34 | { 35 | return $this->get(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Support/Str.php: -------------------------------------------------------------------------------- 1 | static::ucfirst($word), $words); 20 | 21 | return static::$studlyCache[$key] = implode($studlyWords); 22 | } 23 | 24 | public static function ucfirst($string): string 25 | { 26 | return static::upper(static::substr($string, 0, 1)) . static::substr($string, 1); 27 | } 28 | 29 | public static function upper($value): string 30 | { 31 | return mb_strtoupper($value, 'UTF-8'); 32 | } 33 | 34 | public static function substr($string, $start, $length = null, $encoding = 'UTF-8'): string 35 | { 36 | return mb_substr($string, $start, $length, $encoding); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Data/Post/Message/BaseMessage.php: -------------------------------------------------------------------------------- 1 | $handlers 11 | */ 12 | public function __construct( 13 | protected array $handlers 14 | ) { 15 | } 16 | 17 | protected function carry(): Closure 18 | { 19 | return function ($stack, $pipe) { 20 | return function ($data) use ($stack, $pipe) { 21 | return $pipe($data, $stack); 22 | }; 23 | }; 24 | } 25 | 26 | protected function pipes(): array 27 | { 28 | return array_map(function ($callback) { 29 | return function ($data, $next) use ($callback) { 30 | return $callback($data, $next); 31 | }; 32 | }, $this->handlers); 33 | } 34 | 35 | public function handle(mixed $data) 36 | { 37 | $pipeline = array_reduce( 38 | array_reverse($this->pipes()), 39 | $this->carry(), 40 | fn (mixed $data) => $data 41 | ); 42 | 43 | return $pipeline($data); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Data/GetGroupInfo.php: -------------------------------------------------------------------------------- 1 | group_id/$this->group_id/100"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Data/Struct/File.php: -------------------------------------------------------------------------------- 1 | 收 + 发 22 | * @param string|null $text 自定义回复的信息 收 + 发 23 | * @param int|null $qq 自定义回复时的自定义QQ, 如果使用自定义信息必须指定. 收 + 发 24 | * @param int|null $time 自定义回复时的时间, 格式为Unix时间 收 + 发 25 | * @param int|null $seq 起始消息序号, 可通过 get_msg 获得 收 + 发 26 | */ 27 | public function __construct( 28 | public int $id, 29 | public ?string $text = '', 30 | public ?int $qq = null, 31 | public ?int $time = null, 32 | public ?int $seq = null, 33 | ...$args 34 | ) { 35 | } 36 | 37 | public function __toString(): string 38 | { 39 | return $this->get(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Data/Struct/Status.php: -------------------------------------------------------------------------------- 1 | stat = StatusStatistics::create($stat); 34 | $this->plugins_good = $plugins_good ?? false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Data/GetMsg.php: -------------------------------------------------------------------------------- 1 | sender = $sender; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Data/Post/Request/GroupRequest.php: -------------------------------------------------------------------------------- 1 | 收 + 发 23 | * @param string $audio 音乐 URL 收 + 发 24 | * @param string $title 标题 收 + 发 25 | * @param string $content 发送时可选, 内容描述 收 + 发 26 | * @param string $image 发送时可选, 图片 URL 收 + 发 27 | * @param string $type 表示音乐自定义分享 28 | */ 29 | public function __construct( 30 | public string $url, 31 | public string $audio, 32 | public string $title, 33 | public string $content = '', 34 | public string $image = '', 35 | public string $type = 'custom', 36 | ...$args 37 | ) { 38 | } 39 | 40 | public function __toString(): string 41 | { 42 | return $this->get(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Data/Struct/JoinRequest.php: -------------------------------------------------------------------------------- 1 | 收 + 发 22 | * @param int $magic 发送时可选, 默认 0, 设置为 1 表示变声 收 + 发 23 | * @param int $cache 只在通过网络 URL 发送时有效, 表示是否使用已缓存的文件, 默认 1 24 | * @param int $proxy 只在通过网络 URL 发送时有效, 表示是否通过代理下载文件 ( 需通过环境变量或配置文件配置代理 ) , 默认 1 25 | * @param int $timeout 只在通过网络 URL 发送时有效, 单位秒, 表示下载网络文件的超时时间 , 默认不超时 26 | * @param string $url 语音 URL 27 | */ 28 | public function __construct( 29 | public string $file, 30 | public int $magic = 0, 31 | public int $cache = 1, 32 | public int $proxy = 1, 33 | public int $timeout = 0, 34 | public string $url = '', 35 | ...$args 36 | ) { 37 | } 38 | 39 | public function __toString(): string 40 | { 41 | return $this->get(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Data/Struct/Sender.php: -------------------------------------------------------------------------------- 1 | getProperties(\ReflectionProperty::IS_PUBLIC); 25 | foreach ($properties as $property) { 26 | if (!empty($data[$property->getName()] ?? '')) { 27 | $type = $property->getType()?->getName(); 28 | // 判断$type是否是CreateData的子类 29 | if (is_subclass_of($type, CreateData::class)) { 30 | $value = $type::create($data[$property->getName()]); 31 | } else { 32 | $value = $data[$property->getName()]; 33 | } 34 | $property->setValue($class, $value); 35 | } 36 | } 37 | return $class; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Data/Post/Message/GroupMessage.php: -------------------------------------------------------------------------------- 1 | 收 + 发 24 | * @param string $type 图片类型, flash 表示闪照, show 表示秀图, 默认普通图片 收 + 发 25 | * @param int<0,13> $subType 图片子类型, 只出现在群聊. 收 + 发 26 | * @param string $url 图片 URL 27 | * @param int $cache 只在通过网络 URL 发送时有效, 表示是否使用已缓存的文件, 默认 1 28 | * @param int<40000,40005> $id 发送秀图时的特效id, 默认为40000 29 | * @param int<1,3> $c 通过网络下载图片时的线程数, 默认单线程. (在资源不支持并发时会自动处理) 30 | */ 31 | public function __construct( 32 | public string $file, 33 | public string $type = '', 34 | public int $subType = 0, 35 | public string $url = '', 36 | public int $cache = 1, 37 | public int $id = 40000, 38 | public int $c = 1, 39 | ...$args 40 | ) { 41 | } 42 | 43 | public function __toString(): string 44 | { 45 | return $this->get(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Apis/Record.php: -------------------------------------------------------------------------------- 1 | client->get('/get_record', [ 29 | 'query' => compact('file', 'out_format') 30 | ])->getData()['file']; 31 | } 32 | 33 | /** 34 | * 检查是否可以发送语音 35 | * 36 | * @return bool 37 | * 38 | * @throws \GuzzleHttp\Exception\GuzzleException 39 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 40 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 41 | * 42 | * @noinspection PhpFullyQualifiedNameUsageInspection 43 | */ 44 | public function canSendRecord(): bool 45 | { 46 | return $this->client->get('/can_send_record')->getData()['yes']; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Data/GetGroupMemberInfo.php: -------------------------------------------------------------------------------- 1 | 发 26 | * @param int $minwidth 默认不填为400, 最小width 27 | * @param int $minheight 默认不填为400, 最小height 28 | * @param int $maxwidth 默认不填为500, 最大width 29 | * @param int $maxheight 默认不填为1000, 最大height 30 | * @param string $source 分享来源的名称, 可以留空 31 | * @param string $icon 分享来源的icon图标url, 可以留空 32 | */ 33 | public function __construct( 34 | public string $file, 35 | public int $minwidth = 400, 36 | public int $minheight = 400, 37 | public int $maxwidth = 500, 38 | public int $maxheight = 1000, 39 | public string $source = '', 40 | public string $icon = '', 41 | ...$args 42 | ) { 43 | } 44 | 45 | public function __toString(): string 46 | { 47 | return $this->get(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Data/CreateData.php: -------------------------------------------------------------------------------- 1 | $value) { 20 | if ($value instanceof Arrayable) { 21 | $array[$key] = $value->toArray(); 22 | } 23 | } 24 | return $array; 25 | } 26 | 27 | /** 28 | * @param array $data 29 | * @param class-string $class_name 30 | * @return ArrayData 31 | */ 32 | protected function createArrayData(array $data, string $class_name): ArrayData 33 | { 34 | $data = array_map(function ($item) use ($class_name) { 35 | return $class_name::create($item); 36 | }, $data); 37 | 38 | return new ArrayData($data); 39 | } 40 | 41 | public function __toString(): string 42 | { 43 | return json_encode($this->toArray()); 44 | } 45 | 46 | public function offsetExists(mixed $offset): bool 47 | { 48 | return property_exists($this, $offset); 49 | } 50 | 51 | public function offsetGet(mixed $offset): mixed 52 | { 53 | return $this->$offset; 54 | } 55 | 56 | public function offsetSet(mixed $offset, mixed $value): void 57 | { 58 | $this->$offset = $value; 59 | } 60 | 61 | public function offsetUnset(mixed $offset): void 62 | { 63 | unset($this->$offset); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Apis/Request.php: -------------------------------------------------------------------------------- 1 | client->post('/set_friend_add_request', [ 25 | 'form_params' => compact('flag', 'approve', 'remark') 26 | ]); 27 | } 28 | 29 | /** 30 | * 处理加群请求/邀请 31 | * 32 | * @param string $flag 加好友请求的 flag(需从上报的数据中获得 33 | * @param string $sub_type add 或 invite, 请求类型(需要和上报消息中的 sub_type 字段相符) 34 | * @param bool $approve 是否同意请求/邀请 35 | * @param string $reason 拒绝理由(仅在拒绝时有效) 36 | * 37 | * @return void 38 | * 39 | * @throws \GuzzleHttp\Exception\GuzzleException 40 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 41 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 42 | * 43 | * @noinspection PhpFullyQualifiedNameUsageInspection 44 | */ 45 | public function setGroupAddRequest(string $flag, string $sub_type, bool $approve = true, string $reason = ''): void 46 | { 47 | $this->client->post('/set_group_add_request', [ 48 | 'form_params' => compact('flag', 'sub_type', 'approve', 'reason') 49 | ]); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/CqCode/BaseCqCode.php: -------------------------------------------------------------------------------- 1 | getConstructor(); 22 | $params = $constructor->getParameters(); 23 | $params = array_filter($params, fn ($param) => !$param->isDefaultValueAvailable() && 'args' !== $param->getName()); 24 | $params = array_map(fn ($param) => $param->getName(), $params); 25 | if (count(array_diff($params, array_keys($data))) > 0) { 26 | return false; 27 | } 28 | return new static(...$data); 29 | } 30 | 31 | public function get(): string 32 | { 33 | $data = []; 34 | foreach ($this->sendFields as $field) { 35 | $data[$field] = $this->$field; 36 | } 37 | return $this->buildCode($data); 38 | } 39 | 40 | protected function buildCode($data): string 41 | { 42 | $data = array_filter($data, function ($value) { 43 | return '' !== $value && !is_null($value); 44 | }); 45 | $str = ''; 46 | foreach ($data as $key => $value) { 47 | $value = $this->escape($value); 48 | $str .= ",$key=$value"; 49 | } 50 | return '[CQ:' . static::$_type . $str . ']'; 51 | } 52 | 53 | protected function escape(string $str): string 54 | { 55 | return str_replace(['&', '[', ']', ','], ['&', '[', ']', ','], $str); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Support/Utils.php: -------------------------------------------------------------------------------- 1 | $v) { 49 | if ($k !== ++$nextKey) { 50 | return false; 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | 57 | public static function getMiddleware(string $class, ...$params) 58 | { 59 | if (class_exists($class) && method_exists($class, '__invoke')) { 60 | $handler = function (...$args) use ($class) { 61 | return (new $class())(...$args); 62 | }; 63 | return $handler(...$params); 64 | } 65 | 66 | throw new InvalidArgumentException('中间件配置错误'); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Apis/Image.php: -------------------------------------------------------------------------------- 1 | client->get('/get_image', [ 25 | 'query' => compact('file') 26 | ])->getData(); 27 | } 28 | 29 | /** 30 | * 检查是否可以发送图片 31 | * 32 | * @return bool 33 | * 34 | * @throws \GuzzleHttp\Exception\GuzzleException 35 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 36 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 37 | * 38 | * @noinspection PhpFullyQualifiedNameUsageInspection 39 | */ 40 | public function canSendImage(): bool 41 | { 42 | return $this->client->get('/can_send_image')->getData()['yes']; 43 | } 44 | 45 | /** 46 | * 图片 OCR 47 | * 48 | * 目前图片OCR接口仅支持接受的图片 49 | * 50 | * @param string $image 51 | * 52 | * @return array{ 53 | * language: string, 54 | * texts: array 61 | * }> 62 | * } 63 | * 64 | * @throws \GuzzleHttp\Exception\GuzzleException 65 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 66 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 67 | * 68 | * @noinspection PhpFullyQualifiedNameUsageInspection 69 | */ 70 | public function ocrImage(string $image): array 71 | { 72 | return $this->client->post('/ocr_image', [ 73 | 'form_params' => compact('image') 74 | ])->getData(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Api.php: -------------------------------------------------------------------------------- 1 | push(Utils::getMiddleware(ResponseMiddleware::class)); 49 | 50 | $this->client = new Client([ 51 | 'base_uri' => $base_uri, 52 | 'timeout' => 5.0, 53 | 'http_errors' => false, 54 | 'handler' => $stack 55 | ]); 56 | 57 | $this->server = new Server(); 58 | } 59 | 60 | public function getServer(): Server 61 | { 62 | return $this->server; 63 | } 64 | 65 | public function __get(string $name) 66 | { 67 | $name = ucfirst($name); 68 | 69 | if (isset($this->apis[$name])) { 70 | return $this->apis[$name]; 71 | } 72 | 73 | $apiName = '\\Itwmw\\GoCqHttp\\Apis\\' . $name; 74 | if (class_exists($apiName)) { 75 | $this->apis[$name] = new $apiName($this->client); 76 | return $this->apis[$name]; 77 | } 78 | throw new InvalidArgumentException('属性不存在'); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Data/GetGroupHonorInfo.php: -------------------------------------------------------------------------------- 1 | |null 历史龙王, 仅 type 为 talkative 或 all 时有数据 */ 14 | public ?ArrayData $talkative_list; 15 | 16 | /** @var ArrayData|null 群聊之火, 仅 type 为 performer 或 all 时有数据 */ 17 | public ?ArrayData $performer_list; 18 | 19 | /** @var ArrayData|null 群聊炽焰, 仅 type 为 legend 或 all 时有数据 */ 20 | public ?ArrayData $legend_list; 21 | 22 | /** @var ArrayData|null 冒尖小春笋, 仅 type 为 strong_newbie 或 all 时有数据 */ 23 | public ?ArrayData $strong_newbie_list; 24 | 25 | /** @var ArrayData|null 快乐之源, 仅 type 为 emotion 或 all 时有数据 */ 26 | public ?ArrayData $emotion_list; 27 | 28 | /** 29 | * @param int $group_id 群号 30 | * @param array|null $current_talkative 当前龙王, 仅 type 为 talkative 或 all 时有数据 31 | * @param array|null $talkative_list 历史龙王, 仅 type 为 talkative 或 all 时有数据 32 | * @param array|null $performer_list 群聊之火, 仅 type 为 performer 或 all 时有数据 33 | * @param array|null $legend_list 群聊炽焰, 仅 type 为 legend 或 all 时有数据 34 | * @param array|null $strong_newbie_list 冒尖小春笋, 仅 type 为 strong_newbie 或 all 时有数据 35 | * @param array|null $emotion_list 快乐之源, 仅 type 为 emotion 或 all 时有数据 36 | */ 37 | public function __construct( 38 | public int $group_id, 39 | ?array $current_talkative = null, 40 | ?array $talkative_list = null, 41 | ?array $performer_list = null, 42 | ?array $legend_list = null, 43 | ?array $strong_newbie_list = null, 44 | ?array $emotion_list = null, 45 | ...$args 46 | ) { 47 | $this->current_talkative = $current_talkative ? TalkativeHonorInfo::create($current_talkative) : null; 48 | $this->talkative_list = $talkative_list ? $this->createArrayData($talkative_list, HonorInfo::class) : null; 49 | $this->performer_list = $performer_list ? $this->createArrayData($performer_list, HonorInfo::class) : null; 50 | $this->legend_list = $legend_list ? $this->createArrayData($legend_list, HonorInfo::class) : null; 51 | $this->strong_newbie_list = $strong_newbie_list ? $this->createArrayData($strong_newbie_list, HonorInfo::class) : null; 52 | $this->emotion_list = $emotion_list ? $this->createArrayData($emotion_list, HonorInfo::class) : null; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Data/ArrayData.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | final class ArrayData implements ArrayAccess 16 | { 17 | /** 18 | * @var array 19 | */ 20 | protected array $data = []; 21 | 22 | /** 23 | * @param iterable $data 24 | */ 25 | public function __construct(array $data) 26 | { 27 | $this->data = $data; 28 | } 29 | 30 | /** 31 | * @template TGetDefault 32 | * 33 | * @param TKey $key 34 | * @param mixed|TGetDefault|(\Closure(): TGetDefault) $default 35 | * @return TValue|TGetDefault 36 | * 37 | * @noinspection PhpFullyQualifiedNameUsageInspection 38 | */ 39 | public function get($key, mixed $default = null) 40 | { 41 | if (array_key_exists($key, $this->data)) { 42 | return $this->data[$key]; 43 | } 44 | 45 | return Utils::value($default); 46 | } 47 | 48 | /** 49 | * @param TKey|array $key 50 | * @return bool 51 | */ 52 | public function has(mixed $key): bool 53 | { 54 | $keys = is_array($key) ? $key : func_get_args(); 55 | 56 | foreach ($keys as $value) { 57 | if (! array_key_exists($value, $this->data)) { 58 | return false; 59 | } 60 | } 61 | 62 | return true; 63 | } 64 | 65 | /** 66 | * @param TKey $offset 67 | * @return bool 68 | */ 69 | public function offsetExists($offset): bool 70 | { 71 | return isset($this->data[$offset]); 72 | } 73 | 74 | /** 75 | * @param TKey $offset 76 | * @return TValue 77 | */ 78 | public function offsetGet($offset): mixed 79 | { 80 | return $this->data[$offset]; 81 | } 82 | 83 | /** 84 | * @param TKey $offset 85 | * @param TValue $value 86 | * @return void 87 | */ 88 | public function offsetSet($offset, $value): void 89 | { 90 | $this->data[$offset] = $value; 91 | } 92 | 93 | /** 94 | * @param TKey $offset 95 | * @return void 96 | */ 97 | public function offsetUnset($offset): void 98 | { 99 | unset($this->data[$offset]); 100 | } 101 | 102 | public function toArray(): array 103 | { 104 | $data = []; 105 | foreach ($this->data as $key => $value) { 106 | if ($value instanceof Arrayable) { 107 | $data[$key] = $value->toArray(); 108 | } else { 109 | $data[$key] = $value; 110 | } 111 | } 112 | return $data; 113 | } 114 | 115 | /** 116 | * @return array 117 | */ 118 | public function all(): array 119 | { 120 | return $this->data; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/Data/GetGroupMsgHistory.php: -------------------------------------------------------------------------------- 1 | sender = Sender::create($sender); 54 | $this->anonymous = $anonymous ? Anonymous::create($anonymous) : null; 55 | } 56 | 57 | /** 58 | * @return array{ 59 | * post_type: string, 60 | * message_type: string, 61 | * time: int, 62 | * self_id: int, 63 | * sub_type: string, 64 | * anonymous: null|array{ 65 | * id: int, 66 | * name: string, 67 | * flag: string 68 | * }, 69 | * group_id: int, 70 | * message_seq: int, 71 | * user_id: int, 72 | * font: int, 73 | * message: string, 74 | * raw_message: string, 75 | * sender: array{ 76 | * age: int, 77 | * area: string, 78 | * card: string, 79 | * level: string, 80 | * role: string, 81 | * title: string, 82 | * sex: string, 83 | * user_id: int, 84 | * nickname: string 85 | * }, 86 | * message_id: int 87 | * } 88 | */ 89 | public function toArray(): array 90 | { 91 | return parent::toArray(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Apis/Friend.php: -------------------------------------------------------------------------------- 1 | client->post('/get_stranger_info', [ 29 | 'form_params' => compact('user_id', 'no_cache') 30 | ])->getData(); 31 | } 32 | 33 | /** 34 | * 删除好友 35 | * 36 | * @param int $user_id 好友 QQ 号 37 | * 38 | * @return void 39 | * 40 | * @throws \GuzzleHttp\Exception\GuzzleException 41 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 42 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 43 | * 44 | * @noinspection PhpFullyQualifiedNameUsageInspection 45 | */ 46 | public function deleteFriend(int $user_id): void 47 | { 48 | $this->client->post('/delete_friend', [ 49 | 'form_params' => compact('user_id') 50 | ]); 51 | } 52 | 53 | /** 54 | * 删除单向好友 55 | * 56 | * @param int $user_id 单向好友QQ号 57 | * 58 | * @return void 59 | * 60 | * @throws \GuzzleHttp\Exception\GuzzleException 61 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 62 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 63 | * 64 | * @noinspection PhpFullyQualifiedNameUsageInspection 65 | */ 66 | public function deleteUnidirectionalFriend(int $user_id): void 67 | { 68 | $this->client->post('/delete_unidirectional_friend', [ 69 | 'form_params' => compact('user_id') 70 | ]); 71 | } 72 | 73 | /** 74 | * 获取好友列表 75 | * 76 | * @return ArrayData 77 | * 78 | * @throws \GuzzleHttp\Exception\GuzzleException 79 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 80 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 81 | * 82 | * @noinspection PhpFullyQualifiedNameUsageInspection 83 | */ 84 | public function GetFriendList(): ArrayData 85 | { 86 | return $this->client->post('/get_friend_list')->getData(); 87 | } 88 | 89 | /** 90 | * 获取单向好友列表 91 | * 92 | * @return ArrayData 93 | * 94 | * @throws \GuzzleHttp\Exception\GuzzleException 95 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 96 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 97 | * 98 | * @noinspection PhpFullyQualifiedNameUsageInspection 99 | */ 100 | public function getUnidirectionalFriendList(): ArrayData 101 | { 102 | return $this->client->post('/get_unidirectional_friend_list')->getData(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Middlewares/ResponseMiddleware.php: -------------------------------------------------------------------------------- 1 | 'messages', 20 | 'get_group_msg_history' => 'messages', 21 | ]; 22 | 23 | public function __invoke(): Closure 24 | { 25 | return function (callable $handler) { 26 | return function ( 27 | RequestInterface $request, 28 | array $options 29 | ) use ($handler) { 30 | $promise = $handler($request, $options); 31 | return $promise->then( 32 | function ($response) use ($request) { 33 | return $this->responseHandler($response, $request); 34 | } 35 | ); 36 | }; 37 | }; 38 | } 39 | 40 | /** 41 | * @param ResponseInterface $response 42 | * @param RequestInterface $request 43 | * 44 | * @return ApiResponse 45 | * @throws ApiException 46 | * @throws ApiHttpException 47 | */ 48 | protected function responseHandler(ResponseInterface $response, RequestInterface $request): ApiResponse 49 | { 50 | if (200 !== $response->getStatusCode()) { 51 | throw new ApiHttpException('访问接口失败', -1, null, $response); 52 | } 53 | 54 | $body = $response->getBody(); 55 | if ($body->isSeekable()) { 56 | $body->rewind(); 57 | } 58 | $data = $body->getContents(); 59 | $body->rewind(); 60 | $data = json_decode($data, true); 61 | if (JSON_ERROR_NONE !== json_last_error()) { 62 | throw new ApiHttpException('数据解析失败', -2, null, $response); 63 | } 64 | $code = $data['retcode'] ?? 404; 65 | if (0 != $code && 1 != $code) { 66 | throw new ApiException($data['message'] ?? 'API错误', -3, null, $response); 67 | } 68 | 69 | $apiPath = $request->getUri()->getPath(); 70 | $apiPath = substr($apiPath, 1); 71 | $secondaryField = null; 72 | if (isset($this->dataMap[$apiPath])) { 73 | $secondaryField = $this->dataMap[$apiPath]; 74 | } 75 | if (str_starts_with($apiPath, '_')) { 76 | $apiPath = substr($apiPath, 1); 77 | } 78 | $apiPath = Str::studly($apiPath); 79 | /** @var $dataClassName CreateData */ 80 | $dataClassName = '\\Itwmw\\GoCqHttp\\Data\\' . $apiPath; 81 | $data = $data['data'] ?? null; 82 | if (!is_null($secondaryField) && is_array($data)) { 83 | $data = $data[$secondaryField] ?? null; 84 | } 85 | if (class_exists($dataClassName) && is_array($data)) { 86 | if (Utils::arrayIsList($data)) { 87 | $data = array_map(function ($item) use ($dataClassName) { 88 | return $dataClassName::create($item); 89 | }, $data); 90 | $data = new ArrayData($data); 91 | } else { 92 | $data = $dataClassName::create($data); 93 | } 94 | } 95 | return new ApiResponse( 96 | $response->getStatusCode(), 97 | $response->getHeaders(), 98 | $body, 99 | $response->getProtocolVersion(), 100 | $response->getReasonPhrase(), 101 | $data ?: null 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Apis/GroupSetting.php: -------------------------------------------------------------------------------- 1 | client->post('/set_group_name', [ 24 | 'form_params' => compact('group_id', 'group_name') 25 | ]); 26 | } 27 | 28 | /** 29 | * 设置群头像 30 | * 31 | * 目前这个API在登录一段时间后因cookie失效而失效, 请考虑后使用 32 | * 33 | * @param int $group_id 群号 34 | * @param string $file 图片文件名 35 | * @param int $cache 表示是否使用已缓存的文件 36 | * 37 | * @return void 38 | * 39 | * @throws \GuzzleHttp\Exception\GuzzleException 40 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 41 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 42 | * 43 | * @noinspection PhpFullyQualifiedNameUsageInspection 44 | */ 45 | public function setGroupPortrait(int $group_id, string $file, int $cache = 1): void 46 | { 47 | $this->client->post('/set_group_portrait', [ 48 | 'form_params' => compact('group_id', 'file', 'cache') 49 | ]); 50 | } 51 | 52 | /** 53 | * 设置群管理员 54 | * 55 | * @param int $group_id 群号 56 | * @param int $user_id 要设置管理员的 QQ 号 57 | * @param bool $enable true 为设置, false 为取消 58 | * 59 | * @return void 60 | * 61 | * @throws \GuzzleHttp\Exception\GuzzleException 62 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 63 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 64 | * 65 | * @noinspection PhpFullyQualifiedNameUsageInspection 66 | */ 67 | public function setGroupAdmin(int $group_id, int $user_id, bool $enable = true): void 68 | { 69 | $this->client->post('/set_group_admin', [ 70 | 'form_params' => compact('group_id', 'user_id', 'enable') 71 | ]); 72 | } 73 | 74 | /** 75 | * 设置群名片 ( 群备注 ) 76 | * 77 | * @param int $group_id 群号 78 | * @param int $user_id 要设置的 QQ 号 79 | * @param string $card 群名片内容, 不填或空字符串表示删除群名片 80 | * 81 | * @return void 82 | * 83 | * @throws \GuzzleHttp\Exception\GuzzleException 84 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 85 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 86 | * 87 | * @noinspection PhpFullyQualifiedNameUsageInspection 88 | */ 89 | public function setGroupCard(int $group_id, int $user_id, string $card = ''): void 90 | { 91 | $this->client->post('/set_group_card', [ 92 | 'form_params' => compact('group_id', 'user_id', 'card') 93 | ]); 94 | } 95 | 96 | /** 97 | * 设置群组专属头衔 98 | * 99 | * @param int $group_id 群号 100 | * @param int $user_id 要设置的 QQ 号 101 | * @param string $special_title 专属头衔, 不填或空字符串表示删除专属头衔 102 | * @param int $duration 专属头衔有效期, 单位秒, -1 表示永久, 不过此项似乎没有效果, 可能是只有某些特殊的时间长度有效, 有待测试 103 | * 104 | * @return void 105 | * 106 | * @throws \GuzzleHttp\Exception\GuzzleException 107 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 108 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 109 | * 110 | * @noinspection PhpFullyQualifiedNameUsageInspection 111 | */ 112 | public function setGroupSpecialTitle(int $group_id, int $user_id, string $special_title = '', int $duration = -1): void 113 | { 114 | $this->client->post('/set_group_special_title', [ 115 | 'form_params' => compact('group_id', 'user_id', 'special_title', 'duration') 116 | ]); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Apis/Bot.php: -------------------------------------------------------------------------------- 1 | client->post('/get_login_info')->getData(); 25 | } 26 | 27 | /** 28 | * 设置登录号资料 29 | * 30 | * @param string|null $nickname 名称 31 | * @param string|null $company 公司 32 | * @param string|null $email 邮箱 33 | * @param string|null $college 学校 34 | * @param string|null $personal_note 个人说明 35 | * 36 | * @return void 37 | * 38 | * @throws \GuzzleHttp\Exception\GuzzleException 39 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 40 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 41 | * 42 | * @noinspection PhpFullyQualifiedNameUsageInspection 43 | */ 44 | public function setQqProfile( 45 | ?string $nickname = null, 46 | ?string $company = null, 47 | ?string $email = null, 48 | ?string $college = null, 49 | ?string $personal_note = null 50 | ): void { 51 | $this->client->post('/set_qq_profile', [ 52 | 'form_params' => compact('nickname', 'company', 'email', 'college', 'personal_note') 53 | ]); 54 | } 55 | 56 | /** 57 | * 获取企点账号信息 58 | * 59 | * **该API只有企点协议可用** 60 | * 61 | * @return array 62 | * 63 | * @throws \GuzzleHttp\Exception\GuzzleException 64 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 65 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 66 | * 67 | * @noinspection PhpFullyQualifiedNameUsageInspection 68 | */ 69 | public function qiDianGetAccountInfo(): array 70 | { 71 | return $this->client->get('/qidian_get_account_info')->getData(); 72 | } 73 | 74 | /** 75 | * 获取在线机型 76 | * 77 | * @param string $model 机型名称 78 | * 79 | * @return GetModelShow 80 | * 81 | * @throws \GuzzleHttp\Exception\GuzzleException 82 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 83 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 84 | * 85 | * @noinspection PhpFullyQualifiedNameUsageInspection 86 | */ 87 | public function getModelShow(string $model): GetModelShow 88 | { 89 | return $this->client->post('/_get_model_show', [ 90 | 'form_params' => compact('model') 91 | ])->getData(); 92 | } 93 | 94 | /** 95 | * 设置在线机型 96 | * 97 | * @param string $model 机型名称 98 | * @param string|null $model_show 机型展示名称 99 | * 100 | * @return void 101 | * 102 | * @throws \GuzzleHttp\Exception\GuzzleException 103 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 104 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 105 | * 106 | * @noinspection PhpFullyQualifiedNameUsageInspection 107 | */ 108 | public function setModelShow(string $model, ?string $model_show = null): void 109 | { 110 | $this->client->post('/_set_model_show', [ 111 | 'form_params' => compact('model', 'model_show') 112 | ]); 113 | } 114 | 115 | /** 116 | * 获取当前账号在线客户端列表 117 | * 118 | * @param bool $no_cache 是否无视缓存 119 | * 120 | * @return GetOnlineClients 121 | * 122 | * @throws \GuzzleHttp\Exception\GuzzleException 123 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 124 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 125 | * 126 | * @noinspection PhpFullyQualifiedNameUsageInspection 127 | */ 128 | public function getOnlineClients(bool $no_cache = false): GetOnlineClients 129 | { 130 | return $this->client->post('/get_online_clients', [ 131 | 'form_params' => compact('no_cache') 132 | ])->getData(); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/Apis/GroupInfo.php: -------------------------------------------------------------------------------- 1 | client->get('/get_group_info', [ 34 | 'query' => compact('group_id', 'no_cache') 35 | ])->getData(); 36 | } 37 | 38 | /** 39 | * 获取群列表 40 | * 41 | * @param bool $no_cache 42 | * 43 | * @return ArrayData 是否不使用缓存(使用缓存可能更新不及时, 但响应更快) 44 | * 45 | * @throws \GuzzleHttp\Exception\GuzzleException 46 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 47 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 48 | * 49 | * @noinspection PhpFullyQualifiedNameUsageInspection 50 | */ 51 | public function getGroupList(bool $no_cache = false): ArrayData 52 | { 53 | return $this->client->get('/get_group_list', [ 54 | 'query' => compact('no_cache') 55 | ])->getData(); 56 | } 57 | 58 | /** 59 | * 获取群成员信息 60 | * 61 | * @param int $group_id 群号 62 | * @param int $user_id QQ 号 63 | * @param bool $no_cache 是否不使用缓存(使用缓存可能更新不及时, 但响应更快) 64 | * 65 | * @return GetGroupMemberInfo 66 | * 67 | * @throws \GuzzleHttp\Exception\GuzzleException 68 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 69 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 70 | * 71 | * @noinspection PhpFullyQualifiedNameUsageInspection 72 | */ 73 | public function getGroupMemberInfo(int $group_id, int $user_id, bool $no_cache = false): GetGroupMemberInfo 74 | { 75 | return $this->client->get('/get_group_member_info', [ 76 | 'query' => compact('group_id', 'user_id', 'no_cache') 77 | ])->getData(); 78 | } 79 | 80 | /** 81 | * 获取群成员列表 82 | * 83 | * @param int $group_id 群号 84 | * @param bool $no_cache 是否不使用缓存(使用缓存可能更新不及时, 但响应更快) 85 | * 86 | * @return ArrayData 87 | * 88 | * @throws \GuzzleHttp\Exception\GuzzleException 89 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 90 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 91 | * 92 | * @noinspection PhpFullyQualifiedNameUsageInspection 93 | */ 94 | public function getGroupMemberList(int $group_id, bool $no_cache = false): ArrayData 95 | { 96 | return $this->client->get('/get_group_member_list', [ 97 | 'query' => compact('group_id', 'no_cache') 98 | ])->getData(); 99 | } 100 | 101 | /** 102 | * 获取群荣誉信息 103 | * 104 | * @param int $group_id 群号 105 | * @param string $type 106 | * 要获取的群荣誉类型, 可传入 talkative performer legend strong_newbie emotion 以分别获取单个类型的群荣誉数据, 107 | * 或传入 all 获取所有数据 108 | * 109 | * @return GetGroupHonorInfo 110 | * 111 | * @throws \GuzzleHttp\Exception\GuzzleException 112 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 113 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 114 | * 115 | * @noinspection PhpFullyQualifiedNameUsageInspection 116 | */ 117 | public function getGroupHonorInfo( 118 | int $group_id, 119 | #[ExpectedValues(values: ['talkative', 'performer', 'legend', 'strong_newbie', 'emotion', 'all'])] 120 | string $type = 'all' 121 | ): GetGroupHonorInfo { 122 | return $this->client->get('/get_group_honor_info', [ 123 | 'query' => compact('group_id', 'type') 124 | ])->getData(); 125 | } 126 | 127 | /** 128 | * 获取群系统消息 129 | * 130 | * @return GetGroupSystemMsg 131 | * 132 | * @throws \GuzzleHttp\Exception\GuzzleException 133 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 134 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 135 | * 136 | * @noinspection PhpFullyQualifiedNameUsageInspection 137 | */ 138 | public function getGroupSystemMsg(): GetGroupSystemMsg 139 | { 140 | return $this->client->get('/get_group_system_msg')->getData(); 141 | } 142 | 143 | /** 144 | * 获取精华消息列表 145 | * 146 | * @param int $group_id 群号 147 | * 148 | * @return ArrayData 149 | * 150 | * @throws \GuzzleHttp\Exception\GuzzleException 151 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 152 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 153 | * 154 | * @noinspection PhpFullyQualifiedNameUsageInspection 155 | */ 156 | public function getEssenceMsgList(int $group_id): ArrayData 157 | { 158 | return $this->client->get('/get_essence_msg_list', [ 159 | 'query' => compact('group_id') 160 | ])->getData(); 161 | } 162 | 163 | /** 164 | * 获取群 @全体成员 剩余次数 165 | * 166 | * @param int $group_id 群号 167 | * 168 | * @return GetGroupAtAllRemain 169 | * 170 | * @throws \GuzzleHttp\Exception\GuzzleException 171 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 172 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 173 | * 174 | * @noinspection PhpFullyQualifiedNameUsageInspection 175 | */ 176 | public function getGroupAtAllRemain(int $group_id): GetGroupAtAllRemain 177 | { 178 | return $this->client->get('/get_group_at_all_remain', [ 179 | 'query' => compact('group_id') 180 | ])->getData(); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/Server.php: -------------------------------------------------------------------------------- 1 | refreshMessage(); 27 | } 28 | 29 | /** 30 | * @param callable|class-string $handler 31 | * @return $this 32 | */ 33 | public function addHandler(callable|string $handler): static 34 | { 35 | $this->handlers[] = $this->makeClosure($handler); 36 | return $this; 37 | } 38 | 39 | /** 40 | * @param string $type 41 | * @param callable|class-string $handler 42 | * @return $this 43 | */ 44 | public function addMessageListener( 45 | #[ExpectedValues(valuesFromClass: PostMessageType::class)] 46 | string $type, 47 | callable|string $handler 48 | ): static { 49 | $handler = $this->makeClosure($handler); 50 | 51 | $this->addHandler( 52 | function (BasePostMessage $message, Closure $next) use ($type, $handler): mixed { 53 | return PostType::MESSAGE === $message->post_type && $message->message_type === $type ? $handler($message, $next) : $next($message); 54 | } 55 | ); 56 | 57 | return $this; 58 | } 59 | 60 | /** 61 | * @param string $type 62 | * @param callable|class-string $handler 63 | * @return $this 64 | */ 65 | public function addNoticeListener( 66 | #[ExpectedValues(valuesFromClass: PostNoticeType::class)] 67 | string $type, 68 | callable|string $handler 69 | ): static { 70 | $handler = $this->makeClosure($handler); 71 | 72 | $this->addHandler( 73 | function (BasePostMessage $message, Closure $next) use ($type, $handler): mixed { 74 | return PostType::NOTICE === $message->post_type && $message->notice_type === $type ? $handler($message, $next) : $next($message); 75 | } 76 | ); 77 | 78 | return $this; 79 | } 80 | 81 | /** 82 | * @param string $type 83 | * @param callable|class-string $handler 84 | * @return $this 85 | */ 86 | public function addRequestListener( 87 | #[ExpectedValues(valuesFromClass: PostRequestType::class)] 88 | string $type, 89 | callable|string $handler 90 | ): static { 91 | $handler = $this->makeClosure($handler); 92 | 93 | $this->addHandler( 94 | function (BasePostMessage $message, Closure $next) use ($type, $handler): mixed { 95 | return PostType::REQUEST === $message->post_type && $message->request_type === $type ? $handler($message, $next) : $next($message); 96 | } 97 | ); 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * @param string $type 104 | * @param callable|class-string $handler 105 | * @return $this 106 | */ 107 | public function addMetaEventListener( 108 | #[ExpectedValues(valuesFromClass: PostMetaEventType::class)] 109 | string $type, 110 | callable|string $handler 111 | ): static { 112 | $handler = $this->makeClosure($handler); 113 | 114 | $this->addHandler( 115 | function (BasePostMessage $message, Closure $next) use ($type, $handler): mixed { 116 | return PostType::META_EVENT === $message->post_type && $message->meta_event_type === $type ? $handler($message, $next) : $next($message); 117 | } 118 | ); 119 | 120 | return $this; 121 | } 122 | 123 | protected function makeClosure(callable|string $handler): callable 124 | { 125 | if (is_callable($handler)) { 126 | return $handler; 127 | } 128 | 129 | if (class_exists($handler) && method_exists($handler, '__invoke')) { 130 | return fn (): mixed => (new $handler())(...func_get_args()); 131 | } 132 | 133 | throw new InvalidArgumentException(sprintf('Invalid handler: %s.', $handler)); 134 | } 135 | 136 | public static function setMessageProvider(Closure $provider): void 137 | { 138 | static::$messageProvider = $provider; 139 | } 140 | 141 | public function refreshMessage(): BasePostMessage|false 142 | { 143 | if (isset(static::$messageProvider)) { 144 | $input = call_user_func(static::$messageProvider); 145 | } else { 146 | $input = file_get_contents('php://input'); 147 | } 148 | 149 | $data = json_decode($input, true); 150 | if (JSON_ERROR_NONE !== json_last_error()) { 151 | return false; 152 | } 153 | 154 | if (!isset($data['post_type'])) { 155 | return false; 156 | } 157 | 158 | $postType = $data['post_type']; 159 | if ('message_sent' === $postType) { 160 | $postType = 'message'; 161 | } 162 | 163 | $subType = match ($postType) { 164 | 'message' => 'message_type', 165 | 'request' => 'request_type', 166 | 'notice' => 'notice_type', 167 | 'meta_event' => 'meta_event_type', 168 | default => null 169 | }; 170 | 171 | $class = '\Itwmw\GoCqHttp\Data\Post\\' . Str::studly($postType) . '\\' . Str::studly($data[$subType]) . Str::studly($postType); 172 | if (!class_exists($class)) { 173 | return false; 174 | } 175 | 176 | $this->message = $class::create($data); 177 | return $this->message; 178 | } 179 | 180 | public function getMessage(): ?BasePostMessage 181 | { 182 | return $this->message ?? null; 183 | } 184 | 185 | public function handle(): string 186 | { 187 | if (!$this->getMessage()) { 188 | return ''; 189 | } 190 | $handler = new Support\Handler($this->handlers); 191 | $result = $handler->handle($this->message); 192 | return $result instanceof BasePostMessage ? '' : $result; 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/Apis/GroupFile.php: -------------------------------------------------------------------------------- 1 | 在不提供 folder 参数的情况下默认上传到根目录 17 | * 只能上传本地文件, 需要上传 http 文件的话请先调用 {@see Cq::downloadFile()} API下载 18 | * 19 | * @param int $group_id 群号 20 | * @param string $file 本地文件路径 21 | * @param string $name 储存名称 22 | * @param string|null $folder 父目录ID 23 | * 24 | * @return void 25 | * 26 | * @throws \GuzzleHttp\Exception\GuzzleException 27 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 28 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 29 | * 30 | * @noinspection PhpFullyQualifiedNameUsageInspection 31 | */ 32 | public function uploadGroupFile(int $group_id, string $file, string $name, ?string $folder = null): void 33 | { 34 | $this->client->post('/upload_group_file', [ 35 | 'form_params' => compact('group_id', 'file', 'name', 'folder') 36 | ]); 37 | } 38 | 39 | /** 40 | * 删除群文件 41 | * 42 | * @param int $group_id 群号 43 | * @param string $file_id 文件ID 参考 {@see FileStruct File} 对象 44 | * @param int $busid 文件类型 参考 {@see FileStruct File} 对象 45 | * 46 | * @return void 47 | * 48 | * @throws \GuzzleHttp\Exception\GuzzleException 49 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 50 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 51 | * 52 | * @noinspection PhpFullyQualifiedNameUsageInspection 53 | */ 54 | public function deleteGroupFile(int $group_id, string $file_id, int $busid): void 55 | { 56 | $this->client->post('/delete_group_file', [ 57 | 'form_params' => compact('group_id', 'file_id', 'busid') 58 | ]); 59 | } 60 | 61 | /** 62 | * 创建群文件文件夹 63 | * 64 | * 仅能在根目录创建文件夹 65 | * 66 | * @param int $group_id 群号 67 | * @param string $name 文件夹名称 68 | * @param string $parent_id 仅能为 / 69 | * 70 | * @return void 71 | * 72 | * @throws \GuzzleHttp\Exception\GuzzleException 73 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 74 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 75 | * 76 | * @noinspection PhpFullyQualifiedNameUsageInspection 77 | */ 78 | public function createGroupFileFolder(int $group_id, string $name, string $parent_id = '/'): void 79 | { 80 | $this->client->post('/create_group_file_folder', [ 81 | 'form_params' => compact('group_id', 'name', 'parent_id') 82 | ]); 83 | } 84 | 85 | /** 86 | * 删除群文件文件夹 87 | * 88 | * @param int $group_id 群号 89 | * @param string $folder_id 文件夹ID 参考 {@see Folder} 对象 90 | * 91 | * @return void 92 | * 93 | * @throws \GuzzleHttp\Exception\GuzzleException 94 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 95 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 96 | * 97 | * @noinspection PhpFullyQualifiedNameUsageInspection 98 | */ 99 | public function deleteGroupFolder(int $group_id, string $folder_id): void 100 | { 101 | $this->client->post('/delete_group_folder', [ 102 | 'form_params' => compact('group_id', 'folder_id') 103 | ]); 104 | } 105 | 106 | /** 107 | * 获取群文件系统信息 108 | * 109 | * @param int $group_id 群号 110 | * 111 | * @return GetGroupFileSystemInfo 112 | * 113 | * @throws \GuzzleHttp\Exception\GuzzleException 114 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 115 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 116 | * 117 | * @noinspection PhpFullyQualifiedNameUsageInspection 118 | */ 119 | public function getGroupFileSystemInfo(int $group_id): GetGroupFileSystemInfo 120 | { 121 | return $this->client->post('/get_group_file_system_info', [ 122 | 'form_params' => compact('group_id') 123 | ])->getData(); 124 | } 125 | 126 | /** 127 | * 获取群根目录文件列表 128 | * 129 | * @param int $group_id 群号 130 | * 131 | * @return GetGroupRootFiles 132 | * 133 | * @throws \GuzzleHttp\Exception\GuzzleException 134 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 135 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 136 | * 137 | * @noinspection PhpFullyQualifiedNameUsageInspection 138 | */ 139 | public function getGroupRootFiles(int $group_id): GetGroupRootFiles 140 | { 141 | return $this->client->post('/get_group_root_files', [ 142 | 'form_params' => compact('group_id') 143 | ])->getData(); 144 | } 145 | 146 | /** 147 | * 获取群子目录文件列表 148 | * 149 | * @param int $group_id 群号 150 | * @param string $folder_id 文件夹ID 参考 {@see Folder} 对象 151 | * 152 | * @return GetGroupFilesByFolder 153 | * 154 | * @throws \GuzzleHttp\Exception\GuzzleException 155 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 156 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 157 | * 158 | * @noinspection PhpFullyQualifiedNameUsageInspection 159 | */ 160 | public function getGroupFilesByFolder(int $group_id, string $folder_id): GetGroupFilesByFolder 161 | { 162 | return $this->client->post('/get_group_files_by_folder', [ 163 | 'form_params' => compact('group_id', 'folder_id') 164 | ])->getData(); 165 | } 166 | 167 | /** 168 | * 获取群文件资源链接 169 | * 170 | * @param int $group_id 群号 171 | * @param string $file_id 文件ID 参考 {@see FileStruct File} 对象 172 | * @param int $busid 文件类型 参考 {@see FileStruct File} 对象 173 | * 174 | * @return string 文件下载链接 175 | * 176 | * @throws \GuzzleHttp\Exception\GuzzleException 177 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 178 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 179 | * 180 | * @noinspection PhpFullyQualifiedNameUsageInspection 181 | */ 182 | public function getGroupFileUrl(int $group_id, string $file_id, int $busid): string 183 | { 184 | return $this->client->post('/get_group_file_url', [ 185 | 'form_params' => compact('group_id', 'file_id', 'busid') 186 | ])->getData()['url']; 187 | } 188 | 189 | /** 190 | * 上传私聊文件 191 | * 192 | * 在不提供 folder 参数的情况下默认上传到根目录 193 | * 只能上传本地文件, 需要上传 http 文件的话请先调用 {@see Cq::downloadFile()} API下载 194 | * 195 | * @param int $user_id 对方 QQ 号 196 | * @param string $file 本地文件路径 197 | * @param string $name 文件名称 198 | * 199 | * @return void 200 | * 201 | * @throws \GuzzleHttp\Exception\GuzzleException 202 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 203 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 204 | * 205 | * @noinspection PhpFullyQualifiedNameUsageInspection 206 | */ 207 | public function uploadPrivateFile(int $user_id, string $file, string $name): void 208 | { 209 | $this->client->post('/upload_private_file', [ 210 | 'form_params' => compact('user_id', 'file', 'name') 211 | ]); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/Apis/Cq.php: -------------------------------------------------------------------------------- 1 | client->post('/get_cookies', [ 28 | 'form_params' => compact('domain') 29 | ])->getData()['cookies']; 30 | } 31 | 32 | /** 33 | * 获取 CSRF Token 34 | * 35 | * @deprecated 该 API 暂未被 go-cqhttp 支持, 您可以提交 pr 以使该 API 被支持 提交 pr 36 | * 37 | * @return int CSRF Token 38 | * 39 | * @throws \GuzzleHttp\Exception\GuzzleException 40 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 41 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 42 | * 43 | * @noinspection PhpFullyQualifiedNameUsageInspection 44 | */ 45 | public function getCsrfToken(): int 46 | { 47 | return $this->client->post('/get_csrf_token')->getData()['token']; 48 | } 49 | 50 | /** 51 | * 获取 QQ 相关接口凭证 52 | * 53 | * @deprecated 该 API 暂未被 go-cqhttp 支持, 您可以提交 pr 以使该 API 被支持 提交 pr 54 | * 55 | * @param string $domain 需要获取 cookies 的域名 56 | * 57 | * @return array{ 58 | * cookies: string, 59 | * csrf_token: int 60 | * } 61 | * 62 | * @throws \GuzzleHttp\Exception\GuzzleException 63 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 64 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 65 | * 66 | * @noinspection PhpFullyQualifiedNameUsageInspection 67 | */ 68 | public function getCredentials(string $domain): array 69 | { 70 | return $this->client->post('/get_credentials', [ 71 | 'form_params' => compact('domain') 72 | ])->getData(); 73 | } 74 | 75 | /** 76 | * 获取版本信息 77 | * 78 | * @return GetVersionInfo 79 | * 80 | * @throws \GuzzleHttp\Exception\GuzzleException 81 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 82 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 83 | * 84 | * @noinspection PhpFullyQualifiedNameUsageInspection 85 | */ 86 | public function getVersionInfo(): GetVersionInfo 87 | { 88 | return $this->client->post('/get_version_info')->getData(); 89 | } 90 | 91 | /** 92 | * 获取状态 93 | * 94 | * @return GetStatus 95 | * 96 | * @throws \GuzzleHttp\Exception\GuzzleException 97 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 98 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 99 | * 100 | * @noinspection PhpFullyQualifiedNameUsageInspection 101 | */ 102 | public function getStatus(): GetStatus 103 | { 104 | return $this->client->post('/get_status')->getData(); 105 | } 106 | 107 | /** 108 | * 清理缓存 109 | * 110 | * @deprecated 该 API 暂未被 go-cqhttp 支持, 您可以提交 pr 以使该 API 被支持 提交 pr 111 | * 112 | * @return void 113 | * 114 | * @throws \GuzzleHttp\Exception\GuzzleException 115 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 116 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 117 | * 118 | * @noinspection PhpFullyQualifiedNameUsageInspection 119 | */ 120 | public function cleanCache(): void 121 | { 122 | $this->client->post('/clean_cache'); 123 | } 124 | 125 | /** 126 | * 重载事件过滤器 127 | * 128 | * @param string $file 事件过滤器文件 129 | * 130 | * @return void 131 | * 132 | * @throws \GuzzleHttp\Exception\GuzzleException 133 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 134 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 135 | * 136 | * @noinspection PhpFullyQualifiedNameUsageInspection 137 | */ 138 | public function reloadEventFilter(string $file): void 139 | { 140 | $this->client->post('/reload_event_filter', [ 141 | 'form_params' => compact('file') 142 | ]); 143 | } 144 | 145 | /** 146 | * 下载文件到缓存目录 147 | * 148 | * 通过这个API下载的文件能直接放入CQ码作为图片或语音发送,调用后会阻塞直到下载完成后才会返回数据,请注意下载大文件时的超时 149 | * 150 | * @param string $url 下载地址 151 | * @param int $thread_count 下载线程数 152 | * @param string|array $headers 自定义请求头,[\r\n] 为换行符, 使用http请求时请注意编码 153 | * 154 | * @return string 下载文件的绝对路径 155 | * 156 | * @throws \GuzzleHttp\Exception\GuzzleException 157 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 158 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 159 | * 160 | * @noinspection PhpFullyQualifiedNameUsageInspection 161 | */ 162 | public function downloadFile(string $url, int $thread_count = 1, string|array $headers = []): string 163 | { 164 | return $this->client->post('/download_file', [ 165 | 'form_params' => compact('url', 'thread_count', 'headers') 166 | ])->getData()['file']; 167 | } 168 | 169 | /** 170 | * 检查链接安全性 171 | * 172 | * @param string $url 需要检查的链接 173 | * 174 | * @return int 安全等级, 1: 安全 2: 未知 3: 危险 175 | * 176 | * @throws \GuzzleHttp\Exception\GuzzleException 177 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 178 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 179 | * 180 | * @noinspection PhpFullyQualifiedNameUsageInspection 181 | */ 182 | public function checkUrlSafely(string $url): int 183 | { 184 | return $this->client->post('/check_url_safely', [ 185 | 'form_params' => compact('url') 186 | ])->getData()['level']; 187 | } 188 | 189 | /** 190 | * 获取中文分词 ( 隐藏 API ) 191 | * 192 | * @deprecated 隐藏 API 是不建议一般用户使用的, 它们只应该在 OneBot 实现内部或由 SDK 和框架使用, 因为不正确的使用可能造成程序运行不正常。 193 | * 194 | * @param string $content 内容 195 | * 196 | * @return array 词组 197 | * 198 | * @throws \GuzzleHttp\Exception\GuzzleException 199 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 200 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 201 | * 202 | * @noinspection PhpFullyQualifiedNameUsageInspection 203 | */ 204 | public function getWordSlices(string $content): array 205 | { 206 | return $this->client->post('/.get_word_slices', [ 207 | 'form_params' => compact('content') 208 | ])->getData()['slices']; 209 | } 210 | 211 | /** 212 | * 对事件执行快速操作 ( 隐藏 API ) 213 | * 214 | * @deprecated 隐藏 API 是不建议一般用户使用的, 它们只应该在 OneBot 实现内部或由 SDK 和框架使用, 因为不正确的使用可能造成程序运行不正常。 215 | * 216 | * @param array $context 事件数据对象, 可做精简, 如去掉 message 等无用字段 217 | * @param array $operation 快速操作对象, 例如 {"ban": true, "reply": "请不要说脏话"} 218 | * 219 | * @return void 220 | * 221 | * @throws \GuzzleHttp\Exception\GuzzleException 222 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 223 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 224 | * 225 | * @noinspection PhpFullyQualifiedNameUsageInspection 226 | */ 227 | public function handleQuickOperation(array $context, array $operation): void 228 | { 229 | $this->client->post('/.handle_quick_operation', [ 230 | 'form_params' => compact('context', 'operation') 231 | ]); 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /src/Apis/GroupAction.php: -------------------------------------------------------------------------------- 1 | client->post('/set_group_ban', [ 29 | 'form_params' => compact('group_id', 'user_id', 'duration') 30 | ]); 31 | } 32 | 33 | /** 34 | * 群全员禁言 35 | * 36 | * @param int $group_id 群号 37 | * @param bool $enable true 为开启, false 为关闭 38 | * 39 | * @return void 40 | * 41 | * @throws \GuzzleHttp\Exception\GuzzleException 42 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 43 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 44 | * 45 | * @noinspection PhpFullyQualifiedNameUsageInspection 46 | */ 47 | public function setGroupWholeBan(int $group_id, bool $enable = true): void 48 | { 49 | $this->client->post('/set_group_whole_ban', [ 50 | 'form_params' => compact('group_id', 'enable') 51 | ]); 52 | } 53 | 54 | /** 55 | * 群匿名用户禁言 56 | * 57 | * @param int $group_id 群号 58 | * @param Anonymous|array|null $anonymous 可选, 要禁言的匿名用户对象(群消息上报的 anonymous 字段) 59 | * @param string|null $anonymous_flag 可选, 要禁言的匿名用户的 flag(需从群消息上报的数据中获得) 60 | * @param int $duration 禁言时长, 单位秒, 无法取消匿名用户禁言 61 | * 62 | * @return void 63 | * 64 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 65 | * @throws \GuzzleHttp\Exception\GuzzleException 66 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 67 | * 68 | * @noinspection PhpFullyQualifiedNameUsageInspection 69 | */ 70 | public function setGroupAnonymousBan( 71 | int $group_id, 72 | null|Anonymous|array $anonymous = null, 73 | string $anonymous_flag = null, 74 | int $duration = 30 * 60 75 | ): void { 76 | if (empty($anonymous) && empty($anonymous_flag)) { 77 | throw new \Itwmw\GoCqHttp\Exceptions\ApiException('匿名用户对象和匿名用户flag不能同时为空'); 78 | } 79 | if ($anonymous instanceof Anonymous) { 80 | $anonymous = $anonymous->toArray(); 81 | } 82 | $this->client->post('/set_group_anonymous_ban', [ 83 | 'form_params' => compact('group_id', 'anonymous', 'anonymous_flag', 'duration') 84 | ]); 85 | } 86 | 87 | /** 88 | * 设置精华消息 89 | * 90 | * @param int $message_id 消息ID 91 | * 92 | * @return void 93 | * 94 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 95 | * @throws \GuzzleHttp\Exception\GuzzleException 96 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 97 | * 98 | * @noinspection PhpFullyQualifiedNameUsageInspection 99 | */ 100 | public function setEssenceMsg(int $message_id): void 101 | { 102 | $this->client->post('/set_essence_msg', [ 103 | 'form_params' => compact('message_id') 104 | ]); 105 | } 106 | 107 | /** 108 | * 移出精华消息 109 | * 110 | * @param int $message_id 消息ID 111 | * 112 | * @return void 113 | * 114 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 115 | * @throws \GuzzleHttp\Exception\GuzzleException 116 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 117 | * 118 | * @noinspection PhpFullyQualifiedNameUsageInspection 119 | */ 120 | public function deleteEssenceMsg(int $message_id): void 121 | { 122 | $this->client->post('/delete_essence_msg', [ 123 | 'form_params' => compact('message_id') 124 | ]); 125 | } 126 | 127 | /** 128 | * 群打卡 129 | * 130 | * @param int $group_id 群号 131 | * 132 | * @return void 133 | * 134 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 135 | * @throws \GuzzleHttp\Exception\GuzzleException 136 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 137 | * 138 | * @noinspection PhpFullyQualifiedNameUsageInspection 139 | */ 140 | public function sendGroupSign(int $group_id): void 141 | { 142 | $this->client->post('/send_group_sign', [ 143 | 'form_params' => compact('group_id') 144 | ]); 145 | } 146 | 147 | /** 148 | * 群设置匿名 149 | * 150 | * @param int $group_id 群号 151 | * @param bool $enable 是否允许匿名聊天 152 | * 153 | * @return void 154 | * 155 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 156 | * @throws \GuzzleHttp\Exception\GuzzleException 157 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 158 | * 159 | * @noinspection PhpFullyQualifiedNameUsageInspection 160 | */ 161 | public function setGroupAnonymous(int $group_id, bool $enable = true): void 162 | { 163 | $this->client->post('/set_group_anonymous', [ 164 | 'form_params' => compact('group_id', 'enable') 165 | ]); 166 | } 167 | 168 | /** 169 | * 发送群公告 170 | * 171 | * @param int $group_id 群号 172 | * @param string $content 公告内容 173 | * @param string $image 图片路径(可选) 174 | * 175 | * @return void 176 | * 177 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 178 | * @throws \GuzzleHttp\Exception\GuzzleException 179 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 180 | * 181 | * @noinspection PhpFullyQualifiedNameUsageInspection 182 | */ 183 | public function sendGroupNotice(int $group_id, string $content, string $image = ''): void 184 | { 185 | $this->client->post('/_send_group_notice', [ 186 | 'form_params' => compact('group_id', 'content', 'image') 187 | ]); 188 | } 189 | 190 | /** 191 | * 获取群公告 192 | * 193 | * @param int $group_id 群号 194 | * 195 | * @return ArrayData 196 | * 197 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 198 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 199 | * @throws \GuzzleHttp\Exception\GuzzleException 200 | * 201 | * @noinspection PhpFullyQualifiedNameUsageInspection 202 | */ 203 | public function getGroupNotice(int $group_id): ArrayData 204 | { 205 | return $this->client->post('/_get_group_notice', [ 206 | 'form_params' => compact('group_id') 207 | ])->getData(); 208 | } 209 | 210 | /** 211 | * 群组踢人 212 | * 213 | * @param int $group_id 群号 214 | * @param int $user_id 要踢的 QQ 号 215 | * @param bool $reject_add_request 拒绝此人的加群请求 216 | * 217 | * @return void 218 | * 219 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 220 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 221 | * @throws \GuzzleHttp\Exception\GuzzleException 222 | * 223 | * @noinspection PhpFullyQualifiedNameUsageInspection 224 | */ 225 | public function setGroupKick(int $group_id, int $user_id, bool $reject_add_request = false): void 226 | { 227 | $this->client->post('/set_group_kick', [ 228 | 'form_params' => compact('group_id', 'user_id', 'reject_add_request') 229 | ]); 230 | } 231 | 232 | /** 233 | * 退出群组 234 | * 235 | * @param int $group_id 群号 236 | * @param bool $is_dismiss 是否解散, 如果登录号是群主, 则仅在此项为 true 时能够解散 237 | * 238 | * @return void 239 | * 240 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 241 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 242 | * @throws \GuzzleHttp\Exception\GuzzleException 243 | * 244 | * @noinspection PhpFullyQualifiedNameUsageInspection 245 | */ 246 | public function setGroupLeave(int $group_id, bool $is_dismiss = false): void 247 | { 248 | $this->client->post('/set_group_leave', [ 249 | 'form_params' => compact('group_id', 'is_dismiss') 250 | ]); 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /src/Apis/Message.php: -------------------------------------------------------------------------------- 1 | client->post('/send_private_msg', [ 31 | 'form_params' => compact('user_id', 'message', 'group_id', 'auto_escape') 32 | ])->getData()['message_id']; 33 | } 34 | 35 | /** 36 | * 发送群消息 37 | * 38 | * @param int $group_id 群号 39 | * @param string $message 要发送的内容 40 | * @param bool $auto_escape 消息内容是否作为纯文本发送 ( 即不解析 CQ 码 ) , 只在 message 字段是字符串时有效 41 | * 42 | * @return int 消息 ID 43 | * 44 | * @throws \GuzzleHttp\Exception\GuzzleException 45 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 46 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 47 | * 48 | * @noinspection PhpFullyQualifiedNameUsageInspection 49 | */ 50 | public function sendGroupMsg(int $group_id, string $message, bool $auto_escape = false): int 51 | { 52 | return $this->client->post('/send_group_msg', [ 53 | 'form_params' => compact('group_id', 'message', 'auto_escape') 54 | ])->getData()['message_id']; 55 | } 56 | 57 | /** 58 | * 发送消息 59 | * 60 | * @param string $message 要发送的内容 61 | * @param string|null $message_type 消息类型, 支持 private、group , 分别对应私聊、群组, 如不传入, 则根据传入的 *_id 参数判断 62 | * @param int|null $user_id 对方 QQ 号 ( 消息类型为 private 时需要 ) 63 | * @param int|null $group_id 群号 ( 消息类型为 group 时需要 ) 64 | * @param bool $auto_escape 消息内容是否作为纯文本发送 ( 即不解析 CQ 码 ) , 只在 message 字段是字符串时有效 65 | * 66 | * @return int 消息 ID 67 | * 68 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 69 | * @throws \GuzzleHttp\Exception\GuzzleException 70 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 71 | * 72 | * @noinspection PhpFullyQualifiedNameUsageInspection 73 | */ 74 | public function sendMsg( 75 | string $message, 76 | #[ExpectedValues(values: ['private', 'group'])] 77 | ?string $message_type = null, 78 | ?int $user_id = null, 79 | ?int $group_id = null, 80 | bool $auto_escape = false 81 | ): int { 82 | if (empty($user_id) && empty($group_id)) { 83 | throw new \Itwmw\GoCqHttp\Exceptions\ApiException('QQ号和群号不能同时为空'); 84 | } 85 | 86 | return $this->client->post('/send_msg', [ 87 | 'form_params' => compact('message_type', 'user_id', 'message', 'group_id', 'auto_escape') 88 | ])->getData()['message_id']; 89 | } 90 | 91 | /** 92 | * 获取消息 93 | * 94 | * @param int $message_id 消息ID 95 | * 96 | * @return GetMsg 97 | * 98 | * @throws \GuzzleHttp\Exception\GuzzleException 99 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 100 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 101 | * 102 | * @noinspection PhpFullyQualifiedNameUsageInspection 103 | */ 104 | public function getMsg(int $message_id): GetMsg 105 | { 106 | return $this->client->get('/get_msg', [ 107 | 'query' => compact('message_id') 108 | ])->getData(); 109 | } 110 | 111 | /** 112 | * 撤回消息 113 | * 114 | * @param int $message_id 消息ID 115 | * 116 | * @return void 117 | * 118 | * @throws \GuzzleHttp\Exception\GuzzleException 119 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 120 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 121 | * 122 | * @noinspection PhpFullyQualifiedNameUsageInspection 123 | */ 124 | public function deleteMsg(int $message_id): void 125 | { 126 | $this->client->post('/delete_msg', [ 127 | 'form_params' => compact('message_id') 128 | ]); 129 | } 130 | 131 | /** 132 | * 标记消息已读 133 | * 134 | * @param int $message_id 消息ID 135 | * 136 | * @return void 137 | * 138 | * @throws \GuzzleHttp\Exception\GuzzleException 139 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 140 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 141 | * 142 | * @noinspection PhpFullyQualifiedNameUsageInspection 143 | */ 144 | public function markMsgAsRead(int $message_id): void 145 | { 146 | $this->client->post('/mark_msg_as_read', [ 147 | 'form_params' => compact('message_id') 148 | ]); 149 | } 150 | 151 | /** 152 | * 获取合并转发内容 153 | * 154 | * @param string $message_id 消息id,对应合并转发中的 id 字段 155 | * 156 | * @return array 164 | * 165 | * @throws \GuzzleHttp\Exception\GuzzleException 166 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 167 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 168 | * 169 | * @noinspection PhpFullyQualifiedNameUsageInspection 170 | */ 171 | public function getForwardMsg(string $message_id): array 172 | { 173 | return $this->client->get('/get_forward_msg', [ 174 | 'query' => compact('message_id') 175 | ])->getData()['messages'] ?? []; 176 | } 177 | 178 | /** 179 | * 发送合并转发 ( 群聊 ) 180 | * 181 | * @param int $group_id 群号 182 | * @param array $messages 自定义转发消息 183 | * 184 | * @return array{ 185 | * message_id: int, 186 | * forward_id: int 187 | * } 返回消息 ID 和合并转发 ID 188 | * 189 | * @throws \GuzzleHttp\Exception\GuzzleException 190 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 191 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 192 | * 193 | * @noinspection PhpFullyQualifiedNameUsageInspection 194 | * 195 | * @link https://docs.go-cqhttp.org/cqcode/#%E5%90%88%E5%B9%B6%E8%BD%AC%E5%8F%91%E6%B6%88%E6%81%AF%E8%8A%82%E7%82%B9 196 | */ 197 | public function sendGroupForwardMsg(int $group_id, array $messages): array 198 | { 199 | return $this->client->post('/send_group_forward_msg', [ 200 | 'form_params' => compact('group_id', 'messages') 201 | ])->getData(); 202 | } 203 | 204 | /** 205 | * 发送合并转发 ( 群聊 ) 206 | * 207 | * @param int $user_id 好友QQ号 208 | * @param array $messages 自定义转发消息 209 | * 210 | * @return array{ 211 | * message_id: int, 212 | * forward_id: int 213 | * } 返回消息 ID 和合并转发 ID 214 | * 215 | * @throws \GuzzleHttp\Exception\GuzzleException 216 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 217 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 218 | * 219 | * @noinspection PhpFullyQualifiedNameUsageInspection 220 | * 221 | * @link https://docs.go-cqhttp.org/cqcode/#%E5%90%88%E5%B9%B6%E8%BD%AC%E5%8F%91%E6%B6%88%E6%81%AF%E8%8A%82%E7%82%B9 222 | */ 223 | public function sendPrivateForwardMsg(int $user_id, array $messages): array 224 | { 225 | return $this->client->post('/send_private_forward_msg', [ 226 | 'form_params' => compact('user_id', 'messages') 227 | ])->getData(); 228 | } 229 | 230 | /** 231 | * 获取群消息历史记录 232 | * 233 | * @param int $group_id 群号 234 | * @param int $message_seq 起始消息序号, 可通过 get_msg 获得 235 | * 236 | * @return ArrayData 237 | * 238 | * @throws \GuzzleHttp\Exception\GuzzleException 239 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiException 240 | * @throws \Itwmw\GoCqHttp\Exceptions\ApiHttpException 241 | * 242 | * @noinspection PhpFullyQualifiedNameUsageInspection 243 | */ 244 | public function getGroupMsgHistory(int $group_id, int $message_seq = 0): ArrayData 245 | { 246 | return $this->client->get('/get_group_msg_history', [ 247 | 'query' => compact('group_id', 'message_seq') 248 | ])->getData(); 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | go-cqhttp 4 | 5 |

6 | 7 |
8 | 9 |

go-cqhttp-sdk

10 | 11 | [go-cqhttp](https://github.com/Mrs4s/go-cqhttp)项目的PHP版SDK,拥有完整注释和代码提示 12 | 13 |
14 | 15 |

16 | 17 | license 18 | 19 | 20 | release 21 | 22 | php-version 23 | 24 |

25 | 26 |

27 | 文档 28 | · 29 | 下载 30 | · 31 | 开始使用 32 |

33 | 34 | ### 安装 35 | ```shell 36 | composer require itwmw/go-cq-http-sdk 37 | ``` 38 | ### 使用示例 39 | ```php 40 | $api = new Itwmw\GoCqHttp\Api(); 41 | // 发送私聊消息 42 | $api->message->sendMsg('测试消息', 'private', 995645888); 43 | ``` 44 | ### 处理上报消息 45 | SDK内置消息的处理: 46 | ```php 47 | $server = $api->getServer(); 48 | ``` 49 | 你可以通过中间件模式来处理消息: 50 | ```php 51 | use Itwmw\GoCqHttp\Data\Post\BasePostMessage; 52 | 53 | $server->addHandler(function(BasePostMessage $message, \Closure $next) { 54 | // 处理消息 55 | return $next($message); 56 | })->addHandler(function(BasePostMessage $message, \Closure $next) { 57 | // 处理消息 58 | return $next($message); 59 | })->addHandler(function(BasePostMessage $message, \Closure $next) { 60 | // 处理消息 61 | return $next($message); 62 | })->addHandler(function(BasePostMessage $message, \Closure $next) { 63 | // 处理消息 64 | return $next($message); 65 | }); 66 | 67 | echo $server->handle(); 68 | ``` 69 | #### 使用独立的类来处理消息 70 | ```php 71 | use Itwmw\GoCqHttp\Data\Post\BasePostMessage; 72 | 73 | class MessageHandle 74 | { 75 | public function __invoke(BasePostMessage $message, \Closure $next) 76 | { 77 | // 处理消息 78 | return $next($message); 79 | } 80 | } 81 | 82 | $server->addHandler(MessageHandle::class); 83 | ``` 84 | > 也支持`callable`类型的处理器 85 | 86 | #### 注册指定类型的处理器 87 | ```php 88 | use Itwmw\GoCqHttp\Data\Struct\Enum\PostMessageType; 89 | use Itwmw\GoCqHttp\Data\Post\Message\PrivateMessage; 90 | 91 | $server->addMessageListener(PostMessageType::PRIVATE, function (PrivateMessage $message, \Closure $next) { 92 | // 处理消息 93 | return $next($message); 94 | }); 95 | ``` 96 | 97 | ```php 98 | use Itwmw\GoCqHttp\Data\Struct\Enum\PostNoticeType; 99 | use Itwmw\GoCqHttp\Data\Post\Notice\GroupIncreaseNotice; 100 | 101 | $server->addNoticeListener(PostNoticeType::GROUP_INCREASE, function (GroupIncreaseNotice $message, Closure $next) { 102 | // 处理群成员增加 103 | return $next($message); 104 | }); 105 | ``` 106 | > 同样也支持使用独立的类来处理消息 107 | 108 | #### 快捷操作 109 | 部分类型的消息支持快捷操作,快捷操作的方法为 `response`,例: 110 | ```php 111 | use Itwmw\GoCqHttp\Data\Post\Message\PrivateMessage; 112 | 113 | $server->addMessageListener(PostMessageType::PRIVATE, function (PrivateMessage $message, \Closure $next) { 114 | if ('再见' === $message->message) { 115 | return $message->response('bye~'); 116 | } 117 | return $next($message); 118 | }); 119 | ``` 120 | ### 支持 121 | 122 |
123 | Bot账号相关的Api 124 | 125 | ```php 126 | $api->bot; 127 | ``` 128 | 129 | | API | 功能 | 130 | | ------------------------ | ---------------------- | 131 | | getLoginInfo | 获取登录号信息 | 132 | | setQqProfile | 设置登录号资料 | 133 | | qiDianGetAccountInfo | 获取企点账号信息 | 134 | | getModelShow | 获取在线机型 | 135 | | setModelShow | 设置在线机型 | 136 | | getOnlineClients | 获取当前账号在线客户端列表 | 137 |
138 | 139 | 140 |
141 | 好友相关的Api 142 | 143 | ```php 144 | $api->friend; 145 | ``` 146 | 147 | | API | 功能 | 148 | | ------------------------ | ---------------------- | 149 | | getStrangerInfo | 获取陌生人信息 | 150 | | GetFriendList | 获取好友列表 | 151 | | getUnidirectionalFriendList | 获取单向好友列表 | 152 | | deleteFriend | 删除好友 | 153 | | deleteUnidirectionalFriend | 删除单向好友 | 154 | | getOnlineClients | 获取当前账号在线客户端列表 | 155 |
156 | 157 | 158 |
159 | 消息相关的Api 160 | 161 | ```php 162 | $api->message; 163 | ``` 164 | 165 | | API | 功能 | 166 | | ------------------------ | ---------------------- | 167 | | sendPrivateMsg | 发送私聊消息 | 168 | | sendGroupMsg | 发送群聊消息 | 169 | | sendMsg | 发送消息 | 170 | | getMsg | 获取消息 | 171 | | deleteMsg | 撤回消息 | 172 | | markMsgAsRead | 标记消息已读 | 173 | | getForwardMsg | 获取合并转发内容 | 174 | | sendGroupForwardMsg | 发送合并转发 ( 群聊 ) | 175 | | sendPrivateForwardMsg | 发送合并转发 ( 好友 ) | 176 | | getGroupMsgHistory | 获取群消息历史记录 | 177 |
178 | 179 | 180 |
181 | 图片相关的Api 182 | 183 | ```php 184 | $api->image; 185 | ``` 186 | 187 | | API | 功能 | 188 | | ------------------------ | ---------------------- | 189 | | getImage | 获取图片信息 | 190 | | canSendImage | 检查是否可以发送图片 | 191 | | ocrImage | 图片 OCR | 192 |
193 | 194 |
195 | 语音相关的Api 196 | 197 | ```php 198 | $api->record; 199 | ``` 200 | 201 | | API | 功能 | 202 | | ------------------------ | ---------------------- | 203 | | getRecord | 获取语音 | 204 | | canSendRecord | 检查是否可以发送语音 | 205 |
206 | 207 |
208 | 处理请求相关的Api 209 | 210 | ```php 211 | $api->request; 212 | ``` 213 | 214 | | API | 功能 | 215 | | ------------------------ | ---------------------- | 216 | | setFriendAddRequest | 处理加好友请求 | 217 | | setGroupAddRequest | 处理加群请求/邀请 | 218 |
219 | 220 | 221 |
222 | 群信息相关的Api 223 | 224 | ```php 225 | $api->groupInfo; 226 | ``` 227 | 228 | | API | 功能 | 229 | | ------------------------ | ---------------------- | 230 | | getGroupInfo | 获取群信息 | 231 | | getGroupList | 获取群列表 | 232 | | getGroupMemberInfo | 获取群成员信息 | 233 | | getGroupMemberList | 获取群成员列表 | 234 | | getGroupHonorInfo | 获取群荣誉信息 | 235 | | getGroupSystemMsg | 获取群系统消息 | 236 | | getEssenceMsgList | 获取精华消息列表 | 237 | | getGroupAtAllRemain | 获取群 @全体成员 剩余次数 | 238 |
239 | 240 |
241 | 群设置相关的Api 242 | 243 | ```php 244 | $api->groupSetting; 245 | ``` 246 | 247 | | API | 功能 | 248 | | ------------------------ | ---------------------- | 249 | | setGroupName | 设置群名 | 250 | | setGroupPortrait | 设置群头像 | 251 | | setGroupAdmin | 设置群管理员 | 252 | | setGroupCard | 设置群名片 ( 群备注 ) | 253 | | setGroupSpecialTitle | 设置群组专属头衔 | 254 |
255 | 256 |
257 | 群操作相关的Api 258 | 259 | ```php 260 | $api->groupAction; 261 | ``` 262 | 263 | | API | 功能 | 264 | | ------------------------ | ---------------------- | 265 | | setGroupBan | 群单人禁言 | 266 | | setGroupWholeBan | 群全员禁言 | 267 | | setGroupAnonymousBan | 群匿名用户禁言 | 268 | | setEssenceMsg | 设置精华消息 | 269 | | deleteEssenceMsg | 移出精华消息 | 270 | | sendGroupSign | 群打卡 | 271 | | setGroupAnonymous | 群设置匿名 | 272 | | sendGroupNotice | 发送群公告 | 273 | | getGroupNotice | 获取群公告 | 274 | | setGroupKick | 群组踢人 | 275 | | setGroupLeave | 退出群组 | 276 |
277 | 278 |
279 | 群文件相关的Api 280 | 281 | ```php 282 | $api->groupFile; 283 | ``` 284 | 285 | | API | 功能 | 286 | | ------------------------ | ---------------------- | 287 | | uploadGroupFile | 上传群文件 | 288 | | deleteGroupFile | 删除群文件 | 289 | | createGroupFileFolder | 创建群文件文件夹 | 290 | | deleteGroupFolder | 删除群文件文件夹 | 291 | | getGroupFileSystemInfo | 获取群文件系统信息 | 292 | | getGroupRootFiles | 获取群根目录文件列表 | 293 | | getGroupFilesByFolder | 获取群子目录文件列表 | 294 | | getGroupFileUrl | 获取群文件资源链接 | 295 | | uploadPrivateFile | 上传私聊文件 | 296 |
297 | 298 |
299 | Go-CqHttp相关的Api 300 | 301 | ```php 302 | $api->cq; 303 | ``` 304 | 305 | | API | 功能 | 306 | | ------------------------ | ---------------------- | 307 | | getCookies | 获取 Cookies | 308 | | getCsrfToken | 获取 CSRF Token | 309 | | getCredentials | 获取 QQ 相关接口凭证 | 310 | | getVersionInfo | 获取版本信息 | 311 | | getStatus | 获取状态 | 312 | | cleanCache | 清理缓存 | 313 | | reloadEventFilter | 重载事件过滤器 | 314 | | downloadFile | 下载文件到缓存目录 | 315 | | checkUrlSafely | 检查链接安全性 | 316 | | getWordSlices | 获取中文分词 ( 隐藏 API ) | 317 | | handleQuickOperation | 对事件执行快速操作 ( 隐藏 API ) | 318 |
319 | 320 |
321 | CQ 码支持 322 | 323 | | 对应的类 | 功能 | 324 | | ----------------------------- | ---------------------- | 325 | | `Itwmw\GoCqHttp\CqCode\Face` | QQ 表情 | 326 | | `Itwmw\GoCqHttp\CqCode\Record` | 语音 | 327 | | `Itwmw\GoCqHttp\CqCode\Video` | 短视频 | 328 | | `Itwmw\GoCqHttp\CqCode\At` | @某人 | 329 | | `Itwmw\GoCqHttp\CqCode\Share` | 链接分享 | 330 | | `Itwmw\GoCqHttp\CqCode\Music` | 音乐分享 | 331 | | `Itwmw\GoCqHttp\CqCode\MusicCustom` | 自定义音乐分享 | 332 | | `Itwmw\GoCqHttp\CqCode\Image` | 图片 | 333 | | `Itwmw\GoCqHttp\CqCode\Reply` | 回复 | 334 | | `Itwmw\GoCqHttp\CqCode\RedBag` | 红包 | 335 | | `Itwmw\GoCqHttp\CqCode\Poke` | 戳一戳 | 336 | | `Itwmw\GoCqHttp\CqCode\Gift` | 礼物 | 337 | | `Itwmw\GoCqHttp\CqCode\Forward` | 合并转发 | 338 | | `Itwmw\GoCqHttp\CqCode\Xml` | XML 消息 | 339 | | `Itwmw\GoCqHttp\CqCode\Json` | JSON 消息 | 340 | | `Itwmw\GoCqHttp\CqCode\CardImage` | 装逼大图 | 341 | | `Itwmw\GoCqHttp\CqCode\Tts` | 文本转语音 | 342 | 343 | #### 使用示例 344 | 发送: 345 | ```php 346 | use Itwmw\GoCqHttp\Api; 347 | use Itwmw\GoCqHttp\CqCode\Tts; 348 | 349 | $api = new Api(); 350 | $tts = new Tts('你好'); 351 | $api->message->sendMsg($tts, user_id: 995645888); 352 | ``` 353 | 解析接受到的消息: 354 | ```php 355 | $msg = "[CQ:share,url=https://www.baidu.com/,title=百度一下,content=百度一下,你就知道,image=https://www.baidu.com/img/bd_logo1.png]"; 356 | $share = Share::create($msg); 357 | print_r($share); 358 | //Itwmw\GoCqHttp\CqCode\Share Object 359 | //( 360 | // [url] => https://www.baidu.com/ 361 | // [title] => 百度一下 362 | // [content] => 百度一下,你就知道 363 | // [image] => https://www.baidu.com/img/bd_logo1.png 364 | //) 365 | echo $share; 366 | // [CQ:share,url=https://www.baidu.com/,title=百度一下,content=百度一下,你就知道,image=https://www.baidu.com/img/bd_logo1.png] 367 | ``` 368 |
369 | 370 | ### 关于: 371 | QQ群: 852297017 372 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [2023] Micro Dream Team(www.MicroDreamTeam.com) 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------