examples/functions/mastodon-post/README.md
Content teams want to automatically share their published articles on Mastodon to reach decentralized social media audiences. Manually cross-posting to multiple social platforms is time-consuming and often forgotten, leading to missed opportunities for content promotion across the fediverse.
This Sanity Function automatically posts to Mastodon when you publish a new post with the mastodonPost field defined using the @humanwhocodes/crosspost library. The function creates a Mastodon post containing the title, mastodonPost, and slug, helping maintain consistent presence across decentralized social networks.
post document type containing:
title field (string)mastodonPost field (text or string)slug field (slug type with current property)This function is built to be compatible with any of the official "clean" templates. We recommend testing the function out in one of those after you have installed them locally.
This function expects your post schema to include:
title field (string)mastodonPost field (text) - for the post contentslug field (slug type with current property)Most official templates already include the title and slug fields, but you will need to add the mastodonPost field.
Add the mastodonPost field to your post schema:
defineField({
name: 'mastodonPost',
title: 'Mastodon Post Content',
type: 'text',
description: 'Content to post on Mastodon when this post is published',
})
Important: Run these commands from the root of your project (not inside the studio/ folder).
Set up Mastodon API Credentials
You'll need to create a Mastodon application and get an access token. There are two methods:
Log into your Mastodon instance:
mastodon.social, mastodon.online, etc.)Access Development Settings:
Create Application:
urn:ietf:wg:oauth:2.0:oob)write:statuses (required for posting)Get Access Token:
MASTODON_TOKENhttps://mastodon.social) - this is your MASTODON_HOSTInitialize the example
Run this if you haven't initialized blueprints:
npx sanity blueprints init
You'll be prompted to select your organization and Sanity studio.
Then run:
npx sanity blueprints add function --example mastodon-post
Add configuration to your blueprint
// sanity.blueprint.ts
import 'dotenv/config'
import process from 'node:process'
import {defineBlueprint, defineDocumentFunction} from '@sanity/blueprints'
const {MASTODON_TOKEN, MASTODON_HOST} = process.env
if (typeof MASTODON_TOKEN !== 'string' || typeof MASTODON_HOST !== 'string') {
throw new Error('MASTODON_TOKEN and MASTODON_HOST must be set')
}
export default defineBlueprint({
resources: [
defineDocumentFunction({
name: 'mastodon-post',
src: './functions/mastodon-post',
memory: 1,
timeout: 10,
event: {
on: ['create'],
filter: "_type == 'post' && defined(mastodonPost)",
projection: '{title, mastodonPost, slug}',
},
env: {
MASTODON_TOKEN: MASTODON_TOKEN,
MASTODON_HOST: MASTODON_HOST,
},
}),
],
})
Install dependencies
Install dependencies in the project root:
npm install dotenv
Configure environment variables
Create a .env file in your project root with the following variables:
# Required
MASTODON_TOKEN=your-access-token-here
MASTODON_HOST=https://your-instance.com
# Examples:
# MASTODON_HOST=https://mastodon.social
# MASTODON_HOST=https://mastodon.online
# MASTODON_HOST=https://fosstodon.org
Required:
MASTODON_TOKEN: Your Mastodon application access tokenMASTODON_HOST: Your Mastodon instance URL (including https://)You can test the mastodon-post function locally using the Sanity CLI before deploying it to production.
Test the function with an existing document ID from your dataset:
npx sanity functions test mastodon-post --document-id <insert-document-id> --dataset production --with-user-token
Test the function with the included sample document:
npx sanity functions test mastodon-post --file functions/mastodon-post/document.json
Start the development server for interactive testing:
npx sanity functions dev
This opens an interactive playground where you can test functions with custom data.
Once you've tested your function locally and are satisfied with its behavior, you can deploy it to production.
Important: Make sure you have the Deploy Studio permission for your Sanity project before attempting to deploy.
Verify your blueprint configuration
Make sure your sanity.blueprint.ts file is properly configured with your function as shown in the implementation section above.
Deploy your blueprint
From your project root, run:
npx sanity blueprints deploy
This command will:
If you're not using a .env file - Add environment variables
After deployment, only if you're not using an .env file, you need to add your Mastodon credentials as environment variables:
npx sanity functions env add mastodon-post MASTODON_TOKEN "your-access-token-here"
npx sanity functions env add mastodon-post MASTODON_HOST "https://your-instance.com"
You can verify the environment variables were added successfully:
npx sanity functions env list mastodon-post
Verify deployment
After deployment, you can verify your function is active by:
Only post when creating posts with postToMastodon set to true:
filter: "_type == 'post' && defined(mastodonPost) && postToMastodon == true"
Add more fields to the projection and use them in the post:
projection: '{title, mastodonPost, slug, author, tags}'
const hashtags = data.tags?.map((tag) => `#${tag}`).join(' ') || ''
const postContent = `${title}
${mastodonPost}
${slug.current}
${hashtags}`