Skip to content

Commit

Permalink
feat: Add Text Input metadata support (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
taycaldwell authored Feb 2, 2024
1 parent 0bb89f6 commit 58e29a9
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/core/farcasterTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,14 @@ export type FrameButtonMetadata = {
action?: 'post' | 'post_redirect';
};

export type FrameInputMetadata = {
text: string;
};

export type FrameMetadata = {
buttons?: [FrameButtonMetadata, ...FrameButtonMetadata[]];
image: string;
input?: FrameInputMetadata;
post_url?: string;
refresh_period?: number;
};
22 changes: 22 additions & 0 deletions src/core/getFrameHtmlResponse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ describe('getFrameHtmlResponse', () => {
{ label: 'button4' },
],
image: 'https://example.com/image.png',
input: {
text: 'Enter a message...',
},
post_url: 'https://example.com/api/frame',
refresh_period: 10,
});

expect(html).toBe(
'<!DOCTYPE html><html><head><meta property="fc:frame" content="vNext" />' +
'<meta property="fc:frame:image" content="https://example.com/image.png" />' +
'<meta property="fc:frame:input:text" content="Enter a message..." />' +
'<meta property="fc:frame:button:1" content="button1" />' +
'<meta property="fc:frame:button:1:action" content="post" />' +
'<meta property="fc:frame:button:2" content="button2" />' +
Expand All @@ -28,6 +32,24 @@ describe('getFrameHtmlResponse', () => {
);
});

it('should handle no input', () => {
const html = getFrameHtmlResponse({
buttons: [{ label: 'button1' }],
image: 'https://example.com/image.png',
post_url: 'https://example.com/api/frame',
});

expect(html).toContain('<meta property="fc:frame" content="vNext" />');
expect(html).toContain('<meta property="fc:frame:button:1" content="button1" />');
expect(html).toContain(
'<meta property="fc:frame:image" content="https://example.com/image.png" />',
);
expect(html).toContain(
'<meta property="fc:frame:post_url" content="https://example.com/api/frame" />',
);
expect(html).not.toContain('fc:frame:input:text');
});

it('should handle no buttons', () => {
const html = getFrameHtmlResponse({
image: 'https://example.com/image.png',
Expand Down
14 changes: 12 additions & 2 deletions src/core/getFrameHtmlResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@ import { FrameMetadata } from './farcasterTypes';
*
* @param buttons: The buttons to use for the frame.
* @param image: The image to use for the frame.
* @param input: The text input to use for the frame.
* @param post_url: The URL to post the frame to.
* @param refresh_period: The refresh period for the image used.
* @returns An HTML string containing metadata for the frame.
*/
function getFrameHtmlResponse({ buttons, image, post_url, refresh_period }: FrameMetadata): string {
function getFrameHtmlResponse({
buttons,
image,
input,
post_url,
refresh_period,
}: FrameMetadata): string {
// Set the image metadata if it exists.
const imageHtml = image ? `<meta property="fc:frame:image" content="${image}" />` : '';

// Set the input metadata if it exists.
const inputHtml = input ? `<meta property="fc:frame:input:text" content="${input.text}" />` : '';

// Set the button metadata if it exists.
let buttonsHtml = '';
if (buttons) {
Expand All @@ -37,7 +47,7 @@ function getFrameHtmlResponse({ buttons, image, post_url, refresh_period }: Fram

// Return the HTML string containing all the metadata.
let html = '<!DOCTYPE html><html><head><meta property="fc:frame" content="vNext" />';
html += `${imageHtml}${buttonsHtml}${postUrlHtml}${refreshPeriodHtml}</head></html>`;
html += `${imageHtml}${inputHtml}${buttonsHtml}${postUrlHtml}${refreshPeriodHtml}</head></html>`;

return html;
}
Expand Down
8 changes: 7 additions & 1 deletion src/core/getFrameMetadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,24 @@ describe('getFrameMetadata', () => {
});
});

it('should return the correct metadata with no refresh_period', () => {
it('should return the correct metadata with input', () => {
expect(
getFrameMetadata({
buttons: [{ label: 'button1' }],
image: 'image',
input: {
text: 'Enter a message...',
},
post_url: 'post_url',
refresh_period: 10,
}),
).toEqual({
'fc:frame': 'vNext',
'fc:frame:button:1': 'button1',
'fc:frame:image': 'image',
'fc:frame:input:text': 'Enter a message...',
'fc:frame:post_url': 'post_url',
'fc:frame:refresh_period': '10',
});
});
});
5 changes: 5 additions & 0 deletions src/core/getFrameMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ type FrameMetadataResponse = Record<string, string>;
* This function generates the metadata for a Farcaster Frame.
* @param buttons: The buttons to use for the frame.
* @param image: The image to use for the frame.
* @param input: The text input to use for the frame.
* @param post_url: The URL to post the frame to.
* @param refresh_period: The refresh period for the image used.
* @returns The metadata for the frame.
*/
export const getFrameMetadata = function ({
buttons,
image,
input,
post_url,
refresh_period,
}: FrameMetadata): FrameMetadataResponse {
const metadata: Record<string, string> = {
'fc:frame': 'vNext',
};
metadata['fc:frame:image'] = image;
if (input) {
metadata['fc:frame:input:text'] = input.text;
}
if (buttons) {
buttons.forEach((button, index) => {
metadata[`fc:frame:button:${index + 1}`] = button.label;
Expand Down

0 comments on commit 58e29a9

Please sign in to comment.