SimSimi(小黃雞)是知名聊天機器人服務,官方未公開正式 API,但可透過模擬瀏覽器請求串接。核心難點在於:首次請求需取得 Cookie、訊息需雙重 URL 編碼、Referer 標頭驗證。本文提供完整可用的 PHP 封裝類別。
<?php
class SimSimiClient {
private const BASE_URL = 'https://www.simsimi.com';
private const API_URL = 'https://www.simsimi.com/func/req';
private $cookie = '';
private $ch;
public function __construct() {
$this->ch = curl_init();
curl_setopt_array($this->ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_TIMEOUT => 10,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
CURLOPT_COOKIEJAR => '', // 僅記憶體維持 Cookie
CURLOPT_COOKIEFILE => '',
]);
}
public function __destruct() {
curl_close($this->ch);
}
/** 取得初始 Cookie */
private function fetchCookie(): void {
curl_setopt($this->ch, CURLOPT_URL, self::BASE_URL);
curl_setopt($this->ch, CURLOPT_HEADER, true);
curl_setopt($this->ch, CURLOPT_NOBODY, false);
$response = curl_exec($this->ch);
if ($response === false) {
throw new RuntimeException('Fetch cookie failed: ' . curl_error($this->ch));
}
// 解析 Set-Cookie
if (preg_match('/^Set-Cookie:\s*([^;]+)/mi', $response, $m)) {
$this->cookie = $m[1];
}
curl_setopt($this->ch, CURLOPT_HEADER, false);
}
/**
* 發送訊息並取得回覆
* @param string $message 使用者訊息(UTF-8)
* @param string $lc 語言代碼:ch(繁中)、zh(簡中)、en、jp、kr...
* @return string 機器人回覆
*/
public function ask(string $message, string $lc = 'ch'): string {
if (!$this->cookie) $this->fetchCookie();
// 關鍵:雙重 urlencode
$encodedMsg = urlencode(urlencode($message));
$url = self::API_URL . "?lc={$lc}&msg={$encodedMsg}&ft=0.0";
curl_setopt_array($this->ch, [
CURLOPT_URL => $url,
CURLOPT_REFERER => self::BASE_URL . "/talk.htm?lc={$lc}",
CURLOPT_COOKIE => $this->cookie,
CURLOPT_HTTPHEADER => [
'Accept: application/json, text/javascript, */*; q=0.01',
'X-Requested-With: XMLHttpRequest',
],
]);
$response = curl_exec($this->ch);
if ($response === false) {
throw new RuntimeException('API request failed: ' . curl_error($this->ch));
}
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException('Invalid JSON response: ' . $response);
}
if (($data['result'] ?? 0) == 100) {
return $data['response'] ?? '...';
}
// 常見錯誤代碼:404(教學模式)、101(內容過濾)、200(伺服器錯誤)
return '我還不會回答這個問題... (code: ' . ($data['result'] ?? 'unknown') . ')';
}
}
// 使用範例
$bot = new SimSimiClient();
echo $bot->ask('你好,你是誰?');
// 輸出:我是小黃雞,很高興認識你!
| 步驟 | 關鍵點 | 說明 |
|---|---|---|
| 首頁請求 | CURLOPT_HEADER => true | 需回應標頭解析 Set-Cookie |
| Cookie 維持 | 記憶體變數 $this->cookie | 避免檔案 I/O,適合短生命週期;長期服務建議用資料庫/Redis 儲存 |
| 雙重編碼 | urlencode(urlencode($msg)) | SimSimi 伺服器端會解碼兩次,單次編碼會導致特殊字元錯誤 |
| Referer 驗證 | CURLOPT_REFERER | 缺少或錯誤 Referer 會回傳 403/空回應 |
| 語言代碼 | lc=ch (繁中)、lc=zh (簡中) | 影響回覆語言與知識庫 |
100 成功
101 內容被過濾(敏感詞)
102 訊息過長
103 帳號被封鎖
200 伺服器內部錯誤
404 教學模式(需先教導機器人)
$this->cookie 存入 Redis(Key: simsimi:cookie,TTL 1 小時),多程序共享。透過模擬瀏覽器流程(取 Cookie → 雙重編碼 → 攜帶 Referer/Cookie 請求 API),即可在 PHP 中串接 SimSimi 聊天機器人。理解「雙重編碼」與「Referer 驗證」兩大核心機制,是成功串接的關鍵。實務部署請加入快取、重試、監控與合規評估。