Developer-driven AI approach0:08
Okay, so in the last episode, we vibe coded a project from scratch. And again, that's incredible for things where you genuinely do not care about the code quality at all. It's irrelevant. But now in this episode, we're gonna take a slightly different perspective, I think of this more as developer driven AI come along. So here I have a fresh installation of Laravel and yeah, for this demo, here's what I wanna do.
Planning Telegram bot integration0:29
So here I have a fresh installation of Laravel and yeah, for this demo, here's what I wanna do. Let's set up a telegram bot so that we can interact with our application through a telegram chat. Let's get going. We'll start with Juni here. I'd like to set up a telegram bot for this application. And here's how I imagine it working. I start a chat with a bot that we create on Telegram, and when I send it a message, that message is posted to a web hook on my server.
and when I send it a message, that message is posted to a web hook on my server. The server receives the message and it parses it to determine which action to take. It performs that action and then it replies or returns a response to my Telegram chat. So I want you to start working on a plan for this and then we'll get started. Okay? So this is fine for the initial plan, but I'll give you a little tip.
Okay? So this is fine for the initial plan, but I'll give you a little tip. Often when you're working on features, uh, sometimes it can be cumbersome to go through the chat. So often what I will do is this, once you have a plan, I want you to write the contents of that plan to a file called telegram.md within my project route. Okay? So yeah, it's just going to make a plan and write it to a file so I can review it with a fine tooth comb.
Reviewing initial AI plan1:34
and write it to a file so I can review it with a fine tooth comb. Alright, that seems to be done. So it has a detailed telegram bot implementation here. And, uh, let's go over this together. All right, we'll do this side by side. Hi, uh, telegram bot implementation plan. All right, architecture user sends a message to the bot, telegram sends a web hook. Good Laravel recognizes, validates the web hook application.
telegram sends a web hook. Good Laravel recognizes, validates the web hook application. Parses parses the message. Good. It executes the action. So it parses, it figures out what are we trying to do here? Are we refining an account? Are we sending a coupon? Are we updating a record or something? Uh, executes the action, sends the response user receives the response. That's, that's the flow we want. Alright, so here are the implementation steps
That's, that's the flow we want. Alright, so here are the implementation steps and yeah, this is where it's different from Vibe coding, by the way, with Vibe coding to a certain extent, you just don't care. It's like whatever it makes is what it makes. If it works, it works. And if it doesn't work, then you update the chat and you say, that didn't work, right? This is a little different.
and you say, that didn't work, right? This is a little different. I wanna be involved every step of the way. I, I don't want the code base to end up in a state where I do not understand any of it. I very much want to avoid that. So before it writes any big feature like this, I'm very much involved. I'm going over every step. I'm reviewing what the controller name is,
I'm going over every step. I'm reviewing what the controller name is, what the route is, how it goes about it, are we using caching, uh, which package did did we pull in? I wanna be involved every step of the way. Okay? So anyways, uh, implementation steps. Create a new bot. This is correct. Save the bot token fine. Uh, so it's like a token to interact with your telegram bot, uh, or the API set up a web hook. Correct. Okay. Store web hook secret. All right.
uh, or the API set up a web hook. Correct. Okay. Store web hook secret. All right. Okay, so now we're just setting up environment variables fine. Database schema. So they're actually storing this within a database. Yeah, so this is another good example. Like, I didn't necessarily say that I wanna store the chat within a database, uh, that might be useful for the future,
that I wanna store the chat within a database, uh, that might be useful for the future, but I didn't ask for that. It's just making assumptions, which is why we start with a plan before the AI gets to work. All right? 'cause I don't necessarily want, uh, a database here. All right, next API routes, that's fine. Um, yep, that's what I would do. Uh, no CSRF protection. That's why you put it within your route slash API file.
Um, yep, that's what I would do. Uh, no CSRF protection. That's why you put it within your route slash API file. That's good. Here's your web hook controller fine. Um, middleware. So it wants a middleware that basically validates that the request is coming specifically from a telegram. Fine. Um, next, yeah, so it's, it's building up a command parser. A command handler. Yeah, I mean, these are terms that you often use, um,
A command handler. Yeah, I mean, these are terms that you often use, um, when building a bot like this, but notice it's sending a little alarm bells for me. I'm, I'm seeing a lot of program jargon, which I don't necessarily love, but command is fine. But yeah, like handler interface, I'm like, we're just building a simple bot chat here. We don't need to get too crazy. Anyways, let's keep going. This is why we do this. Uh,
We don't need to get too crazy. Anyways, let's keep going. This is why we do this. Uh, the handler will have a handle method. Next, it's gonna create an API client and it will use the Laravel HTTP client to communicate fine. It's gonna have messages like send message and send photos. Yeah, so what you can see here is it's basically building the entire functionality and interaction and client from scratch. Maybe it should have considered
and client from scratch. Maybe it should have considered that there are packages already available that will do this better and, um, more bug free than we might, um, than we might do. Alright, next, it has a job to process telegram message. It has form request to validate the incoming request, uh, a service provider to register, um, maybe our middleware and the client. We got a bunch of artisan command set, web hook command,
maybe our middleware and the client. We got a bunch of artisan command set, web hook command, get webhook, delete. I, I hope alarm bells are going up for you as we do this. And this is again, the distinction between what we might call developer driven AI versus vibe coding. We have some exception handling. We have some tests that's good. It's just, okay, here's the deal. We're at the end. I like, I've already lost interest
It's just, okay, here's the deal. We're at the end. I like, I've already lost interest because I think we can hopefully all agree it's too much. We're, we're building a simple little feature here, and this is like a whole thing. This is a whole thing and I don't want it. So this is why we need to very much be involved in the entire process. So here's what I'm gonna do. We're gonna go right back to the AI and work on a new plan.
Simplifying with Nutgram6:03
So here's what I'm gonna do. We're gonna go right back to the AI and work on a new plan. So I've reviewed your plan and I've come to the conclusion that it is drastically to complex. There's way too much going on here. You didn't review, uh, or you didn't consider the possibility that there are dedicated composer packages that will wrap all of this functionality up so
that there are dedicated composer packages that will wrap all of this functionality up so that we don't have to write it out by hand. For example, I'd like you to take a look at the Nut Graham Composer package, which I believe offers a, a, a very nice and clean API to, um, interact with Telegram. And I believe they offer, uh, a feature where we can register dedicated commands, um, so that from the Telegram chat we could just say slash refund email
that from the Telegram chat we could just say slash refund email and then we can register a command to respond to that. So again, I want you to note that your current plan is too complex and too verbose. Your job is to simplify this, make it more clear and pull in a dedicated Nut Graham package through Composer. To simplify this drastically. Please work on a new plan and update Telegram md. All right? And it's gonna give it another try.
Please work on a new plan and update Telegram md. All right? And it's gonna give it another try. Alright, so now, yeah, while, while this is doing its thing, yeah, I just want you to consider that if we were vibe coding this, we would've just approved, approved, approved. And look, it would still work and maybe the future is just the quality of the code doesn't matter really at all. But right now, to me it does matter.
of the code doesn't matter really at all. But right now, to me it does matter. And if we took a vibe coding approach for this feature, it would've been too complex and too verbose, way more than is necessary. And what about the next feature? And the next feature very, very quickly. You can end up in a situation where every single feature is like five times more verbose than it needs to be.
where every single feature is like five times more verbose than it needs to be. This is why as developers, our job at this point is to very much be involved, uh, in the process. Alright, so now we have an updated Telegram file. Let's take a look and we're gonna go through this very quickly. So now it's using Nut Graham, uh, spelled awkwardly it once us to pull in. All right, so it figured out we're using Laravel
it once us to pull in. All right, so it figured out we're using Laravel and there is a Nut Graham, uh, slash Laravel package. It knows that we can create telegram commands. Next, you can see it's recommending in a service provider or a routes file to register the command. And it's doing an all in line. We definitely don't wanna do this within a service provider. We can create a dedicated route slash telegram file. So once again, uh, we'll need to update that.
We can create a dedicated route slash telegram file. So once again, uh, we'll need to update that. Let's keep going. Um, alright, so it is detecting that there are, um, dedicated nut gram specific commands for registering webhooks with the Telegram API. Much better than what we had before. Uh, for complex commands, uh, commands create dedicated handler classes. So yeah, we register the command. And yeah, real quick, if you've never done this
So yeah, we register the command. And yeah, real quick, if you've never done this before in Telegram, you can do things like this where you say slash refunds, that's the name of our command. You would send through an email and this would get parsed by Nut Graham. It would detect that we're running a refund command and it would trigger the handler and pass through the associated email. But yeah, even in this case, like this is too much.
and pass through the associated email. But yeah, even in this case, like this is too much. Uh, as well, it's just parsing the message text to figure out the email. Um, we can use wild cards for that and then for, for some reason it's not picking up on that. All right, next, uh, we register it, how to handle it. Testing. Yep. Okay, so this is using the API. This, alright, there's a few issues here, but this is 10 times better than the first
This, alright, there's a few issues here, but this is 10 times better than the first plan it came up with. Okay? So we'll make a, a slight tweak here and then we're gonna get started. But real quick, it's important for me to reiterate. Look, if we had run that, um, that initial chat multiple times, sometimes it might've pulled in Nut Graham immediately, right? Sometimes it might've written the claim out from
immediately, right? Sometimes it might've written the claim out from scratch manually with no dependencies. Sometimes it might have found a different, uh, package or SDK or something like that to pull in. So that's why you wanna be a little bit careful and sometimes it can be useful to try two or three different approaches and then work with AI to choose the best implementation and we can talk about that in the future.
and then work with AI to choose the best implementation and we can talk about that in the future. Okay? Anyways, back to the chat. I think this is significantly better. Good job. Uh, one thing I did notice is that when it comes to the command, uh, parameters, you're still parsing them and using Explode. Uh, have a look at the Nut Graham documentation and you will find that we can accept wild cards to our Nut Graham commands in the same way
and you will find that we can accept wild cards to our Nut Graham commands in the same way that we can accept wild cards for Laravel routes. So I'm gonna link you to that. I want you to review it and then I want you to update the plan and then you can get started. Okay? So very quickly, I'm visiting Nut graham.dev. Let's go into the documentation, down to, um, handlers perhaps. And we're gonna look for parameters. Yeah, here we go.
um, handlers perhaps. And we're gonna look for parameters. Yeah, here we go. Here's an example. So we can register, um, listen for text or even a command and notice that it can capture wild cards. And those wild cards are then sent to, um, the, the handler or the callback. So I'm just gonna copy this and include it with our chat review this documentation. Okay, so now it has updated this file and yeah, let's see how it's gonna prepare this.
Okay, so now it has updated this file and yeah, let's see how it's gonna prepare this. Yeah, this is what we want. It accepts the email address as the wild card that is received within the handler. Uh, does some validation, that's fine. Next it has the section on order. That's fine. It doesn't really know what we are working on. We can tweak that ourselves, but this looks, uh, fairly good.
We can tweak that ourselves, but this looks, uh, fairly good. So now what I think I'm gonna do is create a brand new chat just so we can truncate things and I can say read telegram.md plan and implement it has everything it needs at that point. And by the way, just to show you that we can mix and match agents. Yeah, there's nothing keeping you from uh, implementing this feature in both Juni and Claude.
Implementing and fixing gaps11:48
Yeah, there's nothing keeping you from uh, implementing this feature in both Juni and Claude. And then you can review, uh, the results. Alright, it looks like that's done. Now we can see all the to-dos have been completed. Okay? So if we take a look at our project, we have a new telegram folder, we have a help command, a refund command and a start command. That's fine. You'll see if I scroll down. We have a test for telegram, um, command tests.
That's fine. You'll see if I scroll down. We have a test for telegram, um, command tests. If I give this a run, they all return green. We should also have a routes slash telegram file and this is where we register our commands. Notice bot register command, uh, start command help command refund command. And then we have a fallback if we don't understand, uh, what you want. Perfect. Next, let's go into our environment file.
understand, uh, what you want. Perfect. Next, let's go into our environment file. And there should be, yeah, we have a telegram bot token that it is currently waiting on. Good. Uh, what else? Let's go into our route slash ap. I, ooh, did it not create one? No. So yeah, this is just such a great example. It did most of what it said it would do, but it didn't complete the job. So if entirely forgot the portion of, uh,
but it didn't complete the job. So if entirely forgot the portion of, uh, registering a endpoint to receive the web hook. So in these cases, what we would do, and this is why we call this developer driven API, if we could create a new file manually and we're just gonna pair with it, we'll say routes. We're gonna listen for a post request to, uh, telegram slash webhook
We're gonna listen for a post request to, uh, telegram slash webhook and let's see if we have any controllers within here. Uh, HTTP controllers. Nope. So let's create one now, let's create a Laravel controller. We'll call it telegram webhook controller. Alright, so now let's accept the Nut Graham bot. And yeah, here we could just say something like bot run and why don't we make this, uh, an invo controller. Yeah, and that's basically it.
and why don't we make this, uh, an invo controller. Yeah, and that's basically it. So now if we switch back to route slash API, yeah, we could, we could defer to that. And of course, yeah, if you want, you can add whatever middleware is necessary. So for example, if you want to throttle it, um, asset protection, uh, if you wanna limit it to a particular, uh, user or telegram, user only, all of these things can be done.
uh, user or telegram, user only, all of these things can be done. Okay? So now we have a route, let's register that and we can do that right here. Our API specific routes will live here. Again, these will not receive CSRF um, protection or things like that. Okay? So now I don't wanna leave you hanging, I at least want you to see something here. So let's quickly register the bot on the telegram end.
Registering bot and testing14:29
I at least want you to see something here. So let's quickly register the bot on the telegram end. The first step is to visit telegram and search for bot father and start a chat. Okay? And one of the commands we can do is register a new bot. So notice how we, we use a command forward slash and then the name of the command for our project, we'll have forward slash and refund or slash and coupon stuff like that.
we'll have forward slash and refund or slash and coupon stuff like that. Okay, let's make a new bot, we'll call it demo bot. Next, we need a username. It just needs to end with bots. Why don't we say lc for RAAs demo under bot. All right. And now it's gonna give us a unique, uh, telegram token so we can copy this, switch back to our project, go into MV and I will paste it here. So yeah, generally what you might wanna do is set up one bot specifically for your local testing
So yeah, generally what you might wanna do is set up one bot specifically for your local testing and then a different bot, uh, for your production. And that's one way that you can handle things like this. Okay? So now if we open up our terminal, uh, let's run PHP Artisan and you'll see that there are a bunch of Nut Graham specific commands we can run. So the ones I want you to focus on right now are Nut Graham. Listen, this starts the polling for local development
So the ones I want you to focus on right now are Nut Graham. Listen, this starts the polling for local development and then also Nut Graham hook set, which will set the bot, uh, web hook. And it's basically our way of saying, alright, telegram, here's the URL that I want you to ping whenever a new message comes in. And again, to reiterate that happens, uh, for production. Finally, notice Nut Graham register commands. This is what tells Telegram about all of the commands
Finally, notice Nut Graham register commands. This is what tells Telegram about all of the commands that we have registered within our Routes slash Telegram file. So in this case, we would have three. Okay, let's do it. PHB, artisan Nut Graham, register commands. Good. Next, let's do peach B Artisan Nut Graham, listen. All right, it's running. So now let's try a chat. I can click here to chat with our bots and welcome to the order manager.
I can click here to chat with our bots and welcome to the order manager. Yeah, it's just assuming we have orders here and we could have been more specific. So I, I might start by saying gibberish and this should hit the fallback unknown command. And that's happening because if I switch back right here we have our fallback command. Alright, so let's see what happens if we run help,
right here we have our fallback command. Alright, so let's see what happens if we run help, I can say forward slash help. And notice, by the way, this will list all of the commands and these are available because we ran that register commands, uh, artisan command. And yeah, we can see three different commands we can run. And yeah, just to reiterate, they are defined here. Alright, so here is our start to command. We register it here, we add a description,
Alright, so here is our start to command. We register it here, we add a description, and then we add a handler. Okay? So I wanna show you some other things in the next episode, but here's what I wanna leave you with. I want you to notice how if we had just vibe coded this project, it would've used the first implementation, which is like building everything from scratch and creating all of these command classes and handler classes and client classes.
and creating all of these command classes and handler classes and client classes. And it's just not necessary. So we had to work with it to guide it in the direction that we care about. And that's our job as developers to review this plan and constantly tweak it and constantly let AI know when it's going too far out on a limb and when to reign it in. Alright, so there's other stuff I wanna show you
limb and when to reign it in. Alright, so there's other stuff I wanna show you that is somewhat related to this. So let's keep watching in the next episode.
