duane blake

Published on March 30, 2023 | Posted in Laravel

Using the Chat GPT API to create a Tweet from content on a URL

With all the talk going around with Chat GPT and the latest development with AI. I decided to spend some time looking at using the API to create a very small MVP. The aim was to spend a couple of hours building a app. Where a user provides a URL and then selects from a list of predefined tones from the site, the site would then generates the tweet on that link with the chosen tone.

Using the Chat GPT API to create a Tweet from content on a URL

My first point of call was what I was going to build the app in I’m familiar with building apps in WordPress, Laravel, VueJs and most recently Svelte. I decided to go with Laravel as WordPress isn’t suitable for something like this. If in the future I decided to develop the app I would need authentication options. So I decided to go with Laravel. As its got all scaffolding for user auth if I use Jetstream or Breeze.

Outside of building the routes and the controller, the first thing I needed to build was a form to capture the user URL and an option for the tone of the tweet. Which will be a choice of three different options Clickbait, Sincere and Homously.

<form method="POST" action="{{route('tweets')}}" class="space-y-6">
    <div>
        @csrf
        <label for="url" class="block mb-2 sr-only">Enter Url</label>
        @error('url')
        <span class="mt-2 text-sm text-tomaoto-500">{{ $message }}</span>
        @enderror
        <input type="url" name="url" placeholder="Enter your webpage url" class="py-3 px-4 rounded-sm w-full border-0 bg-iron-25 placeholder-iron-500 ring-1 ring-inset ring-iron-500 focus:ring-2 focus:ring-inset focus:ring-pumpkin-800" />
    </div>
    <div class="flex">
        <div>
            <label for="tone" class="block leading-6 ">Tone</label>
            <select id="tone" name="tone" class="py-3 px-4 mt-2 block w-52 rounded-sm border-0 bg-iron-25 placeholder-iron-500 ring-1 ring-inset ring-iron-500 focus:ring-2 focus:ring-inset focus:ring-pumpkin-800">
                <option value="clickbait">Clickbait</option>
                <option value="humorously">Humorously</option>
                <option value="sincere">Sincere</option>
            </select>
        </div>
        <div class="ml-8 self-end">
            <button type="submit" class="self-end rounded-md bg-pumpkin-500 py-3 px-7 text-sm font-semibold text-white shadow-sm transition-all hover:bg-pumpkin-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pumpkin-800">Create Tweet</button>
        </div>
    </div>
</form>

Onto the controller, once the form has been submitted, I need to validate that the URL has been submitted and is in a format of a URL then assign a variable to the inputs. As I would need to pass these to the result page.

$validated = $request->validate([
      'url' => 'required|url'
]);

$url = $validated['url'];
$tone = $request['tone'];

I’m using Laravel HTTP client to fetch the data from the URL. The HTTP response returns all the HTML code. From what I’ve been reading if you provide that content it increases the cost of the API call. As all the HTML tags would generate more tokens. Also there is a limit on the amount of text that can be read in one request. To reduce the amount of text provided to the Open AI. I decided to remove certain HTML tags from being submitted to the API. Such as script, style and a few other tags from the page.

$response = Http::get($url);

$dom = new DOMDocument('1.0', 'UTF-8');
$internalErrors = libxml_use_internal_errors(true);
$dom->loadHTML($response->body());
$tags_to_remove = array('script', 'style', 'nav', 'footer', 'header', 'form', 'aside');
foreach ($tags_to_remove as $tag) {
    $element = $dom->getElementsByTagName($tag);
    foreach ($element  as $item) {
        $item->parentNode->removeChild($item);
    }
}

$html = $dom->saveHTML();

Now that I have removed all the unnecessary tags. I am going to remove the all tags and just leave the content. Then remove all the whitespace using the Laravel Str:squish helper.

$content = Str::squish(strip_tags($html));

The next thing I needed to do is get an API key for Open AI. When I signed up you’re given a $5 credit which will be perfect to use on this demo project. To work with Open AI I will be using the fantastic Laravel composer package which does all the heavy lifting called Openai-php. From reading the documentation on the Open AI website. They have several different models which I can use. I’m using gpt-3.5-turbo model as that’s the cheapest model which helps me stay under the $5 trial limit.

$results = OpenAI::chat()->create([
	'model' => 'gpt-3.5-turbo',
	'messages' => [
		['role' => 'user', 'content' => "Write tweet as $tone based on the following  $content"],
	]
]);

$answer = $results['choices'][0]['message']['content'];

Once the form has been submitted to the page we return the $answer, $url, and $tone to the user. Then display the information to the user.

<div>
	<h1 class="text-5xl text-iron-800 font-semibold ">Great!</h1>
	<p class="text-lg mt-6">Your tweet for the webpage <a href="{}" class="underline text-pumpkin-500 hover:no-underline hover:text-pumpkin-700">{{$url}}</a> as been written in tone of {{$tone}}.</p>
  <div class="bg-white overflow-hidden py-10">
		<textarea class="w-full h-56 py-3 px-4 rounded-sm border-0 bg-iron-25 placeholder-iron-500 ring-1 ring-inset ring-iron-500 focus:ring-2 focus:ring-inset focus:ring-pumpkin-800" readonly>{{$answer}}</textarea>
	</div>
</div>

Demo

The video below shows a quick demo of how the code works.

Further Improvements

  • Since I’m using Laravel Jetstream for Auth, the user is logging in so I can easily store the previous requests in the database. Then present them in a dashboard for the user.
  • Convert it over to Livewire there are a couple benefits of moving over to Livewire such as loading animations
  • Since there is a token limit the API has issues when a page has to much content. I would need to find a way of splitting up or summarising the request.
  • Not too sure if the Twitter API still works with all the changes happening there but you could post the Tweet to the user account.

Further information

As I was writing up this blog post Syntax.fm released a good podcast called Coding with the Open AI / Chat GPT API about using the API

Final thoughts

I was surprised by how quick and easy to get up and running with the API to build something. Granted the code can be improved and refactored. I just wanted to build something in a quick couple of hours and see how easy it was to build something.

Also, the cost of the API is a lot cheaper than I thought it would be I was expecting it to be loads and building the app I only reached $0.50 and I was doing loads of requests.

Leave a comment

Your email address will not be published. Required fields are marked *