diff --git a/package.json b/package.json index fc1ccd7..20a1514 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "packageManager": "pnpm@8.6.12", "dependencies": { "@googleapis/calendar": "^9.5.0", + "axios": "^1.6.5", "googleapis": "^129.0.0" } } diff --git a/packages/forge/blocks/messenger/actions/sendMessage.tsx b/packages/forge/blocks/messenger/actions/sendMessage.tsx new file mode 100644 index 0000000..6e54417 --- /dev/null +++ b/packages/forge/blocks/messenger/actions/sendMessage.tsx @@ -0,0 +1,56 @@ +import { option, createAction } from '@typebot.io/forge'; +import axios from 'axios'; +import { auth } from '../auth'; // Adjust the path as necessary +import { messengerBaseOptions } from '../baseOptions'; // Adjust the path as necessary + +// Define the messengerMessageOptions +const messengerMessageOptions = option.object({ + receiverId: option.string.layout({ + label: 'Receiver ID', + placeholder: 'Enter the receiver\'s Facebook User ID', + isRequired: true, + helperText: 'The Facebook User ID of the message recipient.', + }), + messageContent: option.string.layout({ + input: 'textarea', + label: 'Message Content', + placeholder: 'Type your message here...', + isRequired: true, + helperText: 'The content of the message to be sent.', + }), + // You can add more fields as necessary +}); + +// Define the sendMessageToMessenger action +export const sendMessageToMessenger = createAction({ + name: 'Send Message to Messenger', + auth: auth, + baseOptions: messengerBaseOptions, + options: messengerMessageOptions, // Use the messengerMessageOptions here + run: { + server: async ({ credentials, options }) => { + const pageAccessToken = credentials.pageAccessToken; + const recipientId = options.receiverId; + const messageContent = options.messageContent; + + // Construct the request payload + const payload = { + messaging_type: 'RESPONSE', + recipient: { + id: recipientId, + }, + message: { + text: messageContent, + }, + }; + + try { + const response = await axios.post(`https://graph.facebook.com/v14.0/me/messages?access_token=${pageAccessToken}`, payload); + console.log(response.data); + } catch (error) { + console.error('Error sending message to Messenger:', error); + } + }, + }, + // ... other configurations as needed +}); diff --git a/packages/forge/blocks/messenger/auth.ts b/packages/forge/blocks/messenger/auth.ts new file mode 100644 index 0000000..674c890 --- /dev/null +++ b/packages/forge/blocks/messenger/auth.ts @@ -0,0 +1,20 @@ +import { createAuth, option } from '@typebot.io/forge'; + +export const auth = createAuth({ + type: 'encryptedCredentials', + name: 'Messenger Account', + schema: option.object({ + pageAccessToken: option.string.layout({ + label: 'Page Access Token', + isRequired: true, + input: 'password', // Use 'password' to hide the token in the UI + helperText: 'Enter the Page Access Token from the Facebook Developer Portal.', + }), + // Optionally, you can add Page ID if your implementation requires it + pageId: option.string.layout({ + label: 'Facebook Page ID', + isRequired: false, // Set to true if Page ID is necessary for your implementation + helperText: 'Enter the Facebook Page ID (if required by your implementation).', + }), + }), +}); diff --git a/packages/forge/blocks/messenger/baseOptions.ts b/packages/forge/blocks/messenger/baseOptions.ts new file mode 100644 index 0000000..2213813 --- /dev/null +++ b/packages/forge/blocks/messenger/baseOptions.ts @@ -0,0 +1,24 @@ +import { option } from '@typebot.io/forge'; +import { messengerConstants } from './constants'; // Assuming you have a constants file for Messenger + +export const messengerBaseOptions = option.object({ + baseUrl: option.string.layout({ + accordion: 'Customize Messenger Settings', + label: 'Messenger Base URL', + defaultValue: messengerConstants.baseUrl, + helperText: 'URL for Messenger API requests.' + }), + apiVersion: option.string.layout({ + accordion: 'Customize Messenger Settings', + label: 'Messenger API version', + helperText: 'Version of the Messenger API to use.', + defaultValue: 'v14.0', // Set the default API version you are targeting + }), + pageAccessToken: option.string.layout({ + accordion: 'Authentication', + label: 'Page Access Token', + input: 'password', // Use 'password' to hide the token in UI + helperText: 'Access token for the Facebook Page.', + }), + // Include other options as needed for your Messenger integration +}); diff --git a/packages/forge/blocks/messenger/constants.ts b/packages/forge/blocks/messenger/constants.ts new file mode 100644 index 0000000..074b088 --- /dev/null +++ b/packages/forge/blocks/messenger/constants.ts @@ -0,0 +1,14 @@ +export const messengerConstants = { + baseUrl: 'https://graph.facebook.com/v14.0', // Use the appropriate version + defaultPageAccessToken: '', // Default token, if applicable + defaultMessageOptions: { + messaging_type: 'RESPONSE', // Default messaging type + }, +} as const; + +export const defaultMessengerModelOptions = { + model: 'your-messenger-model', // If you have a specific model or version you're working with + // Other default options specific to your implementation +} as const; + +// Include other constants as needed for your application diff --git a/packages/forge/blocks/messenger/index.ts b/packages/forge/blocks/messenger/index.ts new file mode 100644 index 0000000..b7c86bf --- /dev/null +++ b/packages/forge/blocks/messenger/index.ts @@ -0,0 +1,15 @@ +import { createBlock } from '@typebot.io/forge' +import { MessengerLogo } from './logo' +import { auth } from './auth' +import { messengerBaseOptions } from './baseOptions' +import { sendMessageToMessenger } from './actions/sendMessage' + +export const messenger = createBlock({ + id: 'messenger', + name: 'Messenger', + tags: [], + LightLogo: MessengerLogo, + auth, + options: messengerBaseOptions, + actions: [sendMessageToMessenger], +}) diff --git a/packages/forge/blocks/messenger/logo.tsx b/packages/forge/blocks/messenger/logo.tsx new file mode 100644 index 0000000..b4ba725 --- /dev/null +++ b/packages/forge/blocks/messenger/logo.tsx @@ -0,0 +1,36 @@ +import React from 'react' + +export const MessengerLogo = (props: React.SVGProps) => ( + + + + + + + + + + + + +) diff --git a/packages/forge/blocks/messenger/package.json b/packages/forge/blocks/messenger/package.json new file mode 100644 index 0000000..72d141b --- /dev/null +++ b/packages/forge/blocks/messenger/package.json @@ -0,0 +1,15 @@ +{ + "name": "@typebot.io/messenger-block", + "version": "1.0.0", + "description": "", + "main": "index.ts", + "keywords": [], + "license": "ISC", + "devDependencies": { + "@typebot.io/forge": "workspace:*", + "@typebot.io/tsconfig": "workspace:*", + "@types/react": "18.2.15", + "typescript": "5.3.2", + "@typebot.io/lib": "workspace:*" + } +} diff --git a/packages/forge/blocks/messenger/tsconfig.json b/packages/forge/blocks/messenger/tsconfig.json new file mode 100644 index 0000000..1eb9c77 --- /dev/null +++ b/packages/forge/blocks/messenger/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@typebot.io/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"], + "compilerOptions": { + "lib": ["ESNext", "DOM"], + "noEmit": true, + "jsx": "react" + } +} diff --git a/packages/forge/repository/index.ts b/packages/forge/repository/index.ts index 8726429..2923f25 100644 --- a/packages/forge/repository/index.ts +++ b/packages/forge/repository/index.ts @@ -4,4 +4,5 @@ export const enabledBlocks = [ 'zemantic-ai', 'cal-com', 'chat-node', + 'messenger', ] as const diff --git a/packages/forge/schemas/index.ts b/packages/forge/schemas/index.ts index 90d8a3f..659cd2d 100644 --- a/packages/forge/schemas/index.ts +++ b/packages/forge/schemas/index.ts @@ -1,4 +1,5 @@ // Do not edit this file manually +import { messenger } from '@typebot.io/messenger-block' import { chatNode } from '@typebot.io/chat-node-block' import { calCom } from '@typebot.io/cal-com-block' import { zemanticAi } from '@typebot.io/zemantic-ai-block' @@ -16,6 +17,7 @@ export const forgedBlocks = [ zemanticAi, calCom, chatNode, + messenger, ] as BlockDefinition<(typeof enabledBlocks)[number], any, any>[] export type ForgedBlockDefinition = (typeof forgedBlocks)[number] diff --git a/packages/forge/schemas/package.json b/packages/forge/schemas/package.json index 8540163..03d7292 100644 --- a/packages/forge/schemas/package.json +++ b/packages/forge/schemas/package.json @@ -12,6 +12,7 @@ "@typebot.io/openai-block": "workspace:*", "@typebot.io/zemantic-ai-block": "workspace:*", "@typebot.io/cal-com-block": "workspace:*", - "@typebot.io/chat-node-block": "workspace:*" + "@typebot.io/chat-node-block": "workspace:*", + "@typebot.io/messenger-block": "workspace:*" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index df00cac..81fd583 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@googleapis/calendar': specifier: ^9.5.0 version: 9.5.0 + axios: + specifier: ^1.6.5 + version: 1.6.5 googleapis: specifier: ^129.0.0 version: 129.0.0 @@ -1271,6 +1274,24 @@ importers: specifier: 5.3.2 version: 5.3.2 + packages/forge/blocks/messenger: + devDependencies: + '@typebot.io/forge': + specifier: workspace:* + version: link:../../core + '@typebot.io/lib': + specifier: workspace:* + version: link:../../../lib + '@typebot.io/tsconfig': + specifier: workspace:* + version: link:../../../tsconfig + '@types/react': + specifier: 18.2.15 + version: 18.2.15 + typescript: + specifier: 5.3.2 + version: 5.3.2 + packages/forge/blocks/openai: dependencies: ai: @@ -1364,6 +1385,9 @@ importers: '@typebot.io/forge-repository': specifier: workspace:* version: link:../repository + '@typebot.io/messenger-block': + specifier: workspace:* + version: link:../blocks/messenger '@typebot.io/openai-block': specifier: workspace:* version: link:../blocks/openai @@ -11960,6 +11984,16 @@ packages: - debug dev: false + /axios@1.6.5: + resolution: {integrity: sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==} + dependencies: + follow-redirects: 1.15.5 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + /axobject-query@3.2.1: resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} dependencies: @@ -15274,6 +15308,16 @@ packages: debug: optional: true + /follow-redirects@1.15.5: + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: