教你利用PHP制作一个奇葩聊天机器人

2022-10-11 21:14:44 243 0
魁首哥

各位条子,大家上午好!

今天由小编来教大家 如何利用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

)

);

}

收藏
分享
海报
0 条评论
243
上一篇:推送微信消息中文乱码解决方法,和通过递归对数组进行urlencode 下一篇:PHP第五节课:函数explode和strlen的使用

本站已关闭游客评论,请登录或者注册后再评论吧~

忘记密码?

图形验证码