You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel+Twilio WhatsApp聊天机器人11200 HTTP检索失败问题求助

WhatsApp货币转换机器人Twilio 11200错误及500内部服务器错误排查

问题概述

按照Twilio相关教程步骤,基于Laravel搭建WhatsApp货币转换聊天机器人,两次尝试后测试时Twilio返回11200 - Http Retrieval Failure错误;同时使用ngrok和sail share暴露本地应用时,均出现500 Internal Server Error。

错误详情

Debug event SID:NOa58ef5b2f604abf9ea4718ea95d5ede4
Service SID:SM28801242e0831dd259f663885446f69f
Resource SID:SM28801242e0831dd259f663885446f69f
时间戳:2023年4月26日UTC上午11:28
错误信息:URI null的协议必须为'http'、'https'、'ws'或'wss'(忽略大小写)

相关代码

BotController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\CurrencyConverterClient;
use Twilio\TwiML\MessagingResponse;
use App\Currency;
use Exception;

class BotController extends Controller
{
    protected $client;

    public function __construct(CurrencyConverterClient $client)
    {
        $this->client = $client;
    }

    public function sendReplies(Request $request)
    {
        $response = new MessagingResponse();

        $body = $request->input('Body');

        $content = $this->determineMessageContent($body);

        $response->message($content);

        return $response;
    }

    private function determineMessageContent(string $content)
    {
        $formatContent = strtolower($content);

        if (strpos($formatContent, 'hello') !== false) {
            $message = "Welcome to the WhatsApp Bot for Currency Conversion \n";
            $message .= "Use the following format to chat with the bot \n";
            $message .= "Convert 5 USD to NGN \n";
            return $message;
        }

        if (strpos($formatContent, 'convert') !== false) {
            return $this->formatContentForConversion($formatContent);
        }

        return $this->formatContentForInvalidMessageFormat();
    }

    private function formatContentForConversion($formatContent)
    {
        $contentInArray = explode(" ", $formatContent);
        $itemsInArray = count($contentInArray);

        if ($itemsInArray < 5 || $itemsInArray > 5) {
            return $this->formatContentForInvalidMessageFormat();
        }

        return $this->performConversion($contentInArray);
    }

    private function formatContentForInvalidMessageFormat()
    {
        $message = "The Conversion Format is Invalid \n";
        $message .= "Please use the format \n";
        $message .= "Convert 5 USD to NGN";

        return $message;
    }

    private function performConversion(array $contentInArray)
    {
        $amount = $contentInArray[1];
        $baseCurrency = strtoupper($contentInArray[2]);
        $toCurrency = strtoupper($contentInArray[4]);

        if (!is_numeric($amount)) {
            return "Please provide a valid amount";
        }

        $items = $this->getCurrencyCode($baseCurrency, $toCurrency);

        if ($items->count() < 2) {
            return "Please enter a valid Currency Code";
        }

        try {
            $convertedAmount = $this->client->convertCurrency($amount, $baseCurrency, $toCurrency);
            return "{$amount} {$baseCurrency} is {$convertedAmount} {$toCurrency}";
        } catch (Exception $e) {
            return "We could not perform this conversion now, please bear with us";
        }
    }

    private function getCurrencyCode(string $baseCurrency, string $currency)
    {
        $items = [$baseCurrency, $currency];

        $currencyCode = Currency::findByCurrencyCode($items);

        return $currencyCode;
    }
}

CurrencySeeder.php

<?php

namespace Database\Seeders;

use App\CurrencyConverterClient;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class CurrencySeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run(CurrencyConverterClient $client)
    {
        $currencies = $client->getSupportedCurrencies();

        foreach ($currencies as $currency => $key) {
            foreach ($key as $k) {
                DB::table('currencies')->insert([
                    'name' => $k['currencyName'],
                    'code' => $k['id']
                ]);
            }
        }
    }
}

web.php

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::post('/currency', 'BotController@sendReplies');

排查解决方案

1. 检查Twilio Webhook配置

  • 确认Twilio控制台中WhatsApp沙箱的Webhook URL为完整的http/https地址(例如https://xxx.ngrok.io/currency),不能留空或格式错误;
  • 验证Webhook请求方法设置为POST,与Laravel路由的请求方法一致。

2. 定位500内部服务器错误根源

  • 查看Laravel日志文件storage/logs/laravel.log,获取具体错误信息,常见问题包括:
    • CurrencyConverterClient类未正确配置(如API密钥缺失、请求地址错误);
    • Currency模型的findByCurrencyCode方法未定义或逻辑错误;
    • 数据库未完成迁移,currencies表不存在;
    • 依赖包未安装完整(如Twilio SDK、HTTP客户端);
  • 使用Postman等工具,向暴露的/currency路由发送POST请求(模拟Twilio的请求格式),直接查看返回的错误详情。

3. 验证数据库与Seeder

  • 确认CurrencyConverterClient::getSupportedCurrencies()能正常返回数据,否则Seeder无法填充currencies表;
  • 手动执行php artisan db:seed --class=CurrencySeeder,检查数据库中currencies表是否有数据。

4. 修复Laravel路由与中间件

  • 若使用Laravel 8及以上版本,路由需使用完整控制器类名:
    Route::post('/currency', [\App\Http\Controllers\BotController::class, 'sendReplies']);
    
  • 将/currency路由排除在CSRF验证之外,编辑app/Http/Middleware/VerifyCsrfToken.php:
    protected $except = [
        '/currency',
    ];
    

内容的提问来源于stack exchange,提问作者PreolanN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:37:03