Skip to content

Cast Actions

Cast Actions let developers create custom buttons which users can install into their action bar on any Farcaster application (see the spec).

Overview

At a glance:

  1. User installs Cast Action via specific deeplink or by clicking on <Button.AddCastAction> element with a specified target .castAction route in a Frame.
  2. When the user presses the Cast Action button in the App, the App will make a POST request to the .castAction route.
  3. Server performs any action and returns a response to the App which is shown as a toast.

Walkthrough

Here is a trivial example on how to expose an action with a frame. We will break it down below.

1. Render Frame & Add Action Intent

In the example above, we are rendering Add Action intent:

action property is used to set the path to the cast action route.

src/index.tsx
app.frame('/', (c) => {
  return c.res({
    image: (
      <div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
        Add "Log this!" Action
      </div>
    ),
    intents: [
      <Button.AddCastAction action="/log-this">
        Add
      </Button.AddCastAction>,
    ]
  })
})
 
// ...

2. Handle /log-this Requests

Without a route handler to handle the Action request, the Cast Action will be meaningless.

To specify the name and icon for your action, the next properties are used in the action handler definition:

  1. name property is used to set the name of the action. It must be less than 30 characters
  2. icon property is used to associate your Cast Action with one of the Octicons. You can see the supported list here.
  3. (optional) description property is used to describe your action, up to 80 characters.
  4. (optional) aboutUrl property is used to show an "About" link when installing an action.

Let's define a /log-this route to handle the the Cast Action:

src/index.tsx
app.frame('/', (c) => {
  return c.res({
    image: (
      <div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
        Add "Log this!" Action
      </div>
    ),
    intents: [
      <Button.AddCastAction action="/log-this">
        Add
      </Button.AddCastAction>,
    ]
  })
})
 
app.castAction(
  '/log-this',
  (c) => {
    console.log(
      `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${
        c.actionData.fid
      }`,
    )
    return c.res({ type: 'message', message: 'Action Succeeded' })
  },
  { name: "Log This!", icon: "log" })
) 

A breakdown of the /log-this route handler:

  • We are responding with a c.res response and specifying a message that will appear in the success toast.

3. Bonus: Shorthand c.message

Instead of c.res({ type: 'message' }), you can use a shorthand c.message(...).

src/index.tsx
app.castAction(
  '/log-this',
  (c) => {
    console.log(
      `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${
        c.actionData.fid
      }`,
    ) 
    return c.message({ message: 'Action Succeeded' })
  }, 
  { name: "Log This!", icon: "log" })
)

4. Bonus: Returning an error

You can return an error response for a Client to render an error toast by using c.error.

src/index.tsx
app.castAction(
  '/log-this',
  (c) => {
    console.log(
      `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${
        c.actionData.fid
      }`,
    ) 
    return c.error({ message: 'Action Failed' })
  }, 
  { name: "Log This!", icon: "log" })
)

5. Bonus: Learn the API