Compare commits

..

1 Commits

411 changed files with 11631 additions and 20871 deletions

View File

@@ -130,7 +130,6 @@ When running with Docker, use `host.docker.internal` if vLLM is on your host mac
**Requirements:**
- [Bun](https://bun.sh/) runtime
- [Node.js](https://nodejs.org/) v20+ (required for sandboxed code execution)
- PostgreSQL 12+ with [pgvector extension](https://github.com/pgvector/pgvector) (required for AI embeddings)
**Note:** Sim uses vector embeddings for AI features like knowledge bases and semantic search, which requires the `pgvector` PostgreSQL extension.

View File

@@ -1,4 +1,3 @@
import type React from 'react'
import { findNeighbour } from 'fumadocs-core/page-tree'
import defaultMdxComponents from 'fumadocs-ui/mdx'
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page'
@@ -11,15 +10,14 @@ import { LLMCopyButton } from '@/components/page-actions'
import { StructuredData } from '@/components/structured-data'
import { CodeBlock } from '@/components/ui/code-block'
import { Heading } from '@/components/ui/heading'
import { type PageData, source } from '@/lib/source'
import { source } from '@/lib/source'
export default async function Page(props: { params: Promise<{ slug?: string[]; lang: string }> }) {
const params = await props.params
const page = source.getPage(params.slug, params.lang)
if (!page) notFound()
const data = page.data as PageData
const MDX = data.body
const MDX = page.data.body
const baseUrl = 'https://docs.sim.ai'
const pageTreeRecord = source.pageTree as Record<string, any>
@@ -53,7 +51,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
if (index === urlParts.length - 1) {
breadcrumbs.push({
name: data.title,
name: page.data.title,
url: `${baseUrl}${page.url}`,
})
} else {
@@ -170,15 +168,15 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
return (
<>
<StructuredData
title={data.title}
description={data.description || ''}
title={page.data.title}
description={page.data.description || ''}
url={`${baseUrl}${page.url}`}
lang={params.lang}
breadcrumb={breadcrumbs}
/>
<DocsPage
toc={data.toc}
full={data.full}
toc={page.data.toc}
full={page.data.full}
breadcrumb={{
enabled: false,
}}
@@ -209,32 +207,20 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
</div>
<PageNavigationArrows previous={neighbours?.previous} next={neighbours?.next} />
</div>
<DocsTitle>{data.title}</DocsTitle>
<DocsDescription>{data.description}</DocsDescription>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
</div>
<DocsBody>
<MDX
components={{
...defaultMdxComponents,
CodeBlock,
h1: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h1' {...props} />
),
h2: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h2' {...props} />
),
h3: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h3' {...props} />
),
h4: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h4' {...props} />
),
h5: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h5' {...props} />
),
h6: (props: React.HTMLAttributes<HTMLHeadingElement>) => (
<Heading as='h6' {...props} />
),
h1: (props) => <Heading as='h1' {...props} />,
h2: (props) => <Heading as='h2' {...props} />,
h3: (props) => <Heading as='h3' {...props} />,
h4: (props) => <Heading as='h4' {...props} />,
h5: (props) => <Heading as='h5' {...props} />,
h6: (props) => <Heading as='h6' {...props} />,
}}
/>
</DocsBody>
@@ -254,17 +240,13 @@ export async function generateMetadata(props: {
const page = source.getPage(params.slug, params.lang)
if (!page) notFound()
const data = page.data as PageData
const baseUrl = 'https://docs.sim.ai'
const fullUrl = `${baseUrl}${page.url}`
const description = data.description || ''
const ogImageUrl = `${baseUrl}/api/og?title=${encodeURIComponent(data.title)}&category=DOCUMENTATION${description ? `&description=${encodeURIComponent(description)}` : ''}`
return {
title: data.title,
title: page.data.title,
description:
data.description || 'Sim visual workflow builder for AI applications documentation',
page.data.description || 'Sim visual workflow builder for AI applications documentation',
keywords: [
'AI workflow builder',
'visual workflow editor',
@@ -273,16 +255,16 @@ export async function generateMetadata(props: {
'AI agents',
'no-code AI',
'drag and drop workflows',
data.title?.toLowerCase().split(' '),
page.data.title?.toLowerCase().split(' '),
]
.flat()
.filter(Boolean),
authors: [{ name: 'Sim Team' }],
category: 'Developer Tools',
openGraph: {
title: data.title,
title: page.data.title,
description:
data.description || 'Sim visual workflow builder for AI applications documentation',
page.data.description || 'Sim visual workflow builder for AI applications documentation',
url: fullUrl,
siteName: 'Sim Documentation',
type: 'article',
@@ -290,23 +272,12 @@ export async function generateMetadata(props: {
alternateLocale: ['en', 'es', 'fr', 'de', 'ja', 'zh']
.filter((lang) => lang !== params.lang)
.map((lang) => (lang === 'en' ? 'en_US' : `${lang}_${lang.toUpperCase()}`)),
images: [
{
url: ogImageUrl,
width: 1200,
height: 630,
alt: data.title,
},
],
},
twitter: {
card: 'summary_large_image',
title: data.title,
card: 'summary',
title: page.data.title,
description:
data.description || 'Sim visual workflow builder for AI applications documentation',
images: [ogImageUrl],
creator: '@simdotai',
site: '@simdotai',
page.data.description || 'Sim visual workflow builder for AI applications documentation',
},
robots: {
index: true,

View File

@@ -1,185 +0,0 @@
import { ImageResponse } from 'next/og'
import type { NextRequest } from 'next/server'
export const runtime = 'edge'
const TITLE_FONT_SIZE = {
large: 64,
medium: 56,
small: 48,
} as const
function getTitleFontSize(title: string): number {
if (title.length > 45) return TITLE_FONT_SIZE.small
if (title.length > 30) return TITLE_FONT_SIZE.medium
return TITLE_FONT_SIZE.large
}
/**
* Loads a Google Font dynamically by fetching the CSS and extracting the font URL.
*/
async function loadGoogleFont(font: string, weights: string, text: string): Promise<ArrayBuffer> {
const url = `https://fonts.googleapis.com/css2?family=${font}:wght@${weights}&text=${encodeURIComponent(text)}`
const css = await (await fetch(url)).text()
const resource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/)
if (resource) {
const response = await fetch(resource[1])
if (response.status === 200) {
return await response.arrayBuffer()
}
}
throw new Error('Failed to load font data')
}
/**
* Generates dynamic Open Graph images for documentation pages.
*/
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url)
const title = searchParams.get('title') || 'Documentation'
const category = searchParams.get('category') || 'DOCUMENTATION'
const description = searchParams.get('description') || ''
const baseUrl = new URL(request.url).origin
const allText = `${title}${category}${description}docs.sim.ai`
const fontData = await loadGoogleFont('Geist', '400;500;600', allText)
return new ImageResponse(
<div
style={{
height: '100%',
width: '100%',
display: 'flex',
flexDirection: 'column',
background: '#0c0c0c',
position: 'relative',
fontFamily: 'Geist',
}}
>
{/* Base gradient layer - very subtle purple tint across the entire image */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background:
'radial-gradient(ellipse 150% 100% at 50% 100%, rgba(88, 28, 135, 0.15) 0%, rgba(88, 28, 135, 0.08) 25%, rgba(88, 28, 135, 0.03) 50%, transparent 80%)',
display: 'flex',
}}
/>
{/* Secondary glow - adds depth without harsh edges */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background:
'radial-gradient(ellipse 100% 80% at 80% 90%, rgba(112, 31, 252, 0.12) 0%, rgba(112, 31, 252, 0.04) 40%, transparent 70%)',
display: 'flex',
}}
/>
{/* Top darkening - creates natural vignette */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
background:
'linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, transparent 40%, transparent 100%)',
display: 'flex',
}}
/>
{/* Content */}
<div
style={{
display: 'flex',
flexDirection: 'column',
padding: '56px 72px',
height: '100%',
justifyContent: 'space-between',
}}
>
{/* Logo */}
<img src={`${baseUrl}/static/logo.png`} alt='sim' height={32} />
{/* Category + Title + Description */}
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: 12,
}}
>
<span
style={{
fontSize: 15,
fontWeight: 600,
color: '#802fff',
letterSpacing: '0.02em',
}}
>
{category}
</span>
<span
style={{
fontSize: getTitleFontSize(title),
fontWeight: 600,
color: '#ffffff',
lineHeight: 1.1,
letterSpacing: '-0.02em',
}}
>
{title}
</span>
{description && (
<span
style={{
fontSize: 18,
fontWeight: 400,
color: '#a1a1aa',
lineHeight: 1.4,
marginTop: 4,
}}
>
{description.length > 100 ? `${description.slice(0, 100)}...` : description}
</span>
)}
</div>
{/* Footer */}
<span
style={{
fontSize: 15,
fontWeight: 500,
color: '#52525b',
}}
>
docs.sim.ai
</span>
</div>
</div>,
{
width: 1200,
height: 630,
fonts: [
{
name: 'Geist',
data: fontData,
style: 'normal',
},
],
}
)
}

View File

@@ -56,14 +56,6 @@ export const metadata = {
title: 'Sim Documentation - Visual Workflow Builder for AI Applications',
description:
'Comprehensive documentation for Sim - the visual workflow builder for AI applications. Create powerful AI agents, automation workflows, and data processing pipelines.',
images: [
{
url: 'https://docs.sim.ai/api/og?title=Sim%20Documentation&category=DOCUMENTATION',
width: 1200,
height: 630,
alt: 'Sim Documentation',
},
],
},
twitter: {
card: 'summary_large_image',
@@ -72,7 +64,7 @@ export const metadata = {
'Comprehensive documentation for Sim - the visual workflow builder for AI applications.',
creator: '@simdotai',
site: '@simdotai',
images: ['https://docs.sim.ai/api/og?title=Sim%20Documentation&category=DOCUMENTATION'],
images: ['/og-image.png'],
},
robots: {
index: true,

View File

@@ -2452,56 +2452,6 @@ export const GeminiIcon = (props: SVGProps<SVGSVGElement>) => (
</svg>
)
export const VertexIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
{...props}
id='standard_product_icon'
xmlns='http://www.w3.org/2000/svg'
version='1.1'
viewBox='0 0 512 512'
>
<g id='bounding_box'>
<rect width='512' height='512' fill='none' />
</g>
<g id='art'>
<path
d='M128,244.99c-8.84,0-16-7.16-16-16v-95.97c0-8.84,7.16-16,16-16s16,7.16,16,16v95.97c0,8.84-7.16,16-16,16Z'
fill='#ea4335'
/>
<path
d='M256,458c-2.98,0-5.97-.83-8.59-2.5l-186-122c-7.46-4.74-9.65-14.63-4.91-22.09,4.75-7.46,14.64-9.65,22.09-4.91l177.41,116.53,177.41-116.53c7.45-4.74,17.34-2.55,22.09,4.91,4.74,7.46,2.55,17.34-4.91,22.09l-186,122c-2.62,1.67-5.61,2.5-8.59,2.5Z'
fill='#fbbc04'
/>
<path
d='M256,388.03c-8.84,0-16-7.16-16-16v-73.06c0-8.84,7.16-16,16-16s16,7.16,16,16v73.06c0,8.84-7.16,16-16,16Z'
fill='#34a853'
/>
<circle cx='128' cy='70' r='16' fill='#ea4335' />
<circle cx='128' cy='292' r='16' fill='#ea4335' />
<path
d='M384.23,308.01c-8.82,0-15.98-7.14-16-15.97l-.23-94.01c-.02-8.84,7.13-16.02,15.97-16.03h.04c8.82,0,15.98,7.14,16,15.97l.23,94.01c.02,8.84-7.13,16.02-15.97,16.03h-.04Z'
fill='#4285f4'
/>
<circle cx='384' cy='70' r='16' fill='#4285f4' />
<circle cx='384' cy='134' r='16' fill='#4285f4' />
<path
d='M320,220.36c-8.84,0-16-7.16-16-16v-103.02c0-8.84,7.16-16,16-16s16,7.16,16,16v103.02c0,8.84-7.16,16-16,16Z'
fill='#fbbc04'
/>
<circle cx='256' cy='171' r='16' fill='#34a853' />
<circle cx='256' cy='235' r='16' fill='#34a853' />
<circle cx='320' cy='265' r='16' fill='#fbbc04' />
<circle cx='320' cy='329' r='16' fill='#fbbc04' />
<path
d='M192,217.36c-8.84,0-16-7.16-16-16v-100.02c0-8.84,7.16-16,16-16s16,7.16,16,16v100.02c0,8.84-7.16,16-16,16Z'
fill='#fbbc04'
/>
<circle cx='192' cy='265' r='16' fill='#fbbc04' />
<circle cx='192' cy='329' r='16' fill='#fbbc04' />
</g>
</svg>
)
export const CerebrasIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
{...props}
@@ -3385,21 +3335,6 @@ export function SalesforceIcon(props: SVGProps<SVGSVGElement>) {
)
}
export function ServiceNowIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 71.1 63.6'>
<path
fillRule='evenodd'
clipRule='evenodd'
fill='#62D84E'
d='M35.8,0C16.1,0,0,15.9,0,35.6c0,9.8,4,19.3,11.2,26c2.5,2.4,6.4,2.6,9.2,0.5c9-6.7,21.4-6.7,30.4,0
c2.8,2.1,6.7,1.9,9.2-0.5C74.3,48,74.9,25.4,61.3,11.1C54.7,4.1,45.4,0.1,35.8,0 M35.6,53.5C26,53.8,18,46.2,17.8,36.7
c0-0.3,0-0.6,0-0.9c0-9.8,8-17.8,17.8-17.8s17.8,8,17.8,17.8c0.3,9.6-7.3,17.5-16.8,17.8C36.2,53.5,35.9,53.5,35.6,53.5'
/>
</svg>
)
}
export function ApolloIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg

View File

@@ -85,7 +85,6 @@ import {
SendgridIcon,
SentryIcon,
SerperIcon,
ServiceNowIcon,
SftpIcon,
ShopifyIcon,
SlackIcon,
@@ -153,7 +152,6 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
shopify: ShopifyIcon,
sharepoint: MicrosoftSharepointIcon,
sftp: SftpIcon,
servicenow: ServiceNowIcon,
serper: SerperIcon,
sentry: SentryIcon,
sendgrid: SendgridIcon,

View File

@@ -111,24 +111,26 @@ Verschiedene Blocktypen erzeugen unterschiedliche Ausgabestrukturen. Hier ist, w
```json
{
"content": "Original content passed through",
"conditionResult": true,
"selectedPath": {
"blockId": "2acd9007-27e8-4510-a487-73d3b825e7c1",
"blockType": "agent",
"blockTitle": "Follow-up Agent"
},
"selectedOption": "condition-1"
"selectedConditionId": "condition-1"
}
```
### Ausgabefelder des Condition-Blocks
- **content**: Der ursprüngliche, durchgeleitete Inhalt
- **conditionResult**: Boolesches Ergebnis der Bedingungsauswertung
- **selectedPath**: Informationen über den ausgewählten Pfad
- **blockId**: ID des nächsten Blocks im ausgewählten Pfad
- **blockType**: Typ des nächsten Blocks
- **blockTitle**: Titel des nächsten Blocks
- **selectedOption**: ID der ausgewählten Bedingung
- **selectedConditionId**: ID der ausgewählten Bedingung
</Tab>
<Tab>

View File

@@ -48,13 +48,8 @@ Ruft detaillierte Informationen zu einem bestimmten Jira-Issue ab
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key \(z.B. PROJ-123\) |
| `summary` | string | Issue-Zusammenfassung |
| `description` | json | Inhalt der Issue-Beschreibung |
| `created` | string | Zeitstempel der Issue-Erstellung |
| `updated` | string | Zeitstempel der letzten Issue-Aktualisierung |
| `issue` | json | Vollständiges Issue-Objekt mit allen Feldern |
| `success` | boolean | Status des Operationserfolgs |
| `output` | object | Jira-Issue-Details mit Issue-Key, Zusammenfassung, Beschreibung, Erstellungs- und Aktualisierungszeitstempeln |
### `jira_update`
@@ -78,9 +73,8 @@ Ein Jira-Issue aktualisieren
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Aktualisierter Issue-Key \(z.B. PROJ-123\) |
| `summary` | string | Issue-Zusammenfassung nach der Aktualisierung |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Aktualisierte Jira-Issue-Details mit Zeitstempel, Issue-Key, Zusammenfassung und Erfolgsstatus |
### `jira_write`
@@ -103,10 +97,8 @@ Ein Jira-Issue erstellen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Erstellter Issue-Key \(z.B. PROJ-123\) |
| `summary` | string | Issue-Zusammenfassung |
| `url` | string | URL zum erstellten Issue |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Erstellte Jira-Issue-Details mit Zeitstempel, Issue-Key, Zusammenfassung, Erfolgsstatus und URL |
### `jira_bulk_read`
@@ -124,7 +116,8 @@ Mehrere Jira-Issues in Masse abrufen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `issues` | array | Array von Jira-Issues mit Zeitstempel, Zusammenfassung, Beschreibung, Erstellungs- und Aktualisierungszeitstempeln |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | array | Array von Jira-Issues mit Zusammenfassung, Beschreibung, Erstellungs- und Aktualisierungszeitstempeln |
### `jira_delete_issue`
@@ -143,8 +136,8 @@ Ein Jira-Issue löschen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Gelöschter Issue-Key |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Details zum gelöschten Issue mit Zeitstempel, Issue-Key und Erfolgsstatus |
### `jira_assign_issue`
@@ -163,9 +156,8 @@ Ein Jira-Issue einem Benutzer zuweisen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key, der zugewiesen wurde |
| `assigneeId` | string | Konto-ID des Bearbeiters |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Zuweisungsdetails mit Zeitstempel, Issue-Key, Bearbeiter-ID und Erfolgsstatus |
### `jira_transition_issue`
@@ -185,9 +177,8 @@ Ein Jira-Issue zwischen Workflow-Status verschieben (z.B. To Do -> In Progress)
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key, der übergangen wurde |
| `transitionId` | string | Angewendete Übergangs-ID |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Übergangsdetails mit Zeitstempel, Issue-Key, Übergangs-ID und Erfolgsstatus |
### `jira_search_issues`
@@ -208,11 +199,8 @@ Nach Jira-Issues mit JQL (Jira Query Language) suchen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `total` | number | Gesamtanzahl der übereinstimmenden Issues |
| `startAt` | number | Paginierungsstartindex |
| `maxResults` | number | Maximale Ergebnisse pro Seite |
| `issues` | array | Array übereinstimmender Issues mit Key, Zusammenfassung, Status, Bearbeiter, Erstellungs- und Aktualisierungsdatum |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Suchergebnisse mit Zeitstempel, Gesamtanzahl, Paginierungsdetails und Array der übereinstimmenden Issues |
### `jira_add_comment`
@@ -231,10 +219,8 @@ Einen Kommentar zu einem Jira-Issue hinzufügen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key, zu dem der Kommentar hinzugefügt wurde |
| `commentId` | string | Erstellte Kommentar-ID |
| `body` | string | Kommentartextinhalt |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Kommentardetails mit Zeitstempel, Issue-Key, Kommentar-ID, Inhalt und Erfolgsstatus |
### `jira_get_comments`
@@ -254,10 +240,8 @@ Alle Kommentare eines Jira-Issues abrufen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `total` | number | Gesamtanzahl der Kommentare |
| `comments` | array | Array von Kommentaren mit ID, Autor, Inhalt, Erstellungs- und Aktualisierungsdatum |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Kommentardaten mit Zeitstempel, Issue-Key, Gesamtanzahl und Array von Kommentaren |
### `jira_update_comment`
@@ -277,10 +261,8 @@ Einen bestehenden Kommentar zu einem Jira-Issue aktualisieren
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `commentId` | string | Aktualisierte Kommentar-ID |
| `body` | string | Aktualisierter Kommentartext |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Aktualisierte Kommentardetails mit Zeitstempel, Issue-Key, Kommentar-ID, Textinhalt und Erfolgsstatus |
### `jira_delete_comment`
@@ -299,9 +281,8 @@ Einen Kommentar aus einem Jira-Issue löschen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `commentId` | string | ID des gelöschten Kommentars |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Löschdetails mit Zeitstempel, Issue-Key, Kommentar-ID und Erfolgsstatus |
### `jira_get_attachments`
@@ -319,9 +300,8 @@ Alle Anhänge eines Jira-Issues abrufen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `attachments` | array | Array von Anhängen mit ID, Dateiname, Größe, MIME-Typ, Erstellungsdatum und Autor |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Anhangsdaten mit Zeitstempel, Issue-Key und Array von Anhängen |
### `jira_delete_attachment`
@@ -339,8 +319,8 @@ Einen Anhang von einem Jira-Issue löschen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `attachmentId` | string | ID des gelöschten Anhangs |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Löschdetails mit Zeitstempel, Anhangs-ID und Erfolgsstatus |
### `jira_add_worklog`
@@ -361,10 +341,8 @@ Einen Zeiterfassungseintrag zu einem Jira-Issue hinzufügen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key, zu dem der Worklog hinzugefügt wurde |
| `worklogId` | string | ID des erstellten Worklogs |
| `timeSpentSeconds` | number | Aufgewendete Zeit in Sekunden |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Worklog-Details mit Zeitstempel, Issue-Key, Worklog-ID, aufgewendeter Zeit in Sekunden und Erfolgsstatus |
### `jira_get_worklogs`
@@ -384,10 +362,8 @@ Alle Worklog-Einträge eines Jira-Issues abrufen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `total` | number | Gesamtanzahl der Worklogs |
| `worklogs` | array | Array von Worklogs mit ID, Autor, aufgewendeter Zeit in Sekunden, aufgewendeter Zeit, Kommentar, Erstellungs-, Aktualisierungs- und Startdatum |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Worklog-Daten mit Zeitstempel, Issue-Key, Gesamtanzahl und Array von Worklogs |
### `jira_update_worklog`
@@ -409,9 +385,8 @@ Aktualisieren eines vorhandenen Worklog-Eintrags in einem Jira-Issue
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `worklogId` | string | ID des aktualisierten Worklogs |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Worklog-Aktualisierungsdetails mit Zeitstempel, Issue-Key, Worklog-ID und Erfolgsstatus |
### `jira_delete_worklog`
@@ -430,9 +405,8 @@ Löschen eines Worklog-Eintrags aus einem Jira-Issue
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `worklogId` | string | ID des gelöschten Worklogs |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Löschdetails mit Zeitstempel, Issue-Key, Worklog-ID und Erfolgsstatus |
### `jira_create_issue_link`
@@ -453,11 +427,8 @@ Eine Verknüpfungsbeziehung zwischen zwei Jira-Issues erstellen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `inwardIssue` | string | Key des eingehenden Issues |
| `outwardIssue` | string | Key des ausgehenden Issues |
| `linkType` | string | Art der Issue-Verknüpfung |
| `linkId` | string | ID der erstellten Verknüpfung |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Issue-Verknüpfungsdetails mit Zeitstempel, eingehendem Issue-Key, ausgehendem Issue-Key, Verknüpfungstyp und Erfolgsstatus |
### `jira_delete_issue_link`
@@ -475,8 +446,8 @@ Eine Verknüpfung zwischen zwei Jira-Issues löschen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `linkId` | string | ID der gelöschten Verknüpfung |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Löschdetails mit Zeitstempel, Link-ID und Erfolgsstatus |
### `jira_add_watcher`
@@ -495,9 +466,8 @@ Einen Beobachter zu einem Jira-Issue hinzufügen, um Benachrichtigungen über Ak
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `watcherAccountId` | string | Account-ID des hinzugefügten Beobachters |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Beobachterdetails mit Zeitstempel, Issue-Key, Beobachter-Account-ID und Erfolgsstatus |
### `jira_remove_watcher`
@@ -516,9 +486,8 @@ Einen Beobachter von einem Jira-Issue entfernen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `ts` | string | Zeitstempel der Operation |
| `issueKey` | string | Issue-Key |
| `watcherAccountId` | string | Account-ID des entfernten Beobachters |
| `success` | boolean | Erfolgsstatus der Operation |
| `output` | object | Entfernungsdetails mit Zeitstempel, Issue-Key, Beobachter-Konto-ID und Erfolgsstatus |
## Hinweise

View File

@@ -1,124 +0,0 @@
---
title: ServiceNow
description: ServiceNow-Datensätze erstellen, lesen, aktualisieren und löschen
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="servicenow"
color="#032D42"
/>
{/* MANUAL-CONTENT-START:intro */}
[ServiceNow](https://www.servicenow.com/) ist eine leistungsstarke Cloud-Plattform zur Optimierung und Automatisierung von IT-Service-Management (ITSM), Workflows und Geschäftsprozessen in Ihrem Unternehmen. ServiceNow ermöglicht Ihnen die Verwaltung von Vorfällen, Anfragen, Aufgaben, Benutzern und mehr über seine umfangreiche API.
Mit ServiceNow können Sie:
- **IT-Workflows automatisieren**: Datensätze in jeder ServiceNow-Tabelle erstellen, lesen, aktualisieren und löschen, z. B. Vorfälle, Aufgaben, Änderungsanfragen und Benutzer.
- **Systeme integrieren**: ServiceNow mit Ihren anderen Tools und Prozessen für nahtlose Automatisierung verbinden.
- **Eine einzige Informationsquelle pflegen**: Alle Ihre Service- und Betriebsdaten organisiert und zugänglich halten.
- **Betriebliche Effizienz steigern**: Manuelle Arbeit reduzieren und Servicequalität mit anpassbaren Workflows und Automatisierung verbessern.
In Sim ermöglicht die ServiceNow-Integration Ihren Agenten, direkt mit Ihrer ServiceNow-Instanz als Teil ihrer Workflows zu interagieren. Agenten können Datensätze in jeder ServiceNow-Tabelle erstellen, lesen, aktualisieren oder löschen und Ticket- oder Benutzerdaten für ausgefeilte Automatisierung und Entscheidungsfindung nutzen. Diese Integration verbindet Ihre Workflow-Automatisierung und IT-Betrieb und befähigt Ihre Agenten, Serviceanfragen, Vorfälle, Benutzer und Assets ohne manuelle Eingriffe zu verwalten. Durch die Verbindung von Sim mit ServiceNow können Sie Service-Management-Aufgaben automatisieren, Reaktionszeiten verbessern und konsistenten, sicheren Zugriff auf die wichtigen Servicedaten Ihres Unternehmens gewährleisten.
{/* MANUAL-CONTENT-END */}
## Nutzungsanweisungen
Integrieren Sie ServiceNow in Ihren Workflow. Erstellen, lesen, aktualisieren und löschen Sie Datensätze in jeder ServiceNow-Tabelle, einschließlich Vorfälle, Aufgaben, Änderungsanfragen, Benutzer und mehr.
## Tools
### `servicenow_create_record`
Einen neuen Datensatz in einer ServiceNow-Tabelle erstellen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Ja | ServiceNow-Instanz-URL \(z. B. https://instance.service-now.com\) |
| `username` | string | Ja | ServiceNow-Benutzername |
| `password` | string | Ja | ServiceNow-Passwort |
| `tableName` | string | Ja | Tabellenname \(z. B. incident, task, sys_user\) |
| `fields` | json | Ja | Felder, die für den Datensatz festgelegt werden sollen \(JSON-Objekt\) |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `record` | json | Erstellter ServiceNow-Datensatz mit sys_id und anderen Feldern |
| `metadata` | json | Metadaten der Operation |
### `servicenow_read_record`
Datensätze aus einer ServiceNow-Tabelle lesen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Ja | ServiceNow-Instanz-URL \(z. B. https://instance.service-now.com\) |
| `username` | string | Ja | ServiceNow-Benutzername |
| `password` | string | Ja | ServiceNow-Passwort |
| `tableName` | string | Ja | Tabellenname |
| `sysId` | string | Nein | Spezifische Datensatz-sys_id |
| `number` | string | Nein | Datensatznummer \(z. B. INC0010001\) |
| `query` | string | Nein | Kodierte Abfragezeichenfolge \(z. B. "active=true^priority=1"\) |
| `limit` | number | Nein | Maximale Anzahl der zurückzugebenden Datensätze |
| `fields` | string | Nein | Durch Kommas getrennte Liste der zurückzugebenden Felder |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `records` | array | Array von ServiceNow-Datensätzen |
| `metadata` | json | Metadaten der Operation |
### `servicenow_update_record`
Einen bestehenden Datensatz in einer ServiceNow-Tabelle aktualisieren
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Ja | ServiceNow-Instanz-URL \(z. B. https://instance.service-now.com\) |
| `username` | string | Ja | ServiceNow-Benutzername |
| `password` | string | Ja | ServiceNow-Passwort |
| `tableName` | string | Ja | Tabellenname |
| `sysId` | string | Ja | Datensatz-sys_id zum Aktualisieren |
| `fields` | json | Ja | Zu aktualisierende Felder \(JSON-Objekt\) |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `record` | json | Aktualisierter ServiceNow-Datensatz |
| `metadata` | json | Metadaten der Operation |
### `servicenow_delete_record`
Einen Datensatz aus einer ServiceNow-Tabelle löschen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Ja | ServiceNow-Instanz-URL \(z. B. https://instance.service-now.com\) |
| `username` | string | Ja | ServiceNow-Benutzername |
| `password` | string | Ja | ServiceNow-Passwort |
| `tableName` | string | Ja | Tabellenname |
| `sysId` | string | Ja | Datensatz-sys_id zum Löschen |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `success` | boolean | Ob das Löschen erfolgreich war |
| `metadata` | json | Metadaten der Operation |
## Hinweise
- Kategorie: `tools`
- Typ: `servicenow`

View File

@@ -54,7 +54,7 @@ Integriert Slack in den Workflow. Kann Nachrichten senden, aktualisieren und lö
### `slack_message`
Sende Nachrichten an Slack-Kanäle oder Direktnachrichten. Unterstützt Slack mrkdwn-Formatierung.
Senden Sie Nachrichten an Slack-Kanäle oder Benutzer über die Slack-API. Unterstützt Slack mrkdwn-Formatierung.
#### Eingabe
@@ -62,9 +62,8 @@ Sende Nachrichten an Slack-Kanäle oder Direktnachrichten. Unterstützt Slack mr
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | Nein | Authentifizierungsmethode: oauth oder bot_token |
| `botToken` | string | Nein | Bot-Token für benutzerdefinierten Bot |
| `channel` | string | Nein | Ziel-Slack-Kanal \(z.B. #general\) |
| `userId` | string | Nein | Ziel-Slack-Benutzer-ID für Direktnachrichten \(z.B. U1234567890\) |
| `text` | string | Ja | Zu sendender Nachrichtentext \(unterstützt Slack mrkdwn-Formatierung\) |
| `channel` | string | Ja | Ziel-Slack-Kanal \(z.B. #general\) |
| `text` | string | Ja | Nachrichtentext zum Senden \(unterstützt Slack mrkdwn-Formatierung\) |
| `thread_ts` | string | Nein | Thread-Zeitstempel für Antworten \(erstellt Thread-Antwort\) |
| `files` | file[] | Nein | Dateien, die an die Nachricht angehängt werden sollen |
@@ -110,11 +109,10 @@ Lesen Sie die neuesten Nachrichten aus Slack-Kanälen. Rufen Sie den Konversatio
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | Nein | Authentifizierungsmethode: oauth oder bot_token |
| `botToken` | string | Nein | Bot-Token für benutzerdefinierten Bot |
| `channel` | string | Nein | Slack-Kanal, aus dem Nachrichten gelesen werden sollen \(z.B. #general\) |
| `userId` | string | Nein | Benutzer-ID für DM-Konversation \(z.B. U1234567890\) |
| `limit` | number | Nein | Anzahl der abzurufenden Nachrichten \(Standard: 10, max: 100\) |
| `oldest` | string | Nein | Beginn des Zeitraums \(Zeitstempel\) |
| `latest` | string | Nein | Ende des Zeitraums \(Zeitstempel\) |
| `channel` | string | Ja | Slack-Kanal, aus dem Nachrichten gelesen werden sollen (z.B. #general) |
| `limit` | number | Nein | Anzahl der abzurufenden Nachrichten (Standard: 10, max: 100) |
| `oldest` | string | Nein | Beginn des Zeitraums (Zeitstempel) |
| `latest` | string | Nein | Ende des Zeitraums (Zeitstempel) |
#### Ausgabe

View File

@@ -39,16 +39,14 @@ Senden Sie eine Chat-Completion-Anfrage an jeden unterstützten LLM-Anbieter
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `model` | string | Ja | Das zu verwendende Modell \(z. B. gpt-4o, claude-sonnet-4-5, gemini-2.0-flash\) |
| `systemPrompt` | string | Nein | System-Prompt zur Festlegung des Verhaltens des Assistenten |
| `context` | string | Ja | Die Benutzernachricht oder der Kontext, der an das Modell gesendet werden soll |
| `apiKey` | string | Nein | API-Schlüssel für den Anbieter \(verwendet Plattform-Schlüssel, falls nicht für gehostete Modelle angegeben\) |
| `temperature` | number | Nein | Temperatur für die Antwortgenerierung \(0-2\) |
| `maxTokens` | number | Nein | Maximale Anzahl von Tokens in der Antwort |
| `model` | string | Ja | Das zu verwendende Modell (z.B. gpt-4o, claude-sonnet-4-5, gemini-2.0-flash) |
| `systemPrompt` | string | Nein | System-Prompt zur Festlegung des Assistentenverhaltens |
| `context` | string | Ja | Die Benutzernachricht oder der Kontext, der an das Modell gesendet wird |
| `apiKey` | string | Nein | API-Schlüssel für den Anbieter (verwendet den Plattformschlüssel, wenn für gehostete Modelle nicht angegeben) |
| `temperature` | number | Nein | Temperatur für die Antwortgenerierung (0-2) |
| `maxTokens` | number | Nein | Maximale Tokens in der Antwort |
| `azureEndpoint` | string | Nein | Azure OpenAI-Endpunkt-URL |
| `azureApiVersion` | string | Nein | Azure OpenAI-API-Version |
| `vertexProject` | string | Nein | Google Cloud-Projekt-ID für Vertex AI |
| `vertexLocation` | string | Nein | Google Cloud-Standort für Vertex AI \(Standard: us-central1\) |
| `azureApiVersion` | string | Nein | Azure OpenAI API-Version |
#### Ausgabe

View File

@@ -39,10 +39,9 @@ Alle Elemente aus einer Webflow CMS-Sammlung auflisten
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Ja | ID der Webflow-Website |
| `collectionId` | string | Ja | ID der Sammlung |
| `offset` | number | Nein | Offset für Paginierung (optional) |
| `limit` | number | Nein | Maximale Anzahl der zurückzugebenden Elemente (optional, Standard: 100) |
| `offset` | number | Nein | Offset für Paginierung \(optional\) |
| `limit` | number | Nein | Maximale Anzahl der zurückzugebenden Elemente \(optional, Standard: 100\) |
#### Ausgabe
@@ -59,7 +58,6 @@ Ein einzelnes Element aus einer Webflow CMS-Sammlung abrufen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Ja | ID der Webflow-Website |
| `collectionId` | string | Ja | ID der Sammlung |
| `itemId` | string | Ja | ID des abzurufenden Elements |
@@ -78,9 +76,8 @@ Ein neues Element in einer Webflow CMS-Sammlung erstellen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Ja | ID der Webflow-Website |
| `collectionId` | string | Ja | ID der Sammlung |
| `fieldData` | json | Ja | Felddaten für das neue Element als JSON-Objekt. Schlüssel sollten mit den Sammlungsfeldnamen übereinstimmen. |
| `fieldData` | json | Ja | Felddaten für das neue Element als JSON-Objekt. Die Schlüssel sollten mit den Feldnamen der Sammlung übereinstimmen. |
#### Ausgabe
@@ -97,7 +94,6 @@ Ein vorhandenes Element in einer Webflow CMS-Sammlung aktualisieren
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Ja | ID der Webflow-Website |
| `collectionId` | string | Ja | ID der Sammlung |
| `itemId` | string | Ja | ID des zu aktualisierenden Elements |
| `fieldData` | json | Ja | Zu aktualisierende Felddaten als JSON-Objekt. Nur Felder einschließen, die geändert werden sollen. |
@@ -117,7 +113,6 @@ Ein Element aus einer Webflow CMS-Sammlung löschen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Ja | ID der Webflow-Website |
| `collectionId` | string | Ja | ID der Sammlung |
| `itemId` | string | Ja | ID des zu löschenden Elements |

View File

@@ -27,14 +27,12 @@ In Sim ermöglicht die Zoom-Integration Ihren Agenten die Automatisierung der Pl
- Details oder Einladungen für jedes Meeting abzurufen
- Bestehende Meetings direkt aus Ihren Automatisierungen zu aktualisieren oder zu löschen
Um eine Verbindung zu Zoom herzustellen, fügen Sie den Zoom-Block ein und klicken Sie auf `Connect`, um sich mit Ihrem Zoom-Konto zu authentifizieren. Nach der Verbindung können Sie die Zoom-Tools verwenden, um Zoom-Meetings zu erstellen, aufzulisten, zu aktualisieren und zu löschen. Sie können Ihr Zoom-Konto jederzeit trennen, indem Sie unter Einstellungen > Integrationen auf `Disconnect` klicken, und der Zugriff auf Ihr Zoom-Konto wird sofort widerrufen.
Diese Funktionen ermöglichen es Ihnen, die Zusammenarbeit aus der Ferne zu optimieren, wiederkehrende Videositzungen zu automatisieren und die Zoom-Umgebung Ihrer Organisation als Teil Ihrer Workflows zu verwalten.
Diese Funktionen ermöglichen es Ihnen, die Remote-Zusammenarbeit zu optimieren, wiederkehrende Videositzungen zu automatisieren und die Zoom-Umgebung Ihrer Organisation als Teil Ihrer Workflows zu verwalten.
{/* MANUAL-CONTENT-END */}
## Gebrauchsanweisung
## Nutzungsanleitung
Integrieren Sie Zoom in Workflows. Erstellen, listen, aktualisieren und löschen Sie Zoom-Meetings. Erhalten Sie Meeting-Details, Einladungen, Aufzeichnungen und Teilnehmerinformationen. Verwalten Sie Cloud-Aufzeichnungen programmatisch.
Integrieren Sie Zoom in Workflows. Erstellen, listen, aktualisieren und löschen Sie Zoom-Meetings. Rufen Sie Meeting-Details, Einladungen, Aufzeichnungen und Teilnehmer ab. Verwalten Sie Cloud-Aufzeichnungen programmgesteuert.
## Tools
@@ -51,7 +49,7 @@ Ein neues Zoom-Meeting erstellen
| `type` | number | Nein | Meeting-Typ: 1=sofort, 2=geplant, 3=wiederkehrend ohne feste Zeit, 8=wiederkehrend mit fester Zeit |
| `startTime` | string | Nein | Meeting-Startzeit im ISO 8601-Format \(z.B. 2025-06-03T10:00:00Z\) |
| `duration` | number | Nein | Meeting-Dauer in Minuten |
| `timezone` | string | Nein | Zeitzone für das Meeting \(z.B. America/Los_Angeles\) |
| `timezone` | string | Nein | Zeitzone für das Meeting \(z.B. Europe/Berlin\) |
| `password` | string | Nein | Meeting-Passwort |
| `agenda` | string | Nein | Meeting-Agenda |
| `hostVideo` | boolean | Nein | Mit eingeschaltetem Host-Video starten |
@@ -61,7 +59,7 @@ Ein neues Zoom-Meeting erstellen
| `waitingRoom` | boolean | Nein | Warteraum aktivieren |
| `autoRecording` | string | Nein | Automatische Aufzeichnungseinstellung: local, cloud oder none |
#### Ausgabe
#### Output
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
@@ -69,18 +67,18 @@ Ein neues Zoom-Meeting erstellen
### `zoom_list_meetings`
Alle Meetings für einen Zoom-Benutzer auflisten
Alle Meetings eines Zoom-Benutzers auflisten
#### Eingabe
#### Input
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Ja | Die Benutzer-ID oder E-Mail-Adresse. Verwenden Sie "me" für den authentifizierten Benutzer. |
| `type` | string | Nein | Meeting-Typ-Filter: scheduled, live, upcoming, upcoming_meetings oder previous_meetings |
| `pageSize` | number | Nein | Anzahl der Datensätze pro Seite \(max. 300\) |
| `pageSize` | number | Nein | Anzahl der Datensätze pro Seite (max. 300) |
| `nextPageToken` | string | Nein | Token für Paginierung, um die nächste Ergebnisseite zu erhalten |
#### Ausgabe
#### Output
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
@@ -91,7 +89,7 @@ Alle Meetings für einen Zoom-Benutzer auflisten
Details eines bestimmten Zoom-Meetings abrufen
#### Eingabe
#### Input
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
@@ -99,13 +97,13 @@ Details eines bestimmten Zoom-Meetings abrufen
| `occurrenceId` | string | Nein | Vorkommnis-ID für wiederkehrende Meetings |
| `showPreviousOccurrences` | boolean | Nein | Frühere Vorkommnisse für wiederkehrende Meetings anzeigen |
#### Ausgabe
#### Output
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `meeting` | object | Die Meeting-Details |
Details eines bestimmten Zoom-Meetings abrufen
### `zoom_update_meeting`
Ein bestehendes Zoom-Meeting aktualisieren
@@ -118,11 +116,11 @@ Ein bestehendes Zoom-Meeting aktualisieren
| `type` | number | Nein | Meeting-Typ: 1=sofort, 2=geplant, 3=wiederkehrend ohne feste Zeit, 8=wiederkehrend mit fester Zeit |
| `startTime` | string | Nein | Meeting-Startzeit im ISO 8601-Format \(z.B. 2025-06-03T10:00:00Z\) |
| `duration` | number | Nein | Meeting-Dauer in Minuten |
| `timezone` | string | Nein | Zeitzone für das Meeting \(z.B. Europe/Berlin\) |
| `timezone` | string | Nein | Zeitzone für das Meeting \(z.B. America/Los_Angeles\) |
| `password` | string | Nein | Meeting-Passwort |
| `agenda` | string | Nein | Meeting-Agenda |
| `hostVideo` | boolean | Nein | Mit eingeschaltetem Host-Video starten |
| `participantVideo` | boolean | Nein | Mit eingeschaltetem Teilnehmer-Video starten |
| `hostVideo` | boolean | Nein | Mit eingeschalteter Host-Kamera starten |
| `participantVideo` | boolean | Nein | Mit eingeschalteter Teilnehmer-Kamera starten |
| `joinBeforeHost` | boolean | Nein | Teilnehmern erlauben, vor dem Host beizutreten |
| `muteUponEntry` | boolean | Nein | Teilnehmer beim Betreten stummschalten |
| `waitingRoom` | boolean | Nein | Warteraum aktivieren |
@@ -134,7 +132,7 @@ Ein bestehendes Zoom-Meeting aktualisieren
| --------- | ---- | ----------- |
| `success` | boolean | Ob das Meeting erfolgreich aktualisiert wurde |
Ein Zoom-Meeting löschen
### `zoom_delete_meeting`
Ein Zoom-Meeting löschen oder abbrechen
@@ -143,9 +141,9 @@ Ein Zoom-Meeting löschen oder abbrechen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Ja | Die zu löschende Meeting-ID |
| `occurrenceId` | string | Nein | Occurrence-ID zum Löschen eines bestimmten Termins eines wiederkehrenden Meetings |
| `occurrenceId` | string | Nein | Vorkommnis-ID zum Löschen eines bestimmten Vorkommnisses eines wiederkehrenden Meetings |
| `scheduleForReminder` | boolean | Nein | Erinnerungs-E-Mail zur Stornierung an Teilnehmer senden |
| `cancelMeetingReminder` | boolean | Nein | Stornierungs-E-Mail an Teilnehmer und alternative Hosts senden |
| `cancelMeetingReminder` | boolean | Nein | Stornierungsmail an Teilnehmer und alternative Hosts senden |
#### Ausgabe
@@ -155,7 +153,7 @@ Ein Zoom-Meeting löschen oder abbrechen
### `zoom_get_meeting_invitation`
Den Einladungstext für ein Zoom-Meeting abrufen
Abrufen des Einladungstextes für ein Zoom-Meeting
#### Eingabe
@@ -167,20 +165,20 @@ Den Einladungstext für ein Zoom-Meeting abrufen
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `invitation` | string | Der Meeting-Einladungstext |
| `invitation` | string | Der Einladungstext für das Meeting |
### `zoom_list_recordings`
Alle Cloud-Aufzeichnungen eines Zoom-Benutzers auflisten
Alle Cloud-Aufzeichnungen für einen Zoom-Benutzer auflisten
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Ja | Die Benutzer-ID oder E-Mail-Adresse. Verwenden Sie "me" für den authentifizierten Benutzer. |
| `from` | string | Nein | Startdatum im Format yyyy-mm-dd (innerhalb der letzten 6 Monate) |
| `to` | string | Nein | Enddatum im Format yyyy-mm-dd |
| `pageSize` | number | Nein | Anzahl der Datensätze pro Seite (max. 300) |
| `from` | string | Nein | Startdatum im Format jjjj-mm-tt \(innerhalb der letzten 6 Monate\) |
| `to` | string | Nein | Enddatum im Format jjjj-mm-tt |
| `pageSize` | number | Nein | Anzahl der Datensätze pro Seite \(max. 300\) |
| `nextPageToken` | string | Nein | Token für die Paginierung, um die nächste Ergebnisseite zu erhalten |
| `trash` | boolean | Nein | Auf true setzen, um Aufzeichnungen aus dem Papierkorb aufzulisten |
@@ -191,7 +189,7 @@ Alle Cloud-Aufzeichnungen eines Zoom-Benutzers auflisten
| `recordings` | array | Liste der Aufzeichnungen |
| `pageInfo` | object | Paginierungsinformationen |
Alle Aufzeichnungen für ein bestimmtes Zoom-Meeting abrufen
### `zoom_get_meeting_recordings`
Alle Aufzeichnungen für ein bestimmtes Zoom-Meeting abrufen
@@ -200,8 +198,8 @@ Alle Aufzeichnungen für ein bestimmtes Zoom-Meeting abrufen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Ja | Die Meeting-ID oder Meeting-UUID |
| `includeFolderItems` | boolean | Nein | Elemente innerhalb eines Ordners einbeziehen |
| `ttl` | number | Nein | Gültigkeitsdauer für Download-URLs in Sekunden \(max. 604800\) |
| `includeFolderItems` | boolean | Nein | Elemente innerhalb eines Ordners einschließen |
| `ttl` | number | Nein | Gültigkeitsdauer für Download-URLs in Sekunden \(max 604800\) |
#### Ausgabe
@@ -209,7 +207,7 @@ Alle Aufzeichnungen für ein bestimmtes Zoom-Meeting abrufen
| --------- | ---- | ----------- |
| `recording` | object | Die Meeting-Aufzeichnung mit allen Dateien |
Cloud-Aufzeichnungen für ein Zoom-Meeting löschen
### `zoom_delete_recording`
Cloud-Aufzeichnungen für ein Zoom-Meeting löschen
@@ -227,7 +225,7 @@ Cloud-Aufzeichnungen für ein Zoom-Meeting löschen
| --------- | ---- | ----------- |
| `success` | boolean | Ob die Aufzeichnung erfolgreich gelöscht wurde |
Teilnehmer eines vergangenen Zoom-Meetings auflisten
### `zoom_list_past_participants`
Teilnehmer eines vergangenen Zoom-Meetings auflisten
@@ -236,14 +234,14 @@ Teilnehmer eines vergangenen Zoom-Meetings auflisten
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Ja | Die vergangene Meeting-ID oder UUID |
| `pageSize` | number | Nein | Anzahl der Datensätze pro Seite \(max. 300\) |
| `pageSize` | number | Nein | Anzahl der Datensätze pro Seite \(max 300\) |
| `nextPageToken` | string | Nein | Token für Paginierung, um die nächste Ergebnisseite zu erhalten |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `participants` | array | Liste der Meeting-Teilnehmer |
| `participants` | array | Liste der Besprechungsteilnehmer |
| `pageInfo` | object | Paginierungsinformationen |
## Hinweise

View File

@@ -106,24 +106,26 @@ Different block types produce different output structures. Here's what you can e
<Tab>
```json
{
"content": "Original content passed through",
"conditionResult": true,
"selectedPath": {
"blockId": "2acd9007-27e8-4510-a487-73d3b825e7c1",
"blockType": "agent",
"blockTitle": "Follow-up Agent"
},
"selectedOption": "condition-1"
"selectedConditionId": "condition-1"
}
```
### Condition Block Output Fields
- **content**: The original content passed through
- **conditionResult**: Boolean result of the condition evaluation
- **selectedPath**: Information about the selected path
- **blockId**: ID of the next block in the selected path
- **blockType**: Type of the next block
- **blockTitle**: Title of the next block
- **selectedOption**: ID of the selected condition
- **selectedConditionId**: ID of the selected condition
</Tab>
<Tab>

View File

@@ -51,13 +51,8 @@ Retrieve detailed information about a specific Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key \(e.g., PROJ-123\) |
| `summary` | string | Issue summary |
| `description` | json | Issue description content |
| `created` | string | Issue creation timestamp |
| `updated` | string | Issue last updated timestamp |
| `issue` | json | Complete issue object with all fields |
| `success` | boolean | Operation success status |
| `output` | object | Jira issue details with issue key, summary, description, created and updated timestamps |
### `jira_update`
@@ -81,9 +76,8 @@ Update a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Updated issue key \(e.g., PROJ-123\) |
| `summary` | string | Issue summary after update |
| `success` | boolean | Operation success status |
| `output` | object | Updated Jira issue details with timestamp, issue key, summary, and success status |
### `jira_write`
@@ -106,10 +100,8 @@ Write a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Created issue key \(e.g., PROJ-123\) |
| `summary` | string | Issue summary |
| `url` | string | URL to the created issue |
| `success` | boolean | Operation success status |
| `output` | object | Created Jira issue details with timestamp, issue key, summary, success status, and URL |
### `jira_bulk_read`
@@ -127,7 +119,8 @@ Retrieve multiple Jira issues in bulk
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `issues` | array | Array of Jira issues with ts, summary, description, created, and updated timestamps |
| `success` | boolean | Operation success status |
| `output` | array | Array of Jira issues with summary, description, created and updated timestamps |
### `jira_delete_issue`
@@ -146,8 +139,8 @@ Delete a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Deleted issue key |
| `success` | boolean | Operation success status |
| `output` | object | Deleted issue details with timestamp, issue key, and success status |
### `jira_assign_issue`
@@ -166,9 +159,8 @@ Assign a Jira issue to a user
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key that was assigned |
| `assigneeId` | string | Account ID of the assignee |
| `success` | boolean | Operation success status |
| `output` | object | Assignment details with timestamp, issue key, assignee ID, and success status |
### `jira_transition_issue`
@@ -188,9 +180,8 @@ Move a Jira issue between workflow statuses (e.g., To Do -> In Progress)
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key that was transitioned |
| `transitionId` | string | Applied transition ID |
| `success` | boolean | Operation success status |
| `output` | object | Transition details with timestamp, issue key, transition ID, and success status |
### `jira_search_issues`
@@ -211,11 +202,8 @@ Search for Jira issues using JQL (Jira Query Language)
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `total` | number | Total number of matching issues |
| `startAt` | number | Pagination start index |
| `maxResults` | number | Maximum results per page |
| `issues` | array | Array of matching issues with key, summary, status, assignee, created, updated |
| `success` | boolean | Operation success status |
| `output` | object | Search results with timestamp, total count, pagination details, and array of matching issues |
### `jira_add_comment`
@@ -234,10 +222,8 @@ Add a comment to a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key the comment was added to |
| `commentId` | string | Created comment ID |
| `body` | string | Comment text content |
| `success` | boolean | Operation success status |
| `output` | object | Comment details with timestamp, issue key, comment ID, body, and success status |
### `jira_get_comments`
@@ -257,10 +243,8 @@ Get all comments from a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `total` | number | Total number of comments |
| `comments` | array | Array of comments with id, author, body, created, updated |
| `success` | boolean | Operation success status |
| `output` | object | Comments data with timestamp, issue key, total count, and array of comments |
### `jira_update_comment`
@@ -280,10 +264,8 @@ Update an existing comment on a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `commentId` | string | Updated comment ID |
| `body` | string | Updated comment text |
| `success` | boolean | Operation success status |
| `output` | object | Updated comment details with timestamp, issue key, comment ID, body text, and success status |
### `jira_delete_comment`
@@ -302,9 +284,8 @@ Delete a comment from a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `commentId` | string | Deleted comment ID |
| `success` | boolean | Operation success status |
| `output` | object | Deletion details with timestamp, issue key, comment ID, and success status |
### `jira_get_attachments`
@@ -322,9 +303,8 @@ Get all attachments from a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `attachments` | array | Array of attachments with id, filename, size, mimeType, created, author |
| `success` | boolean | Operation success status |
| `output` | object | Attachments data with timestamp, issue key, and array of attachments |
### `jira_delete_attachment`
@@ -342,8 +322,8 @@ Delete an attachment from a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `attachmentId` | string | Deleted attachment ID |
| `success` | boolean | Operation success status |
| `output` | object | Deletion details with timestamp, attachment ID, and success status |
### `jira_add_worklog`
@@ -364,10 +344,8 @@ Add a time tracking worklog entry to a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key the worklog was added to |
| `worklogId` | string | Created worklog ID |
| `timeSpentSeconds` | number | Time spent in seconds |
| `success` | boolean | Operation success status |
| `output` | object | Worklog details with timestamp, issue key, worklog ID, time spent in seconds, and success status |
### `jira_get_worklogs`
@@ -387,10 +365,8 @@ Get all worklog entries from a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `total` | number | Total number of worklogs |
| `worklogs` | array | Array of worklogs with id, author, timeSpentSeconds, timeSpent, comment, created, updated, started |
| `success` | boolean | Operation success status |
| `output` | object | Worklogs data with timestamp, issue key, total count, and array of worklogs |
### `jira_update_worklog`
@@ -412,9 +388,8 @@ Update an existing worklog entry on a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `worklogId` | string | Updated worklog ID |
| `success` | boolean | Operation success status |
| `output` | object | Worklog update details with timestamp, issue key, worklog ID, and success status |
### `jira_delete_worklog`
@@ -433,9 +408,8 @@ Delete a worklog entry from a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `worklogId` | string | Deleted worklog ID |
| `success` | boolean | Operation success status |
| `output` | object | Deletion details with timestamp, issue key, worklog ID, and success status |
### `jira_create_issue_link`
@@ -456,11 +430,8 @@ Create a link relationship between two Jira issues
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `inwardIssue` | string | Inward issue key |
| `outwardIssue` | string | Outward issue key |
| `linkType` | string | Type of issue link |
| `linkId` | string | Created link ID |
| `success` | boolean | Operation success status |
| `output` | object | Issue link details with timestamp, inward issue key, outward issue key, link type, and success status |
### `jira_delete_issue_link`
@@ -478,8 +449,8 @@ Delete a link between two Jira issues
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `linkId` | string | Deleted link ID |
| `success` | boolean | Operation success status |
| `output` | object | Deletion details with timestamp, link ID, and success status |
### `jira_add_watcher`
@@ -498,9 +469,8 @@ Add a watcher to a Jira issue to receive notifications about updates
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `watcherAccountId` | string | Added watcher account ID |
| `success` | boolean | Operation success status |
| `output` | object | Watcher details with timestamp, issue key, watcher account ID, and success status |
### `jira_remove_watcher`
@@ -519,9 +489,8 @@ Remove a watcher from a Jira issue
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Timestamp of the operation |
| `issueKey` | string | Issue key |
| `watcherAccountId` | string | Removed watcher account ID |
| `success` | boolean | Operation success status |
| `output` | object | Removal details with timestamp, issue key, watcher account ID, and success status |

View File

@@ -80,7 +80,6 @@
"sendgrid",
"sentry",
"serper",
"servicenow",
"sftp",
"sharepoint",
"shopify",

View File

@@ -1,129 +0,0 @@
---
title: ServiceNow
description: Create, read, update, and delete ServiceNow records
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="servicenow"
color="#032D42"
/>
{/* MANUAL-CONTENT-START:intro */}
[ServiceNow](https://www.servicenow.com/) is a powerful cloud platform designed to streamline and automate IT service management (ITSM), workflows, and business processes across your organization. ServiceNow enables you to manage incidents, requests, tasks, users, and more using its extensive API.
With ServiceNow, you can:
- **Automate IT workflows**: Create, read, update, and delete records in any ServiceNow table, such as incidents, tasks, change requests, and users.
- **Integrate systems**: Connect ServiceNow with your other tools and processes for seamless automation.
- **Maintain a single source of truth**: Keep all your service and operations data organized and accessible.
- **Drive operational efficiency**: Reduce manual work and improve service quality with customizable workflows and automation.
In Sim, the ServiceNow integration enables your agents to interact directly with your ServiceNow instance as part of their workflows. Agents can create, read, update, or delete records in any ServiceNow table and leverage ticket or user data for sophisticated automation and decision-making. This integration bridges your workflow automation and IT operations, empowering your agents to manage service requests, incidents, users, and assets without manual intervention. By connecting Sim with ServiceNow, you can automate service management tasks, improve response times, and ensure consistent, secure access to your organization's vital service data.
{/* MANUAL-CONTENT-END */}
## Usage Instructions
Integrate ServiceNow into your workflow. Create, read, update, and delete records in any ServiceNow table including incidents, tasks, change requests, users, and more.
## Tools
### `servicenow_create_record`
Create a new record in a ServiceNow table
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Yes | ServiceNow instance URL \(e.g., https://instance.service-now.com\) |
| `username` | string | Yes | ServiceNow username |
| `password` | string | Yes | ServiceNow password |
| `tableName` | string | Yes | Table name \(e.g., incident, task, sys_user\) |
| `fields` | json | Yes | Fields to set on the record \(JSON object\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `record` | json | Created ServiceNow record with sys_id and other fields |
| `metadata` | json | Operation metadata |
### `servicenow_read_record`
Read records from a ServiceNow table
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Yes | ServiceNow instance URL \(e.g., https://instance.service-now.com\) |
| `username` | string | Yes | ServiceNow username |
| `password` | string | Yes | ServiceNow password |
| `tableName` | string | Yes | Table name |
| `sysId` | string | No | Specific record sys_id |
| `number` | string | No | Record number \(e.g., INC0010001\) |
| `query` | string | No | Encoded query string \(e.g., "active=true^priority=1"\) |
| `limit` | number | No | Maximum number of records to return |
| `fields` | string | No | Comma-separated list of fields to return |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `records` | array | Array of ServiceNow records |
| `metadata` | json | Operation metadata |
### `servicenow_update_record`
Update an existing record in a ServiceNow table
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Yes | ServiceNow instance URL \(e.g., https://instance.service-now.com\) |
| `username` | string | Yes | ServiceNow username |
| `password` | string | Yes | ServiceNow password |
| `tableName` | string | Yes | Table name |
| `sysId` | string | Yes | Record sys_id to update |
| `fields` | json | Yes | Fields to update \(JSON object\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `record` | json | Updated ServiceNow record |
| `metadata` | json | Operation metadata |
### `servicenow_delete_record`
Delete a record from a ServiceNow table
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Yes | ServiceNow instance URL \(e.g., https://instance.service-now.com\) |
| `username` | string | Yes | ServiceNow username |
| `password` | string | Yes | ServiceNow password |
| `tableName` | string | Yes | Table name |
| `sysId` | string | Yes | Record sys_id to delete |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Whether the deletion was successful |
| `metadata` | json | Operation metadata |
## Notes
- Category: `tools`
- Type: `servicenow`

View File

@@ -56,7 +56,7 @@ Integrate Slack into the workflow. Can send, update, and delete messages, create
### `slack_message`
Send messages to Slack channels or direct messages. Supports Slack mrkdwn formatting.
Send messages to Slack channels or users through the Slack API. Supports Slack mrkdwn formatting.
#### Input
@@ -64,8 +64,7 @@ Send messages to Slack channels or direct messages. Supports Slack mrkdwn format
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | No | Authentication method: oauth or bot_token |
| `botToken` | string | No | Bot token for Custom Bot |
| `channel` | string | No | Target Slack channel \(e.g., #general\) |
| `userId` | string | No | Target Slack user ID for direct messages \(e.g., U1234567890\) |
| `channel` | string | Yes | Target Slack channel \(e.g., #general\) |
| `text` | string | Yes | Message text to send \(supports Slack mrkdwn formatting\) |
| `thread_ts` | string | No | Thread timestamp to reply to \(creates thread reply\) |
| `files` | file[] | No | Files to attach to the message |
@@ -112,8 +111,7 @@ Read the latest messages from Slack channels. Retrieve conversation history with
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | No | Authentication method: oauth or bot_token |
| `botToken` | string | No | Bot token for Custom Bot |
| `channel` | string | No | Slack channel to read messages from \(e.g., #general\) |
| `userId` | string | No | User ID for DM conversation \(e.g., U1234567890\) |
| `channel` | string | Yes | Slack channel to read messages from \(e.g., #general\) |
| `limit` | number | No | Number of messages to retrieve \(default: 10, max: 100\) |
| `oldest` | string | No | Start of time range \(timestamp\) |
| `latest` | string | No | End of time range \(timestamp\) |

View File

@@ -50,8 +50,6 @@ Send a chat completion request to any supported LLM provider
| `maxTokens` | number | No | Maximum tokens in the response |
| `azureEndpoint` | string | No | Azure OpenAI endpoint URL |
| `azureApiVersion` | string | No | Azure OpenAI API version |
| `vertexProject` | string | No | Google Cloud project ID for Vertex AI |
| `vertexLocation` | string | No | Google Cloud location for Vertex AI \(defaults to us-central1\) |
#### Output

View File

@@ -42,7 +42,6 @@ List all items from a Webflow CMS collection
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Yes | ID of the Webflow site |
| `collectionId` | string | Yes | ID of the collection |
| `offset` | number | No | Offset for pagination \(optional\) |
| `limit` | number | No | Maximum number of items to return \(optional, default: 100\) |
@@ -62,7 +61,6 @@ Get a single item from a Webflow CMS collection
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Yes | ID of the Webflow site |
| `collectionId` | string | Yes | ID of the collection |
| `itemId` | string | Yes | ID of the item to retrieve |
@@ -81,7 +79,6 @@ Create a new item in a Webflow CMS collection
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Yes | ID of the Webflow site |
| `collectionId` | string | Yes | ID of the collection |
| `fieldData` | json | Yes | Field data for the new item as a JSON object. Keys should match collection field names. |
@@ -100,7 +97,6 @@ Update an existing item in a Webflow CMS collection
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Yes | ID of the Webflow site |
| `collectionId` | string | Yes | ID of the collection |
| `itemId` | string | Yes | ID of the item to update |
| `fieldData` | json | Yes | Field data to update as a JSON object. Only include fields you want to change. |
@@ -120,7 +116,6 @@ Delete an item from a Webflow CMS collection
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Yes | ID of the Webflow site |
| `collectionId` | string | Yes | ID of the collection |
| `itemId` | string | Yes | ID of the item to delete |

View File

@@ -27,8 +27,6 @@ In Sim, the Zoom integration empowers your agents to automate scheduling and mee
- Retrieve details or invitations for any meeting
- Update or delete existing meetings directly from your automations
To connect to Zoom, drop the Zoom block and click `Connect` to authenticate with your Zoom account. Once connected, you can use the Zoom tools to create, list, update, and delete Zoom meetings. At any given time, you can disconnect your Zoom account by clicking `Disconnect` in Settings > Integrations, and access to your Zoom account will be revoked immediatley.
These capabilities let you streamline remote collaboration, automate recurring video sessions, and manage your organization's Zoom environment all as part of your workflows.
{/* MANUAL-CONTENT-END */}

View File

@@ -111,24 +111,26 @@ Diferentes tipos de bloques producen diferentes estructuras de salida. Esto es l
```json
{
"content": "Original content passed through",
"conditionResult": true,
"selectedPath": {
"blockId": "2acd9007-27e8-4510-a487-73d3b825e7c1",
"blockType": "agent",
"blockTitle": "Follow-up Agent"
},
"selectedOption": "condition-1"
"selectedConditionId": "condition-1"
}
```
### Campos de salida del bloque de condición
- **conditionResult**: resultado booleano de la evaluación de la condición
- **selectedPath**: información sobre la ruta seleccionada
- **content**: El contenido original que se transmite
- **conditionResult**: Resultado booleano de la evaluación de la condición
- **selectedPath**: Información sobre la ruta seleccionada
- **blockId**: ID del siguiente bloque en la ruta seleccionada
- **blockType**: tipo del siguiente bloque
- **blockTitle**: título del siguiente bloque
- **selectedOption**: ID de la condición seleccionada
- **blockType**: Tipo del siguiente bloque
- **blockTitle**: Título del siguiente bloque
- **selectedConditionId**: ID de la condición seleccionada
</Tab>
<Tab>

View File

@@ -48,13 +48,8 @@ Recupera información detallada sobre una incidencia específica de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de la incidencia (p. ej., PROJ-123) |
| `summary` | string | Resumen de la incidencia |
| `description` | json | Contenido de la descripción de la incidencia |
| `created` | string | Marca de tiempo de creación de la incidencia |
| `updated` | string | Marca de tiempo de última actualización de la incidencia |
| `issue` | json | Objeto completo de la incidencia con todos los campos |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de la incidencia de Jira con clave de incidencia, resumen, descripción, marcas de tiempo de creación y actualización |
### `jira_update`
@@ -78,9 +73,8 @@ Actualizar una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de la incidencia actualizada (p. ej., PROJ-123) |
| `summary` | string | Resumen de la incidencia después de la actualización |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles actualizados de la incidencia de Jira con marca de tiempo, clave de incidencia, resumen y estado de éxito |
### `jira_write`
@@ -103,10 +97,8 @@ Escribir una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de la incidencia creada (p. ej., PROJ-123) |
| `summary` | string | Resumen de la incidencia |
| `url` | string | URL de la incidencia creada |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de la incidencia de Jira creada con marca de tiempo, clave de incidencia, resumen, estado de éxito y URL |
### `jira_bulk_read`
@@ -124,7 +116,8 @@ Recuperar múltiples incidencias de Jira en bloque
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `issues` | array | Array de incidencias de Jira con marca de tiempo, resumen, descripción, y marcas de tiempo de creación y actualización |
| `success` | boolean | Estado de éxito de la operación |
| `output` | array | Array de incidencias de Jira con resumen, descripción, marcas de tiempo de creación y actualización |
### `jira_delete_issue`
@@ -143,8 +136,8 @@ Eliminar una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de la incidencia eliminada |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de la incidencia eliminada con marca de tiempo, clave de incidencia y estado de éxito |
### `jira_assign_issue`
@@ -163,9 +156,8 @@ Asignar una incidencia de Jira a un usuario
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de la incidencia que fue asignada |
| `assigneeId` | string | ID de cuenta del asignado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de la asignación con marca de tiempo, clave de incidencia, ID del asignado y estado de éxito |
### `jira_transition_issue`
@@ -185,9 +177,8 @@ Mover una incidencia de Jira entre estados de flujo de trabajo (p. ej., Pendient
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia que fue transicionada |
| `transitionId` | string | ID de transición aplicada |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de la transición con marca de tiempo, clave de incidencia, ID de transición y estado de éxito |
### `jira_search_issues`
@@ -208,11 +199,8 @@ Buscar incidencias de Jira usando JQL (Jira Query Language)
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `total` | number | Número total de incidencias coincidentes |
| `startAt` | number | Índice de inicio de paginación |
| `maxResults` | number | Máximo de resultados por página |
| `issues` | array | Array de incidencias coincidentes con clave, resumen, estado, asignado, creado, actualizado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Resultados de búsqueda con marca de tiempo, recuento total, detalles de paginación y array de incidencias coincidentes |
### `jira_add_comment`
@@ -231,10 +219,8 @@ Añadir un comentario a una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia a la que se añadió el comentario |
| `commentId` | string | ID del comentario creado |
| `body` | string | Contenido de texto del comentario |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles del comentario con marca de tiempo, clave de incidencia, ID del comentario, cuerpo y estado de éxito |
### `jira_get_comments`
@@ -254,10 +240,8 @@ Obtener todos los comentarios de una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `total` | number | Número total de comentarios |
| `comments` | array | Array de comentarios con id, autor, cuerpo, creado, actualizado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Datos de comentarios con marca de tiempo, clave de incidencia, recuento total y array de comentarios |
### `jira_update_comment`
@@ -277,10 +261,8 @@ Actualizar un comentario existente en una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `commentId` | string | ID del comentario actualizado |
| `body` | string | Texto actualizado del comentario |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles del comentario actualizado con marca de tiempo, clave de incidencia, ID de comentario, texto del cuerpo y estado de éxito |
### `jira_delete_comment`
@@ -299,9 +281,8 @@ Eliminar un comentario de una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `commentId` | string | ID del comentario eliminado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de eliminación con marca de tiempo, clave de incidencia, ID de comentario y estado de éxito |
### `jira_get_attachments`
@@ -319,9 +300,8 @@ Obtener todos los adjuntos de una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `attachments` | array | Array de adjuntos con id, nombre de archivo, tamaño, tipo MIME, fecha de creación y autor |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Datos de adjuntos con marca de tiempo, clave de incidencia y array de adjuntos |
### `jira_delete_attachment`
@@ -339,8 +319,8 @@ Eliminar un adjunto de una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `attachmentId` | string | ID del adjunto eliminado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de eliminación con marca de tiempo, ID de adjunto y estado de éxito |
### `jira_add_worklog`
@@ -361,10 +341,8 @@ Añadir una entrada de registro de trabajo de seguimiento de tiempo a una incide
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia a la que se añadió el registro de trabajo |
| `worklogId` | string | ID del registro de trabajo creado |
| `timeSpentSeconds` | number | Tiempo empleado en segundos |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles del registro de trabajo con marca de tiempo, clave de incidencia, ID del registro de trabajo, tiempo dedicado en segundos y estado de éxito |
### `jira_get_worklogs`
@@ -384,10 +362,8 @@ Obtener todas las entradas de registro de trabajo de una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `total` | number | Número total de registros de trabajo |
| `worklogs` | array | Array de registros de trabajo con id, autor, segundos empleados, tiempo empleado, comentario, fecha de creación, actualización e inicio |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Datos de registros de trabajo con marca de tiempo, clave de incidencia, recuento total y array de registros de trabajo |
### `jira_update_worklog`
@@ -409,9 +385,8 @@ Actualizar una entrada existente de registro de trabajo en una incidencia de Jir
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `worklogId` | string | ID del registro de trabajo actualizado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de actualización del registro de trabajo con marca de tiempo, clave de incidencia, ID de registro de trabajo y estado de éxito |
### `jira_delete_worklog`
@@ -430,9 +405,8 @@ Eliminar una entrada de registro de trabajo de una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `worklogId` | string | ID del registro de trabajo eliminado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de eliminación con marca de tiempo, clave de incidencia, ID de registro de trabajo y estado de éxito |
### `jira_create_issue_link`
@@ -453,11 +427,8 @@ Crear una relación de enlace entre dos incidencias de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `inwardIssue` | string | Clave de incidencia de entrada |
| `outwardIssue` | string | Clave de incidencia de salida |
| `linkType` | string | Tipo de enlace de incidencia |
| `linkId` | string | ID del enlace creado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles del enlace de incidencia con marca de tiempo, clave de incidencia de entrada, clave de incidencia de salida, tipo de enlace y estado de éxito |
### `jira_delete_issue_link`
@@ -475,8 +446,8 @@ Eliminar un enlace entre dos incidencias de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `linkId` | string | ID del enlace eliminado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de eliminación con marca de tiempo, ID del enlace y estado de éxito |
### `jira_add_watcher`
@@ -495,9 +466,8 @@ Añadir un observador a una incidencia de Jira para recibir notificaciones sobre
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `watcherAccountId` | string | ID de cuenta del observador añadido |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles del observador con marca de tiempo, clave de incidencia, ID de cuenta del observador y estado de éxito |
### `jira_remove_watcher`
@@ -516,9 +486,8 @@ Eliminar un observador de una incidencia de Jira
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `ts` | string | Marca de tiempo de la operación |
| `issueKey` | string | Clave de incidencia |
| `watcherAccountId` | string | ID de cuenta del observador eliminado |
| `success` | boolean | Estado de éxito de la operación |
| `output` | object | Detalles de eliminación con marca de tiempo, clave de incidencia, ID de cuenta del observador y estado de éxito |
## Notas

View File

@@ -1,124 +0,0 @@
---
title: ServiceNow
description: Crear, leer, actualizar y eliminar registros de ServiceNow
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="servicenow"
color="#032D42"
/>
{/* MANUAL-CONTENT-START:intro */}
[ServiceNow](https://www.servicenow.com/) es una potente plataforma en la nube diseñada para optimizar y automatizar la gestión de servicios de TI (ITSM), flujos de trabajo y procesos empresariales en toda tu organización. ServiceNow te permite gestionar incidencias, solicitudes, tareas, usuarios y más utilizando su amplia API.
Con ServiceNow, puedes:
- **Automatizar flujos de trabajo de TI**: crear, leer, actualizar y eliminar registros en cualquier tabla de ServiceNow, como incidencias, tareas, solicitudes de cambio y usuarios.
- **Integrar sistemas**: conectar ServiceNow con tus otras herramientas y procesos para una automatización fluida.
- **Mantener una única fuente de verdad**: mantener todos tus datos de servicio y operaciones organizados y accesibles.
- **Impulsar la eficiencia operativa**: reducir el trabajo manual y mejorar la calidad del servicio con flujos de trabajo personalizables y automatización.
En Sim, la integración de ServiceNow permite que tus agentes interactúen directamente con tu instancia de ServiceNow como parte de sus flujos de trabajo. Los agentes pueden crear, leer, actualizar o eliminar registros en cualquier tabla de ServiceNow y aprovechar datos de tickets o usuarios para automatización y toma de decisiones sofisticadas. Esta integración conecta tu automatización de flujos de trabajo y operaciones de TI, permitiendo que tus agentes gestionen solicitudes de servicio, incidencias, usuarios y activos sin intervención manual. Al conectar Sim con ServiceNow, puedes automatizar tareas de gestión de servicios, mejorar los tiempos de respuesta y garantizar un acceso consistente y seguro a los datos de servicio vitales de tu organización.
{/* MANUAL-CONTENT-END */}
## Instrucciones de uso
Integra ServiceNow en tu flujo de trabajo. Crea, lee, actualiza y elimina registros en cualquier tabla de ServiceNow, incluyendo incidencias, tareas, solicitudes de cambio, usuarios y más.
## Herramientas
### `servicenow_create_record`
Crear un nuevo registro en una tabla de ServiceNow
#### Entrada
| Parámetro | Tipo | Requerido | Descripción |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Sí | URL de la instancia de ServiceNow \(p. ej., https://instance.service-now.com\) |
| `username` | string | Sí | Nombre de usuario de ServiceNow |
| `password` | string | Sí | Contraseña de ServiceNow |
| `tableName` | string | Sí | Nombre de la tabla \(p. ej., incident, task, sys_user\) |
| `fields` | json | Sí | Campos a establecer en el registro \(objeto JSON\) |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `record` | json | Registro de ServiceNow creado con sys_id y otros campos |
| `metadata` | json | Metadatos de la operación |
### `servicenow_read_record`
Leer registros de una tabla de ServiceNow
#### Entrada
| Parámetro | Tipo | Requerido | Descripción |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Sí | URL de la instancia de ServiceNow \(p. ej., https://instance.service-now.com\) |
| `username` | string | Sí | Nombre de usuario de ServiceNow |
| `password` | string | Sí | Contraseña de ServiceNow |
| `tableName` | string | Sí | Nombre de la tabla |
| `sysId` | string | No | sys_id del registro específico |
| `number` | string | No | Número de registro \(p. ej., INC0010001\) |
| `query` | string | No | Cadena de consulta codificada \(p. ej., "active=true^priority=1"\) |
| `limit` | number | No | Número máximo de registros a devolver |
| `fields` | string | No | Lista de campos separados por comas a devolver |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `records` | array | Array de registros de ServiceNow |
| `metadata` | json | Metadatos de la operación |
### `servicenow_update_record`
Actualiza un registro existente en una tabla de ServiceNow
#### Entrada
| Parámetro | Tipo | Requerido | Descripción |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Sí | URL de la instancia de ServiceNow \(ej., https://instance.service-now.com\) |
| `username` | string | Sí | Nombre de usuario de ServiceNow |
| `password` | string | Sí | Contraseña de ServiceNow |
| `tableName` | string | Sí | Nombre de la tabla |
| `sysId` | string | Sí | sys_id del registro a actualizar |
| `fields` | json | Sí | Campos a actualizar \(objeto JSON\) |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `record` | json | Registro de ServiceNow actualizado |
| `metadata` | json | Metadatos de la operación |
### `servicenow_delete_record`
Elimina un registro de una tabla de ServiceNow
#### Entrada
| Parámetro | Tipo | Requerido | Descripción |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Sí | URL de la instancia de ServiceNow \(ej., https://instance.service-now.com\) |
| `username` | string | Sí | Nombre de usuario de ServiceNow |
| `password` | string | Sí | Contraseña de ServiceNow |
| `tableName` | string | Sí | Nombre de la tabla |
| `sysId` | string | Sí | sys_id del registro a eliminar |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `success` | boolean | Si la eliminación fue exitosa |
| `metadata` | json | Metadatos de la operación |
## Notas
- Categoría: `tools`
- Tipo: `servicenow`

View File

@@ -54,7 +54,7 @@ Integra Slack en el flujo de trabajo. Puede enviar, actualizar y eliminar mensaj
### `slack_message`
Envía mensajes a canales de Slack o mensajes directos. Compatible con el formato mrkdwn de Slack.
Envía mensajes a canales o usuarios de Slack a través de la API de Slack. Compatible con el formato mrkdwn de Slack.
#### Entrada
@@ -62,10 +62,9 @@ Envía mensajes a canales de Slack o mensajes directos. Compatible con el format
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | No | Método de autenticación: oauth o bot_token |
| `botToken` | string | No | Token del bot para Bot personalizado |
| `channel` | string | No | Canal de Slack objetivo (p. ej., #general) |
| `userId` | string | No | ID de usuario de Slack objetivo para mensajes directos (p. ej., U1234567890) |
| `channel` | string | | Canal de Slack objetivo (p. ej., #general) |
| `text` | string | Sí | Texto del mensaje a enviar (admite formato mrkdwn de Slack) |
| `thread_ts` | string | No | Marca de tiempo del hilo al que responder (crea respuesta en hilo) |
| `thread_ts` | string | No | Marca de tiempo del hilo para responder (crea respuesta en hilo) |
| `files` | file[] | No | Archivos para adjuntar al mensaje |
#### Salida
@@ -110,8 +109,7 @@ Lee los últimos mensajes de los canales de Slack. Recupera el historial de conv
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | No | Método de autenticación: oauth o bot_token |
| `botToken` | string | No | Token del bot para Bot personalizado |
| `channel` | string | No | Canal de Slack del que leer mensajes (p. ej., #general) |
| `userId` | string | No | ID de usuario para conversación por MD (p. ej., U1234567890) |
| `channel` | string | | Canal de Slack del que leer mensajes (p. ej., #general) |
| `limit` | number | No | Número de mensajes a recuperar (predeterminado: 10, máx: 100) |
| `oldest` | string | No | Inicio del rango de tiempo (marca de tiempo) |
| `latest` | string | No | Fin del rango de tiempo (marca de tiempo) |

View File

@@ -37,18 +37,16 @@ Envía una solicitud de completado de chat a cualquier proveedor de LLM compatib
#### Entrada
| Parámetro | Tipo | Requerido | Descripción |
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `model` | string | Sí | El modelo a utilizar \(ej., gpt-4o, claude-sonnet-4-5, gemini-2.0-flash\) |
| `model` | string | Sí | El modelo a utilizar \(p. ej., gpt-4o, claude-sonnet-4-5, gemini-2.0-flash\) |
| `systemPrompt` | string | No | Prompt del sistema para establecer el comportamiento del asistente |
| `context` | string | Sí | El mensaje del usuario o contexto a enviar al modelo |
| `apiKey` | string | No | Clave API del proveedor \(usa la clave de la plataforma si no se proporciona para modelos alojados\) |
| `context` | string | Sí | El mensaje del usuario o contexto para enviar al modelo |
| `apiKey` | string | No | Clave API para el proveedor \(usa la clave de la plataforma si no se proporciona para modelos alojados\) |
| `temperature` | number | No | Temperatura para la generación de respuestas \(0-2\) |
| `maxTokens` | number | No | Tokens máximos en la respuesta |
| `azureEndpoint` | string | No | URL del endpoint de Azure OpenAI |
| `azureApiVersion` | string | No | Versión de la API de Azure OpenAI |
| `vertexProject` | string | No | ID del proyecto de Google Cloud para Vertex AI |
| `vertexLocation` | string | No | Ubicación de Google Cloud para Vertex AI \(por defecto us-central1\) |
#### Salida

View File

@@ -39,7 +39,6 @@ Listar todos los elementos de una colección del CMS de Webflow
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Sí | ID del sitio de Webflow |
| `collectionId` | string | Sí | ID de la colección |
| `offset` | number | No | Desplazamiento para paginación \(opcional\) |
| `limit` | number | No | Número máximo de elementos a devolver \(opcional, predeterminado: 100\) |
@@ -59,7 +58,6 @@ Obtener un solo elemento de una colección del CMS de Webflow
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Sí | ID del sitio de Webflow |
| `collectionId` | string | Sí | ID de la colección |
| `itemId` | string | Sí | ID del elemento a recuperar |
@@ -78,7 +76,6 @@ Crear un nuevo elemento en una colección del CMS de Webflow
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Sí | ID del sitio de Webflow |
| `collectionId` | string | Sí | ID de la colección |
| `fieldData` | json | Sí | Datos de campo para el nuevo elemento como objeto JSON. Las claves deben coincidir con los nombres de campo de la colección. |
@@ -97,7 +94,6 @@ Actualizar un elemento existente en una colección CMS de Webflow
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Sí | ID del sitio de Webflow |
| `collectionId` | string | Sí | ID de la colección |
| `itemId` | string | Sí | ID del elemento a actualizar |
| `fieldData` | json | Sí | Datos de campo para actualizar como objeto JSON. Solo incluye los campos que quieres cambiar. |
@@ -117,7 +113,6 @@ Eliminar un elemento de una colección CMS de Webflow
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Sí | ID del sitio de Webflow |
| `collectionId` | string | Sí | ID de la colección |
| `itemId` | string | Sí | ID del elemento a eliminar |

View File

@@ -27,14 +27,12 @@ En Sim, la integración con Zoom permite a tus agentes automatizar la programaci
- Obtener detalles o invitaciones para cualquier reunión
- Actualizar o eliminar reuniones existentes directamente desde tus automatizaciones
Para conectarte a Zoom, arrastra el bloque de Zoom y haz clic en `Connect` para autenticarte con tu cuenta de Zoom. Una vez conectado, puedes usar las herramientas de Zoom para crear, listar, actualizar y eliminar reuniones de Zoom. En cualquier momento, puedes desconectar tu cuenta de Zoom haciendo clic en `Disconnect` en Configuración > Integraciones, y el acceso a tu cuenta de Zoom será revocado inmediatamente.
Estas capacidades te permiten agilizar la colaboración remota, automatizar sesiones de video recurrentes y gestionar el entorno de Zoom de tu organización, todo como parte de tus flujos de trabajo.
Estas capacidades te permiten agilizar la colaboración remota, automatizar sesiones de video recurrentes y gestionar el entorno Zoom de tu organización como parte de tus flujos de trabajo.
{/* MANUAL-CONTENT-END */}
## Instrucciones de uso
Integra Zoom en los flujos de trabajo. Crea, lista, actualiza y elimina reuniones de Zoom. Obtén detalles de reuniones, invitaciones, grabaciones y participantes. Gestiona grabaciones en la nube de forma programática.
Integra Zoom en flujos de trabajo. Crea, lista, actualiza y elimina reuniones de Zoom. Obtén detalles de reuniones, invitaciones, grabaciones y participantes. Gestiona grabaciones en la nube de forma programática.
## Herramientas
@@ -46,12 +44,12 @@ Crear una nueva reunión de Zoom
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Sí | El ID de usuario o dirección de correo electrónico. Use "me" para el usuario autenticado. |
| `userId` | string | Sí | El ID de usuario o dirección de correo electrónico. Usa "me" para el usuario autenticado. |
| `topic` | string | Sí | Tema de la reunión |
| `type` | number | No | Tipo de reunión: 1=instantánea, 2=programada, 3=recurrente sin hora fija, 8=recurrente con hora fija |
| `startTime` | string | No | Hora de inicio de la reunión en formato ISO 8601 \(ej., 2025-06-03T10:00:00Z\) |
| `startTime` | string | No | Hora de inicio de la reunión en formato ISO 8601 \(p. ej., 2025-06-03T10:00:00Z\) |
| `duration` | number | No | Duración de la reunión en minutos |
| `timezone` | string | No | Zona horaria para la reunión \(ej., America/Los_Angeles\) |
| `timezone` | string | No | Zona horaria para la reunión \(p. ej., America/Los_Angeles\) |
| `password` | string | No | Contraseña de la reunión |
| `agenda` | string | No | Agenda de la reunión |
| `hostVideo` | boolean | No | Iniciar con video del anfitrión activado |
@@ -69,13 +67,13 @@ Crear una nueva reunión de Zoom
### `zoom_list_meetings`
Listar todas las reuniones de un usuario de Zoom
Listar todas las reuniones para un usuario de Zoom
#### Entrada
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Sí | El ID de usuario o dirección de correo electrónico. Usa "me" para el usuario autenticado. |
| `userId` | string | Sí | El ID de usuario o dirección de correo electrónico. Use "me" para el usuario autenticado. |
| `type` | string | No | Filtro de tipo de reunión: scheduled, live, upcoming, upcoming_meetings, o previous_meetings |
| `pageSize` | number | No | Número de registros por página \(máximo 300\) |
| `nextPageToken` | string | No | Token para paginación para obtener la siguiente página de resultados |
@@ -105,7 +103,7 @@ Obtener detalles de una reunión específica de Zoom
| --------- | ---- | ----------- |
| `meeting` | object | Los detalles de la reunión |
Obtener detalles de una reunión específica de Zoom
### `zoom_update_meeting`
Actualizar una reunión existente de Zoom
@@ -124,9 +122,9 @@ Actualizar una reunión existente de Zoom
| `hostVideo` | boolean | No | Iniciar con video del anfitrión activado |
| `participantVideo` | boolean | No | Iniciar con video de participantes activado |
| `joinBeforeHost` | boolean | No | Permitir que los participantes se unan antes que el anfitrión |
| `muteUponEntry` | boolean | No | Silenciar participantes al entrar |
| `muteUponEntry` | boolean | No | Silenciar a los participantes al entrar |
| `waitingRoom` | boolean | No | Habilitar sala de espera |
| `autoRecording` | string | No | Configuración de grabación automática: local, cloud o none |
| `autoRecording` | string | No | Configuración de grabación automática: local, en la nube o ninguna |
#### Salida
@@ -134,7 +132,7 @@ Actualizar una reunión existente de Zoom
| --------- | ---- | ----------- |
| `success` | boolean | Si la reunión se actualizó correctamente |
Eliminar una reunión de Zoom
### `zoom_delete_meeting`
Eliminar o cancelar una reunión de Zoom
@@ -144,14 +142,14 @@ Eliminar o cancelar una reunión de Zoom
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Sí | El ID de la reunión a eliminar |
| `occurrenceId` | string | No | ID de ocurrencia para eliminar una ocurrencia específica de una reunión recurrente |
| `scheduleForReminder` | boolean | No | Enviar correo electrónico de recordatorio de cancelación a los registrados |
| `cancelMeetingReminder` | boolean | No | Enviar correo electrónico de cancelación a los registrados y anfitriones alternativos |
| `scheduleForReminder` | boolean | No | Enviar correo electrónico de recordatorio de cancelación a los inscritos |
| `cancelMeetingReminder` | boolean | No | Enviar correo electrónico de cancelación a los inscritos y anfitriones alternativos |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `success` | boolean | Si la reunión se eliminó correctamente |
| `success` | boolean | Indica si la reunión se eliminó correctamente |
### `zoom_get_meeting_invitation`
@@ -177,10 +175,10 @@ Listar todas las grabaciones en la nube para un usuario de Zoom
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Sí | El ID de usuario o dirección de correo electrónico. Usa "me" para el usuario autenticado. |
| `from` | string | No | Fecha de inicio en formato aaaa-mm-dd (dentro de los últimos 6 meses) |
| `userId` | string | Sí | El ID de usuario o dirección de correo electrónico. Use "me" para el usuario autenticado. |
| `from` | string | No | Fecha de inicio en formato aaaa-mm-dd \(dentro de los últimos 6 meses\) |
| `to` | string | No | Fecha de fin en formato aaaa-mm-dd |
| `pageSize` | number | No | Número de registros por página (máx. 300) |
| `pageSize` | number | No | Número de registros por página \(máximo 300\) |
| `nextPageToken` | string | No | Token para paginación para obtener la siguiente página de resultados |
| `trash` | boolean | No | Establecer como true para listar grabaciones de la papelera |
@@ -191,9 +189,9 @@ Listar todas las grabaciones en la nube para un usuario de Zoom
| `recordings` | array | Lista de grabaciones |
| `pageInfo` | object | Información de paginación |
Obtener todas las grabaciones para una reunión específica de Zoom
### `zoom_get_meeting_recordings`
Obtener todas las grabaciones para una reunión específica de Zoom
Obtener todas las grabaciones de una reunión específica de Zoom
#### Entrada
@@ -201,7 +199,7 @@ Obtener todas las grabaciones para una reunión específica de Zoom
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Sí | El ID de la reunión o UUID de la reunión |
| `includeFolderItems` | boolean | No | Incluir elementos dentro de una carpeta |
| `ttl` | number | No | Tiempo de vida para URLs de descarga en segundos \(máx. 604800\) |
| `ttl` | number | No | Tiempo de vida para las URLs de descarga en segundos \(máx. 604800\) |
#### Salida
@@ -209,9 +207,9 @@ Obtener todas las grabaciones para una reunión específica de Zoom
| --------- | ---- | ----------- |
| `recording` | object | La grabación de la reunión con todos los archivos |
Eliminar grabaciones en la nube para una reunión de Zoom
### `zoom_delete_recording`
Eliminar grabaciones en la nube para una reunión de Zoom
Eliminar grabaciones en la nube de una reunión de Zoom
#### Entrada
@@ -227,7 +225,7 @@ Eliminar grabaciones en la nube para una reunión de Zoom
| --------- | ---- | ----------- |
| `success` | boolean | Si la grabación se eliminó correctamente |
Listar participantes de una reunión pasada de Zoom
### `zoom_list_past_participants`
Listar participantes de una reunión pasada de Zoom
@@ -235,7 +233,7 @@ Listar participantes de una reunión pasada de Zoom
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Sí | El ID de la reunión pasada o UUID |
| `meetingId` | string | Sí | El ID o UUID de la reunión pasada |
| `pageSize` | number | No | Número de registros por página \(máx. 300\) |
| `nextPageToken` | string | No | Token para paginación para obtener la siguiente página de resultados |

View File

@@ -111,24 +111,26 @@ Différents types de blocs produisent différentes structures de sortie. Voici c
```json
{
"content": "Original content passed through",
"conditionResult": true,
"selectedPath": {
"blockId": "2acd9007-27e8-4510-a487-73d3b825e7c1",
"blockType": "agent",
"blockTitle": "Follow-up Agent"
},
"selectedOption": "condition-1"
"selectedConditionId": "condition-1"
}
```
### Champs de sortie du bloc de condition
- **content** : le contenu original transmis
- **conditionResult** : résultat booléen de l'évaluation de la condition
- **selectedPath** : informations sur le chemin sélectionné
- **blockId** : ID du bloc suivant dans le chemin sélectionné
- **blockType** : type du bloc suivant
- **blockTitle** : titre du bloc suivant
- **selectedOption** : ID de la condition sélectionnée
- **selectedConditionId** : ID de la condition sélectionnée
</Tab>
<Tab>

View File

@@ -48,13 +48,8 @@ Récupérer des informations détaillées sur un ticket Jira spécifique
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | chaîne | Horodatage de l'opération |
| `issueKey` | chaîne | Clé du ticket \(ex. : PROJ-123\) |
| `summary` | chaîne | Résumé du ticket |
| `description` | json | Contenu de la description du ticket |
| `created` | chaîne | Horodatage de création du ticket |
| `updated` | chaîne | Horodatage de dernière mise à jour du ticket |
| `issue` | json | Objet complet du ticket avec tous les champs |
| `success` | booléen | Statut de réussite de l'opération |
| `output` | objet | Détails du ticket Jira avec la clé du ticket, le résumé, la description, les horodatages de création et de mise à jour |
### `jira_update`
@@ -78,9 +73,8 @@ Mettre à jour un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | chaîne | Horodatage de l'opération |
| `issueKey` | chaîne | Clé du ticket mis à jour \(ex. : PROJ-123\) |
| `summary` | chaîne | Résumé du ticket après mise à jour |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de la demande Jira mise à jour avec horodatage, clé de la demande, résumé et statut de réussite |
### `jira_write`
@@ -103,10 +97,8 @@ Rédiger une demande Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | chaîne | Horodatage de l'opération |
| `issueKey` | chaîne | Clé du ticket créé \(ex. : PROJ-123\) |
| `summary` | chaîne | Résumé du ticket |
| `url` | chaîne | URL vers le ticket créé |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de la demande Jira créée avec horodatage, clé de la demande, résumé, statut de réussite et URL |
### `jira_bulk_read`
@@ -124,7 +116,8 @@ Récupérer plusieurs demandes Jira en masse
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `issues` | tableau | Tableau des tickets Jira avec horodatages ts, résumé, description, création et mise à jour |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | array | Tableau des tickets Jira avec résumé, description, horodatages de création et de mise à jour |
### `jira_delete_issue`
@@ -143,8 +136,8 @@ Supprimer un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | chaîne | Horodatage de l'opération |
| `issueKey` | chaîne | Clé du ticket supprimé |
| `success` | booléen | Statut de réussite de l'opération |
| `output` | objet | Détails du ticket supprimé avec horodatage, clé du ticket et statut de réussite |
### `jira_assign_issue`
@@ -163,9 +156,8 @@ Assigner un ticket Jira à un utilisateur
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | chaîne | Horodatage de l'opération |
| `issueKey` | chaîne | Clé du ticket qui a été assigné |
| `assigneeId` | chaîne | ID de compte de l'assigné |
| `success` | booléen | Statut de réussite de l'opération |
| `output` | objet | Détails de l'assignation avec horodatage, clé du ticket, ID de l'assigné et statut de réussite |
### `jira_transition_issue`
@@ -185,9 +177,8 @@ Déplacer un ticket Jira entre les statuts de workflow (par ex., À faire -> En
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket qui a été transition |
| `transitionId` | string | ID de la transition appliquée |
| `success` | booléen | Statut de réussite de l'opération |
| `output` | objet | Détails de la transition avec horodatage, clé du ticket, ID de transition et statut de réussite |
### `jira_search_issues`
@@ -208,11 +199,8 @@ Rechercher des tickets Jira à l'aide de JQL (Jira Query Language)
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `total` | number | Nombre total de tickets correspondants |
| `startAt` | number | Index de début de pagination |
| `maxResults` | number | Nombre maximum de résultats par page |
| `issues` | array | Tableau des tickets correspondants avec clé, résumé, statut, assigné, créé, mis à jour |
| `success` | booléen | Statut de réussite de l'opération |
| `output` | objet | Résultats de recherche avec horodatage, nombre total, détails de pagination et tableau des tickets correspondants |
### `jira_add_comment`
@@ -231,10 +219,8 @@ Ajouter un commentaire à un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket auquel le commentaire a été ajouté |
| `commentId` | string | ID du commentaire créé |
| `body` | string | Contenu textuel du commentaire |
| `success` | booléen | Statut de réussite de l'opération |
| `output` | objet | Détails du commentaire avec horodatage, clé du ticket, ID du commentaire, corps et statut de réussite |
### `jira_get_comments`
@@ -254,10 +240,8 @@ Obtenir tous les commentaires d'un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `total` | number | Nombre total de commentaires |
| `comments` | array | Tableau des commentaires avec id, auteur, corps, créé, mis à jour |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Données des commentaires avec horodatage, clé du ticket, nombre total et tableau de commentaires |
### `jira_update_comment`
@@ -277,10 +261,8 @@ Mettre à jour un commentaire existant sur un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `commentId` | string | ID du commentaire mis à jour |
| `body` | string | Texte du commentaire mis à jour |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails du commentaire mis à jour avec horodatage, clé du ticket, ID du commentaire, texte du corps et statut de réussite |
### `jira_delete_comment`
@@ -299,9 +281,8 @@ Supprimer un commentaire d'un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `commentId` | string | ID du commentaire supprimé |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de la suppression avec horodatage, clé du ticket, ID du commentaire et statut de réussite |
### `jira_get_attachments`
@@ -319,9 +300,8 @@ Obtenir toutes les pièces jointes d'un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `attachments` | array | Tableau des pièces jointes avec id, nom de fichier, taille, type MIME, date de création, auteur |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Données des pièces jointes avec horodatage, clé du ticket et tableau des pièces jointes |
### `jira_delete_attachment`
@@ -339,8 +319,8 @@ Supprimer une pièce jointe d'un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `attachmentId` | string | ID de la pièce jointe supprimée |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de la suppression avec horodatage, ID de la pièce jointe et statut de réussite |
### `jira_add_worklog`
@@ -361,10 +341,8 @@ Ajouter une entrée de journal de travail pour le suivi du temps à un ticket Ji
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket auquel le journal de travail a été ajouté |
| `worklogId` | string | ID du journal de travail créé |
| `timeSpentSeconds` | number | Temps passé en secondes |
| `success` | booléen | Statut de réussite de l'opération |
| `output` | objet | Détails du journal de travail avec horodatage, clé du ticket, ID du journal de travail, temps passé en secondes et statut de réussite |
### `jira_get_worklogs`
@@ -384,10 +362,8 @@ Obtenir toutes les entrées du journal de travail d'un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `total` | number | Nombre total de journaux de travail |
| `worklogs` | array | Tableau des journaux de travail avec id, auteur, temps passé en secondes, temps passé, commentaire, date de création, mise à jour, démarrage |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Données des journaux de travail avec horodatage, clé du ticket, nombre total et tableau des journaux de travail |
### `jira_update_worklog`
@@ -409,9 +385,8 @@ Mettre à jour une entrée de journal de travail existante sur un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `worklogId` | string | ID du journal de travail mis à jour |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de la mise à jour du journal de travail avec horodatage, clé du ticket, ID du journal de travail et statut de réussite |
### `jira_delete_worklog`
@@ -430,9 +405,8 @@ Supprimer une entrée de journal de travail d'un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `worklogId` | string | ID du journal de travail supprimé |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de la suppression avec horodatage, clé de la demande, ID du journal de travail et statut de réussite |
### `jira_create_issue_link`
@@ -453,11 +427,8 @@ Créer une relation de lien entre deux tickets Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `inwardIssue` | string | Clé du ticket entrant |
| `outwardIssue` | string | Clé du ticket sortant |
| `linkType` | string | Type de lien entre tickets |
| `linkId` | string | ID du lien créé |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails du lien entre tickets avec horodatage, clé du ticket entrant, clé du ticket sortant, type de lien et statut de réussite |
### `jira_delete_issue_link`
@@ -475,8 +446,8 @@ Supprimer un lien entre deux tickets Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `linkId` | string | ID du lien supprimé |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de la suppression avec horodatage, ID du lien et statut de réussite |
### `jira_add_watcher`
@@ -495,9 +466,8 @@ Ajouter un observateur à un ticket Jira pour recevoir des notifications sur les
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `watcherAccountId` | string | ID du compte observateur ajouté |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de l'observateur avec horodatage, clé du ticket, ID de compte de l'observateur et statut de réussite |
### `jira_remove_watcher`
@@ -516,9 +486,8 @@ Supprimer un observateur d'un ticket Jira
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `ts` | string | Horodatage de l'opération |
| `issueKey` | string | Clé du ticket |
| `watcherAccountId` | string | ID du compte observateur supprimé |
| `success` | boolean | Statut de réussite de l'opération |
| `output` | object | Détails de la suppression avec horodatage, clé de la demande, ID du compte observateur et statut de réussite |
## Notes

View File

@@ -1,124 +0,0 @@
---
title: ServiceNow
description: Créer, lire, mettre à jour et supprimer des enregistrements ServiceNow
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="servicenow"
color="#032D42"
/>
{/* MANUAL-CONTENT-START:intro */}
[ServiceNow](https://www.servicenow.com/) est une plateforme cloud puissante conçue pour rationaliser et automatiser la gestion des services informatiques (ITSM), les workflows et les processus métier au sein de votre organisation. ServiceNow vous permet de gérer les incidents, les demandes, les tâches, les utilisateurs et bien plus encore grâce à son API étendue.
Avec ServiceNow, vous pouvez :
- **Automatiser les workflows informatiques** : créer, lire, mettre à jour et supprimer des enregistrements dans n'importe quelle table ServiceNow, tels que les incidents, les tâches, les demandes de changement et les utilisateurs.
- **Intégrer les systèmes** : connecter ServiceNow avec vos autres outils et processus pour une automatisation transparente.
- **Maintenir une source unique de vérité** : garder toutes vos données de service et d'exploitation organisées et accessibles.
- **Améliorer l'efficacité opérationnelle** : réduire le travail manuel et améliorer la qualité du service grâce à des workflows personnalisables et à l'automatisation.
Dans Sim, l'intégration ServiceNow permet à vos agents d'interagir directement avec votre instance ServiceNow dans le cadre de leurs workflows. Les agents peuvent créer, lire, mettre à jour ou supprimer des enregistrements dans n'importe quelle table ServiceNow et exploiter les données de tickets ou d'utilisateurs pour une automatisation et une prise de décision sophistiquées. Cette intégration relie votre automatisation de workflow et vos opérations informatiques, permettant à vos agents de gérer les demandes de service, les incidents, les utilisateurs et les actifs sans intervention manuelle. En connectant Sim avec ServiceNow, vous pouvez automatiser les tâches de gestion des services, améliorer les temps de réponse et garantir un accès cohérent et sécurisé aux données de service vitales de votre organisation.
{/* MANUAL-CONTENT-END */}
## Instructions d'utilisation
Intégrez ServiceNow dans votre workflow. Créez, lisez, mettez à jour et supprimez des enregistrements dans n'importe quelle table ServiceNow, y compris les incidents, les tâches, les demandes de changement, les utilisateurs et bien plus encore.
## Outils
### `servicenow_create_record`
Créer un nouvel enregistrement dans une table ServiceNow
#### Entrée
| Paramètre | Type | Requis | Description |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Oui | URL de l'instance ServiceNow (par ex., https://instance.service-now.com) |
| `username` | string | Oui | Nom d'utilisateur ServiceNow |
| `password` | string | Oui | Mot de passe ServiceNow |
| `tableName` | string | Oui | Nom de la table (par ex., incident, task, sys_user) |
| `fields` | json | Oui | Champs à définir sur l'enregistrement (objet JSON) |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `record` | json | Enregistrement ServiceNow créé avec sys_id et autres champs |
| `metadata` | json | Métadonnées de l'opération |
### `servicenow_read_record`
Lire des enregistrements d'une table ServiceNow
#### Entrée
| Paramètre | Type | Requis | Description |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Oui | URL de l'instance ServiceNow (par ex., https://instance.service-now.com) |
| `username` | string | Oui | Nom d'utilisateur ServiceNow |
| `password` | string | Oui | Mot de passe ServiceNow |
| `tableName` | string | Oui | Nom de la table |
| `sysId` | string | Non | sys_id d'enregistrement spécifique |
| `number` | string | Non | Numéro d'enregistrement (par ex., INC0010001) |
| `query` | string | Non | Chaîne de requête encodée (par ex., "active=true^priority=1") |
| `limit` | number | Non | Nombre maximum d'enregistrements à retourner |
| `fields` | string | Non | Liste de champs à retourner, séparés par des virgules |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `records` | array | Tableau d'enregistrements ServiceNow |
| `metadata` | json | Métadonnées de l'opération |
### `servicenow_update_record`
Mettre à jour un enregistrement existant dans une table ServiceNow
#### Entrée
| Paramètre | Type | Requis | Description |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Oui | URL de l'instance ServiceNow \(par exemple, https://instance.service-now.com\) |
| `username` | string | Oui | Nom d'utilisateur ServiceNow |
| `password` | string | Oui | Mot de passe ServiceNow |
| `tableName` | string | Oui | Nom de la table |
| `sysId` | string | Oui | sys_id de l'enregistrement à mettre à jour |
| `fields` | json | Oui | Champs à mettre à jour \(objet JSON\) |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `record` | json | Enregistrement ServiceNow mis à jour |
| `metadata` | json | Métadonnées de l'opération |
### `servicenow_delete_record`
Supprimer un enregistrement d'une table ServiceNow
#### Entrée
| Paramètre | Type | Requis | Description |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | Oui | URL de l'instance ServiceNow \(par exemple, https://instance.service-now.com\) |
| `username` | string | Oui | Nom d'utilisateur ServiceNow |
| `password` | string | Oui | Mot de passe ServiceNow |
| `tableName` | string | Oui | Nom de la table |
| `sysId` | string | Oui | sys_id de l'enregistrement à supprimer |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Indique si la suppression a réussi |
| `metadata` | json | Métadonnées de l'opération |
## Remarques
- Catégorie : `tools`
- Type : `servicenow`

View File

@@ -54,18 +54,17 @@ Intégrez Slack dans le flux de travail. Peut envoyer, mettre à jour et supprim
### `slack_message`
Envoyez des messages aux canaux Slack ou en messages directs. Prend en charge le formatage mrkdwn de Slack.
Envoyez des messages aux canaux ou utilisateurs Slack via l'API Slack. Prend en charge le formatage mrkdwn de Slack.
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `authMethod` | chaîne | Non | Méthode d'authentification : oauth ou bot_token |
| `botToken` | chaîne | Non | Jeton du bot pour Bot personnalisé |
| `channel` | chaîne | Non | Canal Slack cible \(ex. : #general\) |
| `userId` | chaîne | Non | ID utilisateur Slack cible pour les messages directs \(ex. : U1234567890\) |
| `botToken` | chaîne | Non | Jeton du bot pour le Bot personnalisé |
| `channel` | chaîne | Oui | Canal Slack cible \(par ex., #general\) |
| `text` | chaîne | Oui | Texte du message à envoyer \(prend en charge le formatage mrkdwn de Slack\) |
| `thread_ts` | chaîne | Non | Horodatage du fil de discussion auquel répondre \(crée une réponse dans le fil\) |
| `thread_ts` | chaîne | Non | Horodatage du fil pour répondre \(crée une réponse dans le fil\) |
| `files` | fichier[] | Non | Fichiers à joindre au message |
#### Sortie
@@ -110,8 +109,7 @@ Lisez les derniers messages des canaux Slack. Récupérez l'historique des conve
| --------- | ---- | ---------- | ----------- |
| `authMethod` | chaîne | Non | Méthode d'authentification : oauth ou bot_token |
| `botToken` | chaîne | Non | Jeton du bot pour Bot personnalisé |
| `channel` | chaîne | Non | Canal Slack pour lire les messages \(ex. : #general\) |
| `userId` | chaîne | Non | ID utilisateur pour la conversation en MP \(ex. : U1234567890\) |
| `channel` | chaîne | Oui | Canal Slack pour lire les messages \(ex. : #general\) |
| `limit` | nombre | Non | Nombre de messages à récupérer \(par défaut : 10, max : 100\) |
| `oldest` | chaîne | Non | Début de la plage temporelle \(horodatage\) |
| `latest` | chaîne | Non | Fin de la plage temporelle \(horodatage\) |

View File

@@ -37,18 +37,16 @@ Envoyez une requête de complétion de chat à n'importe quel fournisseur de LLM
#### Entrée
| Paramètre | Type | Requis | Description |
| --------- | ---- | -------- | ----------- |
| `model` | string | Oui | Le modèle à utiliser \(par exemple, gpt-4o, claude-sonnet-4-5, gemini-2.0-flash\) |
| `systemPrompt` | string | Non | Prompt système pour définir le comportement de l'assistant |
| `context` | string | Oui | Le message utilisateur ou le contexte à envoyer au modèle |
| `apiKey` | string | Non | Clé API pour le fournisseur \(utilise la clé de la plateforme si non fournie pour les modèles hébergés\) |
| `temperature` | number | Non | Température pour la génération de réponse \(0-2\) |
| `maxTokens` | number | Non | Nombre maximum de tokens dans la réponse |
| `azureEndpoint` | string | Non | URL du point de terminaison Azure OpenAI |
| `azureApiVersion` | string | Non | Version de l'API Azure OpenAI |
| `vertexProject` | string | Non | ID du projet Google Cloud pour Vertex AI |
| `vertexLocation` | string | Non | Emplacement Google Cloud pour Vertex AI \(par défaut us-central1\) |
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `model` | chaîne | Oui | Le modèle à utiliser (ex. : gpt-4o, claude-sonnet-4-5, gemini-2.0-flash) |
| `systemPrompt` | chaîne | Non | Instruction système pour définir le comportement de l'assistant |
| `context` | chaîne | Oui | Le message utilisateur ou le contexte à envoyer au modèle |
| `apiKey` | chaîne | Non | Clé API pour le fournisseur (utilise la clé de plateforme si non fournie pour les modèles hébergés) |
| `temperature` | nombre | Non | Température pour la génération de réponse (0-2) |
| `maxTokens` | nombre | Non | Nombre maximum de tokens dans la réponse |
| `azureEndpoint` | chaîne | Non | URL du point de terminaison Azure OpenAI |
| `azureApiVersion` | chaîne | Non | Version de l'API Azure OpenAI |
#### Sortie

View File

@@ -38,8 +38,7 @@ Lister tous les éléments d'une collection CMS Webflow
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `siteId` | string | Oui | ID du site Webflow |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Oui | ID de la collection |
| `offset` | number | Non | Décalage pour la pagination \(facultatif\) |
| `limit` | number | Non | Nombre maximum d'éléments à retourner \(facultatif, par défaut : 100\) |
@@ -58,8 +57,7 @@ Obtenir un seul élément d'une collection CMS Webflow
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `siteId` | string | Oui | ID du site Webflow |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Oui | ID de la collection |
| `itemId` | string | Oui | ID de l'élément à récupérer |
@@ -78,9 +76,8 @@ Créer un nouvel élément dans une collection CMS Webflow
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `siteId` | string | Oui | ID du site Webflow |
| `collectionId` | string | Oui | ID de la collection |
| `fieldData` | json | Oui | Données des champs pour le nouvel élément sous forme d'objet JSON. Les clés doivent correspondre aux noms des champs de la collection. |
| `fieldData` | json | Oui | Données de champ pour le nouvel élément sous forme d'objet JSON. Les clés doivent correspondre aux noms des champs de la collection. |
#### Sortie
@@ -97,10 +94,9 @@ Mettre à jour un élément existant dans une collection CMS Webflow
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `siteId` | string | Oui | ID du site Webflow |
| `collectionId` | string | Oui | ID de la collection |
| `itemId` | string | Oui | ID de l'élément à mettre à jour |
| `fieldData` | json | Oui | Données des champs à mettre à jour sous forme d'objet JSON. N'incluez que les champs que vous souhaitez modifier. |
| `fieldData` | json | Oui | Données de champ à mettre à jour sous forme d'objet JSON. N'incluez que les champs que vous souhaitez modifier. |
#### Sortie
@@ -117,7 +113,6 @@ Supprimer un élément d'une collection CMS Webflow
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `siteId` | string | Oui | ID du site Webflow |
| `collectionId` | string | Oui | ID de la collection |
| `itemId` | string | Oui | ID de l'élément à supprimer |

View File

@@ -27,14 +27,12 @@ Dans Sim, l'intégration Zoom permet à vos agents d'automatiser la planificatio
- Récupérer les détails ou les invitations pour n'importe quelle réunion
- Mettre à jour ou supprimer des réunions existantes directement depuis vos automatisations
Pour vous connecter à Zoom, déposez le bloc Zoom et cliquez sur `Connect` pour vous authentifier avec votre compte Zoom. Une fois connecté, vous pouvez utiliser les outils Zoom pour créer, lister, mettre à jour et supprimer des réunions Zoom. À tout moment, vous pouvez déconnecter votre compte Zoom en cliquant sur `Disconnect` dans Paramètres > Intégrations, et l'accès à votre compte Zoom sera immédiatement révoqué.
Ces fonctionnalités vous permettent de rationaliser la collaboration à distance, d'automatiser les sessions vidéo récurrentes et de gérer l'environnement Zoom de votre organisation, le tout dans le cadre de vos flux de travail.
Ces capacités vous permettent de rationaliser la collaboration à distance, d'automatiser les sessions vidéo récurrentes et de gérer l'environnement Zoom de votre organisation, le tout dans le cadre de vos flux de travail.
{/* MANUAL-CONTENT-END */}
## Instructions d'utilisation
Intégrez Zoom dans vos flux de travail. Créez, listez, mettez à jour et supprimez des réunions Zoom. Obtenez les détails des réunions, les invitations, les enregistrements et les participants. Gérez les enregistrements cloud de manière programmatique.
Intégrez Zoom dans les flux de travail. Créez, listez, mettez à jour et supprimez des réunions Zoom. Obtenez les détails des réunions, les invitations, les enregistrements et les participants. Gérez les enregistrements cloud par programmation.
## Outils
@@ -45,7 +43,7 @@ Créer une nouvelle réunion Zoom
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ----------- | ----------- |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Oui | L'ID utilisateur ou l'adresse e-mail. Utilisez "me" pour l'utilisateur authentifié. |
| `topic` | string | Oui | Sujet de la réunion |
| `type` | number | Non | Type de réunion : 1=instantanée, 2=programmée, 3=récurrente sans heure fixe, 8=récurrente à heure fixe |
@@ -59,7 +57,7 @@ Créer une nouvelle réunion Zoom
| `joinBeforeHost` | boolean | Non | Autoriser les participants à rejoindre avant l'hôte |
| `muteUponEntry` | boolean | Non | Mettre les participants en sourdine à l'entrée |
| `waitingRoom` | boolean | Non | Activer la salle d'attente |
| `autoRecording` | string | Non | Paramètre d'enregistrement automatique : local, cloud, ou none |
| `autoRecording` | string | Non | Paramètre d'enregistrement automatique : local, cloud ou none |
#### Sortie
@@ -74,11 +72,11 @@ Lister toutes les réunions pour un utilisateur Zoom
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | -------- | ----------- |
| --------- | ---- | ----------- | ----------- |
| `userId` | string | Oui | L'ID utilisateur ou l'adresse e-mail. Utilisez "me" pour l'utilisateur authentifié. |
| `type` | string | Non | Filtre de type de réunion : scheduled, live, upcoming, upcoming_meetings, ou previous_meetings |
| `pageSize` | number | Non | Nombre d'enregistrements par page \(max 300\) |
| `nextPageToken` | string | Non | Jeton pour la pagination pour obtenir la page suivante de résultats |
| `nextPageToken` | string | Non | Jeton pour la pagination afin d'obtenir la page suivante des résultats |
#### Sortie
@@ -94,7 +92,7 @@ Obtenir les détails d'une réunion Zoom spécifique
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | -------- | ----------- |
| --------- | ---- | ----------- | ----------- |
| `meetingId` | string | Oui | L'ID de la réunion |
| `occurrenceId` | string | Non | ID d'occurrence pour les réunions récurrentes |
| `showPreviousOccurrences` | boolean | Non | Afficher les occurrences précédentes pour les réunions récurrentes |
@@ -105,7 +103,7 @@ Obtenir les détails d'une réunion Zoom spécifique
| --------- | ---- | ----------- |
| `meeting` | object | Les détails de la réunion |
Obtenir les détails d'une réunion Zoom spécifique
### `zoom_update_meeting`
Mettre à jour une réunion Zoom existante
@@ -115,7 +113,7 @@ Mettre à jour une réunion Zoom existante
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Oui | L'ID de la réunion à mettre à jour |
| `topic` | string | Non | Sujet de la réunion |
| `type` | number | Non | Type de réunion : 1=instantanée, 2=programmée, 3=récurrente sans heure fixe, 8=récurrente à heure fixe |
| `type` | number | Non | Type de réunion : 1=instantanée, 2=programmée, 3=récurrente sans horaire fixe, 8=récurrente avec horaire fixe |
| `startTime` | string | Non | Heure de début de la réunion au format ISO 8601 \(ex., 2025-06-03T10:00:00Z\) |
| `duration` | number | Non | Durée de la réunion en minutes |
| `timezone` | string | Non | Fuseau horaire pour la réunion \(ex., America/Los_Angeles\) |
@@ -134,7 +132,7 @@ Mettre à jour une réunion Zoom existante
| --------- | ---- | ----------- |
| `success` | boolean | Indique si la réunion a été mise à jour avec succès |
Supprimer une réunion Zoom
### `zoom_delete_meeting`
Supprimer ou annuler une réunion Zoom
@@ -161,13 +159,13 @@ Obtenir le texte d'invitation pour une réunion Zoom
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Oui | L'ID de la réunion |
| `meetingId` | string | Oui | L'identifiant de la réunion |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `invitation` | string | Le texte d'invitation de la réunion |
| `invitation` | string | Le texte d'invitation à la réunion |
### `zoom_list_recordings`
@@ -177,11 +175,11 @@ Lister tous les enregistrements cloud pour un utilisateur Zoom
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Oui | L'ID utilisateur ou l'adresse e-mail. Utilisez "me" pour l'utilisateur authentifié. |
| `from` | string | Non | Date de début au format aaaa-mm-jj (dans les 6 derniers mois) |
| `userId` | string | Oui | L'identifiant ou l'adresse e-mail de l'utilisateur. Utilisez "me" pour l'utilisateur authentifié. |
| `from` | string | Non | Date de début au format aaaa-mm-jj \(dans les 6 derniers mois\) |
| `to` | string | Non | Date de fin au format aaaa-mm-jj |
| `pageSize` | number | Non | Nombre d'enregistrements par page (max 300) |
| `nextPageToken` | string | Non | Jeton pour la pagination pour obtenir la page suivante de résultats |
| `pageSize` | number | Non | Nombre d'enregistrements par page \(max 300\) |
| `nextPageToken` | string | Non | Jeton pour la pagination afin d'obtenir la page suivante des résultats |
| `trash` | boolean | Non | Définir sur true pour lister les enregistrements de la corbeille |
#### Sortie
@@ -191,7 +189,7 @@ Lister tous les enregistrements cloud pour un utilisateur Zoom
| `recordings` | array | Liste des enregistrements |
| `pageInfo` | object | Informations de pagination |
Obtenir tous les enregistrements pour une réunion Zoom spécifique
### `zoom_get_meeting_recordings`
Obtenir tous les enregistrements pour une réunion Zoom spécifique
@@ -209,9 +207,9 @@ Obtenir tous les enregistrements pour une réunion Zoom spécifique
| --------- | ---- | ----------- |
| `recording` | object | L'enregistrement de la réunion avec tous les fichiers |
Supprimer les enregistrements cloud pour une réunion Zoom
### `zoom_delete_recording`
Supprimer les enregistrements cloud pour une réunion Zoom
Supprimer les enregistrements cloud d'une réunion Zoom
#### Entrée
@@ -227,7 +225,7 @@ Supprimer les enregistrements cloud pour une réunion Zoom
| --------- | ---- | ----------- |
| `success` | boolean | Si l'enregistrement a été supprimé avec succès |
Lister les participants d'une réunion Zoom passée
### `zoom_list_past_participants`
Lister les participants d'une réunion Zoom passée
@@ -235,7 +233,7 @@ Lister les participants d'une réunion Zoom passée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | Oui | L'ID de la réunion passée ou l'UUID |
| `meetingId` | string | Oui | L'ID ou l'UUID de la réunion passée |
| `pageSize` | number | Non | Nombre d'enregistrements par page \(max 300\) |
| `nextPageToken` | string | Non | Jeton pour la pagination pour obtenir la page suivante de résultats |

View File

@@ -110,24 +110,26 @@ import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
```json
{
"content": "Original content passed through",
"conditionResult": true,
"selectedPath": {
"blockId": "2acd9007-27e8-4510-a487-73d3b825e7c1",
"blockType": "agent",
"blockTitle": "Follow-up Agent"
},
"selectedOption": "condition-1"
"selectedConditionId": "condition-1"
}
```
### 条件ブロックの出力フィールド
- **content**: そのまま渡される元のコンテンツ
- **conditionResult**: 条件評価の真偽値結果
- **selectedPath**: 選択されたパスに関する情報
- **blockId**: 選択されたパスの次のブロックのID
- **blockType**: 次のブロックのタイプ
- **blockTitle**: 次のブロックのタイトル
- **selectedOption**: 選択された条件のID
- **selectedConditionId**: 選択された条件のID
</Tab>
<Tab>

View File

@@ -48,13 +48,8 @@ Jiraをワークフローに統合します。課題の読み取り、書き込
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キーPROJ-123 |
| `summary` | string | 課題の要約 |
| `description` | json | 課題の説明内容 |
| `created` | string | 課題作成タイムスタンプ |
| `updated` | string | 課題最終更新タイムスタンプ |
| `issue` | json | すべてのフィールドを含む完全な課題オブジェクト |
| `success` | boolean | 操作成功ステータス |
| `output` | object | 課題キー、要約、説明、作成日時、更新日時を含むJira課題の詳細 |
### `jira_update`
@@ -78,9 +73,8 @@ Jira課題を更新する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 更新された課題キーPROJ-123 |
| `summary` | string | 更新後の課題要約 |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、要約、成功ステータスを含む更新されたJira課題の詳細 |
### `jira_write`
@@ -103,10 +97,8 @@ Jira課題を作成する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 作成された課題キーPROJ-123 |
| `summary` | string | 課題の要約 |
| `url` | string | 作成された課題へのURL |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、要約、成功ステータス、URLを含む作成されたJira課題の詳細 |
### `jira_bulk_read`
@@ -124,7 +116,8 @@ Jira課題を作成する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `issues` | array | タイムスタンプ、要約、説明、作成日時、更新日時を含むJira課題の配列 |
| `success` | boolean | 操作成功ステータス |
| `output` | array | 概要、説明、作成日時、更新日時を含むJiraの課題の配列 |
### `jira_delete_issue`
@@ -143,8 +136,8 @@ Jira課題を削除する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 削除された課題キー |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、成功ステータスを含む削除された課題の詳細 |
### `jira_assign_issue`
@@ -163,9 +156,8 @@ Jira課題をユーザーに割り当てる
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 割り当てられた課題キー |
| `assigneeId` | string | 担当者のアカウントID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、担当者ID、成功ステータスを含む割り当ての詳細 |
### `jira_transition_issue`
@@ -185,9 +177,8 @@ Jira課題をワークフローステータス間で移動するTo Do
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 遷移した課題キー |
| `transitionId` | string | 適用されたトランジションID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、移行ID、成功ステータスを含む移行の詳細 |
### `jira_search_issues`
@@ -208,11 +199,8 @@ JQLJira Query Languageを使用してJira課題を検索する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `total` | number | 一致する課題の総数 |
| `startAt` | number | ページネーション開始インデックス |
| `maxResults` | number | ページあたりの最大結果数 |
| `issues` | array | キー、要約、ステータス、担当者、作成日時、更新日時を含む一致する課題の配列 |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、合計数、ページネーション詳細、一致する課題の配列を含む検索結果 |
### `jira_add_comment`
@@ -231,10 +219,8 @@ Jira課題にコメントを追加する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | コメントが追加された課題キー |
| `commentId` | string | 作成されたコメントID |
| `body` | string | コメントのテキスト内容 |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、コメントID、本文、成功ステータスを含むコメント詳細 |
### `jira_get_comments`
@@ -254,10 +240,8 @@ Jira課題からすべてのコメントを取得する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `total` | number | コメントの総数 |
| `comments` | array | ID、作成者、本文、作成日時、更新日時を含むコメントの配列 |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、合計数、コメントの配列を含むコメントデータ |
### `jira_update_comment`
@@ -277,10 +261,8 @@ Jira課題の既存コメントを更新する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `commentId` | string | 更新されたコメントID |
| `body` | string | 更新されたコメントテキスト |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、コメントID、本文テキスト、成功ステータスを含む更新されたコメントの詳細 |
### `jira_delete_comment`
@@ -299,9 +281,8 @@ Jira課題からコメントを削除する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `commentId` | string | 削除されたコメントID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、コメントID、成功ステータスを含む削除の詳細 |
### `jira_get_attachments`
@@ -319,9 +300,8 @@ Jira課題からすべての添付ファイルを取得する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `attachments` | array | ID、ファイル名、サイズ、MIMEタイプ、作成日時、作成者を含む添付ファイルの配列 |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、添付ファイルの配列を含む添付ファイルデータ |
### `jira_delete_attachment`
@@ -339,8 +319,8 @@ Jira課題から添付ファイルを削除する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `attachmentId` | string | 削除された添付ファイルID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、添付ファイルID、成功ステータスを含む削除の詳細 |
### `jira_add_worklog`
@@ -361,10 +341,8 @@ Jira課題に作業時間記録エントリを追加する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 作業ログが追加された課題キー |
| `worklogId` | string | 作成された作業ログID |
| `timeSpentSeconds` | number | 秒単位の作業時間 |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、作業ログID、秒単位の作業時間、成功ステータスを含む作業ログの詳細 |
### `jira_get_worklogs`
@@ -384,10 +362,8 @@ Jira課題からすべての作業ログエントリを取得する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `total` | number | 作業ログの総数 |
| `worklogs` | array | ID、作成者、秒単位の作業時間、作業時間、コメント、作成日時、更新日時、開始日時を含む作業ログの配列 |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、合計数、作業ログの配列を含む作業ログデータ |
### `jira_update_worklog`
@@ -409,9 +385,8 @@ Jira課題の既存の作業ログエントリを更新する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `worklogId` | string | 更新された作業ログID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、作業ログID、成功ステータスを含む作業ログ更新の詳細 |
### `jira_delete_worklog`
@@ -430,9 +405,8 @@ Jira課題から作業ログエントリを削除する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `worklogId` | string | 削除された作業ログID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、作業ログID、成功ステータスを含む削除の詳細 |
### `jira_create_issue_link`
@@ -453,11 +427,8 @@ Jira課題から作業ログエントリを削除する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `inwardIssue` | string | インワード課題キー |
| `outwardIssue` | string | アウトワード課題キー |
| `linkType` | string | 課題リンクのタイプ |
| `linkId` | string | 作成されたリンクID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、インワード課題キー、アウトワード課題キー、リンクタイプ、成功ステータスを含む課題リンクの詳細 |
### `jira_delete_issue_link`
@@ -475,8 +446,8 @@ Jira課題から作業ログエントリを削除する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `linkId` | string | 削除されたリンクID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、リンクID、成功ステータスを含む削除の詳細 |
### `jira_add_watcher`
@@ -495,9 +466,8 @@ Jira課題から作業ログエントリを削除する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `watcherAccountId` | string | 追加されたウォッチャーのアカウントID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、ウォッチャーアカウントID、成功ステータスを含むウォッチャーの詳細 |
### `jira_remove_watcher`
@@ -516,9 +486,8 @@ Jira課題からウォッチャーを削除する
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `ts` | string | 操作のタイムスタンプ |
| `issueKey` | string | 課題キー |
| `watcherAccountId` | string | 削除されたウォッチャーのアカウントID |
| `success` | boolean | 操作成功ステータス |
| `output` | object | タイムスタンプ、課題キー、ウォッチャーアカウントID、成功ステータスを含む削除詳細 |
## 注意事項

View File

@@ -1,124 +0,0 @@
---
title: ServiceNow
description: ServiceNowレコードの作成、読み取り、更新、削除
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="servicenow"
color="#032D42"
/>
{/* MANUAL-CONTENT-START:intro */}
[ServiceNow](https://www.servicenow.com/)は、組織全体のITサービス管理ITSM、ワークフロー、ビジネスプロセスを効率化し自動化するために設計された強力なクラウドプラットフォームです。ServiceNowを使用すると、広範なAPIを使用してインシデント、リクエスト、タスク、ユーザーなどを管理できます。
ServiceNowでは、次のことができます。
- **ITワークフローの自動化**: インシデント、タスク、変更リクエスト、ユーザーなど、任意のServiceNowテーブルのレコードを作成、読み取り、更新、削除します。
- **システムの統合**: ServiceNowを他のツールやプロセスと接続して、シームレスな自動化を実現します。
- **単一の信頼できる情報源の維持**: すべてのサービスおよび運用データを整理してアクセス可能な状態に保ちます。
- **運用効率の向上**: カスタマイズ可能なワークフローと自動化により、手作業を削減し、サービス品質を向上させます。
Simでは、ServiceNow統合により、エージェントがワークフローの一部としてServiceNowインスタンスと直接やり取りできるようになります。エージェントは、任意のServiceNowテーブルのレコードを作成、読み取り、更新、削除でき、チケットやユーザーデータを活用して高度な自動化と意思決定を行うことができます。この統合により、ワークフロー自動化とIT運用が橋渡しされ、エージェントは手動介入なしでサービスリクエスト、インシデント、ユーザー、資産を管理できるようになります。SimとServiceNowを接続することで、サービス管理タスクを自動化し、応答時間を改善し、組織の重要なサービスデータへの一貫性のある安全なアクセスを確保できます。
{/* MANUAL-CONTENT-END */}
## 使用方法
ServiceNowをワークフローに統合します。インシデント、タスク、変更リクエスト、ユーザーなど、任意のServiceNowテーブルのレコードを作成、読み取り、更新、削除します。
## ツール
### `servicenow_create_record`
ServiceNowテーブルに新しいレコードを作成
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | はい | ServiceNowインスタンスURL(例: https://instance.service-now.com) |
| `username` | string | はい | ServiceNowユーザー名 |
| `password` | string | はい | ServiceNowパスワード |
| `tableName` | string | はい | テーブル名(例: incident、task、sys_user) |
| `fields` | json | はい | レコードに設定するフィールド(JSONオブジェクト) |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `record` | json | sys_idおよびその他のフィールドを含む作成されたServiceNowレコード |
| `metadata` | json | 操作メタデータ |
### `servicenow_read_record`
ServiceNowテーブルからレコードを読み取ります
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | はい | ServiceNowインスタンスURL(例: https://instance.service-now.com) |
| `username` | string | はい | ServiceNowユーザー名 |
| `password` | string | はい | ServiceNowパスワード |
| `tableName` | string | はい | テーブル名 |
| `sysId` | string | いいえ | 特定のレコードのsys_id |
| `number` | string | いいえ | レコード番号(例: INC0010001) |
| `query` | string | いいえ | エンコードされたクエリ文字列(例: "active=true^priority=1") |
| `limit` | number | いいえ | 返すレコードの最大数 |
| `fields` | string | いいえ | 返すフィールドのカンマ区切りリスト |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `records` | array | ServiceNowレコードの配列 |
| `metadata` | json | 操作メタデータ |
### `servicenow_update_record`
ServiceNowテーブル内の既存のレコードを更新
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | はい | ServiceNowインスタンスURLhttps://instance.service-now.com |
| `username` | string | はい | ServiceNowユーザー名 |
| `password` | string | はい | ServiceNowパスワード |
| `tableName` | string | はい | テーブル名 |
| `sysId` | string | はい | 更新するレコードのsys_id |
| `fields` | json | はい | 更新するフィールドJSONオブジェクト |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `record` | json | 更新されたServiceNowレコード |
| `metadata` | json | 操作メタデータ |
### `servicenow_delete_record`
ServiceNowテーブルからレコードを削除
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | はい | ServiceNowインスタンスURLhttps://instance.service-now.com |
| `username` | string | はい | ServiceNowユーザー名 |
| `password` | string | はい | ServiceNowパスワード |
| `tableName` | string | はい | テーブル名 |
| `sysId` | string | はい | 削除するレコードのsys_id |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `success` | boolean | 削除が成功したかどうか |
| `metadata` | json | 操作メタデータ |
## 注意事項
- カテゴリ: `tools`
- タイプ: `servicenow`

View File

@@ -53,7 +53,7 @@ Slackをワークフローに統合します。メッセージの送信、更新
### `slack_message`
Slackチャンネルまたはダイレクトメッセージにメッセージを送信します。Slack mrkdwn形式をサポートしています。
Slack APIを通じてSlackチャンネルまたはユーザーにメッセージを送信します。Slack mrkdwnフォーマットをサポートしています。
#### 入力
@@ -61,8 +61,7 @@ Slackチャンネルまたはダイレクトメッセージにメッセージを
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | いいえ | 認証方法oauthまたはbot_token |
| `botToken` | string | いいえ | カスタムボット用のボットトークン |
| `channel` | string | いいえ | 対象のSlackチャンネル#general |
| `userId` | string | いいえ | ダイレクトメッセージ用の対象SlackユーザーIDU1234567890 |
| `channel` | string | い | 対象のSlackチャンネル#general |
| `text` | string | はい | 送信するメッセージテキストSlack mrkdwn形式をサポート |
| `thread_ts` | string | いいえ | 返信するスレッドのタイムスタンプ(スレッド返信を作成) |
| `files` | file[] | いいえ | メッセージに添付するファイル |
@@ -109,8 +108,7 @@ Slackチャンネルから最新のメッセージを読み取ります。フィ
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | いいえ | 認証方法oauthまたはbot_token |
| `botToken` | string | いいえ | カスタムボット用のボットトークン |
| `channel` | string | いいえ | メッセージを読み取るSlackチャンネル#general |
| `userId` | string | いいえ | DMの会話用のユーザーIDU1234567890 |
| `channel` | string | い | メッセージを読み取るSlackチャンネル#general |
| `limit` | number | いいえ | 取得するメッセージ数デフォルト10、最大100 |
| `oldest` | string | いいえ | 時間範囲の開始(タイムスタンプ) |
| `latest` | string | いいえ | 時間範囲の終了(タイムスタンプ) |

View File

@@ -42,13 +42,11 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| `model` | string | はい | 使用するモデルgpt-4o、claude-sonnet-4-5、gemini-2.0-flash |
| `systemPrompt` | string | いいえ | アシスタントの動作を設定するシステムプロンプト |
| `context` | string | はい | モデルに送信するユーザーメッセージまたはコンテキスト |
| `apiKey` | string | いいえ | プロバイダーのAPIキーホストされたモデルの場合、提供されない場合はプラットフォームキーを使用) |
| `apiKey` | string | いいえ | プロバイダーのAPIキーホストされたモデルの場合、提供されなければプラットフォームキーを使用) |
| `temperature` | number | いいえ | レスポンス生成の温度0-2 |
| `maxTokens` | number | いいえ | レスポンスの最大トークン数 |
| `azureEndpoint` | string | いいえ | Azure OpenAIエンドポイントURL |
| `azureApiVersion` | string | いいえ | Azure OpenAI APIバージョン |
| `vertexProject` | string | いいえ | Vertex AI用のGoogle CloudプロジェクトID |
| `vertexLocation` | string | いいえ | Vertex AI用のGoogle Cloudロケーションデフォルトはus-central1 |
#### 出力

View File

@@ -39,10 +39,9 @@ Webflow CMSコレクションからすべてのアイテムを一覧表示する
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | はい | WebflowサイトのID |
| `collectionId` | string | はい | コレクションのID |
| `offset` | number | いいえ | ページネーション用のオフセット(オプション) |
| `limit` | number | いいえ | 返す最大アイテム数オプション、デフォルト100 |
| `limit` | number | いいえ | 返すアイテムの最大オプション、デフォルト100 |
#### 出力
@@ -59,7 +58,6 @@ Webflow CMSコレクションから単一のアイテムを取得する
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | はい | WebflowサイトのID |
| `collectionId` | string | はい | コレクションのID |
| `itemId` | string | はい | 取得するアイテムのID |
@@ -78,9 +76,8 @@ Webflow CMSコレクションに新しいアイテムを作成する
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | はい | WebflowサイトのID |
| `collectionId` | string | はい | コレクションのID |
| `fieldData` | json | はい | 新しいアイテムのフィールドデータJSONオブジェクト。キーはコレクションフィールド名と一致する必要があります。 |
| `fieldData` | json | はい | 新しいアイテムのフィールドデータJSONオブジェクト形式)。キーはコレクションフィールド名と一致する必要があります。 |
#### 出力
@@ -97,10 +94,9 @@ Webflow CMSコレクション内の既存アイテムを更新する
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | はい | WebflowサイトのID |
| `collectionId` | string | はい | コレクションのID |
| `itemId` | string | はい | 更新するアイテムのID |
| `fieldData` | json | はい | 更新するフィールドデータJSONオブジェクト。変更したいフィールドのみを含めてください。 |
| `fieldData` | json | はい | 更新するフィールドデータJSONオブジェクト形式)。変更したいフィールドのみを含めてください。 |
#### 出力
@@ -117,7 +113,6 @@ Webflow CMSコレクションからアイテムを削除する
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | はい | WebflowサイトのID |
| `collectionId` | string | はい | コレクションのID |
| `itemId` | string | はい | 削除するアイテムのID |

View File

@@ -27,12 +27,10 @@ Simでは、Zoom統合によりエージェントがスケジュール設定と
- 任意の会議の詳細や招待状を取得
- 自動化から直接既存の会議を更新または削除
Zoomに接続するには、Zoomブロックをドロップして `Connect` をクリックし、Zoomアカウントで認証します。接続後、Zoomツールを使用してZoomミーティングの作成、一覧表示、更新、削除ができます。いつでも設定 > 統合から `Disconnect` をクリックしてZoomアカウントの接続を解除でき、Zoomアカウントへのアクセスは直ちに取り消されます。
これらの機能により、リモートコラボレーションの効率化、定期的なビデオセッションの自動化、組織のZoom環境の管理をワークフローの一部として行うことができます。
これらの機能により、リモートコラボレーションの効率化、定期的なビデオセッションの自動化、ワークフローの一部として組織のZoom環境を管理することができます。
{/* MANUAL-CONTENT-END */}
## 使用手順
## 使用方法
Zoomをワークフローに統合します。Zoomミーティングの作成、一覧表示、更新、削除ができます。ミーティングの詳細、招待状、録画、参加者を取得します。クラウド録画をプログラムで管理します。
@@ -44,11 +42,11 @@ Zoomをワークフローに統合します。Zoomミーティングの作成、
#### 入力
| パラメータ | | 必須 | 説明 |
| パラメータ | 種類 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `userId` | string | はい | ユーザーIDまたはメールアドレス。認証済みユーザーの場合は「me」を使用。 |
| `topic` | string | はい | ミーティングのトピック |
| `type` | number | いいえ | ミーティングタイプ: 1=即時、2=予定済み、3=固定時間なしの定期的、8=固定時間の定期的 |
| `type` | number | いいえ | ミーティングタイプ: 1=即時、2=予定、3=固定時間なしの定期的、8=固定時間の定期的 |
| `startTime` | string | いいえ | ISO 8601形式のミーティング開始時間2025-06-03T10:00:00Z |
| `duration` | number | いいえ | ミーティング時間(分) |
| `timezone` | string | いいえ | ミーティングのタイムゾーンAmerica/Los_Angeles |
@@ -58,8 +56,8 @@ Zoomをワークフローに統合します。Zoomミーティングの作成、
| `participantVideo` | boolean | いいえ | 参加者のビデオをオンにして開始 |
| `joinBeforeHost` | boolean | いいえ | ホスト前の参加者の入室を許可 |
| `muteUponEntry` | boolean | いいえ | 入室時に参加者をミュート |
| `waitingRoom` | boolean | いいえ | 待機室を有効にする |
| `autoRecording` | string | いいえ | 自動録画設定: local、cloud、またはnone |
| `waitingRoom` | boolean | いいえ | 待機室を有効 |
| `autoRecording` | string | いいえ | 自動録画設定local、cloud、またはnone |
#### 出力
@@ -69,14 +67,14 @@ Zoomをワークフローに統合します。Zoomミーティングの作成、
### `zoom_list_meetings`
Zoomユーザーのすべてのミーティングをリスト表示する
Zoomユーザーのすべてのミーティングを一覧表示する
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `userId` | string | はい | ユーザーIDまたはメールアドレス。認証済みユーザーの場合は「me」を使用。 |
| `type` | string | いいえ | ミーティングタイプフィルター: scheduled、live、upcoming、upcoming_meetings、またはprevious_meetings |
| `type` | string | いいえ | ミーティングタイプフィルター: scheduled、live、upcoming、upcoming_meetings、または previous_meetings |
| `pageSize` | number | いいえ | ページあたりのレコード数最大300 |
| `nextPageToken` | string | いいえ | 次のページの結果を取得するためのページネーショントークン |
@@ -96,8 +94,8 @@ Zoomユーザーのすべてのミーティングをリスト表示する
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | はい | ミーティングID |
| `occurrenceId` | string | いいえ | 定期的なミーティングの発生ID |
| `showPreviousOccurrences` | boolean | いいえ | 定期的なミーティングの過去の発生を表示 |
| `occurrenceId` | string | いいえ | 定期的なミーティングの開催ID |
| `showPreviousOccurrences` | boolean | いいえ | 定期的なミーティングの過去の開催を表示 |
#### 出力
@@ -105,17 +103,17 @@ Zoomユーザーのすべてのミーティングをリスト表示する
| --------- | ---- | ----------- |
| `meeting` | object | ミーティングの詳細 |
特定のZoomミーティングの詳細を取得する
### `zoom_update_meeting`
既存のZoomミーティングを更新する
#### 入力
| パラメータ | 種類 | 必須 | 説明 |
| パラメータ | | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | はい | 更新するミーティングID |
| `topic` | string | いいえ | ミーティングのトピック |
| `type` | number | いいえ | ミーティングタイプ: 1=即時、2=予定、3=固定時間なしの定期的、8=固定時間の定期的 |
| `type` | number | いいえ | ミーティングタイプ: 1=インスタント、2=予定済み、3=定期的(固定時間なし、8=定期的(固定時間) |
| `startTime` | string | いいえ | ISO 8601形式のミーティング開始時間2025-06-03T10:00:00Z |
| `duration` | number | いいえ | ミーティング時間(分) |
| `timezone` | string | いいえ | ミーティングのタイムゾーンAmerica/Los_Angeles |
@@ -123,10 +121,10 @@ Zoomユーザーのすべてのミーティングをリスト表示する
| `agenda` | string | いいえ | ミーティングの議題 |
| `hostVideo` | boolean | いいえ | ホストのビデオをオンにして開始 |
| `participantVideo` | boolean | いいえ | 参加者のビデオをオンにして開始 |
| `joinBeforeHost` | boolean | いいえ | ホスト前の参加者の入室を許可 |
| `joinBeforeHost` | boolean | いいえ | ホストより前の参加者の入室を許可 |
| `muteUponEntry` | boolean | いいえ | 入室時に参加者をミュート |
| `waitingRoom` | boolean | いいえ | 待機室を有効 |
| `autoRecording` | string | いいえ | 自動録画設定:local、cloud、またはnone |
| `waitingRoom` | boolean | いいえ | 待機室を有効にする |
| `autoRecording` | string | いいえ | 自動録画設定:ローカル、クラウド、または無し |
#### 出力
@@ -134,17 +132,17 @@ Zoomユーザーのすべてのミーティングをリスト表示する
| --------- | ---- | ----------- |
| `success` | boolean | ミーティングが正常に更新されたかどうか |
Zoomミーティングを削除またはキャンセルする
### `zoom_delete_meeting`
Zoomミーティングを削除またはキャンセルする
#### 入力
| パラメータ | 種類 | 必須 | 説明 |
| パラメータ | | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | はい | 削除するミーティングID |
| `occurrenceId` | string | いいえ | 定期的なミーティングの特定の回を削除するための回数ID |
| `scheduleForReminder` | boolean | いいえ | 登録者にキャンセルリマインダーメールを送信 |
| `occurrenceId` | string | いいえ | 定期的なミーティングの特定の回を削除するための発生ID |
| `scheduleForReminder` | boolean | いいえ | 登録者にキャンセルリマインダーメールを送信 |
| `cancelMeetingReminder` | boolean | いいえ | 登録者と代替ホストにキャンセルメールを送信 |
#### 出力
@@ -171,18 +169,18 @@ Zoomミーティングの招待テキストを取得する
### `zoom_list_recordings`
Zoomユーザーのすべてのクラウド録画を一覧表示する
Zoomユーザーのすべてのクラウド録画をリスト表示する
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `userId` | string | はい | ユーザーIDまたはメールアドレス。認証済みユーザーの場合は「me」を使用。 |
| `from` | string | いいえ | 開始日yyyy-mm-dd形式過去6ヶ月以内 |
| `from` | string | いいえ | 開始日yyyy-mm-dd形式\(過去6ヶ月以内\) |
| `to` | string | いいえ | 終了日yyyy-mm-dd形式 |
| `pageSize` | number | いいえ | 1ページあたりのレコード数最大300 |
| `pageSize` | number | いいえ | ページあたりのレコード数最大300 |
| `nextPageToken` | string | いいえ | 次のページの結果を取得するためのページネーショントークン |
| `trash` | boolean | いいえ | ゴミ箱から録画を一覧表示するにはtrueに設定 |
| `trash` | boolean | いいえ | ゴミ箱から録画をリスト表示するにはtrueに設定 |
#### 出力
@@ -191,9 +189,9 @@ Zoomユーザーのすべてのクラウド録画を一覧表示する
| `recordings` | array | 録画のリスト |
| `pageInfo` | object | ページネーション情報 |
特定のZoomミーティングのすべての録画を取得する
### `zoom_get_meeting_recordings`
特定のZoomミーティングのすべての録画を取得する
特定のZoomミーティングのての録画を取得する
#### 入力
@@ -209,7 +207,7 @@ Zoomユーザーのすべてのクラウド録画を一覧表示する
| --------- | ---- | ----------- |
| `recording` | object | すべてのファイルを含むミーティング録画 |
Zoomミーティングのクラウド録画を削除する
### `zoom_delete_recording`
Zoomミーティングのクラウド録画を削除する
@@ -227,7 +225,7 @@ Zoomミーティングのクラウド録画を削除する
| --------- | ---- | ----------- |
| `success` | boolean | 録画が正常に削除されたかどうか |
過去のZoomミーティングの参加者を一覧表示する
### `zoom_list_past_participants`
過去のZoomミーティングの参加者を一覧表示する
@@ -237,16 +235,16 @@ Zoomミーティングのクラウド録画を削除する
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | はい | 過去のミーティングIDまたはUUID |
| `pageSize` | number | いいえ | ページあたりのレコード数最大300 |
| `nextPageToken` | string | いいえ | 結果の次のページを取得するためのページトークン |
| `nextPageToken` | string | いいえ | 結果の次のページを取得するためのページネーショントークン |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `participants` | array | ミーティング参加者のリスト |
| `participants` | array | 会議参加者のリスト |
| `pageInfo` | object | ページネーション情報 |
## 注意事項
- カテゴリ: `tools`
- カテゴリ: `tools`
- タイプ: `zoom`

View File

@@ -110,24 +110,26 @@ import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
```json
{
"content": "Original content passed through",
"conditionResult": true,
"selectedPath": {
"blockId": "2acd9007-27e8-4510-a487-73d3b825e7c1",
"blockType": "agent",
"blockTitle": "Follow-up Agent"
},
"selectedOption": "condition-1"
"selectedConditionId": "condition-1"
}
```
### 条件模块输出字段
- **conditionResult**:条件判断的布尔值结果
- **selectedPath**:所选路径的信息
- **blockId**:所选路径下一个区块的 ID
- **blockType**下一个块的类型
- **blockTitle**:下一个块的标题
- **selectedOption**:所选条件的 ID
- **content**:传递的原始内容
- **conditionResult**:条件评估的布尔结果
- **selectedPath**:关于选定路径的信息
- **blockId**:选定路径中下一个块的 ID
- **blockType**:下一个块的类型
- **blockTitle**:下一个模块的标题
- **selectedConditionId**:选定条件的 ID
</Tab>
<Tab>

View File

@@ -48,13 +48,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | 字符串 | 操作的时间戳 |
| `issueKey` | 字符串 | 问题键 \(例如PROJ-123\) |
| `summary` | 字符串 | 问题摘要 |
| `description` | JSON | 问题描述内容 |
| `created` | 字符串 | 问题创建的时间戳 |
| `updated` | 字符串 | 问题最后更新的时间戳 |
| `issue` | JSON | 包含所有字段的完整问题对象 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 包含问题键、摘要、描述、创建和更新时间戳的 Jira 问题详细信息 |
### `jira_update`
@@ -78,9 +73,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | 字符串 | 操作的时间戳 |
| `issueKey` | 字符串 | 更新后的问题键 \(例如PROJ-123\) |
| `summary` | 字符串 | 更新后的问题摘要 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 更新的 Jira 问题详情,包括时间戳、问题键、摘要和成功状态 |
### `jira_write`
@@ -103,10 +97,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | 字符串 | 操作的时间戳 |
| `issueKey` | 字符串 | 创建的问题键 \(例如PROJ-123\) |
| `summary` | 字符串 | 问题摘要 |
| `url` | 字符串 | 创建的问题的 URL |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 创建的 Jira 问题详情,包括时间戳、问题键、摘要、成功状态和 URL |
### `jira_bulk_read`
@@ -124,7 +116,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `issues` | 数组 | 包含时间戳、摘要、描述、创建和更新时间戳的 Jira 问题数组 |
| `success` | boolean | 操作成功状态 |
| `output` | array | 包含 Jira 问题的数组,包括摘要、描述、创建和更新的时间戳 |
### `jira_delete_issue`
@@ -143,8 +136,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | 字符串 | 操作的时间戳 |
| `issueKey` | 字符串 | 删除的问题 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 删除的问题详情,包括时间戳、问题键和成功状态 |
### `jira_assign_issue`
@@ -163,9 +156,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | 字符串 | 操作的时间戳 |
| `issueKey` | 字符串 | 分配的任务键 |
| `assigneeId` | 字符串 | 分配者的账户 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 分配详情,包括时间戳、问题键、分配人 ID 和成功状态 |
### `jira_transition_issue`
@@ -185,9 +177,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 转换的问题键 |
| `transitionId` | string | 应用的转换 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 转换详情,包括时间戳、问题键、转换 ID 和成功状态 |
### `jira_search_issues`
@@ -208,11 +199,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `total` | number | 匹配问题的数 |
| `startAt` | number | 分页起始索引 |
| `maxResults` | number | 每页的最大结果数 |
| `issues` | array | 包含键、摘要、状态、负责人、创建时间和更新时间的匹配问题数组 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 搜索结果,包括时间戳、总数、分页详情和匹配问题的数 |
### `jira_add_comment`
@@ -231,10 +219,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 添加评论的问题键 |
| `commentId` | string | 创建的评论 ID |
| `body` | string | 评论的文本内容 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 评论详情,包括时间戳、问题键、评论 ID、正文和成功状态 |
### `jira_get_comments`
@@ -254,10 +240,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `total` | number | 评论的总数 |
| `comments` | array | 包含 ID、作者、正文、创建时间和更新时间的评论数组 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 评论数据,包括时间戳、问题键、总数和评论数组 |
### `jira_update_comment`
@@ -277,10 +261,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `commentId` | string | 更新的评论 ID |
| `body` | string | 更新的评论文本 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 更新的评论详情,包括时间戳、问题键、评论 ID、正文文本和成功状态 |
### `jira_delete_comment`
@@ -299,9 +281,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `commentId` | string | 已删除的评论 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 删除详情,包括时间戳、问题键、评论 ID 和成功状态 |
### `jira_get_attachments`
@@ -319,9 +300,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `attachments` | array | 附件数组,包括 id、文件名、大小、mimeType、创建时间、作者 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 附件数据,包括时间戳、问题键和附件数组 |
### `jira_delete_attachment`
@@ -339,8 +319,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `attachmentId` | string | 删除的附件 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 删除详情,包括时间戳、附件 ID 和成功状态 |
### `jira_add_worklog`
@@ -361,10 +341,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 添加工作日志的相关问题键 |
| `worklogId` | string | 创建的工作日志 ID |
| `timeSpentSeconds` | number | 花费的时间(以秒为单位) |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 工作日志详情,包括时间戳、问题键、工作日志 ID、花费的时间以秒为单位和成功状态 |
### `jira_get_worklogs`
@@ -384,10 +362,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `total` | number | 工作日志的总数 |
| `worklogs` | array | 工作日志数组,包括 id、作者、timeSpentSeconds、timeSpent、评论、创建时间、更新时间、开始时间 |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 包含时间戳、问题键、总数和工作日志数组的工作日志数据 |
### `jira_update_worklog`
@@ -409,9 +385,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `worklogId` | string | 更新的工作日志 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 包含时间戳、问题键、工作日志 ID 和成功状态的工作日志更新详情 |
### `jira_delete_worklog`
@@ -430,9 +405,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `worklogId` | string | 已删除的工作日志 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 删除详情,包括时间戳、问题键、工作日志 ID 和成功状态 |
### `jira_create_issue_link`
@@ -453,11 +427,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `inwardIssue` | string | 内部问题键 |
| `outwardIssue` | string | 外部问题键 |
| `linkType` | string | 问题链接的类型 |
| `linkId` | string | 创建的链接 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 问题链接详情,包括时间戳、内部问题键、外部问题键、链接类型和成功状态 |
### `jira_delete_issue_link`
@@ -475,8 +446,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `linkId` | string | 删除的链接 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 删除详情,包括时间戳、链接 ID 和成功状态 |
### `jira_add_watcher`
@@ -495,9 +466,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `watcherAccountId` | string | 添加的观察者账户 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 观察者详情,包括时间戳、问题键、观察者账户 ID 和成功状态 |
### `jira_remove_watcher`
@@ -516,9 +486,8 @@ Jira 的主要功能包括:
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `ts` | string | 操作的时间戳 |
| `issueKey` | string | 问题键 |
| `watcherAccountId` | string | 移除的观察者账户 ID |
| `success` | 布尔值 | 操作成功状态 |
| `output` | 对象 | 移除详情,包括时间戳、问题键、观察者账户 ID 和成功状态 |
## 注意事项

View File

@@ -1,124 +0,0 @@
---
title: ServiceNow
description: 创建、读取、更新和删除 ServiceNow 记录
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="servicenow"
color="#032D42"
/>
{/* MANUAL-CONTENT-START:intro */}
[ServiceNow](https://www.servicenow.com/) 是一款强大的云平台,旨在简化和自动化 IT 服务管理ITSM、工作流以及企业各类业务流程。ServiceNow 让您能够通过其强大的 API 管理事件、请求、任务、用户等多种内容。
使用 ServiceNow您可以
- **自动化 IT 工作流**:在任意 ServiceNow 表中创建、读取、更新和删除记录,如事件、任务、变更请求和用户等。
- **集成系统**:将 ServiceNow 与您的其他工具和流程连接,实现无缝自动化。
- **维护单一数据源**:让所有服务和运营数据井然有序,便于访问。
- **提升运营效率**:通过可定制的工作流和自动化,减少手动操作,提高服务质量。
在 Sim 中ServiceNow 集成让您的代理能够在工作流中直接与 ServiceNow 实例交互。代理可以在任意 ServiceNow 表中创建、读取、更新或删除记录,并利用工单或用户数据实现复杂的自动化和决策。这一集成将您的工作流自动化与 IT 运维无缝衔接,使代理能够自动化管理服务请求、事件、用户和资产,无需人工干预。通过将 Sim 与 ServiceNow 连接,您可以自动化服务管理任务、提升响应速度,并确保对组织关键服务数据的持续、安全访问。
{/* MANUAL-CONTENT-END */}
## 使用说明
将 ServiceNow 集成到您的工作流中。在任意 ServiceNow 表(包括事件、任务、变更请求、用户等)中创建、读取、更新和删除记录。
## 工具
### `servicenow_create_record`
在 ServiceNow 表中创建新记录
#### 输入
| 参数 | 类型 | 是否必填 | 描述 |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | 是 | ServiceNow 实例 URL例如https://instance.service-now.com |
| `username` | string | 是 | ServiceNow 用户名 |
| `password` | string | 是 | ServiceNow 密码 |
| `tableName` | string | 是 | 表名例如incident、task、sys_user |
| `fields` | json | 是 | 记录中要设置的字段JSON 对象) |
#### 输出
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `record` | json | 创建的 ServiceNow 记录,包含 sys_id 及其他字段 |
| `metadata` | json | 操作元数据 |
### `servicenow_read_record`
从 ServiceNow 表中读取记录
#### 输入
| 参数 | 类型 | 是否必填 | 描述 |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | 是 | ServiceNow 实例 URL例如https://instance.service-now.com |
| `username` | string | 是 | ServiceNow 用户名 |
| `password` | string | 是 | ServiceNow 密码 |
| `tableName` | string | 是 | 表名 |
| `sysId` | string | 否 | 指定记录 sys_id |
| `number` | string | 否 | 记录编号例如INC0010001 |
| `query` | string | 否 | 编码查询字符串(例如:"active=true^priority=1" |
| `limit` | number | 否 | 返回的最大记录数 |
| `fields` | string | 否 | 要返回的字段列表(以逗号分隔) |
#### 输出
| 参数 | 类型 | 说明 |
| --------- | ---- | ----------- |
| `records` | array | ServiceNow 记录数组 |
| `metadata` | json | 操作元数据 |
### `servicenow_update_record`
更新 ServiceNow 表中的现有记录
#### 输入
| 参数 | 类型 | 必填 | 说明 |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | 是 | ServiceNow 实例 URL例如https://instance.service-now.com |
| `username` | string | 是 | ServiceNow 用户名 |
| `password` | string | 是 | ServiceNow 密码 |
| `tableName` | string | 是 | 表名 |
| `sysId` | string | 是 | 要更新的记录 sys_id |
| `fields` | json | 是 | 要更新的字段JSON 对象) |
#### 输出
| 参数 | 类型 | 说明 |
| --------- | ---- | ----------- |
| `record` | json | 已更新的 ServiceNow 记录 |
| `metadata` | json | 操作元数据 |
### `servicenow_delete_record`
从 ServiceNow 表中删除记录
#### 输入
| 参数 | 类型 | 必填 | 说明 |
| --------- | ---- | -------- | ----------- |
| `instanceUrl` | string | 是 | ServiceNow 实例 URL例如https://instance.service-now.com |
| `username` | string | 是 | ServiceNow 用户名 |
| `password` | string | 是 | ServiceNow 密码 |
| `tableName` | string | 是 | 表名 |
| `sysId` | string | 是 | 要删除的记录 sys_id |
#### 输出
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `success` | boolean | 删除是否成功 |
| `metadata` | json | 操作元数据 |
## 备注
- 分类:`tools`
- 类型:`servicenow`

View File

@@ -52,7 +52,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
### `slack_message`
向 Slack 频道或直接消息发送消息。支持 Slack mrkdwn 格式。
通过 Slack API 向 Slack 频道或用户发送消息。支持 Slack mrkdwn 格式
#### 输入
@@ -60,11 +60,10 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | 否 | 认证方法oauth 或 bot_token |
| `botToken` | string | 否 | 自定义 Bot 的令牌 |
| `channel` | string | | 目标 Slack 频道(例如,#general |
| `userId` | string | 否 | 目标 Slack 用户 ID用于直接消息例如U1234567890 |
| `channel` | string | | 目标 Slack 频道(例如,#general |
| `text` | string | 是 | 要发送的消息文本(支持 Slack mrkdwn 格式) |
| `thread_ts` | string | 否 | 回复的线程时间戳(创建线程回复) |
| `files` | file[] | 否 | 附加到消息的文件 |
| `thread_ts` | string | 否 | 回复的线程时间戳(创建线程回复) |
| `files` | file[] | 否 | 附加到消息的文件 |
#### 输出
@@ -104,12 +103,11 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
#### 输入
| 参数 | 类型 | 是否必需 | 描述 |
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `authMethod` | string | 否 | 认证方法oauth 或 bot_token |
| `botToken` | string | 否 | 自定义 Bot 的令牌 |
| `channel` | string | | 要读取消息的 Slack 频道(例如#general |
| `userId` | string | 否 | DM 对话的用户 ID例如U1234567890 |
| `botToken` | string | 否 | 自定义 Bot 的 Bot token |
| `channel` | string | | 要读取消息的 Slack 频道(例如#general |
| `limit` | number | 否 | 要检索的消息数量默认10最大100 |
| `oldest` | string | 否 | 时间范围的开始(时间戳) |
| `latest` | string | 否 | 时间范围的结束(时间戳) |

View File

@@ -37,18 +37,16 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
#### 输入
| 参数 | 类型 | 必 | 说明 |
| 参数 | 类型 | 必 | 描述 |
| --------- | ---- | -------- | ----------- |
| `model` | string | 是 | 要使用的模型例如 gpt-4o、claude-sonnet-4-5、gemini-2.0-flash |
| `systemPrompt` | string | 否 | 设置助手行为的 system prompt |
| `context` | string | 是 | 发送给模型的用户消息或上下文 |
| `apiKey` | string | 否 | 提供的 API key如未提供托管模型将使用平台密钥 |
| `temperature` | number | 否 | 响应生成的 temperature0-2 |
| `maxTokens` | number | 否 | 响应的最大 tokens 数 |
| `azureEndpoint` | string | 否 | Azure OpenAI endpoint URL |
| `model` | string | 是 | 要使用的模型 \(例如gpt-4o、claude-sonnet-4-5、gemini-2.0-flash\) |
| `systemPrompt` | string | 否 | 设置助手行为的系统提示 |
| `context` | string | 是 | 发送给模型的用户消息或上下文 |
| `apiKey` | string | 否 | 提供的 API 密钥 \(如果未为托管模型提供,则使用平台密钥\) |
| `temperature` | number | 否 | 响应生成的温度 \(0-2\) |
| `maxTokens` | number | 否 | 响应的最大令牌数 |
| `azureEndpoint` | string | 否 | Azure OpenAI 端点 URL |
| `azureApiVersion` | string | 否 | Azure OpenAI API 版本 |
| `vertexProject` | string | 否 | Vertex AI 的 Google Cloud 项目 ID |
| `vertexLocation` | string | 否 | Vertex AI 的 Google Cloud 区域(默认为 us-central1 |
#### 输出

View File

@@ -38,10 +38,9 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | 是 | Webflow 网站的 ID |
| `collectionId` | string | 是 | 集合的 ID |
| `offset` | number | 否 | 分页偏移量(可选) |
| `limit` | number | 否 | 返回的最大项目数可选默认值100 |
| `offset` | number | 否 | 分页偏移量(可选) |
| `limit` | number | 否 | 返回的最大项目数可选默认值100 |
#### 输出
@@ -58,9 +57,8 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | 是 | Webflow 网站的 ID |
| `collectionId` | string | 是 | 集合的 ID |
| `itemId` | string | 是 | 要检索项目 ID |
| `itemId` | string | 是 | 要检索项目 ID |
#### 输出
@@ -77,9 +75,8 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | 是 | Webflow 网站的 ID |
| `collectionId` | string | 是 | 集合的 ID |
| `fieldData` | json | 是 | 新项目的字段数据,格式为 JSON 对象。键名应与集合字段名匹配。 |
| `fieldData` | json | 是 | 新项目的字段数据,格式为 JSON 对象。键名应与集合字段名匹配。 |
#### 输出
@@ -96,10 +93,9 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | 是 | Webflow 网站的 ID |
| `collectionId` | string | 是 | 集合的 ID |
| `itemId` | string | 是 | 要更新项目的 ID |
| `fieldData` | json | 是 | 要更新的字段数据,格式为 JSON 对象。仅包含需要更改的字段。 |
| `fieldData` | json | 是 | 要更新的字段数据,格式为 JSON 对象。仅包含您想更改的字段。 |
#### 输出
@@ -116,7 +112,6 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | 是 | Webflow 网站的 ID |
| `collectionId` | string | 是 | 集合的 ID |
| `itemId` | string | 是 | 要删除项目的 ID |

View File

@@ -27,14 +27,12 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
- 检索任何会议的详情或邀请
- 直接从您的自动化中更新或删除现有会议
要连接到 Zoom请拖放 Zoom 模块并点击 `Connect`,使用您的 Zoom 账户进行认证。连接后,您可以使用 Zoom 工具创建、列出、更新和删除 Zoom 会议。您可以随时通过点击“设置 > 集成”中的 `Disconnect` 断开您的 Zoom 账户连接,您的 Zoom 账户访问权限将立即被撤销
这些功能使您能够简化远程协作、自动化定期视频会议,并在工作流中管理您的组织的 Zoom 环境。
这些功能使您能够简化远程协作、自动化定期视频会议,并将您的组织 Zoom 环境管理整合到工作流程中
{/* MANUAL-CONTENT-END */}
## 使用说明
将 Zoom 集成到工作流中。创建、列出、更新和删除 Zoom 会议。获取会议详情、邀请、录制和参与者信息。以编程方式管理云录制。
将 Zoom 集成到工作流中。创建、列出、更新和删除 Zoom 会议。获取会议详情、邀请、录制内容和参与者信息。以编程方式管理云录制内容
## 工具
@@ -48,18 +46,18 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| --------- | ---- | -------- | ----------- |
| `userId` | string | 是 | 用户 ID 或电子邮件地址。使用 "me" 表示已认证用户。 |
| `topic` | string | 是 | 会议主题 |
| `type` | number | 否 | 会议类型1=即时会议2=预定会议3=无固定时间的循环会议8=有固定时间的循环会议 |
| `startTime` | string | 否 | 会议开始时间,采用 ISO 8601 格式 \(例如2025-06-03T10:00:00Z\) |
| `type` | number | 否 | 会议类型1=即时2=计划3=无固定时间的定期会议8=有固定时间的定期会议 |
| `startTime` | string | 否 | ISO 8601 格式的会议开始时间 \(例如2025-06-03T10:00:00Z\) |
| `duration` | number | 否 | 会议时长(分钟) |
| `timezone` | string | 否 | 会议的时区 \(例如America/Los_Angeles\) |
| `password` | string | 否 | 会议密码 |
| `agenda` | string | 否 | 会议议程 |
| `hostVideo` | boolean | 否 | 主持人视频开启时开始会议 |
| `participantVideo` | boolean | 否 | 参与者视频开启时开始会议 |
| `joinBeforeHost` | boolean | 否 | 允许参与者在主持人之前加入会议 |
| `hostVideo` | boolean | 否 | 主持人视频开启时开始 |
| `participantVideo` | boolean | 否 | 参与者视频开启时开始 |
| `joinBeforeHost` | boolean | 否 | 允许参与者在主持人之前加入 |
| `muteUponEntry` | boolean | 否 | 参与者进入时静音 |
| `waitingRoom` | boolean | 否 | 启用等候室 |
| `autoRecording` | string | 否 | 自动录制设置:本地、云或无 |
| `autoRecording` | string | 否 | 自动录制设置:本地、云或无 |
#### 输出
@@ -96,14 +94,14 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | 是 | 会议 ID |
| `occurrenceId` | string | 否 | 定期会议的发生 ID |
| `showPreviousOccurrences` | boolean | 否 | 显示定期会议的先前发生记录 |
| `occurrenceId` | string | 否 | 循环会议的发生 ID |
| `showPreviousOccurrences` | boolean | 否 | 显示循环会议的先前发生记录 |
#### 输出
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `meeting` | object | 会议详细信息 |
| `meeting` | object | 会议详 |
### `zoom_update_meeting`
@@ -115,7 +113,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | 是 | 要更新的会议 ID |
| `topic` | string | 否 | 会议主题 |
| `type` | number | 否 | 会议类型1=即时2=计划3=无固定时间的定期会议8=固定时间的定期会议 |
| `type` | number | 否 | 会议类型1=即时会议2=预定会议3=无固定时间的循环会议8=固定时间的循环会议 |
| `startTime` | string | 否 | ISO 8601 格式的会议开始时间 \(例如2025-06-03T10:00:00Z\) |
| `duration` | number | 否 | 会议时长(分钟) |
| `timezone` | string | 否 | 会议的时区 \(例如America/Los_Angeles\) |
@@ -126,7 +124,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| `joinBeforeHost` | boolean | 否 | 允许参与者在主持人之前加入 |
| `muteUponEntry` | boolean | 否 | 参与者进入时静音 |
| `waitingRoom` | boolean | 否 | 启用等候室 |
| `autoRecording` | string | 否 | 自动录制设置:本地、云或无 |
| `autoRecording` | string | 否 | 自动录制设置:本地、云或无 |
#### 输出
@@ -143,7 +141,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | 是 | 要删除的会议 ID |
| `occurrenceId` | string | 否 | 删除定期会议特定场次的场次 ID |
| `occurrenceId` | string | 否 | 删除循环会议特定场次的场次 ID |
| `scheduleForReminder` | boolean | 否 | 向注册者发送取消提醒邮件 |
| `cancelMeetingReminder` | boolean | 否 | 向注册者和替代主持人发送取消邮件 |
@@ -177,10 +175,10 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `userId` | string | 是 | 用户 ID 或电子邮件地址。使用 "me" 表示已认证用户。 |
| `from` | string | 否 | 开始日期,格式为 yyyy-mm-dd \(最近 6 个月内\) |
| `userId` | string | 是 | 用户 ID 或电子邮件地址。对于已认证用户,请使用 "me"。 |
| `from` | string | 否 | 开始日期,格式为 yyyy-mm-dd最近 6 个月内 |
| `to` | string | 否 | 结束日期,格式为 yyyy-mm-dd |
| `pageSize` | number | 否 | 每页记录数 \(最大 300\) |
| `pageSize` | number | 否 | 每页记录数最大 300 |
| `nextPageToken` | string | 否 | 分页令牌,用于获取下一页结果 |
| `trash` | boolean | 否 | 设置为 true 以列出回收站中的录制 |
@@ -193,39 +191,39 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
### `zoom_get_meeting_recordings`
获取特定 Zoom 会议的所有录制
获取特定 Zoom 会议的所有录制内容
#### 输入
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | 是 | 会议 ID 或会议 UUID |
| `includeFolderItems` | boolean | 否 | 包括文件夹的项目 |
| `includeFolderItems` | boolean | 否 | 包括文件夹的项目 |
| `ttl` | number | 否 | 下载 URL 的有效时间(秒)\(最大值 604800\) |
#### 输出
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `recording` | object | 包含所有文件的会议录制 |
| `recording` | object | 包含所有文件的会议录制内容 |
### `zoom_delete_recording`
删除 Zoom 会议的云录制
删除 Zoom 会议的云录制内容
#### 输入
| 参数 | 类型 | 必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `meetingId` | string | 是 | 会议 ID 或会议 UUID |
| `recordingId` | string | 否 | 要删除的特定录制文件 ID。如果未提供则删除所有录制。 |
| `recordingId` | string | 否 | 要删除的特定录制文件 ID。如果未提供则删除所有录制内容。 |
| `action` | string | 否 | 删除操作:"trash" \(移至回收站\) 或 "delete" \(永久删除\) |
#### 输出
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `success` | boolean | 录制是否成功删除 |
| `success` | boolean | 录制内容是否成功删除 |
### `zoom_list_past_participants`
@@ -243,10 +241,10 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
| 参数 | 类型 | 描述 |
| --------- | ---- | ----------- |
| `participants` | array | 会议参与者列表 |
| `pageInfo` | object | 分页信息 |
| `participants` | 数组 | 会议参与者列表 |
| `pageInfo` | 对象 | 分页信息 |
## 注意事项
- 类别: `tools`
- 类型: `zoom`
- 类别`tools`
- 类型`zoom`

View File

@@ -557,7 +557,7 @@ checksums:
content/8: 6325adefb6e1520835225285b18b6a45
content/9: b7fa85fce9c7476fe132df189e27dac1
content/10: 371d0e46b4bd2c23f559b8bc112f6955
content/11: 7ad14ccfe548588081626cfe769ad492
content/11: 985f435f721b00df4d13fa0a5552684c
content/12: bcadfc362b69078beee0088e5936c98b
content/13: 6af66efd0da20944a87fdb8d9defa358
content/14: b3f310d5ef115bea5a8b75bf25d7ea9a
@@ -889,9 +889,9 @@ checksums:
content/10: 71c6cf129630acff9d8df39d0a5c5407
content/11: 9c8aa3f09c9b2bd50ea4cdff3598ea4e
content/12: 8ee83eff32425b2c52929284e8485c20
content/13: c1ec0b00cb68561551e48616731ea43a
content/13: 6cda87dc9837779f4572ed70b87a5654
content/14: 371d0e46b4bd2c23f559b8bc112f6955
content/15: 117e42c934a7f2a76b0399235841260e
content/15: 2f696275726cdeefd7d7280b5bb43b21
content/16: bcadfc362b69078beee0088e5936c98b
content/17: bb43e4f36fdc1eb6211f46ddeed9e0aa
content/18: 05540cb3028d4d781521c14e5f9e3835
@@ -903,7 +903,7 @@ checksums:
content/24: 228a8ece96627883153b826a1cbaa06c
content/25: 53abe061a259c296c82676b4770ddd1b
content/26: 371d0e46b4bd2c23f559b8bc112f6955
content/27: 03e8b10ec08b354de98e360b66b779e3
content/27: 170ccdc4ce7ee086e9c6b5073efca582
content/28: bcadfc362b69078beee0088e5936c98b
content/29: b82def7d82657f941fbe60df3924eeeb
content/30: 1ca7ee3856805fa1718031c5f75b6ffb
@@ -2511,133 +2511,133 @@ checksums:
content/12: 371d0e46b4bd2c23f559b8bc112f6955
content/13: 8c25606fde43bf4ff519760364fda052
content/14: bcadfc362b69078beee0088e5936c98b
content/15: 4ec31e928a8498d050922adb2f977c98
content/15: 9ee0b1e8873ef165299443a76823e7bc
content/16: be5c68d578443b68c062029104bd6ddb
content/17: 3b38aa70e04f841184b7d958b087af8c
content/18: 371d0e46b4bd2c23f559b8bc112f6955
content/19: 5269008adfae57a3a8fb5d8bf5922498
content/20: bcadfc362b69078beee0088e5936c98b
content/21: 5317f2e9eb34d7297064b381aef6912c
content/21: c66b2996f62f0f7150fce59eed9ad7a8
content/22: ef92d95455e378abe4d27a1cdc5e1aed
content/23: febd6019055f3754953fd93395d0dbf2
content/24: 371d0e46b4bd2c23f559b8bc112f6955
content/25: 7ef3f388e5ee9346bac54c771d825f40
content/26: bcadfc362b69078beee0088e5936c98b
content/27: e0fa91c45aa780fc03e91df77417f893
content/27: 7bccc537f32fabcbb4cd0a85bef612de
content/28: b463f54cd5fe2458b5842549fbb5e1ce
content/29: 55f8c724e1a2463bc29a32518a512c73
content/30: 371d0e46b4bd2c23f559b8bc112f6955
content/31: 770b1f7b3105937d452bc2815ebb6e05
content/32: bcadfc362b69078beee0088e5936c98b
content/33: 0b92b54ce40dc29bb6faccf82eace18b
content/33: b7be768fe967164e71af56dd5cd13f86
content/34: f426b59ee38021a4254fe566995c416c
content/35: 2455b2f418cc79f4a67558678ae444bc
content/36: 371d0e46b4bd2c23f559b8bc112f6955
content/37: 320e2962c7e2d24690c75b2f69e5be9d
content/38: bcadfc362b69078beee0088e5936c98b
content/39: 76f532ccbddb41115e56a7d56d97aa96
content/39: 25501290045d87dad2c5819200528091
content/40: 52233c13208d6e10497340a37b11ef3a
content/41: 9c6bf4c4180c96e31668941aa36f2cde
content/42: 371d0e46b4bd2c23f559b8bc112f6955
content/43: a792b3be1ab2bc6bc570f5dafca56aaa
content/44: bcadfc362b69078beee0088e5936c98b
content/45: 838a4016055b35389dae383f8b4ec2ac
content/45: 120bc8dacae493c314aed0f4a4094c7f
content/46: fe4880697d8adcd75c3a2c7e5b0fec86
content/47: fdd9ab6e60b2c42a18a41ef869fb925b
content/48: 371d0e46b4bd2c23f559b8bc112f6955
content/49: 0ccf3f3f59955dd78558a0e3589579a6
content/50: bcadfc362b69078beee0088e5936c98b
content/51: 8defd6d29c0ddbd9a811caa8f2cf3f39
content/51: 35ce33f78ffa1130c2719885759406a5
content/52: f04e8809e7d4f701cf24b339d844bea5
content/53: 811c364b512dd61a2f40fb8418b6b0cd
content/54: 371d0e46b4bd2c23f559b8bc112f6955
content/55: 2ce7e48a76065784447b75b6bc0fbff9
content/56: bcadfc362b69078beee0088e5936c98b
content/57: 47be5344f0c8a9ede380f37f769b5b3f
content/57: 437fae06c917576e309864634ac006d5
content/58: 8d41bb08f7d4000b665e6786583aa2b5
content/59: 48adb1980e062be3783331522082edaf
content/60: 371d0e46b4bd2c23f559b8bc112f6955
content/61: b89e1b7a15f022c0c13adadb25e3f49d
content/62: bcadfc362b69078beee0088e5936c98b
content/63: 44b209460093fb955b8f6b4e575dde17
content/63: 74e0d576bddb246c672c98a8e9f4fd32
content/64: c02f43d19361be7571e8141a61e83980
content/65: 21a0f57793fb19dd8761b644e22ee731
content/66: 371d0e46b4bd2c23f559b8bc112f6955
content/67: 6aa3e815a37986856a2781ccfdb7b4de
content/68: bcadfc362b69078beee0088e5936c98b
content/69: 9032d6a71c23f90a39232d653c3daf36
content/69: b76190aa5e84cb17cdcf2e061edf706b
content/70: 1845561cd920176e2dbfed65eaccca9e
content/71: 2960e1e609b8c512f5cf1ef715c2a684
content/72: 371d0e46b4bd2c23f559b8bc112f6955
content/73: e3586b13bcb7c91515437d76a0027201
content/74: bcadfc362b69078beee0088e5936c98b
content/75: f14261cdc2105f3c2380a90629edc172
content/75: 520c03c754968a673ed5def1706f919d
content/76: 14a4d1b2c2f1257eadb4b26b85672fab
content/77: 45bd9b1b321f85dc31c720051c12f681
content/78: 371d0e46b4bd2c23f559b8bc112f6955
content/79: 176f866fa8ad12f179eb5466bc968914
content/80: bcadfc362b69078beee0088e5936c98b
content/81: 8f1d8635d9e542fbce4ee4167d8a2bb1
content/81: 1fc32b27418b8efe2abba1beb6d31868
content/82: 5c0b4adc7825b3ed5831bf6c4d83a6a2
content/83: cace0c917728a3a5bc93d26dd65669f7
content/84: 371d0e46b4bd2c23f559b8bc112f6955
content/85: 490b3a3ef8840f1e01a58c6875af027b
content/86: bcadfc362b69078beee0088e5936c98b
content/87: 501cead9242b6febffe4659a63cef613
content/87: f4c4cbcb48dbbd87b27fdf76105aaa8c
content/88: efa34ea34fd3d30088470cf6f4476106
content/89: 47fc6e4fd184baaf72d61223ec944148
content/90: 371d0e46b4bd2c23f559b8bc112f6955
content/91: 43349c22c04743b654d4aee849cc81ff
content/92: bcadfc362b69078beee0088e5936c98b
content/93: a53a400b7cddac3a34435d23332db795
content/93: 82634f835e924e6b2242df6127f0969a
content/94: e3a5c53a79de7fe47abd7f7a9f86fb65
content/95: 2053815e47b54488983f0571f49cd11a
content/96: 371d0e46b4bd2c23f559b8bc112f6955
content/97: 846be448c3cedb87e4bd923c63e04512
content/98: bcadfc362b69078beee0088e5936c98b
content/99: d227cd028bf20eab7f826827efa9ea90
content/99: 11608f282141ee6c31f933f6c2fcaa0d
content/100: 17d1e59a4290138d979568f39e6fea9b
content/101: cf9c3c1b441bde10b35d04d776e9f5ce
content/102: 371d0e46b4bd2c23f559b8bc112f6955
content/103: 599eb9d3e6b88cba7a15d007ce1111f4
content/104: bcadfc362b69078beee0088e5936c98b
content/105: 09d70143b5598699ae1ed593baa4ac61
content/105: ad1bd5c40adabc9f2a97682be1671d67
content/106: afa20ccc5f708cf36a0cb6ede6ec0c4f
content/107: 8a64259005d325f6849527186097f390
content/108: 371d0e46b4bd2c23f559b8bc112f6955
content/109: c2b8a2c90d216d94f24850c8124849ef
content/110: bcadfc362b69078beee0088e5936c98b
content/111: 6bab23a5c82acbd6cd79fbdfc9bbcbde
content/111: b5e005f9e95aead5c9596968b21821e1
content/112: 05141d844a911fb66fd7bdc2b98e8160
content/113: f04861fc73d9abc76dd8e140703baa14
content/114: 371d0e46b4bd2c23f559b8bc112f6955
content/115: 09a884f6fcddd37ad4968718fb48db9e
content/116: bcadfc362b69078beee0088e5936c98b
content/117: a1645115447094e7520eb3d45244a3c8
content/117: 62695bf37dd3fe43470266996e09ef86
content/118: 96b30990733f35886cb04bc6bae18613
content/119: b22baefc2beca09303baa0778b27a4d6
content/120: 371d0e46b4bd2c23f559b8bc112f6955
content/121: 9b936f3424feac6551b709d0c5d5713c
content/122: bcadfc362b69078beee0088e5936c98b
content/123: 6cd2f15ea11b6f07e6ac7e170a90a91f
content/123: 1a249d65588fd4a33bb50af768870bbc
content/124: 573661fdf0cd751a2433052dff8dcdfe
content/125: 81d70f8bd307578a5814374f31a7d6c2
content/126: 371d0e46b4bd2c23f559b8bc112f6955
content/127: d04dcb9d64bc76606af4f9309eeacb75
content/128: bcadfc362b69078beee0088e5936c98b
content/129: b6b0fd5e140401e9f4c4c8a0e5ab0da1
content/129: 7a78c9363ed6fba5d7277a24186c7296
content/130: ce10caa6dcfe95e58c32db33157d989a
content/131: 49df30ca91d4139a38b591311b7a83a8
content/132: 371d0e46b4bd2c23f559b8bc112f6955
content/133: b61b7e3b5e5b7c05fcb65478d744abb5
content/134: bcadfc362b69078beee0088e5936c98b
content/135: 310e65d225fb68cf48f1d44d1047ea12
content/135: 9ec868a621316d03619fc37582084053
content/136: 805790ac8b4ae77c30fbfc9f6023bac8
content/137: 1a4e93e8a49abd71333809a3bc0856c9
content/138: 371d0e46b4bd2c23f559b8bc112f6955
content/139: 33fde4c3da4584b51f06183b7b192a78
content/140: bcadfc362b69078beee0088e5936c98b
content/141: b7451190f100388d999c183958d787a7
content/141: a4e11bf0073b1f1e45c07e3c1c7dd969
content/142: b3f310d5ef115bea5a8b75bf25d7ea9a
content/143: 4930918f803340baa861bed9cdf789de
8f76e389f6226f608571622b015ca6a1:
@@ -4811,9 +4811,9 @@ checksums:
content/19: 85547efea8ae0e8170ac4e2030f6be25
content/20: 25c56dcdc4af1516c3fbf9d82d96b48d
content/21: 56dbe63da14a319cd520ab1615c94be7
content/22: e039f6c905c8aa148cc3e7af19f05239
content/22: e092cde0c92ef09c642a62636e7e3ae3
content/23: c7004f5db8f7134d7e3a36a1916691a2
content/24: 26555018b90fc8fb3ac65cece15f3966
content/24: bbc26961050b132b9bc4f14ba11f407a
content/25: 56dbe63da14a319cd520ab1615c94be7
content/26: 3e835ecc38acf2c76179034360d41670
content/27: a13bbc3dac7388e1ef4e9cbafdcc8241
@@ -5973,31 +5973,31 @@ checksums:
content/9: 5914baadfaf2ca26d54130a36dd5ed29
content/10: 25507380ac7d9c7f8cf9f5256c6a0dbb
content/11: 371d0e46b4bd2c23f559b8bc112f6955
content/12: e034523b05e8c7bd1723ef0ba96c5332
content/12: e7fb612c3323c1e6b05eacfcea360d34
content/13: bcadfc362b69078beee0088e5936c98b
content/14: e5f830d6049ff79a318110098e5e0130
content/15: 711e90714806b91f93923018e82ad2e9
content/16: 0f3f7d9699d7397cb3a094c3229329ee
content/17: 371d0e46b4bd2c23f559b8bc112f6955
content/18: 4b0c581b30f4449b0bfa3cdd4af69e02
content/18: c53b5b8f901066e63fe159ad2fa5e6e0
content/19: bcadfc362b69078beee0088e5936c98b
content/20: 5f2afdd49c3ac13381401c69d1eca22a
content/21: cc4baa9096fafa4c6276f6136412ba66
content/22: 676f76e8a7154a576d7fa20b245cef70
content/23: 371d0e46b4bd2c23f559b8bc112f6955
content/24: d26dd24c5398fd036d1f464ba3789002
content/24: c67c387eb7e274ee7c07b7e1748afce1
content/25: bcadfc362b69078beee0088e5936c98b
content/26: a6ffebda549ad5b903a66c7d9ac03a20
content/27: 0dadd51cde48d6ea75b29ec3ee4ade56
content/28: cdc74f6483a0b4e9933ecdd92ed7480f
content/29: 371d0e46b4bd2c23f559b8bc112f6955
content/30: cec3953ee52d1d3c8b1a495f9684d35b
content/30: 4cda10aa374e1a46d60ad14eeaa79100
content/31: bcadfc362b69078beee0088e5936c98b
content/32: 5f221421953a0e760ead7388cbf66561
content/33: a3c0372590cef72d5d983dbc8dbbc2cb
content/34: 1402e53c08bdd8a741f44b2d66fcd003
content/35: 371d0e46b4bd2c23f559b8bc112f6955
content/36: db921b05a9e5ddceb28a4f3f1af2a377
content/36: 028e579a28e55def4fbc59f39f4610b7
content/37: bcadfc362b69078beee0088e5936c98b
content/38: 4fe4260da2f137679ce2fa42cffcf56a
content/39: b3f310d5ef115bea5a8b75bf25d7ea9a
@@ -47626,73 +47626,72 @@ checksums:
content/4: 0f0165c7e21355d8f8e332c2252100db
content/5: 11289606ffb19f4564a7f0a867a39a55
content/6: 05eb6fe6951b12bcddd3ae36aacc7bb3
content/7: e474de0de136881473833dd6502b6d06
content/8: 715b7f8ee32c3d0dcd20cc0a57a9367b
content/9: 821e6394b0a953e2b0842b04ae8f3105
content/10: e5f8dc06b6db9aeef348d8af9617c787
content/11: 9c8aa3f09c9b2bd50ea4cdff3598ea4e
content/12: 0ec27ddd5601764fadfc363811376d88
content/13: 18e3253cead6514fe5e939d98b64d8fb
content/14: 371d0e46b4bd2c23f559b8bc112f6955
content/15: 676120936020f1a25faea0d5608b7958
content/16: bcadfc362b69078beee0088e5936c98b
content/17: ecad0614a5ec681a43fea86034a30905
content/18: 8eb606aad3db305e12679efb6fe7363e
content/19: 7d9ab020b8312987af94a42c7797a6bc
content/20: 371d0e46b4bd2c23f559b8bc112f6955
content/21: 6854dad4e5e5419803d3b0a387bf36c1
content/22: bcadfc362b69078beee0088e5936c98b
content/23: 051e39427d40ab7c4b5ebbbf65c7910f
content/24: 9c42c50fa5ce2db382867e2da5bca90d
content/25: 7bc9a20018bc365ecf55a54a53ad1013
content/26: 371d0e46b4bd2c23f559b8bc112f6955
content/27: 299dce7368070dd19957ba06efef836b
content/28: bcadfc362b69078beee0088e5936c98b
content/29: d9a5be31d4296b81660b38dcb4c695cc
content/30: d732fd0df847a742d6dabfc5110ba31d
content/31: 9782a621e6d591e72b7ce5e27face7af
content/32: 371d0e46b4bd2c23f559b8bc112f6955
content/33: 2d7dd3ac552ff837d614c510033646ba
content/34: bcadfc362b69078beee0088e5936c98b
content/35: 37d84e8cc60979a8d3f1e48483d23113
content/36: 90bc3ad5e30e5d579f48787e7d8181ae
content/37: 7db1faa939033f49aad8ef462e630c26
content/38: 371d0e46b4bd2c23f559b8bc112f6955
content/39: 5e289bbda737273fa75101e276358ec8
content/40: bcadfc362b69078beee0088e5936c98b
content/41: 805d1a06016797ba04f3cb840ac59e44
content/42: 88260e555a61ba6886e56f3bc06512dc
content/43: 80c4006b7d25c461c18e9a8a35cfac72
content/44: 371d0e46b4bd2c23f559b8bc112f6955
content/45: 645735bd919e64e034c03b98cc75d5be
content/46: bcadfc362b69078beee0088e5936c98b
content/47: 842462f8cd7a897eda330bba54d297df
content/48: 96d58ab5053c5f5db3f15f82442eb3dd
content/49: 148c8f5f3872aa6e9944e221c35bc9a0
content/50: 371d0e46b4bd2c23f559b8bc112f6955
content/51: 7a449b1878a28cff4b713a104581ec63
content/52: bcadfc362b69078beee0088e5936c98b
content/53: 502548c4b9d6be040f73fc431c3c8fd6
content/54: 1304212656a10261692509a67cfae220
content/55: 042eb9071c13eb10ee5fd0bfd4e00c8a
content/56: 371d0e46b4bd2c23f559b8bc112f6955
content/57: 4263559dc306f5edcdfa1bf758adffdf
content/58: bcadfc362b69078beee0088e5936c98b
content/59: 984b85e501fbd9993b7fe38898e5d445
content/60: 12f6776606adce02255b1db24cd58d29
content/61: fc53b00cfedd65f5fd906daebd9c04df
content/62: 371d0e46b4bd2c23f559b8bc112f6955
content/63: 242a47e9aaf5c07859e2a472bed6d3ac
content/64: bcadfc362b69078beee0088e5936c98b
content/65: 2823402034702ff5ca56b9cad3572c4d
content/66: 8ddcef9d1d32bff76ac8e6c5a0e0dca5
content/67: 94a960dd84bd71825b58d2219b98dd74
content/68: 371d0e46b4bd2c23f559b8bc112f6955
content/69: e7777f90d25d134aa0a3cae9cdfc6563
content/70: bcadfc362b69078beee0088e5936c98b
content/71: affc25ff3d47510647c984a1d59b0a0e
content/72: b3f310d5ef115bea5a8b75bf25d7ea9a
content/73: 2d9d3b6969330e7b2d8e1169cfcf0031
content/7: 715b7f8ee32c3d0dcd20cc0a57a9367b
content/8: 821e6394b0a953e2b0842b04ae8f3105
content/9: e5f8dc06b6db9aeef348d8af9617c787
content/10: 9c8aa3f09c9b2bd50ea4cdff3598ea4e
content/11: 0ec27ddd5601764fadfc363811376d88
content/12: 18e3253cead6514fe5e939d98b64d8fb
content/13: 371d0e46b4bd2c23f559b8bc112f6955
content/14: 676120936020f1a25faea0d5608b7958
content/15: bcadfc362b69078beee0088e5936c98b
content/16: ecad0614a5ec681a43fea86034a30905
content/17: 8eb606aad3db305e12679efb6fe7363e
content/18: 7d9ab020b8312987af94a42c7797a6bc
content/19: 371d0e46b4bd2c23f559b8bc112f6955
content/20: 6854dad4e5e5419803d3b0a387bf36c1
content/21: bcadfc362b69078beee0088e5936c98b
content/22: 051e39427d40ab7c4b5ebbbf65c7910f
content/23: 9c42c50fa5ce2db382867e2da5bca90d
content/24: 7bc9a20018bc365ecf55a54a53ad1013
content/25: 371d0e46b4bd2c23f559b8bc112f6955
content/26: 299dce7368070dd19957ba06efef836b
content/27: bcadfc362b69078beee0088e5936c98b
content/28: d9a5be31d4296b81660b38dcb4c695cc
content/29: d732fd0df847a742d6dabfc5110ba31d
content/30: 9782a621e6d591e72b7ce5e27face7af
content/31: 371d0e46b4bd2c23f559b8bc112f6955
content/32: 2d7dd3ac552ff837d614c510033646ba
content/33: bcadfc362b69078beee0088e5936c98b
content/34: 37d84e8cc60979a8d3f1e48483d23113
content/35: 90bc3ad5e30e5d579f48787e7d8181ae
content/36: 7db1faa939033f49aad8ef462e630c26
content/37: 371d0e46b4bd2c23f559b8bc112f6955
content/38: 5e289bbda737273fa75101e276358ec8
content/39: bcadfc362b69078beee0088e5936c98b
content/40: 805d1a06016797ba04f3cb840ac59e44
content/41: 88260e555a61ba6886e56f3bc06512dc
content/42: 80c4006b7d25c461c18e9a8a35cfac72
content/43: 371d0e46b4bd2c23f559b8bc112f6955
content/44: 645735bd919e64e034c03b98cc75d5be
content/45: bcadfc362b69078beee0088e5936c98b
content/46: 842462f8cd7a897eda330bba54d297df
content/47: 96d58ab5053c5f5db3f15f82442eb3dd
content/48: 148c8f5f3872aa6e9944e221c35bc9a0
content/49: 371d0e46b4bd2c23f559b8bc112f6955
content/50: 7a449b1878a28cff4b713a104581ec63
content/51: bcadfc362b69078beee0088e5936c98b
content/52: 502548c4b9d6be040f73fc431c3c8fd6
content/53: 1304212656a10261692509a67cfae220
content/54: 042eb9071c13eb10ee5fd0bfd4e00c8a
content/55: 371d0e46b4bd2c23f559b8bc112f6955
content/56: 4263559dc306f5edcdfa1bf758adffdf
content/57: bcadfc362b69078beee0088e5936c98b
content/58: 984b85e501fbd9993b7fe38898e5d445
content/59: 12f6776606adce02255b1db24cd58d29
content/60: fc53b00cfedd65f5fd906daebd9c04df
content/61: 371d0e46b4bd2c23f559b8bc112f6955
content/62: 242a47e9aaf5c07859e2a472bed6d3ac
content/63: bcadfc362b69078beee0088e5936c98b
content/64: 2823402034702ff5ca56b9cad3572c4d
content/65: 8ddcef9d1d32bff76ac8e6c5a0e0dca5
content/66: 94a960dd84bd71825b58d2219b98dd74
content/67: 371d0e46b4bd2c23f559b8bc112f6955
content/68: e7777f90d25d134aa0a3cae9cdfc6563
content/69: bcadfc362b69078beee0088e5936c98b
content/70: affc25ff3d47510647c984a1d59b0a0e
content/71: b3f310d5ef115bea5a8b75bf25d7ea9a
content/72: 2d9d3b6969330e7b2d8e1169cfcf0031
1db887f91df2e066fc769749f3b2a930:
meta/title: b4c01a60ed020f21556b4a8ef3f24cae
meta/description: b2f402630c2605cff14c3d7ad2c52d16
@@ -49822,41 +49821,3 @@ checksums:
content/472: dbc5fceeefb3ab5fa505394becafef4e
content/473: b3f310d5ef115bea5a8b75bf25d7ea9a
content/474: 27c398e669b297cea076e4ce4cc0c5eb
9a28da736b42bf8de55126d4c06b6150:
meta/title: 418d5c8a18ad73520b38765741601f32
meta/description: 41cb31abf94297849fb8a4023cf0211d
content/0: 1b031fb0c62c46b177aeed5c3d3f8f80
content/1: e72670f88454b5b1c955b029de5fa8b5
content/2: d586e5af506d99add847369c0accfb4d
content/3: a2ce9ed4954ab55bcebed927cec8e890
content/4: 5fc7b723a6adcf201e8deb3f5ed9a9e3
content/5: a78981875c359a3343f26ed4d115f899
content/6: 821e6394b0a953e2b0842b04ae8f3105
content/7: 56a538eaccb1158fb1f7a01cc32f7331
content/8: 9c8aa3f09c9b2bd50ea4cdff3598ea4e
content/9: 263633aee6db9332de806ae50d87de05
content/10: 5a7e2171e5f73fec5eae21a50e5de661
content/11: 371d0e46b4bd2c23f559b8bc112f6955
content/12: 5905ef5d0db0354c08394acb0b5cda4b
content/13: bcadfc362b69078beee0088e5936c98b
content/14: d81ef802f80143282cf4e534561a9570
content/15: 02233e6212003c1d121424cfd8b86b62
content/16: efe2c6dd368708de68a1addbfdb11b0c
content/17: 371d0e46b4bd2c23f559b8bc112f6955
content/18: 2722e8bee100e7bc4590fa02710e9508
content/19: bcadfc362b69078beee0088e5936c98b
content/20: 953f353184dc27db1f20156db2a9ad90
content/21: 2011e87d0555cd0ab133ef2d35e7a37b
content/22: dbf08acb413d845ec419e45b1f986bdb
content/23: 371d0e46b4bd2c23f559b8bc112f6955
content/24: afc35de2990ed0e9bb8f98dc1b9609ce
content/25: bcadfc362b69078beee0088e5936c98b
content/26: c06a5bb458242baa23d34957034c2fe7
content/27: ff043e912417bc29ac7c64520160c07d
content/28: 9c2175ab469cb6ff9e62bc8bdcf7621d
content/29: 371d0e46b4bd2c23f559b8bc112f6955
content/30: 20e6bddad8e7f34a3d09e5b0c5678c13
content/31: bcadfc362b69078beee0088e5936c98b
content/32: fd0f38eb3fe5cf95be366a4ff6b4fb90
content/33: b3f310d5ef115bea5a8b75bf25d7ea9a
content/34: 4a7b2c644e487f3d12b6a6b54f8c6773

View File

@@ -1,10 +1,9 @@
import type { InferPageType } from 'fumadocs-core/source'
import type { PageData, source } from '@/lib/source'
import type { source } from '@/lib/source'
export async function getLLMText(page: InferPageType<typeof source>) {
const data = page.data as PageData
const processed = await data.getText('processed')
return `# ${data.title} (${page.url})
const processed = await page.data.getText('processed')
return `# ${page.data.title} (${page.url})
${processed}`
}

View File

@@ -1,5 +1,4 @@
import { type InferPageType, loader } from 'fumadocs-core/source'
import type { DocData, DocMethods } from 'fumadocs-mdx/runtime/types'
import { loader } from 'fumadocs-core/source'
import { docs } from '@/.source/server'
import { i18n } from './i18n'
@@ -8,13 +7,3 @@ export const source = loader({
source: docs.toFumadocsSource(),
i18n,
})
/** Full page data type including MDX content and metadata */
export type PageData = DocData &
DocMethods & {
title: string
description?: string
full?: boolean
}
export type Page = InferPageType<typeof source>

View File

@@ -19,7 +19,7 @@
"fumadocs-mdx": "14.1.0",
"fumadocs-ui": "16.2.3",
"lucide-react": "^0.511.0",
"next": "16.1.0-canary.21",
"next": "16.0.9",
"next-themes": "^0.4.6",
"react": "19.2.1",
"react-dom": "19.2.1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 KiB

View File

@@ -4,13 +4,10 @@ DATABASE_URL="postgresql://postgres:password@localhost:5432/postgres"
# PostgreSQL Port (Optional) - defaults to 5432 if not specified
# POSTGRES_PORT=5432
# Authentication (Required unless DISABLE_AUTH=true)
# Authentication (Required)
BETTER_AUTH_SECRET=your_secret_key # Use `openssl rand -hex 32` to generate, or visit https://www.better-auth.com/docs/installation
BETTER_AUTH_URL=http://localhost:3000
# Authentication Bypass (Optional - for self-hosted deployments behind private networks)
# DISABLE_AUTH=true # Uncomment to bypass authentication entirely. Creates an anonymous session for all requests.
# NextJS (Required)
NEXT_PUBLIC_APP_URL=http://localhost:3000

View File

@@ -1,7 +1,7 @@
'use server'
import { env } from '@/lib/core/config/env'
import { isProd } from '@/lib/core/config/feature-flags'
import { isProd } from '@/lib/core/config/environment'
export async function getOAuthProviderStatus() {
const githubAvailable = !!(env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET)

View File

@@ -1,6 +1,7 @@
import { getOAuthProviderStatus } from '@/app/(auth)/components/oauth-provider-checker'
import LoginForm from '@/app/(auth)/login/login-form'
// Force dynamic rendering to avoid prerender errors with search params
export const dynamic = 'force-dynamic'
export default async function LoginPage() {

View File

@@ -1,16 +1,16 @@
import { isRegistrationDisabled } from '@/lib/core/config/feature-flags'
import { env, isTruthy } from '@/lib/core/config/env'
import { getOAuthProviderStatus } from '@/app/(auth)/components/oauth-provider-checker'
import SignupForm from '@/app/(auth)/signup/signup-form'
export const dynamic = 'force-dynamic'
export default async function SignupPage() {
if (isRegistrationDisabled) {
const { githubAvailable, googleAvailable, isProduction } = await getOAuthProviderStatus()
if (isTruthy(env.DISABLE_REGISTRATION)) {
return <div>Registration is disabled, please contact your admin.</div>
}
const { githubAvailable, googleAvailable, isProduction } = await getOAuthProviderStatus()
return (
<SignupForm
githubAvailable={githubAvailable}

View File

@@ -1,4 +1,4 @@
import { isEmailVerificationEnabled, isProd } from '@/lib/core/config/feature-flags'
import { isEmailVerificationEnabled, isProd } from '@/lib/core/config/environment'
import { hasEmailService } from '@/lib/messaging/email/mailer'
import { VerifyContent } from '@/app/(auth)/verify/verify-content'

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@/lib/logs/console/logger'
const DEFAULT_STARS = '19.4k'
const DEFAULT_STARS = '18.6k'
const logger = createLogger('GitHubStars')

View File

@@ -13,7 +13,7 @@ import {
SelectValue,
} from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'
import { isHosted } from '@/lib/core/config/feature-flags'
import { isHosted } from '@/lib/core/config/environment'
import { cn } from '@/lib/core/utils/cn'
import { createLogger } from '@/lib/logs/console/logger'
import { quickValidateEmail } from '@/lib/messaging/email/validation'

View File

@@ -4,7 +4,6 @@ export const FOOTER_BLOCKS = [
'Condition',
'Evaluator',
'Function',
'Guardrails',
'Human In The Loop',
'Loop',
'Parallel',
@@ -31,6 +30,7 @@ export const FOOTER_TOOLS = [
'GitHub',
'Gmail',
'Google Drive',
'Guardrails',
'HubSpot',
'HuggingFace',
'Hunter',
@@ -70,7 +70,6 @@ export const FOOTER_TOOLS = [
'Salesforce',
'SendGrid',
'Serper',
'ServiceNow',
'SharePoint',
'Slack',
'Smtp',

View File

@@ -1,6 +1,6 @@
'use client'
import { isHosted } from '@/lib/core/config/feature-flags'
import { isHosted } from '@/lib/core/config/environment'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Footer from '@/app/(landing)/components/footer/footer'
import Nav from '@/app/(landing)/components/nav/nav'

View File

@@ -7,7 +7,7 @@ import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { GithubIcon } from '@/components/icons'
import { useBrandConfig } from '@/lib/branding/branding'
import { isHosted } from '@/lib/core/config/feature-flags'
import { isHosted } from '@/lib/core/config/environment'
import { createLogger } from '@/lib/logs/console/logger'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { getFormattedGitHubStars } from '@/app/(landing)/actions/github'

View File

@@ -2,6 +2,7 @@ import { Suspense } from 'react'
import dynamic from 'next/dynamic'
import { Background, Footer, Nav, StructuredData } from '@/app/(landing)/components'
// Lazy load heavy components for better initial load performance
const Hero = dynamic(() => import('@/app/(landing)/components/hero/hero'), {
loading: () => <div className='h-[600px] animate-pulse bg-gray-50' />,
})

View File

@@ -64,7 +64,6 @@ export default async function Page({ params }: { params: Promise<{ slug: string
sizes='(max-width: 768px) 100vw, 450px'
priority
itemProp='image'
unoptimized
/>
</div>
</div>
@@ -145,7 +144,6 @@ export default async function Page({ params }: { params: Promise<{ slug: string
className='h-[160px] w-full object-cover'
sizes='(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw'
loading='lazy'
unoptimized
/>
<div className='p-3'>
<div className='mb-1 text-gray-600 text-xs'>

View File

@@ -38,7 +38,6 @@ export default async function AuthorPage({ params }: { params: Promise<{ id: str
width={40}
height={40}
className='rounded-full'
unoptimized
/>
) : null}
<h1 className='font-medium text-[32px] leading-tight'>{author.name}</h1>
@@ -53,7 +52,6 @@ export default async function AuthorPage({ params }: { params: Promise<{ id: str
width={600}
height={315}
className='h-[160px] w-full object-cover transition-transform group-hover:scale-[1.02]'
unoptimized
/>
<div className='p-3'>
<div className='mb-1 text-gray-600 text-xs'>

View File

@@ -76,7 +76,6 @@ export default async function StudioIndex({
className='h-48 w-full object-cover'
sizes='(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw'
loading='lazy'
unoptimized
/>
<div className='flex flex-1 flex-col p-4'>
<div className='mb-2 text-gray-600 text-xs'>

View File

@@ -1,23 +1,6 @@
import { toNextJsHandler } from 'better-auth/next-js'
import { type NextRequest, NextResponse } from 'next/server'
import { auth } from '@/lib/auth'
import { createAnonymousSession, ensureAnonymousUserExists } from '@/lib/auth/anonymous'
import { isAuthDisabled } from '@/lib/core/config/feature-flags'
export const dynamic = 'force-dynamic'
const { GET: betterAuthGET, POST: betterAuthPOST } = toNextJsHandler(auth.handler)
export async function GET(request: NextRequest) {
const url = new URL(request.url)
const path = url.pathname.replace('/api/auth/', '')
if (path === 'get-session' && isAuthDisabled) {
await ensureAnonymousUserExists()
return NextResponse.json(createAnonymousSession())
}
return betterAuthGET(request)
}
export const POST = betterAuthPOST
export const { GET, POST } = toNextJsHandler(auth.handler)

View File

@@ -38,6 +38,7 @@ vi.mock('@/lib/logs/console/logger', () => ({
}))
import { db } from '@sim/db'
import { createLogger } from '@/lib/logs/console/logger'
import { refreshOAuthToken } from '@/lib/oauth/oauth'
import {
getCredential,
@@ -48,6 +49,7 @@ import {
const mockDb = db as any
const mockRefreshOAuthToken = refreshOAuthToken as any
const mockLogger = (createLogger as any)()
describe('OAuth Utils', () => {
beforeEach(() => {
@@ -85,6 +87,7 @@ describe('OAuth Utils', () => {
const userId = await getUserId('request-id')
expect(userId).toBeUndefined()
expect(mockLogger.warn).toHaveBeenCalled()
})
it('should return undefined if workflow is not found', async () => {
@@ -93,6 +96,7 @@ describe('OAuth Utils', () => {
const userId = await getUserId('request-id', 'nonexistent-workflow-id')
expect(userId).toBeUndefined()
expect(mockLogger.warn).toHaveBeenCalled()
})
})
@@ -117,6 +121,7 @@ describe('OAuth Utils', () => {
const credential = await getCredential('request-id', 'nonexistent-id', 'test-user-id')
expect(credential).toBeUndefined()
expect(mockLogger.warn).toHaveBeenCalled()
})
})
@@ -134,6 +139,7 @@ describe('OAuth Utils', () => {
expect(mockRefreshOAuthToken).not.toHaveBeenCalled()
expect(result).toEqual({ accessToken: 'valid-token', refreshed: false })
expect(mockLogger.info).toHaveBeenCalledWith(expect.stringContaining('Access token is valid'))
})
it('should refresh token when expired', async () => {
@@ -157,6 +163,9 @@ describe('OAuth Utils', () => {
expect(mockDb.update).toHaveBeenCalled()
expect(mockDb.set).toHaveBeenCalled()
expect(result).toEqual({ accessToken: 'new-token', refreshed: true })
expect(mockLogger.info).toHaveBeenCalledWith(
expect.stringContaining('Successfully refreshed')
)
})
it('should handle refresh token error', async () => {
@@ -173,6 +182,8 @@ describe('OAuth Utils', () => {
await expect(
refreshTokenIfNeeded('request-id', mockCredential, 'credential-id')
).rejects.toThrow('Failed to refresh token')
expect(mockLogger.error).toHaveBeenCalled()
})
it('should not attempt refresh if no refresh token', async () => {
@@ -240,6 +251,7 @@ describe('OAuth Utils', () => {
const token = await refreshAccessTokenIfNeeded('nonexistent-id', 'test-user-id', 'request-id')
expect(token).toBeNull()
expect(mockLogger.warn).toHaveBeenCalled()
})
it('should return null if refresh fails', async () => {
@@ -258,6 +270,7 @@ describe('OAuth Utils', () => {
const token = await refreshAccessTokenIfNeeded('credential-id', 'test-user-id', 'request-id')
expect(token).toBeNull()
expect(mockLogger.error).toHaveBeenCalled()
})
})
})

View File

@@ -18,7 +18,6 @@ interface AccountInsertData {
updatedAt: Date
refreshToken?: string
idToken?: string
accessTokenExpiresAt?: Date
}
/**
@@ -104,7 +103,6 @@ export async function getOAuthToken(userId: string, providerId: string): Promise
accessToken: account.accessToken,
refreshToken: account.refreshToken,
accessTokenExpiresAt: account.accessTokenExpiresAt,
idToken: account.idToken,
})
.from(account)
.where(and(eq(account.userId, userId), eq(account.providerId, providerId)))

View File

@@ -1,14 +1,9 @@
import { headers } from 'next/headers'
import { NextResponse } from 'next/server'
import { auth } from '@/lib/auth'
import { isAuthDisabled } from '@/lib/core/config/feature-flags'
export async function POST() {
try {
if (isAuthDisabled) {
return NextResponse.json({ token: 'anonymous-socket-token' })
}
const hdrs = await headers()
const response = await auth.api.generateOneTimeToken({
headers: hdrs,

View File

@@ -1,14 +1,14 @@
import { db, ssoProvider } from '@sim/db'
import { eq } from 'drizzle-orm'
import { NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { type NextRequest, NextResponse } from 'next/server'
import { auth } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('SSO-Providers')
export async function GET() {
export async function GET(req: NextRequest) {
try {
const session = await getSession()
const session = await auth.api.getSession({ headers: req.headers })
let providers
if (session?.user?.id) {
@@ -38,6 +38,8 @@ export async function GET() {
: ('oidc' as 'oidc' | 'saml'),
}))
} else {
// Unauthenticated users can only see basic info (domain only)
// This is needed for SSO login flow to check if a domain has SSO enabled
const results = await db
.select({
domain: ssoProvider.domain,

View File

@@ -5,7 +5,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkAndBillOverageThreshold } from '@/lib/billing/threshold-billing'
import { checkInternalApiKey } from '@/lib/copilot/utils'
import { isBillingEnabled } from '@/lib/core/config/feature-flags'
import { isBillingEnabled } from '@/lib/core/config/environment'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'

View File

@@ -132,7 +132,7 @@ export async function POST(
if ((password || email) && !input) {
const response = addCorsHeaders(createSuccessResponse({ authenticated: true }), request)
setChatAuthCookie(response, deployment.id, deployment.authType, deployment.password)
setChatAuthCookie(response, deployment.id, deployment.authType)
return response
}
@@ -315,7 +315,7 @@ export async function GET(
if (
deployment.authType !== 'public' &&
authCookie &&
validateAuthToken(authCookie.value, deployment.id, deployment.password)
validateAuthToken(authCookie.value, deployment.id)
) {
return addCorsHeaders(
createSuccessResponse({

View File

@@ -6,12 +6,6 @@ import { NextRequest } from 'next/server'
*/
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
vi.mock('@/lib/core/config/feature-flags', () => ({
isDev: true,
isHosted: false,
isProd: false,
}))
describe('Chat Edit API Route', () => {
const mockSelect = vi.fn()
const mockFrom = vi.fn()
@@ -30,6 +24,7 @@ describe('Chat Edit API Route', () => {
beforeEach(() => {
vi.resetModules()
// Set default return values
mockLimit.mockResolvedValue([])
mockSelect.mockReturnValue({ from: mockFrom })
mockFrom.mockReturnValue({ where: mockWhere })
@@ -82,6 +77,10 @@ describe('Chat Edit API Route', () => {
getEmailDomain: vi.fn().mockReturnValue('localhost:3000'),
}))
vi.doMock('@/lib/core/config/environment', () => ({
isDev: true,
}))
vi.doMock('@/app/api/chat/utils', () => ({
checkChatAccess: mockCheckChatAccess,
}))
@@ -255,6 +254,7 @@ describe('Chat Edit API Route', () => {
mockCheckChatAccess.mockResolvedValue({ hasAccess: true, chat: mockChat })
// Reset and reconfigure mockLimit to return the conflict
mockLimit.mockReset()
mockLimit.mockResolvedValue([{ id: 'other-chat-id', identifier: 'new-identifier' }])
mockWhere.mockReturnValue({ limit: mockLimit })
@@ -291,7 +291,7 @@ describe('Chat Edit API Route', () => {
const req = new NextRequest('http://localhost:3000/api/chat/manage/chat-123', {
method: 'PATCH',
body: JSON.stringify({ authType: 'password' }),
body: JSON.stringify({ authType: 'password' }), // No password provided
})
const { PATCH } = await import('@/app/api/chat/manage/[id]/route')
const response = await PATCH(req, { params: Promise.resolve({ id: 'chat-123' }) })
@@ -316,8 +316,9 @@ describe('Chat Edit API Route', () => {
workflowId: 'workflow-123',
}
// User doesn't own chat but has workspace admin access
mockCheckChatAccess.mockResolvedValue({ hasAccess: true, chat: mockChat })
mockLimit.mockResolvedValueOnce([])
mockLimit.mockResolvedValueOnce([]) // No identifier conflict
const req = new NextRequest('http://localhost:3000/api/chat/manage/chat-123', {
method: 'PATCH',
@@ -398,6 +399,7 @@ describe('Chat Edit API Route', () => {
}),
}))
// User doesn't own chat but has workspace admin access
mockCheckChatAccess.mockResolvedValue({ hasAccess: true })
mockWhere.mockResolvedValue(undefined)

View File

@@ -4,7 +4,7 @@ import { eq } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { isDev } from '@/lib/core/config/feature-flags'
import { isDev } from '@/lib/core/config/environment'
import { encryptSecret } from '@/lib/core/security/encryption'
import { getEmailDomain } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'

View File

@@ -5,7 +5,7 @@ import type { NextRequest } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { isDev } from '@/lib/core/config/feature-flags'
import { isDev } from '@/lib/core/config/environment'
import { encryptSecret } from '@/lib/core/security/encryption'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'

View File

@@ -44,12 +44,6 @@ vi.mock('@/lib/core/utils/request', () => ({
generateRequestId: vi.fn(),
}))
vi.mock('@/lib/core/config/feature-flags', () => ({
isDev: true,
isHosted: false,
isProd: false,
}))
describe('Chat API Utils', () => {
beforeEach(() => {
vi.doMock('@/lib/logs/console/logger', () => ({
@@ -68,6 +62,11 @@ describe('Chat API Utils', () => {
NODE_ENV: 'development',
},
})
vi.doMock('@/lib/core/config/environment', () => ({
isDev: true,
isHosted: false,
}))
})
afterEach(() => {

View File

@@ -1,19 +1,14 @@
import { createHash } from 'crypto'
import { db } from '@sim/db'
import { chat, workflow } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import type { NextRequest, NextResponse } from 'next/server'
import { isDev } from '@/lib/core/config/feature-flags'
import { isDev } from '@/lib/core/config/environment'
import { decryptSecret } from '@/lib/core/security/encryption'
import { createLogger } from '@/lib/logs/console/logger'
import { hasAdminPermission } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('ChatAuthUtils')
function hashPassword(encryptedPassword: string): string {
return createHash('sha256').update(encryptedPassword).digest('hex').substring(0, 8)
}
/**
* Check if user has permission to create a chat for a specific workflow
* Either the user owns the workflow directly OR has admin permission for the workflow's workspace
@@ -82,20 +77,14 @@ export async function checkChatAccess(
return { hasAccess: false }
}
function encryptAuthToken(chatId: string, type: string, encryptedPassword?: string | null): string {
const pwHash = encryptedPassword ? hashPassword(encryptedPassword) : ''
return Buffer.from(`${chatId}:${type}:${Date.now()}:${pwHash}`).toString('base64')
const encryptAuthToken = (chatId: string, type: string): string => {
return Buffer.from(`${chatId}:${type}:${Date.now()}`).toString('base64')
}
export function validateAuthToken(
token: string,
chatId: string,
encryptedPassword?: string | null
): boolean {
export const validateAuthToken = (token: string, chatId: string): boolean => {
try {
const decoded = Buffer.from(token, 'base64').toString()
const parts = decoded.split(':')
const [storedId, _type, timestamp, storedPwHash] = parts
const [storedId, _type, timestamp] = decoded.split(':')
if (storedId !== chatId) {
return false
@@ -103,32 +92,20 @@ export function validateAuthToken(
const createdAt = Number.parseInt(timestamp)
const now = Date.now()
const expireTime = 24 * 60 * 60 * 1000
const expireTime = 24 * 60 * 60 * 1000 // 24 hours
if (now - createdAt > expireTime) {
return false
}
if (encryptedPassword) {
const currentPwHash = hashPassword(encryptedPassword)
if (storedPwHash !== currentPwHash) {
return false
}
}
return true
} catch (_e) {
return false
}
}
export function setChatAuthCookie(
response: NextResponse,
chatId: string,
type: string,
encryptedPassword?: string | null
): void {
const token = encryptAuthToken(chatId, type, encryptedPassword)
export const setChatAuthCookie = (response: NextResponse, chatId: string, type: string): void => {
const token = encryptAuthToken(chatId, type)
response.cookies.set({
name: `chat_auth_${chatId}`,
value: token,
@@ -136,7 +113,7 @@ export function setChatAuthCookie(
secure: !isDev,
sameSite: 'lax',
path: '/',
maxAge: 60 * 60 * 24,
maxAge: 60 * 60 * 24, // 24 hours
})
}
@@ -168,7 +145,7 @@ export async function validateChatAuth(
const cookieName = `chat_auth_${deployment.id}`
const authCookie = request.cookies.get(cookieName)
if (authCookie && validateAuthToken(authCookie.value, deployment.id, deployment.password)) {
if (authCookie && validateAuthToken(authCookie.value, deployment.id)) {
return { authorized: true }
}
@@ -282,8 +259,8 @@ export async function validateChatAuth(
return { authorized: false, error: 'Email not authorized for SSO access' }
}
const { getSession } = await import('@/lib/auth')
const session = await getSession()
const { auth } = await import('@/lib/auth')
const session = await auth.api.getSession({ headers: request.headers })
if (!session || !session.user) {
return { authorized: false, error: 'auth_required_sso' }

View File

@@ -2,7 +2,7 @@ import { db } from '@sim/db'
import { settings } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { auth } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotAutoAllowedToolsAPI')
@@ -10,9 +10,9 @@ const logger = createLogger('CopilotAutoAllowedToolsAPI')
/**
* GET - Fetch user's auto-allowed integration tools
*/
export async function GET() {
export async function GET(request: NextRequest) {
try {
const session = await getSession()
const session = await auth.api.getSession({ headers: request.headers })
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
@@ -31,6 +31,7 @@ export async function GET() {
return NextResponse.json({ autoAllowedTools })
}
// If no settings record exists, create one with empty array
await db.insert(settings).values({
id: userId,
userId,
@@ -49,7 +50,7 @@ export async function GET() {
*/
export async function POST(request: NextRequest) {
try {
const session = await getSession()
const session = await auth.api.getSession({ headers: request.headers })
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
@@ -64,11 +65,13 @@ export async function POST(request: NextRequest) {
const toolId = body.toolId
// Get existing settings
const [existing] = await db.select().from(settings).where(eq(settings.userId, userId)).limit(1)
if (existing) {
const currentTools = (existing.copilotAutoAllowedTools as string[]) || []
// Add tool if not already present
if (!currentTools.includes(toolId)) {
const updatedTools = [...currentTools, toolId]
await db
@@ -86,6 +89,7 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ success: true, autoAllowedTools: currentTools })
}
// Create new settings record with the tool
await db.insert(settings).values({
id: userId,
userId,
@@ -105,7 +109,7 @@ export async function POST(request: NextRequest) {
*/
export async function DELETE(request: NextRequest) {
try {
const session = await getSession()
const session = await auth.api.getSession({ headers: request.headers })
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
@@ -119,6 +123,7 @@ export async function DELETE(request: NextRequest) {
return NextResponse.json({ error: 'toolId query parameter is required' }, { status: 400 })
}
// Get existing settings
const [existing] = await db.select().from(settings).where(eq(settings.userId, userId)).limit(1)
if (existing) {

View File

@@ -303,14 +303,6 @@ export async function POST(req: NextRequest) {
apiVersion: 'preview',
endpoint: env.AZURE_OPENAI_ENDPOINT,
}
} else if (providerEnv === 'vertex') {
providerConfig = {
provider: 'vertex',
model: modelToUse,
apiKey: env.COPILOT_API_KEY,
vertexProject: env.VERTEX_PROJECT,
vertexLocation: env.VERTEX_LOCATION,
}
} else {
providerConfig = {
provider: providerEnv,

View File

@@ -66,14 +66,6 @@ export async function POST(req: NextRequest) {
apiVersion: env.AZURE_OPENAI_API_VERSION,
endpoint: env.AZURE_OPENAI_ENDPOINT,
}
} else if (providerEnv === 'vertex') {
providerConfig = {
provider: 'vertex',
model: modelToUse,
apiKey: env.COPILOT_API_KEY,
vertexProject: env.VERTEX_PROJECT,
vertexLocation: env.VERTEX_LOCATION,
}
} else {
providerConfig = {
provider: providerEnv,

View File

@@ -1,6 +1,6 @@
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { auth } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
import { db } from '@/../../packages/db'
import { settings } from '@/../../packages/db/schema'
@@ -32,7 +32,7 @@ const DEFAULT_ENABLED_MODELS: Record<string, boolean> = {
// GET - Fetch user's enabled models
export async function GET(request: NextRequest) {
try {
const session = await getSession()
const session = await auth.api.getSession({ headers: request.headers })
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
@@ -40,6 +40,7 @@ export async function GET(request: NextRequest) {
const userId = session.user.id
// Try to fetch existing settings record
const [userSettings] = await db
.select()
.from(settings)
@@ -49,11 +50,13 @@ export async function GET(request: NextRequest) {
if (userSettings) {
const userModelsMap = (userSettings.copilotEnabledModels as Record<string, boolean>) || {}
// Merge: start with defaults, then override with user's existing preferences
const mergedModels = { ...DEFAULT_ENABLED_MODELS }
for (const [modelId, enabled] of Object.entries(userModelsMap)) {
mergedModels[modelId] = enabled
}
// If we added any new models, update the database
const hasNewModels = Object.keys(DEFAULT_ENABLED_MODELS).some(
(key) => !(key in userModelsMap)
)
@@ -73,6 +76,7 @@ export async function GET(request: NextRequest) {
})
}
// If no settings record exists, create one with defaults
await db.insert(settings).values({
id: userId,
userId,
@@ -93,7 +97,7 @@ export async function GET(request: NextRequest) {
// PUT - Update user's enabled models
export async function PUT(request: NextRequest) {
try {
const session = await getSession()
const session = await auth.api.getSession({ headers: request.headers })
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
@@ -106,9 +110,11 @@ export async function PUT(request: NextRequest) {
return NextResponse.json({ error: 'enabledModels must be an object' }, { status: 400 })
}
// Check if settings record exists
const [existing] = await db.select().from(settings).where(eq(settings.userId, userId)).limit(1)
if (existing) {
// Update existing record
await db
.update(settings)
.set({
@@ -117,6 +123,7 @@ export async function PUT(request: NextRequest) {
})
.where(eq(settings.userId, userId))
} else {
// Create new settings record
await db.insert(settings).values({
id: userId,
userId,

View File

@@ -7,80 +7,10 @@ import { NextRequest } from 'next/server'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { createMockRequest } from '@/app/api/__test-utils__/utils'
vi.mock('@/lib/execution/isolated-vm', () => ({
executeInIsolatedVM: vi.fn().mockImplementation(async (req) => {
const { code, params, envVars, contextVariables } = req
const stdoutChunks: string[] = []
const mockConsole = {
log: (...args: unknown[]) => {
stdoutChunks.push(
`${args.map((a) => (typeof a === 'object' ? JSON.stringify(a) : String(a))).join(' ')}\n`
)
},
error: (...args: unknown[]) => {
stdoutChunks.push(
'ERROR: ' +
args.map((a) => (typeof a === 'object' ? JSON.stringify(a) : String(a))).join(' ') +
'\n'
)
},
warn: (...args: unknown[]) => mockConsole.log('WARN:', ...args),
info: (...args: unknown[]) => mockConsole.log(...args),
}
try {
const escapePattern = /this\.constructor\.constructor|\.constructor\s*\(/
if (escapePattern.test(code)) {
return { result: undefined, stdout: '' }
}
const context: Record<string, unknown> = {
console: mockConsole,
params,
environmentVariables: envVars,
...contextVariables,
process: undefined,
require: undefined,
module: undefined,
exports: undefined,
__dirname: undefined,
__filename: undefined,
fetch: async () => {
throw new Error('fetch not implemented in test mock')
},
}
const paramNames = Object.keys(context)
const paramValues = Object.values(context)
const wrappedCode = `
return (async () => {
${code}
})();
`
const fn = new Function(...paramNames, wrappedCode)
const result = await fn(...paramValues)
return {
result,
stdout: stdoutChunks.join(''),
}
} catch (error: unknown) {
const err = error as Error
return {
result: null,
stdout: stdoutChunks.join(''),
error: {
message: err.message || String(error),
name: err.name || 'Error',
stack: err.stack,
},
}
}
}),
}))
const mockCreateContext = vi.fn()
const mockRunInContext = vi.fn()
const mockScript = vi.fn()
const mockExecuteInE2B = vi.fn()
vi.mock('@/lib/logs/console/logger', () => ({
createLogger: vi.fn(() => ({
@@ -91,20 +21,35 @@ vi.mock('@/lib/logs/console/logger', () => ({
})),
}))
vi.mock('vm', () => ({
createContext: vi.fn(),
Script: vi.fn(),
}))
vi.mock('@/lib/execution/e2b', () => ({
executeInE2B: vi.fn(),
}))
import { createContext, Script } from 'vm'
import { validateProxyUrl } from '@/lib/core/security/input-validation'
import { executeInE2B } from '@/lib/execution/e2b'
import { createLogger } from '@/lib/logs/console/logger'
import { POST } from './route'
const mockedCreateContext = vi.mocked(createContext)
const mockedScript = vi.mocked(Script)
const mockedExecuteInE2B = vi.mocked(executeInE2B)
const mockedCreateLogger = vi.mocked(createLogger)
describe('Function Execute API Route', () => {
beforeEach(() => {
vi.clearAllMocks()
mockedCreateContext.mockReturnValue({})
mockRunInContext.mockResolvedValue('vm success')
mockedScript.mockImplementation((): any => ({
runInContext: mockRunInContext,
}))
mockedExecuteInE2B.mockResolvedValue({
result: 'e2b success',
stdout: 'e2b output',
@@ -117,77 +62,19 @@ describe('Function Execute API Route', () => {
})
describe('Security Tests', () => {
it.concurrent('should use isolated-vm for secure sandboxed execution', async () => {
it.concurrent('should create secure fetch in VM context', async () => {
const req = createMockRequest('POST', {
code: 'return "test"',
})
const response = await POST(req)
const data = await response.json()
await POST(req)
expect(response.status).toBe(200)
expect(data.success).toBe(true)
expect(data.output.result).toBe('test')
})
expect(mockedCreateContext).toHaveBeenCalled()
const contextArgs = mockedCreateContext.mock.calls[0][0]
expect(contextArgs).toHaveProperty('fetch')
expect(typeof (contextArgs as any).fetch).toBe('function')
it.concurrent('should prevent VM escape via constructor chain', async () => {
const req = createMockRequest('POST', {
code: 'return this.constructor.constructor("return process")().env',
})
const response = await POST(req)
const data = await response.json()
if (response.status === 500) {
expect(data.success).toBe(false)
} else {
const result = data.output?.result
expect(result === undefined || result === null).toBe(true)
}
})
it.concurrent('should prevent access to require via constructor chain', async () => {
const req = createMockRequest('POST', {
code: `
const proc = this.constructor.constructor("return process")();
const fs = proc.mainModule.require("fs");
return fs.readFileSync("/etc/passwd", "utf8");
`,
})
const response = await POST(req)
const data = await response.json()
if (response.status === 200) {
const result = data.output?.result
if (result !== undefined && result !== null && typeof result === 'string') {
expect(result).not.toContain('root:')
}
}
})
it.concurrent('should not expose process object', async () => {
const req = createMockRequest('POST', {
code: 'return typeof process',
})
const response = await POST(req)
const data = await response.json()
expect(response.status).toBe(200)
expect(data.output.result).toBe('undefined')
})
it.concurrent('should not expose require function', async () => {
const req = createMockRequest('POST', {
code: 'return typeof require',
})
const response = await POST(req)
const data = await response.json()
expect(response.status).toBe(200)
expect(data.output.result).toBe('undefined')
expect((contextArgs as any).fetch?.name).toBe('secureFetch')
})
it.concurrent('should block SSRF attacks through secure fetch wrapper', async () => {
@@ -226,20 +113,6 @@ describe('Function Execute API Route', () => {
expect(data.output).toHaveProperty('executionTime')
})
it.concurrent('should return computed result for multi-line code', async () => {
const req = createMockRequest('POST', {
code: 'const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;\nreturn a + b + c + d;',
timeout: 5000,
})
const response = await POST(req)
const data = await response.json()
expect(response.status).toBe(200)
expect(data.success).toBe(true)
expect(data.output.result).toBe(10)
})
it.concurrent('should handle missing code parameter', async () => {
const req = createMockRequest('POST', {
timeout: 5000,
@@ -439,6 +312,20 @@ describe('Function Execute API Route', () => {
describe('Enhanced Error Handling', () => {
it('should provide detailed syntax error with line content', async () => {
const syntaxError = new Error('Invalid or unexpected token')
syntaxError.name = 'SyntaxError'
syntaxError.stack = `user-function.js:5
description: "This has a missing closing quote
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: Invalid or unexpected token
at new Script (node:vm:117:7)
at POST (/path/to/route.ts:123:24)`
mockedScript.mockImplementationOnce(() => {
throw syntaxError
})
const req = createMockRequest('POST', {
code: 'const obj = {\n name: "test",\n description: "This has a missing closing quote\n};\nreturn obj;',
timeout: 5000,
@@ -449,10 +336,28 @@ describe('Function Execute API Route', () => {
expect(response.status).toBe(500)
expect(data.success).toBe(false)
expect(data.error).toBeTruthy()
expect(data.error).toContain('Syntax Error')
expect(data.error).toContain('Line 3')
expect(data.error).toContain('description: "This has a missing closing quote')
expect(data.error).toContain('Invalid or unexpected token')
expect(data.error).toContain('(Check for missing quotes, brackets, or semicolons)')
expect(data.debug).toBeDefined()
expect(data.debug.line).toBe(3)
expect(data.debug.errorType).toBe('SyntaxError')
expect(data.debug.lineContent).toBe('description: "This has a missing closing quote')
})
it('should provide detailed runtime error with line and column', async () => {
const runtimeError = new Error("Cannot read properties of null (reading 'someMethod')")
runtimeError.name = 'TypeError'
runtimeError.stack = `TypeError: Cannot read properties of null (reading 'someMethod')
at user-function.js:4:16
at user-function.js:9:3
at Script.runInContext (node:vm:147:14)`
mockRunInContext.mockRejectedValueOnce(runtimeError)
const req = createMockRequest('POST', {
code: 'const obj = null;\nreturn obj.someMethod();',
timeout: 5000,
@@ -464,10 +369,26 @@ describe('Function Execute API Route', () => {
expect(response.status).toBe(500)
expect(data.success).toBe(false)
expect(data.error).toContain('Type Error')
expect(data.error).toContain('Line 2')
expect(data.error).toContain('return obj.someMethod();')
expect(data.error).toContain('Cannot read properties of null')
expect(data.debug).toBeDefined()
expect(data.debug.line).toBe(2)
expect(data.debug.column).toBe(16)
expect(data.debug.errorType).toBe('TypeError')
expect(data.debug.lineContent).toBe('return obj.someMethod();')
})
it('should handle ReferenceError with enhanced details', async () => {
const referenceError = new Error('undefinedVariable is not defined')
referenceError.name = 'ReferenceError'
referenceError.stack = `ReferenceError: undefinedVariable is not defined
at user-function.js:4:8
at Script.runInContext (node:vm:147:14)`
mockRunInContext.mockRejectedValueOnce(referenceError)
const req = createMockRequest('POST', {
code: 'const x = 42;\nreturn undefinedVariable + x;',
timeout: 5000,
@@ -479,12 +400,21 @@ describe('Function Execute API Route', () => {
expect(response.status).toBe(500)
expect(data.success).toBe(false)
expect(data.error).toContain('Reference Error')
expect(data.error).toContain('Line 2')
expect(data.error).toContain('return undefinedVariable + x;')
expect(data.error).toContain('undefinedVariable is not defined')
})
it('should handle thrown errors gracefully', async () => {
it('should handle errors without line content gracefully', async () => {
const genericError = new Error('Generic error without stack trace')
genericError.name = 'Error'
mockedScript.mockImplementationOnce(() => {
throw genericError
})
const req = createMockRequest('POST', {
code: 'throw new Error("Custom error message");',
code: 'return "test";',
timeout: 5000,
})
@@ -493,10 +423,51 @@ describe('Function Execute API Route', () => {
expect(response.status).toBe(500)
expect(data.success).toBe(false)
expect(data.error).toContain('Custom error message')
expect(data.error).toBe('Generic error without stack trace')
expect(data.debug).toBeDefined()
expect(data.debug.errorType).toBe('Error')
expect(data.debug.line).toBeUndefined()
expect(data.debug.lineContent).toBeUndefined()
})
it('should extract line numbers from different stack trace formats', async () => {
const testError = new Error('Test error')
testError.name = 'Error'
testError.stack = `Error: Test error
at user-function.js:7:25
at async function
at Script.runInContext (node:vm:147:14)`
mockedScript.mockImplementationOnce(() => {
throw testError
})
const req = createMockRequest('POST', {
code: 'const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;\nreturn a + b + c + d;',
timeout: 5000,
})
const response = await POST(req)
const data = await response.json()
expect(response.status).toBe(500)
expect(data.success).toBe(false)
expect(data.debug.line).toBe(5)
expect(data.debug.column).toBe(25)
expect(data.debug.lineContent).toBe('return a + b + c + d;')
})
it.concurrent('should provide helpful suggestions for common syntax errors', async () => {
const syntaxError = new Error('Unexpected end of input')
syntaxError.name = 'SyntaxError'
syntaxError.stack = 'user-function.js:4\nSyntaxError: Unexpected end of input'
mockedScript.mockImplementationOnce(() => {
throw syntaxError
})
const req = createMockRequest('POST', {
code: 'const obj = {\n name: "test"\n// Missing closing brace',
timeout: 5000,
@@ -507,7 +478,9 @@ describe('Function Execute API Route', () => {
expect(response.status).toBe(500)
expect(data.success).toBe(false)
expect(data.error).toBeTruthy()
expect(data.error).toContain('Syntax Error')
expect(data.error).toContain('Unexpected end of input')
expect(data.error).toContain('(Check for missing closing brackets or braces)')
})
})

View File

@@ -1,14 +1,11 @@
import { createContext, Script } from 'vm'
import { type NextRequest, NextResponse } from 'next/server'
import { isE2bEnabled } from '@/lib/core/config/feature-flags'
import { env, isTruthy } from '@/lib/core/config/env'
import { validateProxyUrl } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'
import { executeInE2B } from '@/lib/execution/e2b'
import { executeInIsolatedVM } from '@/lib/execution/isolated-vm'
import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages'
import { createLogger } from '@/lib/logs/console/logger'
import {
createEnvVarPattern,
createWorkflowVariablePattern,
} from '@/executor/utils/reference-validation'
export const dynamic = 'force-dynamic'
export const runtime = 'nodejs'
@@ -16,6 +13,30 @@ export const MAX_DURATION = 210
const logger = createLogger('FunctionExecuteAPI')
function createSecureFetch(requestId: string) {
const originalFetch = (globalThis as any).fetch || require('node-fetch').default
return async function secureFetch(input: any, init?: any) {
const url = typeof input === 'string' ? input : input?.url || input
if (!url || typeof url !== 'string') {
throw new Error('Invalid URL provided to fetch')
}
const validation = validateProxyUrl(url)
if (!validation.isValid) {
logger.warn(`[${requestId}] Blocked fetch request due to SSRF validation`, {
url: url.substring(0, 100),
error: validation.error,
})
throw new Error(`Security Error: ${validation.error}`)
}
return originalFetch(input, init)
}
}
// Constants for E2B code wrapping line counts
const E2B_JS_WRAPPER_LINES = 3 // Lines before user code: ';(async () => {', ' try {', ' const __sim_result = await (async () => {'
const E2B_PYTHON_WRAPPER_LINES = 1 // Lines before user code: 'def __sim_main__():'
@@ -325,9 +346,9 @@ function createUserFriendlyErrorMessage(
): string {
let errorMessage = enhanced.message
// Add line information if available
// Add line and column information if available
if (enhanced.line !== undefined) {
let lineInfo = `Line ${enhanced.line}`
let lineInfo = `Line ${enhanced.line}${enhanced.column !== undefined ? `:${enhanced.column}` : ''}`
// Add the actual line content if available
if (enhanced.lineContent) {
@@ -341,7 +362,8 @@ function createUserFriendlyErrorMessage(
const stackMatch = enhanced.stack.match(/user-function\.js:(\d+)(?::(\d+))?/)
if (stackMatch) {
const line = Number.parseInt(stackMatch[1], 10)
let lineInfo = `Line ${line}`
const column = stackMatch[2] ? Number.parseInt(stackMatch[2], 10) : undefined
let lineInfo = `Line ${line}${column ? `:${column}` : ''}`
// Try to get line content if we have userCode
if (userCode) {
@@ -378,6 +400,27 @@ function createUserFriendlyErrorMessage(
}
}
// For syntax errors, provide additional context
if (enhanced.name === 'SyntaxError') {
if (errorMessage.includes('Invalid or unexpected token')) {
errorMessage += ' (Check for missing quotes, brackets, or semicolons)'
} else if (errorMessage.includes('Unexpected end of input')) {
errorMessage += ' (Check for missing closing brackets or braces)'
} else if (errorMessage.includes('Unexpected token')) {
// Check if this might be due to incomplete code
if (
enhanced.lineContent &&
((enhanced.lineContent.includes('(') && !enhanced.lineContent.includes(')')) ||
(enhanced.lineContent.includes('[') && !enhanced.lineContent.includes(']')) ||
(enhanced.lineContent.includes('{') && !enhanced.lineContent.includes('}')))
) {
errorMessage += ' (Check for missing closing parentheses, brackets, or braces)'
} else {
errorMessage += ' (Check your syntax)'
}
}
}
return errorMessage
}
@@ -391,27 +434,19 @@ function resolveWorkflowVariables(
): string {
let resolvedCode = code
const regex = createWorkflowVariablePattern()
let match: RegExpExecArray | null
const replacements: Array<{
match: string
index: number
variableName: string
variableValue: unknown
}> = []
while ((match = regex.exec(code)) !== null) {
const variableName = match[1].trim()
const variableMatches = resolvedCode.match(/<variable\.([^>]+)>/g) || []
for (const match of variableMatches) {
const variableName = match.slice('<variable.'.length, -1).trim()
// Find the variable by name (workflowVariables is indexed by ID, values are variable objects)
const foundVariable = Object.entries(workflowVariables).find(
([_, variable]) => (variable.name || '').replace(/\s+/g, '') === variableName
)
let variableValue: unknown = ''
if (foundVariable) {
const variable = foundVariable[1]
variableValue = variable.value
// Get the typed value - handle different variable types
let variableValue = variable.value
if (variable.value !== undefined && variable.value !== null) {
try {
@@ -433,30 +468,22 @@ function resolveWorkflowVariables(
// Keep original value if JSON parsing fails
}
}
} catch {
} catch (error) {
// Fallback to original value on error
variableValue = variable.value
}
}
// Create a safe variable reference
const safeVarName = `__variable_${variableName.replace(/[^a-zA-Z0-9_]/g, '_')}`
contextVariables[safeVarName] = variableValue
// Replace the variable reference with the safe variable name
resolvedCode = resolvedCode.replace(new RegExp(escapeRegExp(match), 'g'), safeVarName)
} else {
// Variable not found - replace with empty string to avoid syntax errors
resolvedCode = resolvedCode.replace(new RegExp(escapeRegExp(match), 'g'), '')
}
replacements.push({
match: match[0],
index: match.index,
variableName,
variableValue,
})
}
// Process replacements in reverse order to maintain correct indices
for (let i = replacements.length - 1; i >= 0; i--) {
const { match: matchStr, index, variableName, variableValue } = replacements[i]
// Use variable reference approach
const safeVarName = `__variable_${variableName.replace(/[^a-zA-Z0-9_]/g, '_')}`
contextVariables[safeVarName] = variableValue
resolvedCode =
resolvedCode.slice(0, index) + safeVarName + resolvedCode.slice(index + matchStr.length)
}
return resolvedCode
@@ -473,29 +500,18 @@ function resolveEnvironmentVariables(
): string {
let resolvedCode = code
const regex = createEnvVarPattern()
let match: RegExpExecArray | null
const replacements: Array<{ match: string; index: number; varName: string; varValue: string }> =
[]
while ((match = regex.exec(code)) !== null) {
const varName = match[1].trim()
const envVarMatches = resolvedCode.match(/\{\{([^}]+)\}\}/g) || []
for (const match of envVarMatches) {
const varName = match.slice(2, -2).trim()
// Priority: 1. Environment variables from workflow, 2. Params
const varValue = envVars[varName] || params[varName] || ''
replacements.push({
match: match[0],
index: match.index,
varName,
varValue: String(varValue),
})
}
for (let i = replacements.length - 1; i >= 0; i--) {
const { match: matchStr, index, varName, varValue } = replacements[i]
// Instead of injecting large JSON directly, create a variable reference
const safeVarName = `__var_${varName.replace(/[^a-zA-Z0-9_]/g, '_')}`
contextVariables[safeVarName] = varValue
resolvedCode =
resolvedCode.slice(0, index) + safeVarName + resolvedCode.slice(index + matchStr.length)
// Replace the template with a variable reference
resolvedCode = resolvedCode.replace(new RegExp(escapeRegExp(match), 'g'), safeVarName)
}
return resolvedCode
@@ -685,6 +701,7 @@ export async function POST(req: NextRequest) {
resolvedCode = codeResolution.resolvedCode
const contextVariables = codeResolution.contextVariables
const e2bEnabled = isTruthy(env.E2B_ENABLED)
const lang = isValidCodeLanguage(language) ? language : DEFAULT_CODE_LANGUAGE
// Extract imports once for JavaScript code (reuse later to avoid double extraction)
@@ -705,14 +722,14 @@ export async function POST(req: NextRequest) {
}
// Python always requires E2B
if (lang === CodeLanguage.Python && !isE2bEnabled) {
if (lang === CodeLanguage.Python && !e2bEnabled) {
throw new Error(
'Python execution requires E2B to be enabled. Please contact your administrator to enable E2B, or use JavaScript instead.'
)
}
// JavaScript with imports requires E2B
if (lang === CodeLanguage.JavaScript && hasImports && !isE2bEnabled) {
if (lang === CodeLanguage.JavaScript && hasImports && !e2bEnabled) {
throw new Error(
'JavaScript code with import statements requires E2B to be enabled. Please remove the import statements, or contact your administrator to enable E2B.'
)
@@ -723,13 +740,13 @@ export async function POST(req: NextRequest) {
// - Not a custom tool AND
// - (Python OR JavaScript with imports)
const useE2B =
isE2bEnabled &&
e2bEnabled &&
!isCustomTool &&
(lang === CodeLanguage.Python || (lang === CodeLanguage.JavaScript && hasImports))
if (useE2B) {
logger.info(`[${requestId}] E2B status`, {
enabled: isE2bEnabled,
enabled: e2bEnabled,
hasApiKey: Boolean(process.env.E2B_API_KEY),
language: lang,
})
@@ -883,7 +900,28 @@ export async function POST(req: NextRequest) {
})
}
const executionMethod = 'isolated-vm'
const executionMethod = 'vm'
const context = createContext({
params: executionParams,
environmentVariables: envVars,
...contextVariables,
fetch: createSecureFetch(requestId),
console: {
log: (...args: any[]) => {
const logMessage = `${args
.map((arg) => (typeof arg === 'object' ? JSON.stringify(arg) : String(arg)))
.join(' ')}\n`
stdout += logMessage
},
error: (...args: any[]) => {
const errorMessage = `${args
.map((arg) => (typeof arg === 'object' ? JSON.stringify(arg) : String(arg)))
.join(' ')}\n`
logger.error(`[${requestId}] Code Console Error: ${errorMessage}`)
stdout += `ERROR: ${errorMessage}`
},
},
})
const wrapperLines = ['(async () => {', ' try {']
if (isCustomTool) {
@@ -893,99 +931,36 @@ export async function POST(req: NextRequest) {
})
}
userCodeStartLine = wrapperLines.length + 1
const fullScript = [
...wrapperLines,
` ${resolvedCode.split('\n').join('\n ')}`,
' } catch (error) {',
' console.error(error);',
' throw error;',
' }',
'})()',
].join('\n')
let codeToExecute = resolvedCode
let prependedLineCount = 0
if (isCustomTool) {
const paramKeys = Object.keys(executionParams)
const paramDestructuring = paramKeys.map((key) => `const ${key} = params.${key};`).join('\n')
codeToExecute = `${paramDestructuring}\n${resolvedCode}`
prependedLineCount = paramKeys.length
}
const script = new Script(fullScript, {
filename: 'user-function.js',
lineOffset: 0,
columnOffset: 0,
})
const isolatedResult = await executeInIsolatedVM({
code: codeToExecute,
params: executionParams,
envVars,
contextVariables,
timeoutMs: timeout,
requestId,
const result = await script.runInContext(context, {
timeout,
displayErrors: true,
breakOnSigint: true,
})
const executionTime = Date.now() - startTime
if (isolatedResult.error) {
logger.error(`[${requestId}] Function execution failed in isolated-vm`, {
error: isolatedResult.error,
executionTime,
})
const ivmError = isolatedResult.error
// Adjust line number for prepended param destructuring in custom tools
let adjustedLine = ivmError.line
let adjustedLineContent = ivmError.lineContent
if (prependedLineCount > 0 && ivmError.line !== undefined) {
adjustedLine = Math.max(1, ivmError.line - prependedLineCount)
// Get line content from original user code, not the prepended code
const codeLines = resolvedCode.split('\n')
if (adjustedLine <= codeLines.length) {
adjustedLineContent = codeLines[adjustedLine - 1]?.trim()
}
}
const enhancedError: EnhancedError = {
message: ivmError.message,
name: ivmError.name,
stack: ivmError.stack,
originalError: ivmError,
line: adjustedLine,
column: ivmError.column,
lineContent: adjustedLineContent,
}
const userFriendlyErrorMessage = createUserFriendlyErrorMessage(
enhancedError,
requestId,
resolvedCode
)
logger.error(`[${requestId}] Enhanced error details`, {
originalMessage: ivmError.message,
enhancedMessage: userFriendlyErrorMessage,
line: enhancedError.line,
column: enhancedError.column,
lineContent: enhancedError.lineContent,
errorType: enhancedError.name,
})
return NextResponse.json(
{
success: false,
error: userFriendlyErrorMessage,
output: {
result: null,
stdout: cleanStdout(isolatedResult.stdout),
executionTime,
},
debug: {
line: enhancedError.line,
column: enhancedError.column,
errorType: enhancedError.name,
lineContent: enhancedError.lineContent,
stack: enhancedError.stack,
},
},
{ status: 500 }
)
}
stdout = isolatedResult.stdout
logger.info(`[${requestId}] Function executed successfully using ${executionMethod}`, {
executionTime,
})
return NextResponse.json({
success: true,
output: { result: isolatedResult.result, stdout: cleanStdout(stdout), executionTime },
output: { result, stdout: cleanStdout(stdout), executionTime },
})
} catch (error: any) {
const executionTime = Date.now() - startTime
@@ -1002,6 +977,7 @@ export async function POST(req: NextRequest) {
resolvedCode
)
// Log enhanced error details for debugging
logger.error(`[${requestId}] Enhanced error details`, {
originalMessage: error.message,
enhancedMessage: userFriendlyErrorMessage,
@@ -1020,6 +996,7 @@ export async function POST(req: NextRequest) {
stdout: cleanStdout(stdout),
executionTime,
},
// Include debug information in development or for debugging
debug: {
line: enhancedError.line,
column: enhancedError.column,

View File

@@ -6,22 +6,7 @@ import {
workflowDeploymentVersion,
workflowExecutionLogs,
} from '@sim/db/schema'
import {
and,
desc,
eq,
gt,
gte,
inArray,
isNotNull,
isNull,
lt,
lte,
ne,
or,
type SQL,
sql,
} from 'drizzle-orm'
import { and, desc, eq, gte, inArray, isNotNull, isNull, lte, or, type SQL, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
@@ -37,19 +22,14 @@ const QueryParamsSchema = z.object({
limit: z.coerce.number().optional().default(100),
offset: z.coerce.number().optional().default(0),
level: z.string().optional(),
workflowIds: z.string().optional(),
folderIds: z.string().optional(),
triggers: z.string().optional(),
workflowIds: z.string().optional(), // Comma-separated list of workflow IDs
folderIds: z.string().optional(), // Comma-separated list of folder IDs
triggers: z.string().optional(), // Comma-separated list of trigger types
startDate: z.string().optional(),
endDate: z.string().optional(),
search: z.string().optional(),
workflowName: z.string().optional(),
folderName: z.string().optional(),
executionId: z.string().optional(),
costOperator: z.enum(['=', '>', '<', '>=', '<=', '!=']).optional(),
costValue: z.coerce.number().optional(),
durationOperator: z.enum(['=', '>', '<', '>=', '<=', '!=']).optional(),
durationValue: z.coerce.number().optional(),
workspaceId: z.string(),
})
@@ -69,6 +49,7 @@ export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url)
const params = QueryParamsSchema.parse(Object.fromEntries(searchParams.entries()))
// Conditionally select columns based on detail level to optimize performance
const selectColumns =
params.details === 'full'
? {
@@ -82,9 +63,9 @@ export async function GET(request: NextRequest) {
startedAt: workflowExecutionLogs.startedAt,
endedAt: workflowExecutionLogs.endedAt,
totalDurationMs: workflowExecutionLogs.totalDurationMs,
executionData: workflowExecutionLogs.executionData,
executionData: workflowExecutionLogs.executionData, // Large field - only in full mode
cost: workflowExecutionLogs.cost,
files: workflowExecutionLogs.files,
files: workflowExecutionLogs.files, // Large field - only in full mode
createdAt: workflowExecutionLogs.createdAt,
workflowName: workflow.name,
workflowDescription: workflow.description,
@@ -101,6 +82,7 @@ export async function GET(request: NextRequest) {
deploymentVersionName: workflowDeploymentVersion.name,
}
: {
// Basic mode - exclude large fields for better performance
id: workflowExecutionLogs.id,
workflowId: workflowExecutionLogs.workflowId,
executionId: workflowExecutionLogs.executionId,
@@ -111,9 +93,9 @@ export async function GET(request: NextRequest) {
startedAt: workflowExecutionLogs.startedAt,
endedAt: workflowExecutionLogs.endedAt,
totalDurationMs: workflowExecutionLogs.totalDurationMs,
executionData: sql<null>`NULL`,
executionData: sql<null>`NULL`, // Exclude large execution data in basic mode
cost: workflowExecutionLogs.cost,
files: sql<null>`NULL`,
files: sql<null>`NULL`, // Exclude files in basic mode
createdAt: workflowExecutionLogs.createdAt,
workflowName: workflow.name,
workflowDescription: workflow.description,
@@ -127,7 +109,7 @@ export async function GET(request: NextRequest) {
pausedTotalPauseCount: pausedExecutions.totalPauseCount,
pausedResumedCount: pausedExecutions.resumedCount,
deploymentVersion: workflowDeploymentVersion.version,
deploymentVersionName: sql<null>`NULL`,
deploymentVersionName: sql<null>`NULL`, // Only needed in full mode for details panel
}
const baseQuery = db
@@ -157,28 +139,34 @@ export async function GET(request: NextRequest) {
)
)
// Build additional conditions for the query
let conditions: SQL | undefined
// Filter by level with support for derived statuses (running, pending)
if (params.level && params.level !== 'all') {
const levels = params.level.split(',').filter(Boolean)
const levelConditions: SQL[] = []
for (const level of levels) {
if (level === 'error') {
// Direct database field
levelConditions.push(eq(workflowExecutionLogs.level, 'error'))
} else if (level === 'info') {
// Completed info logs only (not running, not pending)
const condition = and(
eq(workflowExecutionLogs.level, 'info'),
isNotNull(workflowExecutionLogs.endedAt)
)
if (condition) levelConditions.push(condition)
} else if (level === 'running') {
// Running logs: info level with no endedAt
const condition = and(
eq(workflowExecutionLogs.level, 'info'),
isNull(workflowExecutionLogs.endedAt)
)
if (condition) levelConditions.push(condition)
} else if (level === 'pending') {
// Pending logs: info level with pause status indicators
const condition = and(
eq(workflowExecutionLogs.level, 'info'),
or(
@@ -201,6 +189,7 @@ export async function GET(request: NextRequest) {
}
}
// Filter by specific workflow IDs
if (params.workflowIds) {
const workflowIds = params.workflowIds.split(',').filter(Boolean)
if (workflowIds.length > 0) {
@@ -208,6 +197,7 @@ export async function GET(request: NextRequest) {
}
}
// Filter by folder IDs
if (params.folderIds) {
const folderIds = params.folderIds.split(',').filter(Boolean)
if (folderIds.length > 0) {
@@ -215,6 +205,7 @@ export async function GET(request: NextRequest) {
}
}
// Filter by triggers
if (params.triggers) {
const triggers = params.triggers.split(',').filter(Boolean)
if (triggers.length > 0 && !triggers.includes('all')) {
@@ -222,6 +213,7 @@ export async function GET(request: NextRequest) {
}
}
// Filter by date range
if (params.startDate) {
conditions = and(
conditions,
@@ -232,79 +224,33 @@ export async function GET(request: NextRequest) {
conditions = and(conditions, lte(workflowExecutionLogs.startedAt, new Date(params.endDate)))
}
// Filter by search query
if (params.search) {
const searchTerm = `%${params.search}%`
// With message removed, restrict search to executionId only
conditions = and(conditions, sql`${workflowExecutionLogs.executionId} ILIKE ${searchTerm}`)
}
// Filter by workflow name (from advanced search input)
if (params.workflowName) {
const nameTerm = `%${params.workflowName}%`
conditions = and(conditions, sql`${workflow.name} ILIKE ${nameTerm}`)
}
// Filter by folder name (best-effort text match when present on workflows)
if (params.folderName) {
const folderTerm = `%${params.folderName}%`
conditions = and(conditions, sql`${workflow.name} ILIKE ${folderTerm}`)
}
if (params.executionId) {
conditions = and(conditions, eq(workflowExecutionLogs.executionId, params.executionId))
}
if (params.costOperator && params.costValue !== undefined) {
const costField = sql`(${workflowExecutionLogs.cost}->>'total')::numeric`
switch (params.costOperator) {
case '=':
conditions = and(conditions, sql`${costField} = ${params.costValue}`)
break
case '>':
conditions = and(conditions, sql`${costField} > ${params.costValue}`)
break
case '<':
conditions = and(conditions, sql`${costField} < ${params.costValue}`)
break
case '>=':
conditions = and(conditions, sql`${costField} >= ${params.costValue}`)
break
case '<=':
conditions = and(conditions, sql`${costField} <= ${params.costValue}`)
break
case '!=':
conditions = and(conditions, sql`${costField} != ${params.costValue}`)
break
}
}
if (params.durationOperator && params.durationValue !== undefined) {
const durationField = workflowExecutionLogs.totalDurationMs
switch (params.durationOperator) {
case '=':
conditions = and(conditions, eq(durationField, params.durationValue))
break
case '>':
conditions = and(conditions, gt(durationField, params.durationValue))
break
case '<':
conditions = and(conditions, lt(durationField, params.durationValue))
break
case '>=':
conditions = and(conditions, gte(durationField, params.durationValue))
break
case '<=':
conditions = and(conditions, lte(durationField, params.durationValue))
break
case '!=':
conditions = and(conditions, ne(durationField, params.durationValue))
break
}
}
// Execute the query using the optimized join
const logs = await baseQuery
.where(conditions)
.orderBy(desc(workflowExecutionLogs.startedAt))
.limit(params.limit)
.offset(params.offset)
// Get total count for pagination using the same join structure
const countQuery = db
.select({ count: sql<number>`count(*)` })
.from(workflowExecutionLogs)
@@ -333,10 +279,13 @@ export async function GET(request: NextRequest) {
const count = countResult[0]?.count || 0
// Block executions are now extracted from trace spans instead of separate table
const blockExecutionsByExecution: Record<string, any[]> = {}
// Create clean trace spans from block executions
const createTraceSpans = (blockExecutions: any[]) => {
return blockExecutions.map((block, index) => {
// For error blocks, include error information in the output
let output = block.outputData
if (block.status === 'error' && block.errorMessage) {
output = {
@@ -365,6 +314,7 @@ export async function GET(request: NextRequest) {
})
}
// Extract cost information from block executions
const extractCostSummary = (blockExecutions: any[]) => {
let totalCost = 0
let totalInputCost = 0
@@ -383,6 +333,7 @@ export async function GET(request: NextRequest) {
totalPromptTokens += block.cost.tokens?.prompt || 0
totalCompletionTokens += block.cost.tokens?.completion || 0
// Track per-model costs
if (block.cost.model) {
if (!models.has(block.cost.model)) {
models.set(block.cost.model, {
@@ -412,29 +363,34 @@ export async function GET(request: NextRequest) {
prompt: totalPromptTokens,
completion: totalCompletionTokens,
},
models: Object.fromEntries(models),
models: Object.fromEntries(models), // Convert Map to object for JSON serialization
}
}
// Transform to clean log format with workflow data included
const enhancedLogs = logs.map((log) => {
const blockExecutions = blockExecutionsByExecution[log.executionId] || []
// Only process trace spans and detailed cost in full mode
let traceSpans = []
let finalOutput: any
let costSummary = (log.cost as any) || { total: 0 }
if (params.details === 'full' && log.executionData) {
// Use stored trace spans if available, otherwise create from block executions
const storedTraceSpans = (log.executionData as any)?.traceSpans
traceSpans =
storedTraceSpans && Array.isArray(storedTraceSpans) && storedTraceSpans.length > 0
? storedTraceSpans
: createTraceSpans(blockExecutions)
// Prefer stored cost JSON; otherwise synthesize from blocks
costSummary =
log.cost && Object.keys(log.cost as any).length > 0
? (log.cost as any)
: extractCostSummary(blockExecutions)
// Include finalOutput if present on executionData
try {
const fo = (log.executionData as any)?.finalOutput
if (fo !== undefined) finalOutput = fo

View File

@@ -5,7 +5,6 @@ import type { NextRequest } from 'next/server'
import { createLogger } from '@/lib/logs/console/logger'
import { withMcpAuth } from '@/lib/mcp/middleware'
import { mcpService } from '@/lib/mcp/service'
import type { McpServerStatusConfig } from '@/lib/mcp/types'
import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils'
const logger = createLogger('McpServerRefreshAPI')
@@ -51,12 +50,6 @@ export const POST = withMcpAuth<{ id: string }>('read')(
let toolCount = 0
let lastError: string | null = null
const currentStatusConfig: McpServerStatusConfig =
(server.statusConfig as McpServerStatusConfig | null) ?? {
consecutiveFailures: 0,
lastSuccessfulDiscovery: null,
}
try {
const tools = await mcpService.discoverServerTools(userId, serverId, workspaceId)
connectionStatus = 'connected'
@@ -70,40 +63,20 @@ export const POST = withMcpAuth<{ id: string }>('read')(
logger.warn(`[${requestId}] Failed to connect to server ${serverId}:`, error)
}
const now = new Date()
const newStatusConfig =
connectionStatus === 'connected'
? { consecutiveFailures: 0, lastSuccessfulDiscovery: now.toISOString() }
: {
consecutiveFailures: currentStatusConfig.consecutiveFailures + 1,
lastSuccessfulDiscovery: currentStatusConfig.lastSuccessfulDiscovery,
}
const [refreshedServer] = await db
.update(mcpServers)
.set({
lastToolsRefresh: now,
lastToolsRefresh: new Date(),
connectionStatus,
lastError,
lastConnected: connectionStatus === 'connected' ? now : server.lastConnected,
lastConnected: connectionStatus === 'connected' ? new Date() : server.lastConnected,
toolCount,
statusConfig: newStatusConfig,
updatedAt: now,
updatedAt: new Date(),
})
.where(eq(mcpServers.id, serverId))
.returning()
if (connectionStatus === 'connected') {
logger.info(
`[${requestId}] Successfully refreshed MCP server: ${serverId} (${toolCount} tools)`
)
await mcpService.clearCache(workspaceId)
} else {
logger.warn(
`[${requestId}] Refresh completed for MCP server ${serverId} but connection failed: ${lastError}`
)
}
logger.info(`[${requestId}] Successfully refreshed MCP server: ${serverId}`)
return createMcpSuccessResponse({
status: connectionStatus,
toolCount,

View File

@@ -48,19 +48,6 @@ export const PATCH = withMcpAuth<{ id: string }>('write')(
// Remove workspaceId from body to prevent it from being updated
const { workspaceId: _, ...updateData } = body
// Get the current server to check if URL is changing
const [currentServer] = await db
.select({ url: mcpServers.url })
.from(mcpServers)
.where(
and(
eq(mcpServers.id, serverId),
eq(mcpServers.workspaceId, workspaceId),
isNull(mcpServers.deletedAt)
)
)
.limit(1)
const [updatedServer] = await db
.update(mcpServers)
.set({
@@ -84,12 +71,8 @@ export const PATCH = withMcpAuth<{ id: string }>('write')(
)
}
// Only clear cache if URL changed (requires re-discovery)
const urlChanged = body.url && currentServer?.url !== body.url
if (urlChanged) {
await mcpService.clearCache(workspaceId)
logger.info(`[${requestId}] Cleared cache due to URL change`)
}
// Clear MCP service cache after update
mcpService.clearCache(workspaceId)
logger.info(`[${requestId}] Successfully updated MCP server: ${serverId}`)
return createMcpSuccessResponse({ server: updatedServer })

View File

@@ -117,14 +117,12 @@ export const POST = withMcpAuth('write')(
timeout: body.timeout || 30000,
retries: body.retries || 3,
enabled: body.enabled !== false,
connectionStatus: 'connected',
lastConnected: new Date(),
updatedAt: new Date(),
deletedAt: null,
})
.where(eq(mcpServers.id, serverId))
await mcpService.clearCache(workspaceId)
mcpService.clearCache(workspaceId)
logger.info(
`[${requestId}] Successfully updated MCP server: ${body.name} (ID: ${serverId})`
@@ -147,14 +145,12 @@ export const POST = withMcpAuth('write')(
timeout: body.timeout || 30000,
retries: body.retries || 3,
enabled: body.enabled !== false,
connectionStatus: 'connected',
lastConnected: new Date(),
createdAt: new Date(),
updatedAt: new Date(),
})
.returning()
await mcpService.clearCache(workspaceId)
mcpService.clearCache(workspaceId)
logger.info(
`[${requestId}] Successfully registered MCP server: ${body.name} (ID: ${serverId})`
@@ -216,7 +212,7 @@ export const DELETE = withMcpAuth('admin')(
)
}
await mcpService.clearCache(workspaceId)
mcpService.clearCache(workspaceId)
logger.info(`[${requestId}] Successfully deleted MCP server: ${serverId}`)
return createMcpSuccessResponse({ message: `Server ${serverId} deleted successfully` })

View File

@@ -1,103 +0,0 @@
import { db } from '@sim/db'
import { workflow, workflowBlocks } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { createLogger } from '@/lib/logs/console/logger'
import { withMcpAuth } from '@/lib/mcp/middleware'
import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils'
const logger = createLogger('McpStoredToolsAPI')
export const dynamic = 'force-dynamic'
interface StoredMcpTool {
workflowId: string
workflowName: string
serverId: string
serverUrl?: string
toolName: string
schema?: Record<string, unknown>
}
/**
* GET - Get all stored MCP tools from workflows in the workspace
*
* Scans all workflows in the workspace and extracts MCP tools that have been
* added to agent blocks. Returns the stored state of each tool for comparison
* against current server state.
*/
export const GET = withMcpAuth('read')(
async (request: NextRequest, { userId, workspaceId, requestId }) => {
try {
logger.info(`[${requestId}] Fetching stored MCP tools for workspace ${workspaceId}`)
// Get all workflows in workspace
const workflows = await db
.select({
id: workflow.id,
name: workflow.name,
})
.from(workflow)
.where(eq(workflow.workspaceId, workspaceId))
const workflowMap = new Map(workflows.map((w) => [w.id, w.name]))
const workflowIds = workflows.map((w) => w.id)
if (workflowIds.length === 0) {
return createMcpSuccessResponse({ tools: [] })
}
// Get all agent blocks from these workflows
const agentBlocks = await db
.select({
workflowId: workflowBlocks.workflowId,
subBlocks: workflowBlocks.subBlocks,
})
.from(workflowBlocks)
.where(eq(workflowBlocks.type, 'agent'))
const storedTools: StoredMcpTool[] = []
for (const block of agentBlocks) {
if (!workflowMap.has(block.workflowId)) continue
const subBlocks = block.subBlocks as Record<string, unknown> | null
if (!subBlocks) continue
const toolsSubBlock = subBlocks.tools as Record<string, unknown> | undefined
const toolsValue = toolsSubBlock?.value
if (!toolsValue || !Array.isArray(toolsValue)) continue
for (const tool of toolsValue) {
if (tool.type !== 'mcp') continue
const params = tool.params as Record<string, unknown> | undefined
if (!params?.serverId || !params?.toolName) continue
storedTools.push({
workflowId: block.workflowId,
workflowName: workflowMap.get(block.workflowId) || 'Untitled',
serverId: params.serverId as string,
serverUrl: params.serverUrl as string | undefined,
toolName: params.toolName as string,
schema: tool.schema as Record<string, unknown> | undefined,
})
}
}
logger.info(
`[${requestId}] Found ${storedTools.length} stored MCP tools across ${workflows.length} workflows`
)
return createMcpSuccessResponse({ tools: storedTools })
} catch (error) {
logger.error(`[${requestId}] Error fetching stored MCP tools:`, error)
return createMcpErrorResponse(
error instanceof Error ? error : new Error('Failed to fetch stored MCP tools'),
'Failed to fetch stored MCP tools',
500
)
}
}
)

View File

@@ -6,7 +6,7 @@ import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { getPlanPricing } from '@/lib/billing/core/billing'
import { requireStripeClient } from '@/lib/billing/stripe-client'
import { isBillingEnabled } from '@/lib/core/config/feature-flags'
import { isBillingEnabled } from '@/lib/core/config/environment'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('OrganizationSeatsAPI')

View File

@@ -16,6 +16,7 @@ export async function GET() {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// Get organizations where user is owner or admin
const userOrganizations = await db
.select({
id: organization.id,
@@ -31,15 +32,8 @@ export async function GET() {
)
)
const anyMembership = await db
.select({ id: member.id })
.from(member)
.where(eq(member.userId, session.user.id))
.limit(1)
return NextResponse.json({
organizations: userOrganizations,
isMemberOfAnyOrg: anyMembership.length > 0,
})
} catch (error) {
logger.error('Failed to fetch organizations', {

View File

@@ -45,6 +45,7 @@ export async function GET(request: NextRequest) {
host: OLLAMA_HOST,
})
// Return empty array instead of error to avoid breaking the UI
return NextResponse.json({ models: [] })
}
}

View File

@@ -35,8 +35,6 @@ export async function POST(request: NextRequest) {
apiKey,
azureEndpoint,
azureApiVersion,
vertexProject,
vertexLocation,
responseFormat,
workflowId,
workspaceId,
@@ -60,8 +58,6 @@ export async function POST(request: NextRequest) {
hasApiKey: !!apiKey,
hasAzureEndpoint: !!azureEndpoint,
hasAzureApiVersion: !!azureApiVersion,
hasVertexProject: !!vertexProject,
hasVertexLocation: !!vertexLocation,
hasResponseFormat: !!responseFormat,
workflowId,
stream: !!stream,
@@ -108,8 +104,6 @@ export async function POST(request: NextRequest) {
apiKey: finalApiKey,
azureEndpoint,
azureApiVersion,
vertexProject,
vertexLocation,
responseFormat,
workflowId,
workspaceId,

View File

@@ -20,16 +20,10 @@ export async function GET(request: NextRequest) {
baseUrl,
})
const headers: Record<string, string> = {
'Content-Type': 'application/json',
}
if (env.VLLM_API_KEY) {
headers.Authorization = `Bearer ${env.VLLM_API_KEY}`
}
const response = await fetch(`${baseUrl}/v1/models`, {
headers,
headers: {
'Content-Type': 'application/json',
},
next: { revalidate: 60 },
})
@@ -56,6 +50,7 @@ export async function GET(request: NextRequest) {
baseUrl,
})
// Return empty array instead of error to avoid breaking the UI
return NextResponse.json({ models: [] })
}
}

View File

@@ -3,7 +3,7 @@ import { NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { generateInternalToken } from '@/lib/auth/internal'
import { isDev } from '@/lib/core/config/feature-flags'
import { isDev } from '@/lib/core/config/environment'
import { createPinnedUrl, validateUrlWithDNS } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'
import { getBaseUrl } from '@/lib/core/utils/urls'

View File

@@ -1,81 +1,26 @@
import { db } from '@sim/db'
import { chat } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { env } from '@/lib/core/config/env'
import { validateAlphanumericId } from '@/lib/core/security/input-validation'
import { createLogger } from '@/lib/logs/console/logger'
import { validateAuthToken } from '@/app/api/chat/utils'
const logger = createLogger('ProxyTTSStreamAPI')
/**
* Validates chat-based authentication for deployed chat voice mode
* Checks if the user has a valid chat auth cookie for the given chatId
*/
async function validateChatAuth(request: NextRequest, chatId: string): Promise<boolean> {
try {
const chatResult = await db
.select({
id: chat.id,
isActive: chat.isActive,
authType: chat.authType,
password: chat.password,
})
.from(chat)
.where(eq(chat.id, chatId))
.limit(1)
if (chatResult.length === 0 || !chatResult[0].isActive) {
logger.warn('Chat not found or inactive for TTS auth:', chatId)
return false
}
const chatData = chatResult[0]
if (chatData.authType === 'public') {
return true
}
const cookieName = `chat_auth_${chatId}`
const authCookie = request.cookies.get(cookieName)
if (authCookie && validateAuthToken(authCookie.value, chatId, chatData.password)) {
return true
}
return false
} catch (error) {
logger.error('Error validating chat auth for TTS:', error)
return false
}
}
export async function POST(request: NextRequest) {
try {
let body: any
try {
body = await request.json()
} catch {
return new Response('Invalid request body', { status: 400 })
const authResult = await checkHybridAuth(request, { requireWorkflowId: false })
if (!authResult.success) {
logger.error('Authentication failed for TTS stream proxy:', authResult.error)
return new Response('Unauthorized', { status: 401 })
}
const { text, voiceId, modelId = 'eleven_turbo_v2_5', chatId } = body
if (!chatId) {
return new Response('chatId is required', { status: 400 })
}
const body = await request.json()
const { text, voiceId, modelId = 'eleven_turbo_v2_5' } = body
if (!text || !voiceId) {
return new Response('Missing required parameters', { status: 400 })
}
const isChatAuthed = await validateChatAuth(request, chatId)
if (!isChatAuthed) {
logger.warn('Chat authentication failed for TTS, chatId:', chatId)
return new Response('Unauthorized', { status: 401 })
}
const voiceIdValidation = validateAlphanumericId(voiceId, 'voiceId', 255)
if (!voiceIdValidation.isValid) {
logger.error(`Invalid voice ID: ${voiceIdValidation.error}`)

View File

@@ -1,7 +1,6 @@
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId } from '@/lib/core/security/input-validation'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'
import { StorageService } from '@/lib/uploads'
@@ -148,10 +147,6 @@ export async function POST(request: NextRequest) {
{ status: 400 }
)
}
const voiceIdValidation = validateAlphanumericId(body.voiceId, 'voiceId')
if (!voiceIdValidation.isValid) {
return NextResponse.json({ error: voiceIdValidation.error }, { status: 400 })
}
const result = await synthesizeWithElevenLabs({
text,
apiKey,

View File

@@ -42,11 +42,11 @@ describe('Scheduled Workflow Execution API Route', () => {
executeScheduleJob: mockExecuteScheduleJob,
}))
vi.doMock('@/lib/core/config/feature-flags', () => ({
isTriggerDevEnabled: false,
isHosted: false,
isProd: false,
isDev: true,
vi.doMock('@/lib/core/config/env', () => ({
env: {
TRIGGER_DEV_ENABLED: false,
},
isTruthy: vi.fn(() => false),
}))
vi.doMock('drizzle-orm', () => ({
@@ -119,11 +119,11 @@ describe('Scheduled Workflow Execution API Route', () => {
},
}))
vi.doMock('@/lib/core/config/feature-flags', () => ({
isTriggerDevEnabled: true,
isHosted: false,
isProd: false,
isDev: true,
vi.doMock('@/lib/core/config/env', () => ({
env: {
TRIGGER_DEV_ENABLED: true,
},
isTruthy: vi.fn(() => true),
}))
vi.doMock('drizzle-orm', () => ({
@@ -191,11 +191,11 @@ describe('Scheduled Workflow Execution API Route', () => {
executeScheduleJob: vi.fn().mockResolvedValue(undefined),
}))
vi.doMock('@/lib/core/config/feature-flags', () => ({
isTriggerDevEnabled: false,
isHosted: false,
isProd: false,
isDev: true,
vi.doMock('@/lib/core/config/env', () => ({
env: {
TRIGGER_DEV_ENABLED: false,
},
isTruthy: vi.fn(() => false),
}))
vi.doMock('drizzle-orm', () => ({
@@ -250,11 +250,11 @@ describe('Scheduled Workflow Execution API Route', () => {
executeScheduleJob: vi.fn().mockResolvedValue(undefined),
}))
vi.doMock('@/lib/core/config/feature-flags', () => ({
isTriggerDevEnabled: false,
isHosted: false,
isProd: false,
isDev: true,
vi.doMock('@/lib/core/config/env', () => ({
env: {
TRIGGER_DEV_ENABLED: false,
},
isTruthy: vi.fn(() => false),
}))
vi.doMock('drizzle-orm', () => ({

Some files were not shown because too many files have changed in this diff Show More