Laravel项目集成Botman Studio实现数据库查询对话功能求助
Got it, let's walk through how to make your Botman chatbot pull data from your database to answer questions like "What is Example". Since you already have Botman up and running in your Laravel project, we just need to connect the dots between user queries and your database.
1. Core思路拆解
The flow we're building is straightforward:
- User sends a question like "What is Example"
- Botman identifies the intent and extracts the keyword (e.g., "Example")
- Bot queries your database for a matching record
- Bot returns the retrieved info (or a fallback message if no match exists)
2. Step 1: Prepare Database & Model
First, let's assume you have a database table (we'll call it terms) to store your reference info. It should have at least these fields: id, name (the term users will ask about), description (the answer you want to return).
Create the Model
Generate a Laravel model for this table (or use an existing one if you already have it):
// app/Models/Term.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Term extends Model { // Allow mass assignment for these fields protected $fillable = ['name', 'description']; }
Populate the table with test data to work with, e.g.:
INSERT INTO terms (name, description) VALUES ('Example', 'This is a sample term to demonstrate Botman database retrieval. It can be any concept, product, or topic you need to explain.'), ('Laravel', 'Laravel is a PHP web framework designed for building modern, scalable web applications with elegant syntax.');
3. Step 2: Add Botman Conversation Logic
You can handle this in two ways—simple inline logic for basic queries, or a dedicated conversation class for more complex, multi-step interactions.
Option A: Basic Inline Matching (Great for Quick Queries)
Open routes/botman.php and add this code to match user questions and pull data:
use BotMan\BotMan\BotMan; use App\Models\Term; $botman = resolve(BotMan::class); // Match exact "What is {term}" format $botman->hears('What is {term}', function (BotMan $bot, $term) { // Look for a matching term in the database (case-insensitive, fuzzy match) $termRecord = Term::where('name', 'like', "%{$term}%")->first(); if ($termRecord) { $bot->reply("{$termRecord->name}: {$termRecord->description}"); } else { $bot->reply("Sorry, I don't have information about *{$term}* right now."); } }); // Match more flexible question formats (e.g., "Tell me about Laravel", "Explain Example") $botman->hears('/^(What is|Tell me about|Explain) (.+)$/i', function (BotMan $bot, $match) { $term = $match[2]; $termRecord = Term::where('name', 'like', "%{$term}%")->first(); $termRecord ? $bot->reply("{$termRecord->name}: {$termRecord->description}") : $bot->reply("I don't have details on *{$term}* yet."); });
Option B: Dedicated Conversation Class (For Multi-Step Flows)
If you want to add follow-up questions or more structured interactions, create a conversation class:
// app/Conversations/TermInfoConversation.php namespace App\Conversations; use BotMan\BotMan\Messages\Incoming\Answer; use BotMan\BotMan\Messages\Outgoing\Question; use BotMan\BotMan\Messages\Outgoing\Actions\Button; use BotMan\BotMan\Messages\Conversations\Conversation; use App\Models\Term; class TermInfoConversation extends Conversation { protected $selectedTerm; public function askWhichTerm() { $question = Question::create("Which term would you like to learn about?") ->fallback("Sorry, I didn't catch that.") ->addButtons([ Button::create('Example')->value('Example'), Button::create('Laravel')->value('Laravel'), Button::create('Another Term')->value('custom'), ]); $this->ask($question, function (Answer $answer) { $this->selectedTerm = $answer->getValue(); // If user picks "custom", ask them to type the term if ($this->selectedTerm === 'custom') { $this->ask("Please type the term you're curious about:", function (Answer $answer) { $this->selectedTerm = $answer->getText(); $this->shareTermInfo(); }); } else { $this->shareTermInfo(); } }); } public function shareTermInfo() { $termRecord = Term::where('name', 'like', "%{$this->selectedTerm}%")->first(); if ($termRecord) { $this->say("{$termRecord->name}: {$termRecord->description}"); } else { $this->say("Sorry, I don't have information about *{$this->selectedTerm}* right now."); } // Follow up to see if they want more info $this->ask("Would you like to look up another term?", function (Answer $answer) { if (strtolower($answer->getText()) === 'yes' || $answer->getValue() === 'yes') { $this->askWhichTerm(); } else { $this->say("Got it! Feel free to ask me anytime. 😊"); } }, [ Button::create('Yes')->value('yes'), Button::create('No')->value('no'), ]); } public function run() { $this->askWhichTerm(); } }
Then register this conversation in routes/botman.php:
$botman->hears('(Start|Help|What can you do)', function (BotMan $bot) { $bot->startConversation(new \App\Conversations\TermInfoConversation()); });
4. Test It Out
Send a message like "What is Example" to your bot—it should pull the description directly from your terms table. If you use the conversation flow, trigger it with "Start" and follow the prompts.
5. Quick Optimizations for Better Performance
- Use full-text search (Laravel's
whereFullTextmethod) instead oflikefor faster, more accurate matches (requires MySQL/MariaDB full-text indexing) - Add a
synonymsfield to yourtermstable to handle alternative names for the same term (e.g., "Laravel Framework" and "Laravel") - Add error handling for edge cases (e.g., empty database results, invalid user input)
内容的提问来源于stack exchange,提问作者user6780526

