[object Object][object Object][object Object][object Object][object Object][object Object][object Object][object Object]How to turn a Cast Action into a Frame | dTech Skip to content

How to turn a Cast Action into a Frame

This guide assumes you know what Farcaster Frames are and that you have a Cast Action ready.

How to turn a Cast Action into a Frame?

If you already have a cast action you can add an image and button to call the same backend function (logic) that you already have for the cast action.

The way this Frame will work is similar to the Cast Action, though the user does now press a button in the Frame and not a button on the context menu of a post (cast).

Cast Action User and Server Flow visualized

How to easily turn a preexisting cast action into a frame

The code of your cast action will recieve a Frame Message, do something and return a message (or a Frame already).

Let’s turn that into a “pure” Frame.

The technical difference being that you need to serve a starting screen.

The cast action does not need a starting screen as it gets invoked by POST request only.

The starting screen in a Frame the Frame Metadata you respond to a GET request with. It holds your starting Frame (initial Frame) definition.

Your code will look similar to this for the route that handles the cast action.

|
|__ GET request handler -> returns frame Metadata
|
|__ POST request handler -> returns message, error or Frame

What we need is for another GET endpoint that will serve as Frame entrypoint.

Let’s say the action will be served for both GET and POST request on the /action route and we are now adding a /frame route to handle the entry point.

We will tell the Frame to just pass control to the action!

Though for our action there are two cases

  1. THe Cast Action already returns a Frame
  2. The Cast Action does not yet return a Frame

We will first handle the case that it already returns a Frame and then handle the case where it does not. You will see they are similar.

How to turn a Cast Action that returns a Frame into a pure Frame

Let’s add our entry point Frame.

As your code will be different here’s Pseudo Code of what you want to achieve with the Frame parts being spelled out explicitly. Though you can choose Framework, or handle these yourself. The logic doesn’t change, just your implementation may.

GET handler entrypoint for the Frame

Do what ever you want in the function to handle the frame request .. validate the data, or something else.

Then we return a frame that sends to the /action endpoint as we know that already returns a Frame to the user.

We just pass control and have built an entrypoint Frame. The image to show the user we assume is at https://dtech.vision/frame.png

function GET (request) {
// do what ever you want
// return the Frame Metadata with a button to invoke what was the cast action.
// you could use a framework or whatever. The gist is you have a handler and return a frame sending to the /action as that already returns a frame
return (
<html>
<head>
<meta property="fc:frame" content="vNext" />
<meta property="fc:frame:image" content="https://dtech.vision/frame.png" />
<meta property="fc:frame:image:aspect_ratio" content="1:1" />
// This is Button 1 which will redirect to the frame of the cast action
<meta property="fc:frame:button:1" content="Invoke Action" />
<meta property="fc:frame:button:1:action" content="post" />
// set post target to the /action endpoint!
<meta property="fc:frame:button:1:target" content="https://dtech.vision/action" />
</head>
</html>
)
}

How to turn a Cast Action that returns a message into a standalone Frame

Just as in the case where we already return a Frame, we will add a GET handler that will serve as our entrypoint.

As your code will be different here’s Pseudo Code of what you want to achieve with the Frame parts being spelled out explicitly. Though you can choose Framework, or handle these yourself. The logic doesn’t change, just your implementation may.

Though in addition the a GET Handler entrypoint since our action does not return a Frame already, we will reuse the action code and build a /actionframe route that responds to POST messages just like our /action endpoint but returns a Frame instead of a message / error.

The GET Handler is the same as seen here previously, just change the target route to /actionframe instead of /action as we will return the frame from /actionframe

What is missing is the POST handler

Turn the Cast Action Message into a Frame

Let’s take the function that handles our Cast Action for us. The POST handler.

Here we will use the exact same logic we already have! we just return a Frame!

Note that the message of the cast action can be either displayed by the image, or in the button text (we’ll put <your message here> as place holder in the sample). It all depends on what you want the Frame to show or display.

How? Let’s check in the pseudocode below. We assume that https://dtech.vision/frame.png is the image the frame should show and that the user should be redirected to https://dtech.vision on return of the cast action. Change this to what you see fit for your program.

function POST (request) {
// the exact same logic from your cast action. you may even call it :D
// the return is different. We don't return a message here.
// We return a frame. You may do this within your framework or use the HTML directly
return (
<html>
<head>
<meta property="fc:frame" content="vNext" />
<meta property="fc:frame:image" content="https://dtech.vision/frame.png" />
<meta property="fc:frame:image:aspect_ratio" content="1:1" />
// This is Button 1 which will redirect to https://dtech.vision set as "link" is used as action
<meta property="fc:frame:button:1" content="<your message here>" />
<meta property="fc:frame:button:1:action" content="link" />
<meta property="fc:frame:button:1:target" content="https://dtech.vision/" />
</head>
</html>
)
}

How to turn the Cast Action into a Frame that returns a message and not another Frame

Now there is one bonus case that we will include here. The Frame itself could also return a message. It does not need to return another Frame.

How? Well the Frame can error. So we can use the error channel to send messages to the user.

If we use the same logic and thinking as when turning the cast action with message return into a frame and just let it return a message the code will look similar to the following:

function POST (request) {
// the exact same logic from your cast action. you may even call it :D
// the return is different. We return a 400 error and put the message there
return (
status: 400
header: content-type: application/json
{ message: "Invalid email" }
)
}

How to add a Frame as entry point to multiple cast actions? Making the Frame the initial step

The flow to build a Frame from a Cast Action is the same as before.

Therefore we only need to add a new initial step Frame that allows the user to choose what they want to do.

Say that we have “hire dTech” on /hire and “quickstart frames” on /quickstart-farcasterframes on our Frame Server as routes. (btw these do exist hire us for Farcaster work and our Quickstart Frames Tutorial).

Now our Frame needs the Metadata to do that. I will assume that our Image is present at dtech.vision/initialFrameImage.png which may be different in your setup.

Now creating two buttons with these routes and adding the image will give us a simple HTML code with Frame Metatags (why Metatags? learn how Frames work).

The following HTML deployed will give you the initial step Frame you are looking for that then routes to your other Frames. You can also remove buttons or add buttons. Though you can’t add more then 4 Buttons in one Frame.

Notice how post is used as action this tells the Farcaster client to send a POST request to that frame endpoint, which effectively calls the frame for us. Passing control from the initial step frame to that Frame.

<html>
<head>
<meta property="fc:frame" content="vNext" />
<meta property="fc:frame:image" content="https://dtech.vision/initialFrameImage.png" />
<meta property="fc:frame:image:aspect_ratio" content="1:1" />
<!-- This is Button 1 "hire dTech" on `/hire` -->
<meta property="fc:frame:button:1" content="hire dTech" />
<meta property="fc:frame:button:1:action" content="post" />
<meta property="fc:frame:button:1:target" content="https://dtech.vision/hire" />
<!-- This is Button 2 "quickstart frames" on `/quickstart-farcasterFrames` -->
<meta property="fc:frame:button:1" content="quickstart frames" />
<meta property="fc:frame:button:1:action" content="post" />
<meta property="fc:frame:button:1:target" content="https://dtech.vision/quickstart-farcasterFrames" />
</head>
</html>

If you don’t want to write this HTML each time, you can pick a Frames Framework or build your own abstraction.