各位条子,大家上午好!
今天由小编来教大家 如何利用PHP制作一个奇葩聊天机器人!
小提示!小白可能比较难懂哦!
由于源码比较长,需要的朋友可以私聊小编哦!
废话不多说,上源码!
namespace BotMan\BotMan;
use Closure;
use Illuminate\Support\Collection;
use BotMan\BotMan\Commands\Command;
use BotMan\BotMan\ message s\Matcher;
use BotMan\BotMan\Drivers\DriverManager;
use BotMan\BotMan\Traits\ProvidesStorage;
use BotMan\BotMan\Interfaces\UserInterface;
use BotMan\BotMan\Messages\Incoming\Answer;
use BotMan\BotMan\Traits\HandlesExceptions;
use BotMan\BotMan\Handlers\ExceptionHandler;
use BotMan\BotMan\Interfaces\CacheInterface;
use BotMan\BotMan\Messages\Attachments\File;
use BotMan\BotMan\Interfaces\DriverInterface;
use BotMan\BotMan\Messages\Attachments\Audio;
use BotMan\BotMan\Messages\Attachments\Image;
use BotMan\BotMan\Messages\Attachments\Video;
use BotMan\BotMan\Messages\Outgoing\Question;
use BotMan\BotMan\Interfaces\StorageInterface;
use BotMan\BotMan\Traits\HandlesConversations;
use Symfony\Component\HttpFoundation\Response;
use BotMan\BotMan\Commands\ConversationManager;
use BotMan\BotMan\Middleware\MiddlewareManager;
use BotMan\BotMan\Messages\Attachments\Location;
use BotMan\BotMan\Exceptions\Base\BotManException;
use BotMan\BotMan\Interfaces\DriverEventInterface;
use BotMan\BotMan\Messages\Incoming\IncomingMessage;
use BotMan\BotMan\Messages\Outgoing\OutgoingMessage;
use BotMan\BotMan\Interfaces\ExceptionHandlerInterface;
use BotMan\BotMan\Exceptions\Core\BadMethodCallException;
use BotMan\BotMan\Exceptions\Core\UnexpectedValueException;
use BotMan\BotMan\Messages\Conversations\InlineConversation;
/**
* Class BotMan.
*/
class BotMan
{
use ProvidesStorage,
HandlesConversations,
HandlesExceptions;
/** @var \Illuminate\Support\Collection */
protected $event;
/** @var Command */
protected $command;
/** @var IncomingMessage */
protected $message;
/** @var OutgoingMessage|Question */
protected $outgoingMessage;
/** @var string */
protected $driverName;
/** @var array|null */
protected $currentConversationData;
/** @var ExceptionHandlerInterface */
protected $exceptionHandler;
/**
* IncomingMessage service events.
* @var array
*/
protected $events = [];
/**
* The fallback message to use, if no match
* could be heard.
* @var callable|null
*/
protected $fallbackMessage;
/** @var array */
protected $groupAttributes = [];
/** @var array */
protected $matches = [];
/** @var DriverInterface */
protected $driver;
/** @var array */
protected $config = [];
/** @var MiddlewareManager */
public $middleware;
/** @var ConversationManager */
protected $conversationManager;
/** @var CacheInterface */
private $cache;
/** @var StorageInterface */
protected $storage;
/** @var Matcher */
protected $matcher;
/** @var bool */
protected $loadedConversation = false;
/** @var bool */
protected $firedDriverEvents = false;
/** @var bool */
protected $runsOnSocket = false;
/**
* BotMan constructor.
* @param CacheInterface $cache
* @param DriverInterface $driver
* @param array $config
* @param StorageInterface $storage
*/
public function __construct(CacheInterface $cache, DriverInterface $driver, $config, StorageInterface $storage)
{
$this->cache = $cache;
$this->message = new IncomingMessage(”, ”, ”);
$this->driver = $driver;
$this->config = $config;
$this->storage = $storage;
$this->matcher = new Matcher();
$this->middleware = new MiddlewareManager($this);
$this->conversationManager = new ConversationManager();
$this->exceptionHandler = new ExceptionHandler();
}
/**
* Set a fallback message to use if no listener matches.
*
* @param callable $callback
*/
public function fallback($callback)
{
$this->fallbackMessage = $callback;
}
/**
* @param string $name The Driver name or class
*/
public function loadDriver($name)
{
$this->driver = DriverManager::loadFromName($name, $this->config);
}
/**
* @param DriverInterface $driver
*/
public function setDriver(DriverInterface $driver)
{
$this->driver = $driver;
}
/**
* @return DriverInterface
*/
public function getDriver()
{
return $this->driver;
}
/**
* Retrieve the chat message.
*
* @return array
*/
public function getMessages()
{
return $this->getDriver()-> getMessage s();
}
/**
* Retrieve the chat message that are sent from bots.
*
* @return array
*/
public function getBotMessages()
{
return Collection::make($this->getDriver()->getMessages())->filter(function (IncomingMessage $message) {
return $message->isFromBot();
})->toArray();
}
/**
* @return Answer
*/
public function getConversationAnswer()
{
return $this->getDriver()->getConversationAnswer($this->message);
}
/**
* @param bool $running
* @return bool
*/
public function runsOnSocket($running = null)
{
if (is_bool($running)) {
$this->runsOnSocket = $running;
}
return $this->runsOnSocket;
}
/**
* @return UserInterface
*/
public function getUser()
{
if ($user = $this->cache->get(‘user_’.$this->driver->getName().’_’.$this->getMessage()->getSender())) {
return $user;
}
$user = $this->getDriver()->getUser($this->getMessage());
$this->cache->put(‘user_’.$this->driver->getName().’_’.$user->getId(), $user, $this->config[‘user_cache_time’] ?? 30);
return $user;
}
/**
* Get the parameter names for the route.
*
* @param $value
* @return array
*/
protected function compileParameterNames($value)
{
preg_match_all(Matcher::PARAM_NAME_REGEX, $value, $matches);
return array_map(function ($m) {
return trim($m, ‘?’);
}, $matches[1]);
}
/**
* @param string $pattern the pattern to listen for
* @param Closure|string $callback the callback to execute. Either a Closure or a Class@method notation
* @param string $in the channel type to listen to (either direct message or public channel)
* @return Command
*/
public function hears($pattern, $callback, $in = null)
{
$command = new Command($pattern, $callback, $in);
$command->applyGroupAttributes($this->groupAttributes);
$this->conversationManager->listenTo($command);
return $command;
}
/**
* Listen for messaging service events.
*
* @param string $name
* @param Closure|string $callback
*/
public function on($name, $callback)
{
$this->events[] = [
‘name’ => $name,
‘callback’ => $this->getCallable($callback),
];
}
/**
* Listening for image files.
*
* @param $callback
* @return Command
*/
public function receivesImages($callback)
{
return $this->hears(Image::PATTERN, $callback);
}
/**
* Listening for image files.
*
* @param $callback
* @return Command
*/
public function receivesVideos($callback)
{
return $this->hears(Video::PATTERN, $callback);
}
/**
* Listening for audio files.
*
* @param $callback
* @return Command
*/
public function receivesAudio($callback)
{
return $this->hears(Audio::PATTERN, $callback);
}
/**
* Listening for location attachment.
*
* @param $callback
* @return Command
*/
public function receivesLocation($callback)
{
return $this->hears(Location::PATTERN, $callback);
}
/**
* Listening for files attachment.
*
* @param $callback
* @return Command
*/
public function receivesFiles($callback)
{
return $this->hears(File::PATTERN, $callback);
}
/**
* Create a command group with shared attributes.
*
* @param array $attributes
* @param \Closure $callback
*/
public function group(array $attributes, Closure $callback)
{
$previousGroupAttributes = $this->groupAttributes;
$this->groupAttributes = array_merge_recursive($previousGroupAttributes, $attributes);
call_user_func($callback, $this);
$this->groupAttributes = $previousGroupAttributes;
}
/**
* Fire potential driver event callbacks.
*/
protected function fireDriverEvents()
{
$driverEvent = $this->getDriver()->hasMatchingEvent();
if ($driverEvent instanceof DriverEventInterface) {
$this->firedDriverEvents = true;
Collection::make($this->events)->filter(function ($event) use ($driverEvent) {
return $driverEvent->getName() === $event[‘name’];
})->each(function ($event) use ($driverEvent) {
/**
* Load the message, so driver events can reply.
*/
$messages = $this->getDriver()->getMessages();
if (isset($messages[0])) {
$this->message = $messages[0];
}
call_user_func_array($event[‘callback’], [$driverEvent->getPayload(), $this]);
});
}
}
/**
* Try to match messages with the ones we should
* listen to.
*/
public function listen()
{
try {
$this->verifyServices();
$this->fireDriverEvents();
if ($this->firedDriverEvents === false) {
$this->loadActiveConversation();
if ($this->loadedConversation === false) {
$this->callMatchingMessages();
}
/*
* If the driver has a “messagesHandled” method, call it.
* This method can be used to trigger driver methods
* once the messages are handles.
*/
if (method_exists($this->getDriver(), ‘messagesHandled’)) {
$this->getDriver()->messagesHandled();
}
}
$this->firedDriverEvents = false;
} catch (\Throwable $e) {
$this->exceptionHandler->handleException($e, $this);
}
}
/**
* Call matching message callbacks.
*/
protected function callMatchingMessages()
{
$matchingMessages = $this->conversationManager->getMatchingMessages($this->getMessages(), $this->middleware, $this->getConversationAnswer(), $this->getDriver());
foreach ($matchingMessages as $matchingMessage) {
$this->command = $matchingMessage->getCommand();
$callback = $this->command->getCallback();
$callback = $this->getCallable($callback);
// Set the message first, so it’s available for middlewares
$this->message = $matchingMessage->getMessage();
$this->message = $this->middleware->applyMiddleware(‘heard’, $matchingMessage->getMessage(), $this->command->getMiddleware());
$parameterNames = $this->compileParameterNames($this->command->getPattern());
$ parameters = $matchingMessage->getMatches();
if (count($parameterNames) !== count($parameters)) {
$parameters = array_merge(
//First, all named parameters (eg. function ($a, $b, $c))
array_filter(
$parameters,
‘is_string’,
ARRAY_FILTER_USE_KEY
),
//Then, all other unsorted parameters (regex non named results)
array_filter(
$parameters,
‘is_integer’,
ARRAY_FILTER_USE_KEY
)
);
}
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~