Codeigniter - Botman - reply method does not work - php

I'm using Botman 2.0 and Codeigniter 3.1.6
My owner server with HTTPS & FB Webhook setup successfully.
How do I have to setup my project with codeigniter? Because, I set the FB Webhook setup successfully, but, when I type "hi" on messenger this not reply.
Could you give me some advice for that my chat bot works correctly.
Note 1: I had test with PHP (Without framework) and This works correctly.
Note 2: I had test with NodeJS and This works correctly.
use BotMan\BotMan\BotMan;
use BotMan\BotMan\BotManFactory;
use BotMan\BotMan\Drivers\DriverManager;
class Facebook_messenger extends CI_Controller {
function __construct()
{
parent::__construct();
}
public function bot(){
$config = [
// Your driver-specific configuration
'facebook' => [
'token' => 'EAAZA1UK2sl8UBAIueLY2ZCHraasS3E52AS37wUVypMLQatW5taE71LByyl3nWNau8uTKYs1aw11lQXpDOfPrrQE8BLWf6PZBkwuQIdzea7lMeZCc4jCiZCqhKZABKnc2V8FNabVbHF9J6opkb6MCsBAxnqO0kDsgeoYV88gNOIJuTZAr9T7pzoBAZC',
//'app_secret' => 'f1a032fb00484a59c0322617b7623745a',
'verification'=>'xxxxapp',
]
];
// Load the driver(s) you want to use
DriverManager::loadDriver(\BotMan\Drivers\Facebook\FacebookDriver::class);
// Create an instance
$botman = BotManFactory::create($config);
// Give the bot something to listen for.
$botman->hears('hi', function (BotMan $bot) {
$bot->reply('Hello');
});
$botman->hears('delayed', function (BotMan $bot) {
$bot->reply('Field will remain in yellow (delayed)unless a game is scheduled on it.');
});
$botman->hears('canceled', function (BotMan $bot) {
$bot->reply('Games cancelled due to poor field conditions.');
});
// Start listening
$botman->listen();
}
}

Related

Laravel and react, How to give a notification from Laravel to my react application (Unexpected use of 'self' no restricted-globals error)

I can create Notifications In laravel and in React. I have followed the tutorials, but I don't know how to send the notification from laravel to my react application. This is the code that I got in my Laravel Controller.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Feature\HttpHandler;
use App\Notifications\PushDemo;
use App\Models\Users;
use Illuminate\Support\Facades\Auth;
use Notification;
use Illuminate\Support\Facades\Log;
use NotificationChannels\WebPush\PushSubscription;
use Illuminate\Support\Facades\Http;
use App\Feature\ApiResponse;
class PushController extends Controller
{
use ApiResponse;
use HttpHandler;
public function __construct(){
}
public function push(){
Log::info('Push push function called');
$users = Users::all();
Notification::send($users,new PushDemo);
return redirect()->back();
}
public function store(Request $request)
{
Log::info('Push store called');
// get user from request
//$user = Users::findOrFail($request->userId);
$user = Users::whereUrl($request->post('URL'))->firstOrFail();
$b = $request['body'];
// create PushSubscription and connect to this user
$pushsub = $user->updatePushSubscription($request->body['endpoint'], $request->body['keys']['p256dh'], $request->body['keys']['auth']);
Log::info('WORKED');
return $pushsub;
}
}
The store function works.
In react I have this piece of code in my service-worker.js to listen to a event. (this is the piece of code that needs to work, but it says unexpected use of 'self' no restriced-globals)
self.addEventListener('push', function (e) {
console.log('push');
if (!(self.Notification && self.Notification.permission === 'granted')) {
//notifications aren't supported or permission not granted!
return;
}
if (e.data) {
var msg = e.data.json();
console.log(msg)
e.waitUntil(self.registration.showNotification(msg.title, {
body: msg.body,
icon: msg.icon,
actions: msg.actions
}));
}
});
This code is never called it seems but it should be called when I click on this button:
<button onClick={() => test()}>
test notification
</button>
This is the function to go through the Laravel application:
function test(){
console.log('test');
workerApi.makePushNotification({ URL, token})
.then(response => {
if (response.hasOwnProperty('message') && response.hasOwnProperty('type')) {
}
else {
console.log(JSON.stringify(response.data));
}
})
})
}
This function call works. only it seemd like the service worker function is never called and it doesn't send the notification to my react application. How do I solve this?
hey you should use some real-time library for listener real-time events like pusher then you can send the message from the server to the frontend
for installing pusher on laravel application please check this article
https://www.codecheef.org/article/real-time-event-broadcasting-with-laravel-6-and-pusher
and for your react app
npm install --save pusher-js
your component file
import Pusher from 'pusher-js';
useEffect(() => {
var pusher = new Pusher("your-pusher-key", {
cluster: "ap2",
encrypted: true,
});
var channel = pusher.subscribe("notifyChannel");
channel.bind("notifyChannel", async function (response) {
alert('some notification');
})
});

Limit email deployment application wide on non-production environments

I am developing my first Laravel app and want to avoid accidentally deploying emails from my dev and local environments to real people, other than myself. My goal is to have a list of comma-separated email addresses in my .env file that the Laravel's Mailable checks against when APP_ENV is not "production".
# .env
APP_ENV=local
EMAIL_WHITELIST=test#example.com
I checked the send method in vendor\laravel\framework\src\Illuminate\Mail\Mailable.php and could modify the code there but have an eerie feeling that I am not supposed to touch that file.
# vendor\laravel\framework\src\Illuminate\Mail\Mailable.php
public function send($mailer)
{
$this->withLocale($this->locale, function () use ($mailer) {
Container::getInstance()->call([$this, 'build']);
$mailer = $mailer instanceof MailFactory
? $mailer->mailer($this->mailer)
: $mailer;
return $mailer->send($this->buildView(), $this->buildViewData(), function ($message) {
$this->buildFrom($message)
->buildRecipients($message)
->buildSubject($message)
->runCallbacks($message)
->buildAttachments($message);
});
});
}
Thanks!
One option is to create an Event Listener and register it with Laravel's MessageSending event. This allows you to perform all manner of actions on each outgoing message before it is sent.
App\Providers\EventServiceProvider
protected $listen = [
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\PrepareMessageForSending'
],
];
App\Listeners\PrepareMessageForSending
class PrepareMessageForSending
{
public function handle(MessageSending $event)
{
if (env('APP_ENV') !== 'production') {
// for example, you could redirect everything to a mail trap account
$event->message->setTo('mailtrap#example.com');
}
return $event->message;
}
}

Laravel Broadcasting, how to auth to a presence channel?

I'm trying to join a presence channel (Public channels work well), but I can't get this to work:
Vue code:
mounted(){
Echo.join('game.' + "0").here((users) => {
alert("In the channel!");
})
.joining((user) => {
console.log("Someone entered");
})
.leaving((user) => {
console.log(user.name);
})
.listen('GameEvent', (e) => {
console.log("Hey")
});
Echo.channel('NewSentence')
.listen('NewSentence',(sentence)=>{
alert("HOLA");
});
}
I'm trying to join the channel "game.0". As I'm using Laravel Passport I need to authenticate myself with a token, and that is working. Sending the auth request for Laravel Echo returns a key, but the JavaScript events are not triggering .here(), .listening() ....
BroadcastService provider boot function:
public function boot() {
Broadcast::routes(["middleware" => "auth:api"]);
require base_path('routes/channels.php');
}
channels.php
Broadcast::channel('game.0', function ($user,$id) {
return ['id' => $user->id];
});
The auth route:
Route::post('/broadcasting/auth', function(Request $request){
$pusher = new Pusher\Pusher(
env('PUSHER_APP_KEY'),
env('PUSHER_APP_SECRET'),
env('PUSHER_APP_ID'),
array(
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => false,
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'http',
)
);
return $pusher->socket_auth($request->request->get('channel_name'),$request->request->get('socket_id'));
});
Do I need to do something extra to make it work? This is the auth request:
EDIT:
GameEvent event:
class GameEvent implements ShouldBroadcastNow {
use Dispatchable, InteractsWithSockets, SerializesModels;
public $gameEvent;
public $gameId;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($gameEvent, $gameId) {
//
$this->gameEvent = $gameEvent;
$this->gameId = $gameId;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\PresenceChannel|array
*/
public function broadcastOn() {
//return new PrivateChannel('channel-name');
return new PresenceChannel('game.0');
}
public function broadcastWith() {
return $this->gameEvent;
}
}
EDIT:
I've hardcoded the names: 'game.0' is now hardcoded in the routes/channels.php route, in the Echo connection and in the GameEvent. I also removed broadcastAs(). After entering the laravel-websockets debugging dashboard I found that the channel I want to subscribe doesn't even appear. It looks like it won't start a connection, but I can't figure out what it going on.
I hardcoded the
The problem here seems to be that the Echo is not listening on proper channel. First of all the Echo.join is using channel game.0 in which 0 is a user's id, and i don't think that there is actually a user with id 0. Secondly, you are broadcasting as
GameEvent
and Echo is connecting to channel named game.{id} I suggest that you either remove the broadcastAs() function from your event file or listen on GameEvent. Also use the websocket dashboard for testing this. The dashboard will be available at
/laravel-websockets
route automatically, which is available only for local environment so make sure that environment is local in your .env.
Use the debugging dashboard provided by laravel-websockets to send data to channels, first connect to your web socket within the dashboard then just enter the channel name, event name and data in JSON format and hit send on the dashboard.
Try finding out if that helps with resolving your problem.
I also recommend thoroughly reading laravel's official documentation on broadcasting as well as laravel-websockets debugging dashboard guide.
Also update what you got in result to this question.

Next js - Call a function on server side each time a route is changed

I am moving an old stack to next js and i need some help.
I have a php backend and I want to check a controller from this backend each time a route is changed, and I want to do it on server side.
For changing route, I use Link of next-routes, which have an effect only on the client side.
Is there any way I can call the controller on server-side without refreshing the app?
You can take advantage of Router's events and Custom App watching for a route change and perform the actions you need. Below you can find two sample implementations, one using class component and one using hooks. Both should do the trick.
// class component
import NextApp from 'next/app';
import Router from 'next/router';
class App extends NextApp {
componentDidMount() {
Router.events.on('routeChangeStart', () => {
// call to your backend
});
}
render() {
const { Component, pageProps } = this.props;
return <Component {...pageProps} />;
}
}
export default App;
// using hooks
import Router from 'next/router';
const App = ({ Component, pageProps }) => {
React.useEffect(() => {
const doMagic = () => {
// do your thing
}
Router.events.on('routeChangeStart', doMagic); // add listener
return () => {
Router.events.off('routeChangeStart', doMagic); // remove listener
}
}, []);
return <Component {...pageProps} />;
}
export default App;

BotMan - Conversations method is not replying

i am working on facebook messenger bot. I am using Botman (botman.io) without Laravel or botman studio. Version of PHP is 7.4.
Simple hears and reply method works fine, but conversation replying method does not working.
If I try type hi|hello or some greetings, chatbot answer me "Hello! What is your firstname?", then I write my name and chatbot does not returns any text :-/
Can you help me where is a bug?
There is a conversation class:
namespace LiborMatejka\Conversations;
use BotMan\BotMan\Messages\Conversations\Conversation;
use BotMan\BotMan\Messages\Incoming\Answer;
class OnboardingConversation extends Conversation {
protected $firstname;
protected $email;
function askFirstname() {
$this->ask('Hello! What is your firstname?', function (Answer $answer) {
// Save result
$this->firstname = $answer->getText();
$this->say('Nice to meet you ' . $this->firstname);
$this->askEmail();
});
}
public function askEmail() {
$this->ask('One more thing - what is your email?', function (Answer $answer) {
// Save result
$this->email = $answer->getText();
$this->say('Great - that is all we need, ' . $this->firstname);
});
//$this->bot->typesAndWaits(2);
}
public function run() {
// This will be called immediately
$this->askFirstname();
}
}
and there is config:
require_once "vendor/autoload.php";
require_once "class/onboardingConversation.php";
use BotMan\BotMan\BotMan;
use BotMan\BotMan\BotManFactory;
use BotMan\BotMan\Drivers\DriverManager;
use BotMan\Drivers\Facebook\FacebookDriver;
use LiborMatejka\Conversations\OnboardingConversation;
$config = [
// Your driver-specific configuration
'facebook' => [
'token' => 'my_token',
'app_secret' => 'my_secret_app_code',
'verification' => 'verification_code',
],
'botman' => [
'conversation_cache_time' => 0,
],
];
// Load the driver(s) you want to use
DriverManager::loadDriver(\BotMan\Drivers\Facebook\FacebookDriver::class);
// Create an instance
$botman = BotManFactory::create($config);
$botman->hears('ahoj|hi|hello|cau|cus|zdar|zdarec|cago|hey|ciao', function (BotMan $bot) {
$bot->startConversation(new OnboardingConversation);
});
// Start listening
$botman->listen();
Add symfony/cache to your project using composer
composer require symfony/cache
Put following at top of index.php (or other) file where you're setting up BotMan
use BotMan\BotMan\Cache\SymfonyCache;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
Then create your BotMan using the following:
$adapter = new FilesystemAdapter();
$botman = BotManFactory::create($config, new SymfonyCache($adapter));
Then use your $botman variable accordingly, like example below:
$botman->hears('Hi', function (BotMan $bot) {
$bot->typesAndWaits(2);
$bot->reply('Hello and welcome');
$bot->typesAndWaits(2);
$bot->ask('Anything I can do for you today?',function($answer, $bot){
$bot->say("Oh, really! You said '{$answer->getText()}'... is that right?");
});
});
I would rather to use auto-wiring to inject the SymfonyCache anywhere you create the Botman instance, without creating the adapter and cache again and again.
Step 1: config the cache in cache.yaml
framework:
cache:
# botman: cache adapter
app: cache.adapter.filesystem
Step 2: autowiring in services.yaml
services:
BotMan\BotMan\Cache\SymfonyCache:
arguments:
$adapter: '#cache.app'
Step 3: Inject the SymfonyCache where you need, for example in ChatController::message()
public function message(SymfonyCache $symfonyCache): Response
{
....
$botman = BotManFactory::create([], $symfonyCache);
....
$botman->hears(
'survey',
function (BotMan $bot) {
$bot->startConversation(new OnBoardingConversation());
}
);
}
To create the OnBoardingConversation, just follow the documentation on create a conversation in botman

Categories