Codex开发测试群1

项目空间、会话、通讯录和出入站消息

2026-08-14 19:45:36

空间配置

APP tiangong
SpaceID project_456
名称 Codex开发测试群1
外部模式 飞书应用
Webhook https://feige.3e8.cn/api/webhooks/feishu/tiangong/project_456

三方集成配置

状态 active
配置会明文展示便于核对,保存后仍加密存储。外部模式创建后不可修改。

API 文档说明

创建/刷新空间 PUT /api/v1/spaces
查询通讯录 GET /api/v1/contacts?app=...&space_id=...
发送文本消息 POST /api/v1/messages/text
发送卡片消息 POST /api/v1/messages/card
同步通讯录 POST /api/v1/contact-sync-jobs
三方 Webhook https://feige.3e8.cn/api/webhooks/feishu/tiangong/project_456
签名规则 METHOD + "\n" + PATH_WITH_QUERY + "\n" + TIMESTAMP + "\n" + RAW_BODY
PHP 示例代码

运行前设置 FEIGE_APP_SECRET=应用管理中该 APP 的 Secret。示例已带入当前空间信息,三方凭证请替换为真实值。

<?php

$baseUrl = 'https://feige.3e8.cn';
$app = 'tiangong';
$spaceId = 'project_456';

function feigeApiSecret(): string
{
    $secret = getenv('FEIGE_APP_SECRET') ?: '';
    if ($secret === '') {
        throw new RuntimeException('未配置 FEIGE_APP_SECRET');
    }

    return $secret;
}

function feigeRequest(string $method, string $path, ?array $body = null): array
{
    global $baseUrl, $app;

    $method = strtoupper($method);
    $rawBody = $body === null ? '' : json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
    $timestamp = (string) time();
    $signingText = implode("\n", [$method, $path, $timestamp, $rawBody]);
    $signature = hash_hmac('sha256', $signingText, feigeApiSecret());

    $curl = curl_init(rtrim($baseUrl, '/') . $path);
    $options = [
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => [
            'Accept: application/json',
            'Content-Type: application/json',
            'X-Feige-App: ' . $app,
            'X-Feige-Timestamp: ' . $timestamp,
            'X-Feige-Signature: ' . $signature,
        ],
    ];
    if ($body !== null) {
        $options[CURLOPT_POSTFIELDS] = $rawBody;
    }
    curl_setopt_array($curl, $options);

    $response = curl_exec($curl);
    if ($response === false) {
        throw new RuntimeException(curl_error($curl));
    }

    $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
    curl_close($curl);

    return [
        'status' => $status,
        'body' => json_decode($response, true, 512, JSON_THROW_ON_ERROR),
    ];
}

// 0. 验证 APP ID、APP Secret 和签名算法
$authResult = feigeRequest('GET', '/api/v1/spaces?app=' . rawurlencode($app));

// 1. 创建或刷新当前空间
$spaceResult = feigeRequest('PUT', '/api/v1/spaces', [
    'app' => $app,
    'space_id' => $spaceId,
    'space_name' => 'Codex开发测试群1',
    'external_mode' => 'feishu',
    'third_party_key' => [
        'app_id' => 'cli_xxx',
        'app_secret' => 'your_app_secret',
    ],
]);

// 2. 同步当前空间通讯录
$syncResult = feigeRequest('POST', '/api/v1/contact-sync-jobs', [
    'app' => $app,
    'space_id' => $spaceId,
]);

// 3. 查询通讯录,取得飞鸽 contact_id
$contactsResult = feigeRequest('GET', '/api/v1/contacts?' . http_build_query([
    'app' => $app,
    'space_id' => $spaceId,
    'status' => 'active',
]));
$contactId = $contactsResult['body']['data'][0]['contact_id'] ?? null;

// 4. 向联系人发送文本消息
$textResult = feigeRequest('POST', '/api/v1/messages/text', [
    'app' => $app,
    'space_id' => $spaceId,
    'contact_id' => $contactId,
    'content' => '这是一条来自 PHP 的飞鸽测试消息',
]);

// 5. 向联系人发送卡片消息
$cardResult = feigeRequest('POST', '/api/v1/messages/card', [
    'app' => $app,
    'space_id' => $spaceId,
    'contact_id' => $contactId,
    'content' => [
        'card' => [
            'schema' => '2.0',
            'header' => ['title' => ['tag' => 'plain_text', 'content' => '测试通知']],
            'body' => ['elements' => [
                ['tag' => 'markdown', 'content' => 'PHP 调用飞鸽成功。'],
            ]],
        ],
    ],
]);

print_r([$authResult, $spaceResult, $syncResult, $contactsResult, $textResult, $cardResult]);

支持功能

能力 send_message / receive_message