diff --git a/components/discord/actions/common/common.mjs b/components/discord/actions/common/common.mjs index edf36b8e7b75a..e963ae3c9ad93 100644 --- a/components/discord/actions/common/common.mjs +++ b/components/discord/actions/common/common.mjs @@ -66,7 +66,16 @@ export default { }, getSentViaPipedreamText() { const workflowId = process.env.PIPEDREAM_WORKFLOW_ID; - return `Sent via [Pipedream]()`; + const baseLink = "https://pipedream.com"; + const linkText = !workflowId + ? "Pipedream Connect" + : "Pipedream"; + + const link = !workflowId + ? `${baseLink}/connect` + : `${baseLink}/@/${encodeURIComponent(workflowId)}?o=a&a=discord`; + + return `Sent via [${linkText}](<${link}>)`; }, getMessageFlags(suppressNotifications) { let flags = 0; diff --git a/components/discord/actions/send-message-advanced/send-message-advanced.mjs b/components/discord/actions/send-message-advanced/send-message-advanced.mjs index 75cda2917d440..73dc6cc7a2c85 100644 --- a/components/discord/actions/send-message-advanced/send-message-advanced.mjs +++ b/components/discord/actions/send-message-advanced/send-message-advanced.mjs @@ -6,7 +6,7 @@ export default { key: "discord-send-message-advanced", name: "Send Message (Advanced)", description: "Send a simple or structured message (using embeds) to a Discord channel", - version: "1.0.2", + version: "1.0.3", type: "action", props: { ...common.props, diff --git a/components/discord/actions/send-message-with-file/send-message-with-file.mjs b/components/discord/actions/send-message-with-file/send-message-with-file.mjs index 65f6ce82fac05..93f1290ac60e2 100644 --- a/components/discord/actions/send-message-with-file/send-message-with-file.mjs +++ b/components/discord/actions/send-message-with-file/send-message-with-file.mjs @@ -8,7 +8,7 @@ export default { key: "discord-send-message-with-file", name: "Send Message With File", description: "Post a message with an attached file", - version: "1.1.1", + version: "1.1.2", type: "action", props: { ...common.props, diff --git a/components/discord/actions/send-message/send-message.mjs b/components/discord/actions/send-message/send-message.mjs index f30742084ecf7..d853a12b96fd7 100644 --- a/components/discord/actions/send-message/send-message.mjs +++ b/components/discord/actions/send-message/send-message.mjs @@ -5,7 +5,7 @@ export default { key: "discord-send-message", name: "Send Message", description: "Send a simple message to a Discord channel", - version: "1.0.2", + version: "1.0.3", type: "action", async run({ $ }) { const { diff --git a/components/discord/discord.app.mjs b/components/discord/discord.app.mjs index eeda121d54bde..47c5c51afe265 100644 --- a/components/discord/discord.app.mjs +++ b/components/discord/discord.app.mjs @@ -11,8 +11,8 @@ export default { type: "boolean", optional: true, default: true, - label: "Include link to workflow", - description: "Defaults to `true`, includes a link to this workflow at the end of your Discord message.", + label: "Include link to Pipedream", + description: "Defaults to `true`, includes a link to Pipedream at the end of your Discord message.", }, embeds: { type: "any", diff --git a/components/discord/package.json b/components/discord/package.json index 8e8ec3371b708..00e126a78adf6 100644 --- a/components/discord/package.json +++ b/components/discord/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/discord", - "version": "1.2.4", + "version": "1.2.5", "description": "Pipedream Discord Components", "main": "discord.app.mjs", "keywords": [ diff --git a/components/discord/sources/message-deleted/message-deleted.mjs b/components/discord/sources/message-deleted/message-deleted.mjs index ace0d9e941f61..e33bf4d110956 100644 --- a/components/discord/sources/message-deleted/message-deleted.mjs +++ b/components/discord/sources/message-deleted/message-deleted.mjs @@ -4,7 +4,7 @@ export default { key: "discord-message-deleted", name: "Message Deleted (Instant)", description: "Emit new event for each message deleted", - version: "0.0.3", + version: "0.0.4", dedupe: "unique", type: "source", props: { diff --git a/components/discord/sources/new-command-received/new-command-received.mjs b/components/discord/sources/new-command-received/new-command-received.mjs index caa85d199c823..927057aa16274 100644 --- a/components/discord/sources/new-command-received/new-command-received.mjs +++ b/components/discord/sources/new-command-received/new-command-received.mjs @@ -6,7 +6,7 @@ export default { key: "discord-new-command-received", name: "New Command Received (Instant)", description: "Emit new event for each command posted to one or more channels in a Discord server", - version: "0.0.3", + version: "0.0.4", dedupe: "unique", props: { discord, diff --git a/components/discord/sources/new-guild-member/new-guild-member.mjs b/components/discord/sources/new-guild-member/new-guild-member.mjs index 91fccc1707377..25da3ff44d97e 100644 --- a/components/discord/sources/new-guild-member/new-guild-member.mjs +++ b/components/discord/sources/new-guild-member/new-guild-member.mjs @@ -4,7 +4,7 @@ export default { key: "discord-new-guild-member", name: "New Guild Member (Instant)", description: "Emit new event for each new member added to a guild", - version: "0.0.3", + version: "0.0.4", dedupe: "unique", type: "source", props: { diff --git a/components/discord/sources/new-message/new-message.mjs b/components/discord/sources/new-message/new-message.mjs index 4110ece097d74..c9f006544072d 100644 --- a/components/discord/sources/new-message/new-message.mjs +++ b/components/discord/sources/new-message/new-message.mjs @@ -6,7 +6,7 @@ export default { key: "discord-new-message", name: "New Message (Instant)", description: "Emit new event for each message posted to one or more channels in a Discord server", - version: "1.0.3", + version: "1.0.4", dedupe: "unique", props: { diff --git a/components/discord/sources/reaction-added/reaction-added.mjs b/components/discord/sources/reaction-added/reaction-added.mjs index 494e5f9db97c0..f778508a95182 100644 --- a/components/discord/sources/reaction-added/reaction-added.mjs +++ b/components/discord/sources/reaction-added/reaction-added.mjs @@ -4,7 +4,7 @@ export default { key: "discord-reaction-added", name: "Reaction Added (Instant)", description: "Emit new event for each reaction added to a message", - version: "0.0.3", + version: "0.0.4", type: "source", props: { discord, diff --git a/components/slack/actions/common/send-message.mjs b/components/slack/actions/common/send-message.mjs index ff923367dbdbb..02925a73b0054 100644 --- a/components/slack/actions/common/send-message.mjs +++ b/components/slack/actions/common/send-message.mjs @@ -146,7 +146,7 @@ export default { const link = !workflowId ? `${baseLink}/connect` - : `${baseLink}/@/${workflowId}?o=a&a=slack`; + : `${baseLink}/@/${encodeURIComponent(workflowId)}?o=a&a=slack`; return { "type": "context", diff --git a/components/slack/actions/reply-to-a-message/reply-to-a-message.mjs b/components/slack/actions/reply-to-a-message/reply-to-a-message.mjs index fe983a74f0fd8..419e062e4a368 100644 --- a/components/slack/actions/reply-to-a-message/reply-to-a-message.mjs +++ b/components/slack/actions/reply-to-a-message/reply-to-a-message.mjs @@ -6,7 +6,7 @@ export default { key: "slack-reply-to-a-message", name: "Reply to a Message Thread", description: "Send a message as a threaded reply. See [postMessage](https://api.slack.com/methods/chat.postMessage) or [scheduleMessage](https://api.slack.com/methods/chat.scheduleMessage) docs here", - version: "0.1.28", + version: "0.1.29", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-block-kit-message/send-block-kit-message.mjs b/components/slack/actions/send-block-kit-message/send-block-kit-message.mjs index 8e7695e168aa8..478ea33c675fc 100644 --- a/components/slack/actions/send-block-kit-message/send-block-kit-message.mjs +++ b/components/slack/actions/send-block-kit-message/send-block-kit-message.mjs @@ -7,7 +7,7 @@ export default { key: "slack-send-block-kit-message", name: "Build and Send a Block Kit Message", description: "Configure custom blocks and send to a channel, group, or user. [See the documentation](https://api.slack.com/tools/block-kit-builder).", - version: "0.4.4", + version: "0.4.5", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-large-message/send-large-message.mjs b/components/slack/actions/send-large-message/send-large-message.mjs index 412f13940a8cb..ba9550a711a7d 100644 --- a/components/slack/actions/send-large-message/send-large-message.mjs +++ b/components/slack/actions/send-large-message/send-large-message.mjs @@ -5,7 +5,7 @@ export default { key: "slack-send-large-message", name: "Send a Large Message (3000+ characters)", description: "Send a large message (more than 3000 characters) to a channel, group or user. See [postMessage](https://api.slack.com/methods/chat.postMessage) or [scheduleMessage](https://api.slack.com/methods/chat.scheduleMessage) docs here", - version: "0.0.23", + version: "0.0.24", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-message-advanced/send-message-advanced.mjs b/components/slack/actions/send-message-advanced/send-message-advanced.mjs index 1a724cbb50d20..e828e5a4462eb 100644 --- a/components/slack/actions/send-message-advanced/send-message-advanced.mjs +++ b/components/slack/actions/send-message-advanced/send-message-advanced.mjs @@ -7,7 +7,7 @@ export default { key: "slack-send-message-advanced", name: "Send Message (Advanced)", description: "Customize advanced setttings and send a message to a channel, group or user. See [postMessage](https://api.slack.com/methods/chat.postMessage) or [scheduleMessage](https://api.slack.com/methods/chat.scheduleMessage) docs here", - version: "0.0.6", + version: "0.0.7", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-message-to-channel/send-message-to-channel.mjs b/components/slack/actions/send-message-to-channel/send-message-to-channel.mjs index c5dd32cf4ca32..0fe4d5450dd97 100644 --- a/components/slack/actions/send-message-to-channel/send-message-to-channel.mjs +++ b/components/slack/actions/send-message-to-channel/send-message-to-channel.mjs @@ -6,7 +6,7 @@ export default { key: "slack-send-message-to-channel", name: "Send Message to Channel", description: "Send a message to a public or private channel. [See the documentation](https://api.slack.com/methods/chat.postMessage)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs b/components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs index 5a11024688ab5..f5e72394bea2a 100644 --- a/components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs +++ b/components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs @@ -7,7 +7,7 @@ export default { key: "slack-send-message-to-user-or-group", name: "Send Message to User or Group", description: "Send a message to a user or group. [See the documentation](https://api.slack.com/methods/chat.postMessage)", - version: "0.0.4", + version: "0.0.5", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-message/send-message.mjs b/components/slack/actions/send-message/send-message.mjs index 514495ea0ab1e..991bcf08822d1 100644 --- a/components/slack/actions/send-message/send-message.mjs +++ b/components/slack/actions/send-message/send-message.mjs @@ -6,7 +6,7 @@ export default { key: "slack-send-message", name: "Send Message", description: "Send a message to a user, group, private channel or public channel. [See the documentation](https://api.slack.com/methods/chat.postMessage)", - version: "0.0.19", + version: "0.0.20", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/package.json b/components/slack/package.json index 8860416ac1880..2eec0bd177b9d 100644 --- a/components/slack/package.json +++ b/components/slack/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/slack", - "version": "0.9.5", + "version": "0.9.6", "description": "Pipedream Slack Components", "main": "slack.app.mjs", "keywords": [ diff --git a/packages/connect-react/CHANGELOG.md b/packages/connect-react/CHANGELOG.md index 354ab2afcd45b..0b7f6c76c35f5 100644 --- a/packages/connect-react/CHANGELOG.md +++ b/packages/connect-react/CHANGELOG.md @@ -2,6 +2,26 @@ # Changelog +# [1.4.0] - 2025-06-13 + +## Added + +- Support for `oauthAppId` parameter in `ComponentForm` and `ComponentFormContainer` components +- Pass `oauthAppId` through to `ControlApp` component for OAuth app-specific account connections + +## Usage + +```typescript + +``` + +This allows you to specify which OAuth app to use when connecting accounts, matching the behavior of the SDK's `connectAccount` method. + # [1.3.0] - 2025-06-10 ## Added diff --git a/packages/connect-react/README.md b/packages/connect-react/README.md index 210abf58162e8..e71426214b24e 100644 --- a/packages/connect-react/README.md +++ b/packages/connect-react/README.md @@ -83,10 +83,10 @@ import { fetchToken } from "./actions"; export default function Page() { // https://pipedream.com/docs/connect/api#external-users - const userId = "my-authed-user-id"; + const externalUserId = "my-authed-user-id"; const client = createFrontendClient({ environment: "development", - externalUserId: userId, + externalUserId: externalUserId, tokenCallback: fetchToken, }); const [configuredProps, setConfiguredProps] = useState({ @@ -97,7 +97,7 @@ export default function Page() {
My application
; /** Filtering configurable props */ propNames?: string[]; /** Shows submit button + callback when clicked */ - onSubmit: (ctx: FormContext) => Awaitable; + onSubmit?: (ctx: FormContext) => Awaitable; /** To control and store configured values on form updates, can be used to call actionRun or triggerDeploy */ - onUpdateConfiguredProps: (v: Record) => void; + onUpdateConfiguredProps?: (v: Record) => void; /** Hide optional props section */ - hideOptionalProps: boolean; + hideOptionalProps?: boolean; /** SDK response payload. Used in conjunction with enableDebugging to * show errors in the form. */ - sdkResponse: unknown[] | unknown | undefined; - /** Whether to show show errors in the form. Requires sdkErrors to be set. */ + sdkResponse?: unknown[] | unknown | undefined; + /** Whether to show errors in the form. Requires sdkResponse to be set. */ enableDebugging?: boolean; + /** Optional OAuth app ID for app-specific account connections */ + oauthAppId?: string; }; ``` +## OAuth Configuration + +By default, apps use Pipedream OAuth clients. To configured your own, refer to the docs [here](https://pipedream.com/docs/connect/managed-auth/oauth-clients). + +### Using a custom OAuth client + +1. Create an OAuth app in your target service (e.g., Slack, Google, etc.) +2. Configure the client in Pipedream ([refer to the docs](https://pipedream.com/docs/connect/managed-auth/oauth-clients)) +3. Use the `oauthAppId` prop to specify which OAuth client to use for account connections + +```typescript + +``` + +When `oauthAppId` is provided, all app connections within that component form will use your specified OAuth app instead of Pipedream's default. + ## Customization Style individual components using the `CustomizeProvider` and a `CustomizationConfig`. @@ -164,7 +190,8 @@ Style individual components using the `CustomizeProvider` and a `CustomizationCo diff --git a/packages/connect-react/package.json b/packages/connect-react/package.json index 412efcbabae97..6c5429f534709 100644 --- a/packages/connect-react/package.json +++ b/packages/connect-react/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/connect-react", - "version": "1.3.0", + "version": "1.4.0", "description": "Pipedream Connect library for React", "files": [ "dist" diff --git a/packages/connect-react/src/components/ComponentForm.tsx b/packages/connect-react/src/components/ComponentForm.tsx index 2ebe0b2dbaabf..01420ae6936eb 100644 --- a/packages/connect-react/src/components/ComponentForm.tsx +++ b/packages/connect-react/src/components/ComponentForm.tsx @@ -8,6 +8,7 @@ import type { V1Component, } from "@pipedream/sdk"; import { InternalComponentForm } from "./InternalComponentForm"; +import { OAuthAppProvider } from "../hooks/oauth-app-context"; export type ComponentFormProps> = { /** @@ -29,15 +30,22 @@ export type ComponentFormProps(props: ComponentFormProps) { + const { + oauthAppId, ...formProps + } = props; + return ( - - - + + + + + ); } diff --git a/packages/connect-react/src/components/ComponentFormContainer.tsx b/packages/connect-react/src/components/ComponentFormContainer.tsx index d6e3dc51906c1..474a8c57c87cd 100644 --- a/packages/connect-react/src/components/ComponentFormContainer.tsx +++ b/packages/connect-react/src/components/ComponentFormContainer.tsx @@ -37,5 +37,9 @@ export function ComponentFormContainer(props: Compo } // TODO move / improve lib.ts and make sure V1Component and it match / are shared - return ; + const { + componentKey, ...componentFormProps + } = props; + void componentKey; // Mark as intentionally unused + return ; } diff --git a/packages/connect-react/src/components/ControlApp.tsx b/packages/connect-react/src/components/ControlApp.tsx index 0535ce881c00e..4fabfa374cacc 100644 --- a/packages/connect-react/src/components/ControlApp.tsx +++ b/packages/connect-react/src/components/ControlApp.tsx @@ -4,6 +4,7 @@ import { useAccounts } from "../hooks/use-accounts"; import { useFormFieldContext } from "../hooks/form-field-context"; import { useFormContext } from "../hooks/form-context"; import { useCustomize } from "../hooks/customization-context"; +import { useOAuthAppContext } from "../hooks/oauth-app-context"; import type { BaseReactSelectProps } from "../hooks/customization-context"; import { useMemo } from "react"; import type { CSSProperties } from "react"; @@ -30,6 +31,7 @@ type ControlAppProps = { export function ControlApp({ app }: ControlAppProps) { const client = useFrontendClient(); const { externalUserId } = useFormContext(); + const { oauthAppId } = useOAuthAppContext(); const formFieldCtx = useFormFieldContext(); const { id, prop, value, onChange, @@ -67,7 +69,6 @@ export function ControlApp({ app }: ControlAppProps) { }; const selectProps = select.getProps("controlAppSelect", baseSelectProps); - const oauthAppId = undefined; // XXX allow customizing const { isLoading: isLoadingAccounts, // TODO error @@ -75,7 +76,7 @@ export function ControlApp({ app }: ControlAppProps) { refetch: refetchAccounts, } = useAccounts( { - externalUserId, + external_user_id: externalUserId, app: app.name_slug, oauth_app_id: oauthAppId, }, diff --git a/packages/connect-react/src/hooks/oauth-app-context.tsx b/packages/connect-react/src/hooks/oauth-app-context.tsx new file mode 100644 index 0000000000000..7ef2bfb1a5e4e --- /dev/null +++ b/packages/connect-react/src/hooks/oauth-app-context.tsx @@ -0,0 +1,30 @@ +import { + createContext, useContext, ReactNode, +} from "react"; + +export type OAuthAppContextValue = { + oauthAppId?: string; +}; + +const OAuthAppContext = createContext({}); + +export const useOAuthAppContext = () => { + return useContext(OAuthAppContext); +}; + +export type OAuthAppProviderProps = { + children: ReactNode; + oauthAppId?: string; +}; + +export function OAuthAppProvider({ + children, oauthAppId, +}: OAuthAppProviderProps) { + return ( + + {children} + + ); +} diff --git a/packages/connect-react/src/index.ts b/packages/connect-react/src/index.ts index b8ff8968f8893..47304a111c527 100644 --- a/packages/connect-react/src/index.ts +++ b/packages/connect-react/src/index.ts @@ -26,6 +26,7 @@ export * from "./hooks/customization-context"; export * from "./hooks/form-context"; export * from "./hooks/form-field-context"; export * from "./hooks/frontend-client-context"; +export * from "./hooks/oauth-app-context"; export * from "./hooks/use-accounts"; export * from "./hooks/use-app"; export * from "./hooks/use-apps"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9f0834b2c1962..b1dabc27217e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10360,8 +10360,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/postmaster: - specifiers: {} + components/postmaster: {} components/power_automate: {}