I have been programming for almost as long as I can remember. As young kid I was already fascinated with everything that had to do with websites. Quickly I started creating websites for my parents and local clubs.
When I was born, my father bought a film camera to record my childhood. Later on this evolved into a hobby: making short movies and documentaries. Always having a camera around of course had its influence on me: I wanted to create my own movies.
While programming became my profession, film has always stayed a hobby, averaging at 1 or 2 productions per year. Last few years I've been working together with my father on creating short movies.
When my father sent me the screenplay for last years movie ("Greetings, Henk"), I was immediately enthusiastic. Especially because of one specific scene. In this scene the main actress keeps getting a pop-up of a dating site, eventually signs-up and starts chatting. This scene had a few challenges:
At first I planned to create a simple chat app with Laravel Echo. That meant someone in the same room would have to respond at the right moments without any mistakes in the messages. As we didn't have internet at the set, I decided to take a different approach: a chatbot.
I created a new Laravel app and installed Botman.
"require": {
"php": ">=7.0.0",
"botman/botman": "^2.0",
"botman/driver-web": "^1.0",
"fideloper/proxy": "~3.3",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
"predis/predis": "^1.1"
},
The goal was to create an auto-responder to specific messages the actress would type. I created a bot based on the WebDriver.
I split up each scene in the film into conversations. The conversation could be triggered by typing {scene_number} in the chat. (Of course this message would be hidden after being sent).
Route::match(['get', 'post'], '/botman', function () {
$henk = resolve('botman');
$henk->hears('18', function (BotMan $henk) {
$henk->startConversation(new Scene18);
});
// Other scenes
$henk->listen();
});
In the first chat scene, the actress has just signed up to "DreamPartner" and immediately starts chatting with her match of the day.
<?php
namespace App\Conversations;
class Scene18 extends BaseScene
{
/**
* @return void
*/
public function run()
{
// Auto start with the first message.
$this->watLeuk();
}
protected function watLeuk()
{
$this->wait(1);
$this->typesAndWaits(4);
$this->ask('Hallo Lieve, wat leuk dat we kunnen chatten.', function () {
$this->woontNietVerVandaan();
});
}
protected function woontNietVerVandaan()
{
$this->wait(2);
$this->typesAndWaits(4);
$this->ask('Zo te zien woon je niet ver hier vandaan.', function () {
$this->oke();
});
}
// more chat messages
}
(Film is in Dutch, so chat messages are in Dutch too)
Now the bot would start auto-replying the correct, pre-scripted messages. It wouldn't really matter what the actress would type, it would always give the correct answer based on the screenplay.
To make the responding more realistic (but still predictable), I created a wait() and typesAndWaits() method.
<?php
namespace App\Bots;
use App\Events\Typing;
use BotMan\BotMan\Messages\Incoming\IncomingMessage;
use BotMan\Drivers\Web\WebDriver;
class HenkBot extends WebDriver
{
public function types(IncomingMessage $matchingMessage)
{
event(new Typing);
}
}
The types() method broadcasts a Typing event to the frontend.
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
class Typing implements ShouldBroadcastNow
{
public function broadcastOn()
{
return new Channel('chatscreen');
}
}
In the VueJS frontend I would listening for this event with Laravel Echo.
created() {
window.Echo.channel('chatscreen').listen('Typing', (e) => {
this.henkTyping = true;
this.scrollTo('typing');
});
},
To display the chat messages in the frontend, I just post the message with axios to the botman api and add all responses to the chatbox.
axios.post('/api/botman', {
driver: 'web',
userId: 1,
message: messageText
}).then(response => {
this.henkTyping = false;
let messages = response.data.messages || [];
messages.forEach(msg => {
this.messages.push({
'user': 'henk',
'text': msg
});
this.scrollTo(msg);
});
}});
After doing a couple of practise runs, it was finally time to use it on the set. When the scene would start, the actress would type the scene number and the conversation would start. Everything went according to plan and it saved us a lot of time doing it this way. The answers of the bot were flawless and well timed.
The film has been sent to several film festivals. It was great seeing the film on the big screen and was delighted with all the great responses. Last November the film won the price for best fiction film at the Dutch Film Festival for non-commercial filmmakers.
It was a great experience combining my two passions. If you are interested in creating chatbots, I really recommend you checking out BotMan. It helped me greatly in writing the dating app in a very short time span. Also Laravel Echo VueJS and TailwindCSS were great timesavers.
I work at Maatwebsite on weekdays and I am a passionate filmmaker in my free time. Find me on Twitter & Github.