Botman laravel REST API setup - php

Im new to Botman.
I try to implement a simple function to test how it works, but I keep getting empty response, it look like botman do not hears my message.
I installed botman without studio since, I'm trying to keep things simple. I also installed a webdriver as it says in documentation.
In my project I use JWT as an authentification, so i created a protected route like this:
Route::group(['middleware' => ['assign.guard:user', 'jwt.auth']], function () {
Route::post(
'/',
'UserBotManController#startConversation'
)->name('botman.user.start');
});
The controller looks like this:
<?php
namespace Project\UI\Api\Controllers\User\Botman;
use App\Http\Controllers\Controller;
use BotMan\BotMan\BotMan;
use BotMan\BotMan\BotManFactory;
use BotMan\BotMan\Drivers\DriverManager;
class UserBotManController extends Controller
{
public function startConversation()
{
$config = [];
DriverManager::loadDriver(\BotMan\Drivers\Web\WebDriver::class);
$botman = BotManFactory::create($config);
$botman->hears('hello', function (BotMan $bot) {
$bot->reply('Hello yourself.');
});
$botman->listen();
}
}
No when I send a request to this route a get empty response:
Looks like botman can't hear my message...
I try to looked inside with: dd($botman->getDriver());
And I see that the content has all the data:
Can any one help me to understand, how I can make it work?

Ok, so finally I found a solution. I have checked what request it sends from https://botman.io website and it is Form Data, not JSON.
diver field must be set to web!
Hope it will help someone.

Related

Laravel 5 Basic Auth custom error

In Laravel 5, if basic auth fails for a user then the default message that is returned is an "Invalid Credentials" error string. I am trying to return a custom JSON error when this situation occurs.
I can edit the returned response in vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php
however I have not seen where you can change the behavior of this message outside of the vendor directory. Is there a way?
Looks like there were some ways to do this through Laravel 4: Laravel 4 Basic Auth custom error
Figured it out, looks like I had to create custom middleware to handle this.
Note that this solution didn't work when calling my API from my browser, only when calling it from a tool like Postman. For some reason when calling it from my browser I always got the error before seeing the basic auth prompt.
In my controller I changed the middleware to my newly created one:
$this->middleware('custom');
In Kernel I added the location for it:
protected $routeMiddleware = [
'auth.basic.once' => \App\Http\Middleware\Custom::class,
]
Then I created the middleware. I used Stateless Basic Auth since I'm creating an API:
<?php
namespace App\Http\Middleware;
use Auth;
use Closure;
use Illuminate\Http\Request as HttpRequest;
use App\Entities\CustomErrorResponse
class Custom
{
public function __construct(CustomErrorResponse $customErrorResponse) {
$this->customErrorResponse = $customErrorResponse
}
public function handle($request, Closure $next)
{
$response = Auth::onceBasic();
if (!$response) {
return $next($request);
}
return $this->customErrorResponse->send();
}
}

Cant get Beautymail to work for Laravel 5.2

I'm trying to use Beautymail for my project to send a receipt after a customer ordered something. The problem is I'm using Beautymail in a function not in a route like their Documentation states.
This is how im using it in my function:
class OrderController extends Controller {
public function postOrder(Request $request) {
// More stuff here, shortned for question purposes
// Get an instance of the currently authenticated user
$user = Auth::user();
// Send email conformation to user that just bought a product or products.
$beautymail = app()->make(Snowfire\Beautymail\Beautymail::class);
$beautymail->send('emails.welcome', [], function($message) {
$message
->from('example#admin.com')
->to($user->email, $user->username)
->subject('Your Receipt');
});
// Then return redirect back with success message
flash()->success('Success', 'Your order was processed successfully. A receipt has been emailed to you');
return redirect()->route('cart');
}
}
And this is the error I get when I "Checkout":
Is there something I have to add? I already did my composer.json file along with adding it into the Providers Array, and publishing it to assets folder like in documentation.
$beautymail = app()->make(\Snowfire\Beautymail\Beautymail::class);
Note the \ before Snowfire\Beautymail\Beautymail::class.
Or, at the top of your controller:
use Snowfire\Beautymail\Beautymail;
and in your method you can have Laravel automatically resolve it through the IoC container, like:
public function postOrder(Request $request, Beautymail $beautymail)
{
$beautymail->send('emails.welcome', [], function($message) {
// etc...
}
Extra info on namespaces in PHP:
When you reference a class outside of use, you need to declare where the if your class is in the global namespace or not. So when you had:
app()->make(Snowfire\Beautymail\Beautymail::class);
without the leading \, PHP will assume you're looking for the requested with in the current namespace, which for you is \App\Http\Controllers.
By adding the leading \ you're telling PHP that the path to your class is relative to the global namespace.
Here's more info: http://php.net/manual/en/language.namespaces.basics.php
It looks like Snowfire\Beautymail\Beautymail::class is missing in your Laravel project. Have you installed as it mentions on https://github.com/Snowfire/Beautymail If you have not, please do so.

How to find the route param from the top level middleware in Slim

I'm trying to accomplish API versioning of the APIs I've written using Slim framework.
All my versioned APIs look like this:
$app->get('/:version/book/search', function() {...});
I'm trying to create an application wide Route Condition for this version as follows:
\Slim\Route::setDefaultConditions(array(
'version' => 'v[3-6]'
));
So only the APIs with version number v3,v4,v5 and v6 should be allowed to get it.
My requirement is to store the exact version of the API call made in $app->version, and then do version specific code changes if needed for that. I have created a middleware which I added to the $app itself, so it gets executed for each API calls:
$app->add(new \GetVerMiddleware());
class GetVerMiddleware extends \Slim\Middleware
{
public function call()
{
// HOW TO GET THE version route parameter??
// ????
$app->version = $version;
$this->next->call();
}
}
So I want to know how to get the route parameter version inside the GetVerMiddleware. Is it even possible to get that? I know how to get the entire route printed (link), but I'm interested only in the version parameter.
OK, I've figured out the solution after some researching, the following link particularly helped:
Slim Framework forum
$app->add(new \GetVerMiddleware());
class GetVerMiddleware extends \Slim\Middleware
{
public function call()
{
$this->app->hook('slim.before.dispatch', array($this, 'onBeforeDispatch'));
$this->next->call();
}
public function onBeforeDispatch()
{
$route_params = $this->app->router()->getCurrentRoute()->getParam('version');
$this->app->version = $version;
}
}
I think the solution was pretty much there, apologies!

CakePHP - creating an API for my cakephp app

I have created a fully functional CakePHP web application. Now, i wanna get it to the next level and make my app more "opened". Thus i want to create an RESTful API. In the CakePHP docs,i found this link (http://book.cakephp.org/2.0/en/development/rest.html) which describes the way to make your app RESTful. I added in the routes.php the the two lines needed,as noted at the top of the link,and now i want to test it.
I have an UsersController.php controller,where there is a function add(),which adds new users to databases. But when i try to browse under mydomain.com/users.json (even with HTTP POST),this returns me the webpage,and not a json formatted page,as i was expecting .
Now i think that i have done something wrong or i have not understood something correctly. What's actually happening,can you help me a bit around here?
Thank you in advace!
You need to parse JSON extensions. So in your routes.php file add:
Router::parseExtensions('json');
So a URL like http://example.com/news/index you can now access like http://example.com/news/index.json.
To actually return JSON though, you need to amend your controller methods. You need to set a _serialize key in your action, so your news controller could look like this:
<?php
class NewsController extends AppController {
public function index() {
$news = $this->paginate('News');
$this->set('news', $news);
$this->set('_serialize', array('news'));
}
}
That’s the basics. For POST requests, you’ll want to use the RequestHandler component. Add it to your controller:
<?php
class NewsController extends AppController {
public $components = array(
'RequestHandler',
...
);
And then you can check if an incoming request used the .json file extension:
public function add() {
if ($this->RequestHandler->extension == 'json') {
// JSON request
} else {
// do things as normal
}
}

server side of Backbone urlRoot setup with Laravel

I am just starting to look at backbone.js but am struggling with the server side of things.
I have seen documentation declaring the urlRoot as 'user/' after a bit of googling I have figured out that this is a reference to a RESTful API, however I have not been able to figure out how to implement such a structure with WAMP (will be moving to a hosted server once I have a working solution).
I had a play with Laravel but after 2 days I have not been able to set up a route to a dummy controller. This is my current attempt:
routes.php
Route::post('users', 'UsersController#create');
UsersController.php
<?php
class UsersController extends BaseController {
public function index() {
}
public function create() {
$input = Input::json();
return json_encode($input);
}
}
backbone.js
window.User = Backbone.Model.extend({
defaults: {
FirstName: "Test",
LastName: "User"
},
urlRoot: "user/"
})
However when I create a new user and attempt to call save, chromes network tools tell me that it sends a post request to users/ and then a get request to users
Is there an easier way to set my site up to talk with backbone or am I just doing something really wrong?
You should use :
Route::controller('users', 'UserController');
and
public function getCreate() {}
see this http://laravel.com/docs/controllers#restful-controllers

Categories