From fc1dd44f3974d9bc2ab52a2d0c42c61e0504e238 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 14:48:12 +0000 Subject: [PATCH 001/133] Added the new integrations system into the mono-repo --- .vscode/launch.json | 11 + apps/integrations/.eslintrc.json | 16 + apps/integrations/.gitignore | 105 + apps/integrations/.prettierignore | 4 + apps/integrations/README.md | 2 + apps/integrations/package.json | 41 + .../src/core/action/simpleAction.ts | 28 + apps/integrations/src/core/action/types.ts | 34 + .../integrations/src/core/action/utilities.ts | 48 + .../core/authentication/credentials.test.ts | 82 + .../src/core/authentication/credentials.ts | 85 + .../src/core/authentication/types.ts | 39 + apps/integrations/src/core/cache/types.ts | 4 + apps/integrations/src/core/catalog.ts | 5 + .../src/core/endpoint/endpoint.ts | 36 + apps/integrations/src/core/endpoint/types.ts | 64 + apps/integrations/src/core/request/errors.ts | 60 + .../src/core/request/requestEndpoint.ts | 201 + apps/integrations/src/core/request/types.ts | 30 + .../core/schemas/json-schema-deref-sync.d.ts | 1 + .../src/core/schemas/schemaBuilder.test.ts | 13 + .../src/core/schemas/schemaBuilder.ts | 15 + .../core/schemas/test-openapi-spec-v2.json | 2837 ++ apps/integrations/src/core/schemas/types.ts | 3 + .../integrations/src/core/schemas/validate.ts | 22 + apps/integrations/src/core/service/types.ts | 11 + .../src/generators/combineSchemas.test.ts | 106 + .../src/generators/combineSchemas.ts | 77 + .../src/generators/generateTypes.test.ts | 119 + .../src/generators/generateTypes.ts | 9 + apps/integrations/src/integrations/catalog.ts | 8 + .../src/integrations/slack/actions/actions.ts | 146 + .../src/integrations/slack/authentication.ts | 84 + .../integrations/slack/endpoints/endpoints.ts | 8 + .../schemas/slack_web_openapi_v2.json | 27441 ++++++++++++++++ .../slack/endpoints/schemas/spec.ts | 3 + .../src/integrations/slack/endpoints/specs.ts | 350 + .../src/integrations/slack/index.ts | 11 + .../integrations/slack/tests/actions.test.ts | 84 + .../slack/tests/endpoints.test.ts | 91 + apps/integrations/src/trigger/sdk/generate.ts | 16 + .../src/trigger/sdk/generateService.test.ts | 9 + .../src/trigger/sdk/generateService.ts | 176 + .../src/trigger/sdk/templates/README.md | 3 + .../src/trigger/sdk/templates/package.json | 33 + .../src/trigger/sdk/templates/tsconfig.json | 21 + .../src/trigger/sdk/templates/tsup.config.ts | 22 + apps/integrations/tsconfig.json | 19 + apps/integrations/vitest.config.ts | 12 + apps/webapp/package.json | 2 +- package.json | 8 +- pnpm-lock.yaml | 1939 +- turbo.json | 3 + vitest.config.ts | 12 + 54 files changed, 34519 insertions(+), 90 deletions(-) create mode 100644 apps/integrations/.eslintrc.json create mode 100644 apps/integrations/.gitignore create mode 100644 apps/integrations/.prettierignore create mode 100644 apps/integrations/README.md create mode 100644 apps/integrations/package.json create mode 100644 apps/integrations/src/core/action/simpleAction.ts create mode 100644 apps/integrations/src/core/action/types.ts create mode 100644 apps/integrations/src/core/action/utilities.ts create mode 100644 apps/integrations/src/core/authentication/credentials.test.ts create mode 100644 apps/integrations/src/core/authentication/credentials.ts create mode 100644 apps/integrations/src/core/authentication/types.ts create mode 100644 apps/integrations/src/core/cache/types.ts create mode 100644 apps/integrations/src/core/catalog.ts create mode 100644 apps/integrations/src/core/endpoint/endpoint.ts create mode 100644 apps/integrations/src/core/endpoint/types.ts create mode 100644 apps/integrations/src/core/request/errors.ts create mode 100644 apps/integrations/src/core/request/requestEndpoint.ts create mode 100644 apps/integrations/src/core/request/types.ts create mode 100644 apps/integrations/src/core/schemas/json-schema-deref-sync.d.ts create mode 100644 apps/integrations/src/core/schemas/schemaBuilder.test.ts create mode 100644 apps/integrations/src/core/schemas/schemaBuilder.ts create mode 100644 apps/integrations/src/core/schemas/test-openapi-spec-v2.json create mode 100644 apps/integrations/src/core/schemas/types.ts create mode 100644 apps/integrations/src/core/schemas/validate.ts create mode 100644 apps/integrations/src/core/service/types.ts create mode 100644 apps/integrations/src/generators/combineSchemas.test.ts create mode 100644 apps/integrations/src/generators/combineSchemas.ts create mode 100644 apps/integrations/src/generators/generateTypes.test.ts create mode 100644 apps/integrations/src/generators/generateTypes.ts create mode 100644 apps/integrations/src/integrations/catalog.ts create mode 100644 apps/integrations/src/integrations/slack/actions/actions.ts create mode 100644 apps/integrations/src/integrations/slack/authentication.ts create mode 100644 apps/integrations/src/integrations/slack/endpoints/endpoints.ts create mode 100644 apps/integrations/src/integrations/slack/endpoints/schemas/slack_web_openapi_v2.json create mode 100644 apps/integrations/src/integrations/slack/endpoints/schemas/spec.ts create mode 100644 apps/integrations/src/integrations/slack/endpoints/specs.ts create mode 100644 apps/integrations/src/integrations/slack/index.ts create mode 100644 apps/integrations/src/integrations/slack/tests/actions.test.ts create mode 100644 apps/integrations/src/integrations/slack/tests/endpoints.test.ts create mode 100644 apps/integrations/src/trigger/sdk/generate.ts create mode 100644 apps/integrations/src/trigger/sdk/generateService.test.ts create mode 100644 apps/integrations/src/trigger/sdk/generateService.ts create mode 100644 apps/integrations/src/trigger/sdk/templates/README.md create mode 100644 apps/integrations/src/trigger/sdk/templates/package.json create mode 100644 apps/integrations/src/trigger/sdk/templates/tsconfig.json create mode 100644 apps/integrations/src/trigger/sdk/templates/tsup.config.ts create mode 100644 apps/integrations/tsconfig.json create mode 100644 apps/integrations/vitest.config.ts create mode 100644 vitest.config.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index 5578de126..e14f2c5d1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -17,6 +17,17 @@ "name": "Chrome webapp", "url": "http://localhost:3000", "webRoot": "${workspaceFolder}/apps/webapp/app" + }, + { + "type": "node", + "request": "launch", + "name": "Debug Current Test File", + "autoAttachChildProcesses": true, + "skipFiles": ["/**", "**/node_modules/**"], + "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs", + "args": ["run", "${relativeFile}"], + "smartStep": true, + "console": "integratedTerminal" } ] } diff --git a/apps/integrations/.eslintrc.json b/apps/integrations/.eslintrc.json new file mode 100644 index 000000000..3bc8ecb51 --- /dev/null +++ b/apps/integrations/.eslintrc.json @@ -0,0 +1,16 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "root": true, + "rules": { + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": "off", + "no-console": "off" + } +} diff --git a/apps/integrations/.gitignore b/apps/integrations/.gitignore new file mode 100644 index 000000000..a6b984db0 --- /dev/null +++ b/apps/integrations/.gitignore @@ -0,0 +1,105 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port +.DS_Store diff --git a/apps/integrations/.prettierignore b/apps/integrations/.prettierignore new file mode 100644 index 000000000..5a37124cf --- /dev/null +++ b/apps/integrations/.prettierignore @@ -0,0 +1,4 @@ +node_modules + +/build +.env \ No newline at end of file diff --git a/apps/integrations/README.md b/apps/integrations/README.md new file mode 100644 index 000000000..10abcd844 --- /dev/null +++ b/apps/integrations/README.md @@ -0,0 +1,2 @@ +# trigger-integrations +You can create API integrations using this data and system diff --git a/apps/integrations/package.json b/apps/integrations/package.json new file mode 100644 index 000000000..e31521451 --- /dev/null +++ b/apps/integrations/package.json @@ -0,0 +1,41 @@ +{ + "private": true, + "name": "integrations", + "version": "1.0.0", + "description": "API integrations in a format that can be used to generate clients", + "main": "src/index.ts", + "scripts": { + "test": "vitest", + "lint": "eslint src/**", + "lint-fix": "eslint --fix src/**", + "generate-sdks": "tsx src/trigger/sdk/generate.ts" + }, + "dependencies": { + "@cfworker/json-schema": "^1.12.5", + "@trigger.dev/sdk": "^0.2.13", + "json-pointer": "^0.6.2", + "json-schema-deref-sync": "^0.14.0", + "json-schema-to-typescript": "^11.0.3", + "node-fetch": "^3.3.0" + }, + "devDependencies": { + "@types/eslint": "^8.4.6", + "@types/json-pointer": "^1.0.31", + "@types/node": "^18.13.0", + "@typescript-eslint/eslint-plugin": "^5.51.0", + "eslint": "^8.34.0", + "eslint-config-prettier": "^8.5.0", + "eslint-config-standard-with-typescript": "^34.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^15.6.1", + "eslint-plugin-promise": "^6.1.1", + "rimraf": "^4.1.2", + "ts-morph": "^17.0.1", + "tsup": "^6.6.2", + "tsx": "^3.12.3", + "typescript": "^4.9.5", + "vite": "^4.1.1", + "vite-tsconfig-paths": "^4.0.5", + "vitest": "^0.28.4" + } +} diff --git a/apps/integrations/src/core/action/simpleAction.ts b/apps/integrations/src/core/action/simpleAction.ts new file mode 100644 index 000000000..17e29816b --- /dev/null +++ b/apps/integrations/src/core/action/simpleAction.ts @@ -0,0 +1,28 @@ +import { CacheService } from "core/cache/types"; +import { Endpoint } from "core/endpoint/types"; +import { RequestData } from "core/request/types"; +import { Metadata } from "./types"; +import { makeInputSpec, makeOutputSpec } from "./utilities"; + +export const makeRequestAction = (endpoint: Endpoint) => { + const action = async ( + data: RequestData, + cache?: CacheService, + metadata?: Metadata + ) => { + //a simple request doesn't use the cache or metadata + return await endpoint.request(data); + }; + + return { + name: endpoint.spec.endpointSpec.metadata.name, + description: endpoint.spec.endpointSpec.metadata.description, + path: endpoint.spec.endpointSpec.path, + method: endpoint.spec.endpointSpec.method, + spec: { + input: makeInputSpec(endpoint), + output: makeOutputSpec(endpoint), + }, + action, + }; +}; diff --git a/apps/integrations/src/core/action/types.ts b/apps/integrations/src/core/action/types.ts new file mode 100644 index 000000000..a610ef12c --- /dev/null +++ b/apps/integrations/src/core/action/types.ts @@ -0,0 +1,34 @@ +import { CacheService } from "core/cache/types"; +import { EndpointSpec, HTTPMethod } from "core/endpoint/types"; +import { RequestData, RequestResponse } from "core/request/types"; + +export type InputSpec = { + security?: EndpointSpec["security"]; + parameters?: EndpointSpec["parameters"]; + body?: NonNullable["schema"]; +}; + +export type OutputSpec = { + responses: EndpointSpec["responses"]; +}; + +export type Metadata = Record; + +export type Action = { + name: string; + description: string; + path: string; + method: HTTPMethod; + spec: { + input: InputSpec; + output: OutputSpec; + }; + action: ( + /** The data to be sent to the endpoint */ + data: RequestData, + /** The cache service to use for caching */ + cache?: CacheService, + /** Additional metadata that can be used to modify the request */ + metadata?: Metadata + ) => Promise; +}; diff --git a/apps/integrations/src/core/action/utilities.ts b/apps/integrations/src/core/action/utilities.ts new file mode 100644 index 000000000..10b1aac84 --- /dev/null +++ b/apps/integrations/src/core/action/utilities.ts @@ -0,0 +1,48 @@ +import { Endpoint } from "core/endpoint/types"; + +export function makeInputSpec(endpoint: Endpoint) { + return { + security: endpoint.spec.endpointSpec.security, + parameters: endpoint.spec.endpointSpec.parameters, + body: endpoint.spec.endpointSpec.request.body?.schema, + }; +} + +export function makeOutputSpec(endpoint: Endpoint) { + return { + responses: endpoint.spec.endpointSpec.responses, + }; +} + +export function combineSecurityScopes( + securities: (Record | undefined)[] +): Record | undefined { + const securityA = securities[0]; + const securityB = securities[1]; + + //where a key already exists, concatenate the scope arrays together + //where a key does not exist, add it to the object + let combined: Record = {}; + + if (securityA) { + combined = { + ...securityA, + }; + } + + if (securityB) { + for (const key in securityB) { + if (combined[key]) { + combined[key] = [...combined[key], ...securityB[key]]; + } else { + combined[key] = securityB[key]; + } + } + } + + if (securities.length > 2) { + return combineSecurityScopes([combined, ...securities.slice(2)]); + } + + return combined; +} diff --git a/apps/integrations/src/core/authentication/credentials.test.ts b/apps/integrations/src/core/authentication/credentials.test.ts new file mode 100644 index 000000000..0d00cc45d --- /dev/null +++ b/apps/integrations/src/core/authentication/credentials.test.ts @@ -0,0 +1,82 @@ +import { EndpointSpec } from "core/endpoint/types"; +import { FetchConfig } from "core/request/types"; +import { expect, test } from "vitest"; +import { checkRequiredScopes, applyCredentials } from "./credentials"; +import { AuthCredentials, IntegrationAuthentication } from "./types"; + +test("Required scopes present", async () => { + const credentials: AuthCredentials = { + type: "oauth2", + name: "authName", + accessToken: "token", + scopes: ["scope1", "scope2"], + }; + + const requiredScopes = ["scope1", "scope2"]; + + const result = checkRequiredScopes(requiredScopes, credentials); + expect(result.success).toEqual(true); +}); + +test("Required scopes missing", async () => { + const credentials: AuthCredentials = { + type: "oauth2", + name: "authName", + accessToken: "token", + scopes: ["scope1", "scope2"], + }; + + const requiredScopes = ["scope1", "scope2", "scope3"]; + + const result = checkRequiredScopes(requiredScopes, credentials); + expect(result.success).toEqual(false); + if (result.success) throw new Error("Should not be success"); + expect(result.missingScopes).toEqual(["scope3"]); +}); + +test("Applied credentials", async () => { + const credentials: AuthCredentials = { + type: "oauth2", + name: "authName", + accessToken: "123456", + scopes: ["scope1", "scope2"], + }; + const endpointSecurity: EndpointSpec["security"] = { + authName: ["scope1", "scope2"], + }; + + const integrationAuthentication: IntegrationAuthentication = { + authName: { + type: "oauth2", + placement: { + in: "header", + type: "bearer", + key: "Authorization", + }, + authorizationUrl: "https://example.com", + tokenUrl: "https://example.com", + flow: "accessCode", + scopes: { + scope1: "scope1", + scope2: "scope2", + }, + }, + }; + + const existingFetch: FetchConfig = { + url: "https://example.com", + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }; + + const fetchConfig = applyCredentials(existingFetch, { + endpointSecurity, + authentication: integrationAuthentication, + credentials, + }); + + expect(fetchConfig.headers.Authorization).toEqual("Bearer 123456"); + expect(fetchConfig.headers["Content-Type"]).toEqual("application/json"); +}); diff --git a/apps/integrations/src/core/authentication/credentials.ts b/apps/integrations/src/core/authentication/credentials.ts new file mode 100644 index 000000000..460916505 --- /dev/null +++ b/apps/integrations/src/core/authentication/credentials.ts @@ -0,0 +1,85 @@ +import { EndpointSpec } from "core/endpoint/types"; +import { InsufficientScopesError } from "core/request/errors"; +import { FetchConfig } from "core/request/types"; +import { IntegrationAuthentication, AuthCredentials } from "./types"; + +/** Apply the given credentials to the given fetch config */ +export function applyCredentials( + fetch: FetchConfig, + { + endpointSecurity, + authentication, + credentials, + }: { + endpointSecurity: EndpointSpec["security"]; + authentication: IntegrationAuthentication; + credentials: AuthCredentials; + } +): FetchConfig { + if (endpointSecurity === undefined) return fetch; + // check if the credentials have the required scopes + const requiredScopes = endpointSecurity[credentials.name] ?? []; + const scopesCheckResult = checkRequiredScopes(requiredScopes, credentials); + if (!scopesCheckResult.success) { + const error: InsufficientScopesError = { + type: "insufficient_scopes", + missingScopes: scopesCheckResult.missingScopes, + }; + throw error; + } + + // apply the credentials + switch (credentials.type) { + case "oauth2": { + const authConfig = authentication[credentials.name]; + switch (authConfig.placement.in) { + case "header": { + fetch.headers[ + authConfig.placement.key + ] = `Bearer ${credentials.accessToken}`; + return fetch; + } + } + break; + } + case "api_key": { + const authConfig = authentication[credentials.name]; + if (authConfig.placement.in === "header") { + fetch.headers[authConfig.placement.key] = credentials.api_key; + } + return fetch; + } + } + + throw new Error("Invalid credentials"); +} + +type ScopesCheckResult = + | { + success: true; + } + | { + success: false; + missingScopes: string[]; + }; + +/** Check if the given credentials have the required scopes */ +export function checkRequiredScopes( + requiredScopes: string[], + credentials: AuthCredentials +): ScopesCheckResult { + const missingScopes = requiredScopes.filter( + (scope) => !credentials.scopes.includes(scope) + ); + + if (missingScopes.length > 0) { + return { + success: false, + missingScopes, + }; + } + + return { + success: true, + }; +} diff --git a/apps/integrations/src/core/authentication/types.ts b/apps/integrations/src/core/authentication/types.ts new file mode 100644 index 000000000..0be657a1a --- /dev/null +++ b/apps/integrations/src/core/authentication/types.ts @@ -0,0 +1,39 @@ +export type IntegrationAuthentication = Record< +string, +AuthenticationDefinition +> + +type AuthenticationDefinition = OAuth2 + +interface OAuth2 { + type: "oauth2"; + placement: AuthenticationPlacement + authorizationUrl: string + tokenUrl: string + flow: "accessCode" | "implicit" | "password" | "application"; + scopes: Record +} + +type AuthenticationPlacement = HeaderAuthentication + +interface HeaderAuthentication { + in: "header"; + type: "basic" | "bearer"; + key: string +} + +export type AuthCredentials = OAuth2Credentials | APIKeyCredentials + +interface OAuth2Credentials { + type: "oauth2"; + name: string + accessToken: string + scopes: string[] +} +interface APIKeyCredentials { + type: "api_key"; + name: string + api_key: string + additionalFields?: Record + scopes: string[] +} diff --git a/apps/integrations/src/core/cache/types.ts b/apps/integrations/src/core/cache/types.ts new file mode 100644 index 000000000..61f55ab90 --- /dev/null +++ b/apps/integrations/src/core/cache/types.ts @@ -0,0 +1,4 @@ +export interface CacheService { + get: (key: string) => Promise; + set: (key: string, value: string, ttl?: number) => Promise; +} diff --git a/apps/integrations/src/core/catalog.ts b/apps/integrations/src/core/catalog.ts new file mode 100644 index 000000000..172b7cbf1 --- /dev/null +++ b/apps/integrations/src/core/catalog.ts @@ -0,0 +1,5 @@ +import { Service } from "./service/types"; + +export type Catalog = { + services: Record; +}; diff --git a/apps/integrations/src/core/endpoint/endpoint.ts b/apps/integrations/src/core/endpoint/endpoint.ts new file mode 100644 index 000000000..6fef44a82 --- /dev/null +++ b/apps/integrations/src/core/endpoint/endpoint.ts @@ -0,0 +1,36 @@ +import { IntegrationAuthentication } from "core/authentication/types"; +import { requestEndpoint } from "core/request/requestEndpoint"; +import { RequestData, RequestResponse, RequestSpec } from "core/request/types"; +import { Endpoint, EndpointSpec } from "./types"; + +export const makeEndpoint = (spec: RequestSpec) => { + const request = async (data: RequestData) => { + return await requestEndpoint(spec, data); + }; + + return { + spec, + request, + }; +}; + +export const makeEndpoints = < + TSpecs extends Record, + K extends keyof TSpecs +>( + baseUrl: string, + authentication: IntegrationAuthentication, + specs: TSpecs +): Record => { + const endpoints: any = {}; + + Object.entries(specs).forEach(([name, spec]) => { + endpoints[name as K] = makeEndpoint({ + baseUrl, + endpointSpec: spec, + authentication, + }); + }); + + return endpoints; +}; diff --git a/apps/integrations/src/core/endpoint/types.ts b/apps/integrations/src/core/endpoint/types.ts new file mode 100644 index 000000000..e7cea4aa4 --- /dev/null +++ b/apps/integrations/src/core/endpoint/types.ts @@ -0,0 +1,64 @@ +import { RequestData, RequestResponse, RequestSpec } from "core/request/types"; +import { JSONSchema } from "core/schemas/types"; + +export type Endpoint = { + spec: RequestSpec; + request: (data: RequestData) => Promise; +}; + +export type HTTPMethod = + | "GET" + | "POST" + | "PUT" + | "PATCH" + | "DELETE" + | "HEAD" + | "OPTIONS" + | "TRACE"; + +export interface EndpointSpec { + path: string; + method: HTTPMethod; + metadata: EndpointSpecMetadata; + parameters?: EndpointSpecParameter[]; + security?: Record; + request: EndpointSpecRequest; + responses: { default: EndpointSpecResponse[] } & Record< + string, + EndpointSpecResponse[] + >; +} + +interface EndpointSpecParameter { + name: string; + description: string; + in: "query" | "path" | "header"; + required?: boolean; + schema: JSONSchema; +} + +interface EndpointSpecRequest { + headers?: Record; + body?: { + schema: JSONSchema; + }; +} + +export interface EndpointSpecResponse { + success: boolean; + name: string; + description?: string; + schema: JSONSchema; +} + +interface EndpointSpecMetadata { + name: string; + description: string; + externalDocs?: ExternalDocs; + tags: string[]; +} + +interface ExternalDocs { + description: string; + url: string; +} diff --git a/apps/integrations/src/core/request/errors.ts b/apps/integrations/src/core/request/errors.ts new file mode 100644 index 000000000..e326c4a34 --- /dev/null +++ b/apps/integrations/src/core/request/errors.ts @@ -0,0 +1,60 @@ +import { type ErrorObject } from "ajv"; + +export type RequestError = + | RequestBodyInvalid + | ParameterMissing + | ParametersInvalid + | ExtraParametersError + | InsufficientScopesError + | MissingResponseSpec + | ResponseBodyInvalid; + +export interface RequestBodyInvalid { + type: "request_body_invalid"; + errors: any[]; +} + +export interface ParameterMissing { + type: "missing_parameter"; + parameter: { + name: string; + }; +} + +export interface ParametersInvalid { + type: "parameter_invalid"; + parameter: { + name: string; + value: any; + }; + errors: Array<{ name: string; errors: ErrorObject[] }>; +} + +export interface ExtraParametersError { + type: "extra_parameters"; + parameters: Array<{ + name: string; + value: any; + }>; +} + +export interface MissingCredentialsError { + type: "missing_credentials"; +} + +export interface InsufficientScopesError { + type: "insufficient_scopes"; + missingScopes: string[]; +} + +export interface MissingResponseSpec { + type: "no_response_spec"; + status: number; +} + +export interface ResponseBodyInvalid { + type: "response_invalid"; + errors: Array<{ name: string; errors: ErrorObject[] }>; + status: number; + body?: any; +} diff --git a/apps/integrations/src/core/request/requestEndpoint.ts b/apps/integrations/src/core/request/requestEndpoint.ts new file mode 100644 index 000000000..01b2e8e47 --- /dev/null +++ b/apps/integrations/src/core/request/requestEndpoint.ts @@ -0,0 +1,201 @@ +import { type ErrorObject } from "ajv"; +import { applyCredentials } from "core/authentication/credentials"; +import { EndpointSpec, EndpointSpecResponse } from "core/endpoint/types"; +import { validate } from "core/schemas/validate"; +import fetch, { type Response } from "node-fetch"; +import { + RequestSpec, + RequestData, + RequestResponse, + FetchConfig, +} from "./types"; + +export async function requestEndpoint( + { baseUrl, endpointSpec, authentication }: RequestSpec, + { parameters, body, credentials }: RequestData +): Promise { + const { method, security, request, responses } = endpointSpec; + let path = endpointSpec.path; + + // validate the request body + const requestValid = validate(body, request.body?.schema); + if (!requestValid.success) { + throw { + type: "request_body_invalid", + errors: requestValid.errors, + }; + } + + let headers: Record = {}; + + // validate and add the parameters + if (endpointSpec.parameters != null) { + for (const parameter of endpointSpec.parameters) { + const { name, in: location, required } = parameter; + + // if the parameter is missing + if (parameters === undefined || parameters[name] == null) { + if (required) { + throw { + type: "missing_parameter", + parameter: { + name, + }, + }; + } else { + continue; + } + } + + const element = parameters[name]; + //validate the parameter against the schema + const valid = validate(element, parameter.schema); + if (!valid.success) { + throw { + type: "parameter_invalid", + parameter: { + name, + value: element, + }, + errors: valid.errors, + }; + } + + //add the parameter + switch (location) { + case "path": + path = path.replace(`{${name}}`, element as string); + break; + case "query": + path = `${path}${path.includes("?") ? "&" : "?"}${name}=${element}`; + break; + case "header": + headers = { + ...headers, + [name]: `${element}`, + }; + break; + } + } + } + + // add headers from the config + for (const name in request.headers) { + if (Object.prototype.hasOwnProperty.call(request.headers, name)) { + const element = request.headers[name]; + headers = { + ...headers, + [name]: element, + }; + } + } + + // build the fetch config + const url = `${baseUrl}${path}`; + let fetchConfig: FetchConfig = { + url, + method, + headers: { + ...headers, + }, + body: JSON.stringify(body), + }; + + // apply credentials + if (security != null) { + if (credentials == null) { + throw { + type: "missing_credentials", + }; + } + fetchConfig = applyCredentials(fetchConfig, { + endpointSecurity: security, + authentication, + credentials, + }); + } + + // do the fetch and try get the JSON + const fetchObject = { + method: fetchConfig.method, + headers: fetchConfig.headers, + body: fetchConfig.body, + }; + const response = await fetch(fetchConfig.url, fetchObject); + const json = await safeGetJson(response); + + // validate the response against the specs + const responseSpecs = getResponseSpecsForStatusCode( + response.status, + responses + ); + if (!responseSpecs) { + throw { + type: "no_response_spec", + status: response.status, + }; + } + + // start with the first spec and loop through them, if one succeeds then return that + const specErrors: Array<{ name: string; errors: ErrorObject[] }> = []; + for (const spec of responseSpecs) { + const responseValid = validate(json, spec.schema); + if (responseValid.success) { + return { + success: spec.success, + status: response.status, + headers: normalizeHeaders(response.headers), + body: json, + }; + } else { + if (responseValid.errors != null) { + specErrors.push({ name: spec.name, errors: responseValid.errors }); + } + } + } + + throw { + type: "response_invalid", + status: response.status, + body: json, + errors: specErrors, + }; +} + +async function safeGetJson(response: Response) { + try { + return await response.json(); + } catch (error) { + return undefined; + } +} + +function normalizeHeaders(headers: Headers): Record { + const normalizedHeaders: Record = {}; + + headers.forEach((value, key) => { + normalizedHeaders[key.toLowerCase()] = value; + }); + + return normalizedHeaders; +} + +/** Get the appropriate endpoint response object based on the status code. It supports wild cards like 20x and 2xx */ +function getResponseSpecsForStatusCode( + statusCode: number, + endpointResponseSpecs: EndpointSpec["responses"] +): EndpointSpecResponse[] { + let specs = endpointResponseSpecs[statusCode.toString()]; + if (specs) return specs; + + specs = + endpointResponseSpecs[ + `${statusCode.toString().charAt(0)}${statusCode.toString().charAt(1)}x` + ]; + if (specs) return specs; + + specs = endpointResponseSpecs[`${statusCode.toString().charAt(0)}xx`]; + if (specs) return specs; + + return endpointResponseSpecs.default; +} diff --git a/apps/integrations/src/core/request/types.ts b/apps/integrations/src/core/request/types.ts new file mode 100644 index 000000000..879ee631c --- /dev/null +++ b/apps/integrations/src/core/request/types.ts @@ -0,0 +1,30 @@ +import { + IntegrationAuthentication, + AuthCredentials, +} from "core/authentication/types"; +import { HTTPMethod, EndpointSpec } from "core/endpoint/types"; + +export interface FetchConfig { + url: string; + method: HTTPMethod; + headers: Record; + body?: any; +} + +export interface RequestSpec { + baseUrl: string; + endpointSpec: EndpointSpec; + authentication: IntegrationAuthentication; +} +export interface RequestData { + parameters?: Record; + body?: any; + credentials?: AuthCredentials; +} + +export interface RequestResponse { + success: boolean; + status: number; + headers?: Record; + body?: any; +} diff --git a/apps/integrations/src/core/schemas/json-schema-deref-sync.d.ts b/apps/integrations/src/core/schemas/json-schema-deref-sync.d.ts new file mode 100644 index 000000000..844042b69 --- /dev/null +++ b/apps/integrations/src/core/schemas/json-schema-deref-sync.d.ts @@ -0,0 +1 @@ +declare module "json-schema-deref-sync"; diff --git a/apps/integrations/src/core/schemas/schemaBuilder.test.ts b/apps/integrations/src/core/schemas/schemaBuilder.test.ts new file mode 100644 index 000000000..ed28cad0b --- /dev/null +++ b/apps/integrations/src/core/schemas/schemaBuilder.test.ts @@ -0,0 +1,13 @@ +import { expect, test } from "vitest"; +import spec from "./test-openapi-spec-v2.json"; +import { dereferenceSpec, schemaFromOpenApiSpecV2 } from "./schemaBuilder"; + +test("Returns the correct schema", async () => { + const dereferenced = dereferenceSpec(spec); + const schema = schemaFromOpenApiSpecV2( + dereferenced, + "/paths//conversations.list/get/responses/200/schema" + ) + expect(schema.type).toEqual("object"); + expect(schema.additionalProperties).toEqual(false); +}); diff --git a/apps/integrations/src/core/schemas/schemaBuilder.ts b/apps/integrations/src/core/schemas/schemaBuilder.ts new file mode 100644 index 000000000..34e1d5ea5 --- /dev/null +++ b/apps/integrations/src/core/schemas/schemaBuilder.ts @@ -0,0 +1,15 @@ +import deref from "json-schema-deref-sync"; +import pointer from "json-pointer"; +import { type JSONSchema } from "./types"; + +export function dereferenceSpec(spec: any): any { + return deref(spec); +} + +// todo validate that it's a valid json schema +export function schemaFromOpenApiSpecV2(spec: any, path: string): JSONSchema { + // we need to escape the path because it contains ~ and / characters + path = path.replace(/~/g, "~0").replace(/\/\//g, "/~1"); + const schema = pointer.get(spec as pointer.JsonObject, path); + return schema; +} diff --git a/apps/integrations/src/core/schemas/test-openapi-spec-v2.json b/apps/integrations/src/core/schemas/test-openapi-spec-v2.json new file mode 100644 index 000000000..2c3f6ed0b --- /dev/null +++ b/apps/integrations/src/core/schemas/test-openapi-spec-v2.json @@ -0,0 +1,2837 @@ +{ + "basePath": "/api", + "definitions": { + "defs_app_id": { + "pattern": "^A[A-Z0-9]{1,}$", + "title": "App ID", + "type": "string" + }, + "defs_bot_id": { + "pattern": "^B[A-Z0-9]{8,}$", + "title": "Bot User ID", + "type": "string" + }, + "defs_channel": { + "pattern": "^[CGD][A-Z0-9]{8,}$", + "title": "Channel-like conversation ID", + "type": "string" + }, + "defs_channel_id": { + "pattern": "^[C][A-Z0-9]{2,}$", + "title": "Channel ID", + "type": "string" + }, + "defs_channel_name": { + "title": "Name of a channel", + "type": "string" + }, + "defs_comment_id": { + "pattern": "^Fc[A-Z0-9]{8,}$", + "title": "File Comment ID", + "type": "string" + }, + "defs_dm_id": { + "pattern": "^[D][A-Z0-9]{8,}$", + "title": "Direct Message Channel ID", + "type": "string" + }, + "defs_enterprise_id": { + "pattern": "^[E][A-Z0-9]{8,}$", + "title": "Enterprise ID", + "type": "string" + }, + "defs_enterprise_name": { + "title": "Name of the enterprise org", + "type": "string" + }, + "defs_enterprise_user_id": { + "pattern": "^[WU][A-Z0-9]{8,}$", + "title": "Enterprise User ID", + "type": "string" + }, + "defs_file_id": { + "pattern": "^[F][A-Z0-9]{8,}$", + "title": "File ID", + "type": "string" + }, + "defs_group_id": { + "pattern": "^[G][A-Z0-9]{8,}$", + "title": "Private Channel ID", + "type": "string" + }, + "defs_ok_false": { + "enum": [false], + "title": "default failure response", + "type": "boolean" + }, + "defs_ok_true": { + "enum": [true], + "title": "default success response", + "type": "boolean" + }, + "defs_optional_app_id": { + "pattern": "^(A[A-Z0-9]{1,})?$", + "title": "App ID or empty string", + "type": "string" + }, + "defs_pinned_info": { + "additionalProperties": false, + "title": "Info for a pinned item", + "type": "object" + }, + "defs_reminder_id": { + "pattern": "^Rm[A-Z0-9]{8,}$", + "title": "Reminder ID", + "type": "string" + }, + "defs_subteam_id": { + "pattern": "^S[A-Z0-9]{2,}$", + "title": "Subteam ID", + "type": "string" + }, + "defs_team": { + "pattern": "^[T][A-Z0-9]{2,}$", + "title": "Team ID", + "type": "string" + }, + "defs_topic_purpose_creator": { + "pattern": "^[UW][A-Z0-9]{8,}$|^$", + "title": "User ID or empty string, used for topic and purpose creation", + "type": "string" + }, + "defs_ts": { + "pattern": "^\\d{10}\\.\\d{6}$", + "title": "Timestamp in format 0123456789.012345", + "type": "string" + }, + "defs_user_id": { + "pattern": "^[UW][A-Z0-9]{2,}$", + "title": "User ID", + "type": "string" + }, + "defs_workspace_id": { + "pattern": "^[TE][A-Z0-9]{8,}$", + "title": "Team or Enterprise ID", + "type": "string" + }, + "objs_bot_profile": { + "additionalProperties": false, + "properties": { + "app_id": { + "$ref": "#/definitions/defs_app_id" + }, + "deleted": { + "type": "boolean" + }, + "icons": { + "additionalProperties": false, + "properties": { + "image_36": { + "format": "uri", + "type": "string" + }, + "image_48": { + "format": "uri", + "type": "string" + }, + "image_72": { + "format": "uri", + "type": "string" + } + }, + "required": ["image_36", "image_48", "image_72"], + "type": "object" + }, + "id": { + "$ref": "#/definitions/defs_bot_id" + }, + "name": { + "type": "string" + }, + "team_id": { + "$ref": "#/definitions/defs_team" + }, + "updated": { + "type": "integer" + } + }, + "required": [ + "id", + "deleted", + "name", + "updated", + "app_id", + "icons", + "team_id" + ], + "title": "Bot Profile Object", + "type": "object" + }, + "objs_channel": { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "created": { + "type": "integer" + }, + "creator": { + "$ref": "#/definitions/defs_user_id" + }, + "id": { + "$ref": "#/definitions/defs_channel_id" + }, + "is_archived": { + "type": "boolean" + }, + "is_channel": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_general": { + "type": "boolean" + }, + "is_member": { + "type": "boolean" + }, + "is_moved": { + "type": "integer" + }, + "is_mpim": { + "type": "boolean" + }, + "is_non_threadable": { + "type": "boolean" + }, + "is_org_shared": { + "type": "boolean" + }, + "is_pending_ext_shared": { + "type": "boolean" + }, + "is_private": { + "type": "boolean" + }, + "is_read_only": { + "type": "boolean" + }, + "is_shared": { + "type": "boolean" + }, + "is_thread_only": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "items": [ + { + "$ref": "#/definitions/objs_message" + }, + { + "type": "null" + } + ] + }, + "members": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "name": { + "type": "string" + }, + "name_normalized": { + "type": "string" + }, + "num_members": { + "type": "integer" + }, + "pending_shared": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "previous_names": { + "items": { + "$ref": "#/definitions/defs_channel_name" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "priority": { + "type": "number" + }, + "purpose": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": ["value", "creator", "last_set"], + "type": "object" + }, + "topic": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": ["value", "creator", "last_set"], + "type": "object" + }, + "unlinked": { + "title": "Field to determine whether a channel has ever been shared/disconnected in the past", + "type": "integer" + }, + "unread_count": { + "type": "integer" + }, + "unread_count_display": { + "type": "integer" + } + }, + "required": [ + "id", + "name", + "created", + "creator", + "is_channel", + "is_org_shared", + "is_private", + "is_mpim", + "is_shared", + "name_normalized", + "members", + "topic", + "purpose" + ], + "title": "Channel Object", + "type": "object" + }, + "objs_comment": { + "additionalProperties": false, + "properties": { + "comment": { + "type": "string" + }, + "created": { + "type": "integer" + }, + "id": { + "$ref": "#/definitions/defs_comment_id" + }, + "is_intro": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "num_stars": { + "type": "integer" + }, + "pinned_info": { + "$ref": "#/definitions/defs_pinned_info" + }, + "pinned_to": { + "items": { + "$ref": "#/definitions/defs_channel" + }, + "type": "array" + }, + "reactions": { + "items": { + "$ref": "#/definitions/objs_reaction" + }, + "type": "array" + }, + "timestamp": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": ["id", "created", "timestamp", "user", "is_intro", "comment"], + "title": "File Comment Object", + "type": "object" + }, + "objs_comments": { + "items": {}, + "title": "file comments object", + "type": "array" + }, + "objs_conversation": { + "items": [ + { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "connected_team_ids": { + "items": { + "$ref": "#/definitions/defs_workspace_id" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "conversation_host_id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "created": { + "type": "integer" + }, + "creator": { + "$ref": "#/definitions/defs_user_id" + }, + "display_counts": { + "additionalProperties": false, + "properties": { + "display_counts": { + "type": "integer" + }, + "guest_counts": { + "type": "integer" + } + }, + "required": ["display_counts", "guest_counts"], + "type": "object" + }, + "enterprise_id": { + "$ref": "#/definitions/defs_enterprise_id" + }, + "has_pins": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_channel" + }, + "internal_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "is_archived": { + "type": "boolean" + }, + "is_channel": { + "type": "boolean" + }, + "is_ext_shared": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_general": { + "type": "boolean" + }, + "is_global_shared": { + "type": "boolean" + }, + "is_group": { + "type": "boolean" + }, + "is_im": { + "type": "boolean" + }, + "is_member": { + "type": "boolean" + }, + "is_moved": { + "type": "integer" + }, + "is_mpim": { + "enum": [false], + "type": "boolean" + }, + "is_non_threadable": { + "type": "boolean" + }, + "is_open": { + "type": "boolean" + }, + "is_org_default": { + "type": "boolean" + }, + "is_org_mandatory": { + "type": "boolean" + }, + "is_org_shared": { + "type": "boolean" + }, + "is_pending_ext_shared": { + "type": "boolean" + }, + "is_private": { + "type": "boolean" + }, + "is_read_only": { + "type": "boolean" + }, + "is_shared": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "is_thread_only": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "items": [ + { + "$ref": "#/definitions/objs_message" + }, + { + "type": "null" + } + ] + }, + "members": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "name": { + "type": "string" + }, + "name_normalized": { + "type": "string" + }, + "num_members": { + "type": "integer" + }, + "parent_conversation": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "type": "null" + } + ] + }, + "pending_connected_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "pending_shared": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "pin_count": { + "type": "integer" + }, + "previous_names": { + "items": { + "$ref": "#/definitions/defs_channel_name" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "priority": { + "type": "number" + }, + "purpose": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": ["value", "creator", "last_set"], + "type": "object" + }, + "shared_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "shares": { + "items": { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "is_active": { + "type": "boolean" + }, + "team": { + "$ref": "#/definitions/objs_team" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": ["team", "user", "is_active"], + "type": "object" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "timezone_count": { + "type": "integer" + }, + "topic": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": ["value", "creator", "last_set"], + "type": "object" + }, + "unlinked": { + "title": "Field to determine whether a channel has ever been shared/disconnected in the past", + "type": "integer" + }, + "unread_count": { + "type": "integer" + }, + "unread_count_display": { + "type": "integer" + }, + "use_case": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "name", + "created", + "creator", + "is_archived", + "is_channel", + "is_general", + "is_mpim", + "is_group", + "is_org_shared", + "is_im", + "is_shared", + "is_private", + "name_normalized", + "topic", + "purpose" + ], + "title": "Conversation object", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "connected_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "conversation_host_id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "created": { + "type": "integer" + }, + "creator": { + "$ref": "#/definitions/defs_user_id" + }, + "display_counts": { + "additionalProperties": false, + "properties": { + "display_counts": { + "type": "integer" + }, + "guest_counts": { + "type": "integer" + } + }, + "required": ["display_counts", "guest_counts"], + "type": "object" + }, + "id": { + "$ref": "#/definitions/defs_channel" + }, + "internal_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "is_archived": { + "type": "boolean" + }, + "is_channel": { + "type": "boolean" + }, + "is_ext_shared": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_general": { + "type": "boolean" + }, + "is_group": { + "type": "boolean" + }, + "is_im": { + "type": "boolean" + }, + "is_member": { + "type": "boolean" + }, + "is_moved": { + "type": "integer" + }, + "is_mpim": { + "enum": [true], + "type": "boolean" + }, + "is_non_threadable": { + "type": "boolean" + }, + "is_open": { + "type": "boolean" + }, + "is_org_shared": { + "type": "boolean" + }, + "is_pending_ext_shared": { + "type": "boolean" + }, + "is_private": { + "type": "boolean" + }, + "is_read_only": { + "type": "boolean" + }, + "is_shared": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "is_thread_only": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "items": [ + { + "$ref": "#/definitions/objs_message" + }, + { + "type": "null" + } + ] + }, + "members": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "name": { + "type": "string" + }, + "name_normalized": { + "type": "string" + }, + "num_members": { + "type": "integer" + }, + "parent_conversation": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "type": "null" + } + ] + }, + "pending_connected_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "pending_shared": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "pin_count": { + "type": "integer" + }, + "previous_names": { + "items": { + "$ref": "#/definitions/defs_channel_name" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "priority": { + "type": "number" + }, + "purpose": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": ["value", "creator", "last_set"], + "type": "object" + }, + "shared_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "shares": { + "items": { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "is_active": { + "type": "boolean" + }, + "team": { + "$ref": "#/definitions/objs_team" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": ["team", "user", "is_active"], + "type": "object" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "timezone_count": { + "type": "integer" + }, + "topic": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": ["value", "creator", "last_set"], + "type": "object" + }, + "unlinked": { + "title": "Field to determine whether a channel has ever been shared/disconnected in the past", + "type": "integer" + }, + "unread_count": { + "type": "integer" + }, + "unread_count_display": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "name", + "created", + "creator", + "is_archived", + "is_channel", + "is_general", + "is_mpim", + "is_group", + "is_org_shared", + "is_im", + "is_shared", + "is_private", + "name_normalized", + "topic", + "purpose" + ], + "title": "Conversation MPIM Object", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "created": { + "type": "integer" + }, + "has_pins": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_dm_id" + }, + "is_archived": { + "type": "boolean" + }, + "is_ext_shared": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_im": { + "type": "boolean" + }, + "is_open": { + "type": "boolean" + }, + "is_org_shared": { + "type": "boolean" + }, + "is_shared": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "is_user_deleted": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "items": [ + { + "$ref": "#/definitions/objs_message" + }, + { + "type": "null" + } + ] + }, + "parent_conversation": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "type": "null" + } + ] + }, + "pin_count": { + "type": "integer" + }, + "priority": { + "type": "number" + }, + "shares": { + "items": { + "additionalProperties": false, + "properties": { + "date_create": { + "type": "integer" + }, + "id": { + "$ref": "#/definitions/defs_team" + }, + "is_active": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/objs_team" + } + }, + "required": ["id", "name", "team", "date_create", "is_active"], + "type": "object" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "unread_count": { + "type": "integer" + }, + "unread_count_display": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "created", + "is_im", + "is_org_shared", + "user", + "priority" + ], + "title": "Conversation IM Channel Object from conversations.* methods", + "type": "object" + } + ] + }, + "objs_enterprise_user": { + "additionalProperties": false, + "properties": { + "enterprise_id": { + "$ref": "#/definitions/defs_enterprise_id" + }, + "enterprise_name": { + "$ref": "#/definitions/defs_enterprise_name" + }, + "id": { + "$ref": "#/definitions/defs_enterprise_user_id" + }, + "is_admin": { + "type": "boolean" + }, + "is_owner": { + "type": "boolean" + }, + "teams": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "id", + "enterprise_id", + "enterprise_name", + "is_admin", + "is_owner", + "teams" + ], + "type": "object" + }, + "objs_external_org_migrations": { + "properties": { + "current": { + "items": { + "properties": { + "date_started": { + "type": "integer" + }, + "team_id": { + "type": "string" + } + }, + "required": ["team_id", "date_started"], + "type": "object" + }, + "type": "array" + }, + "date_updated": { + "type": "integer" + } + }, + "required": ["date_updated", "current"], + "title": "External Org Migrations", + "type": "object" + }, + "objs_file": { + "additionalProperties": false, + "properties": { + "channels": { + "items": { + "$ref": "#/definitions/defs_channel_id" + }, + "type": "array", + "uniqueItems": true + }, + "comments_count": { + "type": "integer" + }, + "created": { + "type": "integer" + }, + "date_delete": { + "type": "integer" + }, + "display_as_bot": { + "type": "boolean" + }, + "editable": { + "type": "boolean" + }, + "editor": { + "$ref": "#/definitions/defs_user_id" + }, + "external_id": { + "type": "string" + }, + "external_type": { + "type": "string" + }, + "external_url": { + "format": "uri", + "type": "string" + }, + "filetype": { + "type": "string" + }, + "groups": { + "items": { + "$ref": "#/definitions/defs_group_id" + }, + "type": "array", + "uniqueItems": true + }, + "has_rich_preview": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_file_id" + }, + "image_exif_rotation": { + "type": "integer" + }, + "ims": { + "items": { + "$ref": "#/definitions/defs_dm_id" + }, + "type": "array", + "uniqueItems": true + }, + "is_external": { + "type": "boolean" + }, + "is_public": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "is_tombstoned": { + "type": "boolean" + }, + "last_editor": { + "$ref": "#/definitions/defs_user_id" + }, + "mimetype": { + "type": "string" + }, + "mode": { + "type": "string" + }, + "name": { + "type": "string" + }, + "non_owner_editable": { + "type": "boolean" + }, + "num_stars": { + "type": "integer" + }, + "original_h": { + "type": "integer" + }, + "original_w": { + "type": "integer" + }, + "permalink": { + "format": "uri", + "type": "string" + }, + "permalink_public": { + "format": "uri", + "type": "string" + }, + "pinned_info": { + "$ref": "#/definitions/defs_pinned_info" + }, + "pinned_to": { + "items": { + "$ref": "#/definitions/defs_channel" + }, + "type": "array" + }, + "pretty_type": { + "type": "string" + }, + "preview": { + "type": "string" + }, + "public_url_shared": { + "type": "boolean" + }, + "reactions": { + "items": { + "$ref": "#/definitions/objs_reaction" + }, + "type": "array" + }, + "shares": { + "additionalProperties": false, + "properties": { + "private": { + "additionalProperties": false + }, + "public": { + "additionalProperties": false + } + }, + "type": "object" + }, + "size": { + "type": "integer" + }, + "source_team": { + "$ref": "#/definitions/defs_team" + }, + "state": { + "type": "string" + }, + "thumb_1024": { + "format": "uri", + "type": "string" + }, + "thumb_1024_h": { + "type": "integer" + }, + "thumb_1024_w": { + "type": "integer" + }, + "thumb_160": { + "format": "uri", + "type": "string" + }, + "thumb_360": { + "format": "uri", + "type": "string" + }, + "thumb_360_h": { + "type": "integer" + }, + "thumb_360_w": { + "type": "integer" + }, + "thumb_480": { + "format": "uri", + "type": "string" + }, + "thumb_480_h": { + "type": "integer" + }, + "thumb_480_w": { + "type": "integer" + }, + "thumb_64": { + "format": "uri", + "type": "string" + }, + "thumb_720": { + "format": "uri", + "type": "string" + }, + "thumb_720_h": { + "type": "integer" + }, + "thumb_720_w": { + "type": "integer" + }, + "thumb_80": { + "format": "uri", + "type": "string" + }, + "thumb_800": { + "format": "uri", + "type": "string" + }, + "thumb_800_h": { + "type": "integer" + }, + "thumb_800_w": { + "type": "integer" + }, + "thumb_960": { + "format": "uri", + "type": "string" + }, + "thumb_960_h": { + "type": "integer" + }, + "thumb_960_w": { + "type": "integer" + }, + "thumb_tiny": { + "type": "string" + }, + "timestamp": { + "type": "integer" + }, + "title": { + "type": "string" + }, + "updated": { + "type": "integer" + }, + "url_private": { + "format": "uri", + "type": "string" + }, + "url_private_download": { + "format": "uri", + "type": "string" + }, + "user": { + "type": "string" + }, + "user_team": { + "$ref": "#/definitions/defs_team" + }, + "username": { + "type": "string" + } + }, + "title": "file object", + "type": "object" + }, + "objs_icon": { + "properties": { + "image_102": { + "type": "string" + }, + "image_132": { + "type": "string" + }, + "image_230": { + "type": "string" + }, + "image_34": { + "type": "string" + }, + "image_44": { + "type": "string" + }, + "image_68": { + "type": "string" + }, + "image_88": { + "type": "string" + }, + "image_default": { + "type": "boolean" + } + }, + "type": "object" + }, + "objs_message": { + "additionalProperties": false, + "properties": { + "attachments": { + "items": { + "additionalProperties": false, + "properties": { + "fallback": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "image_bytes": { + "type": "integer" + }, + "image_height": { + "type": "integer" + }, + "image_url": { + "type": "string" + }, + "image_width": { + "type": "integer" + } + }, + "required": ["id"], + "type": "object" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "blocks": { + "$ref": "#/definitions/blocks" + }, + "bot_id": { + "items": [ + { + "$ref": "#/definitions/defs_bot_id" + }, + { + "title": "Nil bot_id set when display_as_bot is false", + "type": "null" + } + ] + }, + "bot_profile": { + "$ref": "#/definitions/objs_bot_profile" + }, + "client_msg_id": { + "type": "string" + }, + "comment": { + "$ref": "#/definitions/objs_comment" + }, + "display_as_bot": { + "type": "boolean" + }, + "file": { + "$ref": "#/definitions/objs_file" + }, + "files": { + "items": { + "$ref": "#/definitions/objs_file" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "icons": { + "additionalProperties": false, + "properties": { + "emoji": { + "type": "string" + }, + "image_64": { + "format": "uri", + "type": "string" + } + }, + "type": "object" + }, + "inviter": { + "$ref": "#/definitions/defs_user_id" + }, + "is_delayed_message": { + "type": "boolean" + }, + "is_intro": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest_reply": { + "$ref": "#/definitions/defs_ts" + }, + "name": { + "type": "string" + }, + "old_name": { + "type": "string" + }, + "parent_user_id": { + "$ref": "#/definitions/defs_user_id" + }, + "permalink": { + "format": "uri", + "type": "string" + }, + "pinned_to": { + "items": { + "$ref": "#/definitions/defs_channel" + }, + "type": "array" + }, + "purpose": { + "type": "string" + }, + "reactions": { + "items": { + "$ref": "#/definitions/objs_reaction" + }, + "type": "array" + }, + "reply_count": { + "type": "integer" + }, + "reply_users": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "reply_users_count": { + "type": "integer" + }, + "source_team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "subscribed": { + "type": "boolean" + }, + "subtype": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "text": { + "type": "string" + }, + "thread_ts": { + "$ref": "#/definitions/defs_ts" + }, + "topic": { + "type": "string" + }, + "ts": { + "$ref": "#/definitions/defs_ts" + }, + "type": { + "type": "string" + }, + "unread_count": { + "type": "integer" + }, + "upload": { + "type": "boolean" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "user_profile": { + "$ref": "#/definitions/objs_user_profile_short" + }, + "user_team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "username": { + "type": "string" + } + }, + "required": ["text", "type", "ts"], + "title": "Message object", + "type": "object" + }, + "objs_paging": { + "additionalProperties": false, + "properties": { + "count": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "pages": { + "type": "integer" + }, + "per_page": { + "type": "integer" + }, + "spill": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "required": ["page", "total"], + "title": "paging object", + "type": "object" + }, + "objs_primary_owner": { + "properties": { + "email": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": ["id", "email"], + "type": "object" + }, + "objs_reaction": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "users": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "type": "array" + } + }, + "required": ["name", "users", "count"], + "title": "Reaction object", + "type": "object" + }, + "objs_reminder": { + "additionalProperties": false, + "properties": { + "complete_ts": { + "type": "integer" + }, + "creator": { + "$ref": "#/definitions/defs_user_id" + }, + "id": { + "$ref": "#/definitions/defs_reminder_id" + }, + "recurring": { + "type": "boolean" + }, + "text": { + "type": "string" + }, + "time": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": ["id", "creator", "user", "text", "recurring"], + "type": "object" + }, + "objs_resources": { + "additionalProperties": false, + "properties": { + "excluded_ids": { + "items": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "$ref": "#/definitions/defs_team" + } + ] + }, + "type": "array" + }, + "ids": { + "items": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "$ref": "#/definitions/defs_team" + } + ] + }, + "type": "array" + }, + "wildcard": { + "type": "boolean" + } + }, + "required": ["ids"], + "title": "resources in info from apps.permissions.info", + "type": "object" + }, + "objs_response_metadata": { + "items": [ + { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string" + } + }, + "required": ["next_cursor"], + "title": "new paging style", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "messages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "warnings": { + "items": { + "enum": ["method_deprecated"], + "type": "string" + }, + "type": "array" + } + }, + "required": ["messages", "warnings"], + "title": "deprecation_warning", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "messages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "next_cursor": { + "type": "string" + }, + "warnings": { + "items": { + "enum": ["method_deprecated"], + "type": "string" + }, + "type": "array" + } + }, + "required": ["messages", "warnings", "next_cursor"], + "title": "deprecation_warning and paging style together", + "type": "object" + } + ] + }, + "objs_scopes": { + "items": { + "title": "Named OAuth scopes", + "type": "string", + "x-examples": ["chat:write", "im:history", "im:read"] + }, + "type": "array" + }, + "objs_subteam": { + "additionalProperties": false, + "properties": { + "auto_provision": { + "type": "boolean" + }, + "auto_type": { + "items": [ + { + "type": "null" + }, + { + "enum": ["owner", "admin"], + "type": "string" + } + ] + }, + "channel_count": { + "type": "integer" + }, + "created_by": { + "$ref": "#/definitions/defs_user_id" + }, + "date_create": { + "type": "integer" + }, + "date_delete": { + "type": "integer" + }, + "date_update": { + "type": "integer" + }, + "deleted_by": { + "items": [ + { + "type": "null" + }, + { + "$ref": "#/definitions/defs_user_id" + } + ] + }, + "description": { + "type": "string" + }, + "enterprise_subteam_id": { + "type": "string" + }, + "handle": { + "type": "string" + }, + "id": { + "$ref": "#/definitions/defs_subteam_id" + }, + "is_external": { + "type": "boolean" + }, + "is_subteam": { + "type": "boolean" + }, + "is_usergroup": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "prefs": { + "additionalProperties": false, + "properties": { + "channels": { + "items": { + "$ref": "#/definitions/defs_channel_id" + }, + "type": "array" + }, + "groups": { + "items": { + "$ref": "#/definitions/defs_group_id" + }, + "type": "array" + } + }, + "required": ["channels", "groups"], + "type": "object" + }, + "team_id": { + "$ref": "#/definitions/defs_team" + }, + "updated_by": { + "$ref": "#/definitions/defs_user_id" + }, + "user_count": { + "type": "integer" + }, + "users": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "type": "array" + } + }, + "required": [ + "id", + "team_id", + "is_usergroup", + "is_subteam", + "name", + "description", + "handle", + "is_external", + "date_create", + "date_update", + "date_delete", + "auto_type", + "auto_provision", + "enterprise_subteam_id", + "created_by", + "updated_by", + "deleted_by", + "prefs" + ], + "title": "Subteam/Usergroup Object", + "type": "object" + }, + "objs_team": { + "additionalProperties": false, + "properties": { + "archived": { + "type": "boolean" + }, + "avatar_base_url": { + "format": "uri", + "type": "string" + }, + "created": { + "type": "integer" + }, + "date_create": { + "type": "integer" + }, + "deleted": { + "type": "boolean" + }, + "description": { + "type": ["null", "string"] + }, + "discoverable": { + "items": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "domain": { + "type": "string" + }, + "email_domain": { + "type": "string" + }, + "enterprise_id": { + "$ref": "#/definitions/defs_enterprise_id" + }, + "enterprise_name": { + "$ref": "#/definitions/defs_enterprise_name" + }, + "external_org_migrations": { + "$ref": "#/definitions/objs_external_org_migrations" + }, + "has_compliance_export": { + "type": "boolean" + }, + "icon": { + "$ref": "#/definitions/objs_icon" + }, + "id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "is_assigned": { + "type": "boolean" + }, + "is_enterprise": { + "type": "integer" + }, + "is_over_storage_limit": { + "type": "boolean" + }, + "limit_ts": { + "type": "integer" + }, + "locale": { + "type": "string" + }, + "messages_count": { + "type": "integer" + }, + "msg_edit_window_mins": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "over_integrations_limit": { + "type": "boolean" + }, + "over_storage_limit": { + "type": "boolean" + }, + "pay_prod_cur": { + "type": "string" + }, + "plan": { + "enum": ["", "std", "plus", "compliance", "enterprise"], + "type": "string" + }, + "primary_owner": { + "$ref": "#/definitions/objs_primary_owner" + }, + "sso_provider": { + "properties": { + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": ["id", "name", "domain", "email_domain", "icon"], + "title": "Team Object", + "type": "object" + }, + "objs_team_profile_field": { + "additionalProperties": false, + "properties": { + "field_name": { + "type": ["null", "string"] + }, + "hint": { + "type": "string" + }, + "id": { + "pattern": "^X[a-zA-Z0-9]{9,}$", + "type": "string" + }, + "is_hidden": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "options": { + "items": [ + { + "type": "null" + }, + { + "$ref": "#/definitions/objs_team_profile_field_option" + } + ] + }, + "ordering": { + "type": "number" + }, + "possible_values": { + "items": { + "type": "string" + }, + "type": ["null", "array"] + }, + "type": { + "enum": ["text", "date", "link", "mailto", "options_list", "user"], + "type": "string" + } + }, + "required": ["id", "ordering", "label", "hint", "type"], + "type": "object" + }, + "objs_team_profile_field_option": { + "additionalProperties": false, + "properties": { + "is_custom": { + "type": ["null", "boolean"] + }, + "is_multiple_entry": { + "type": ["null", "boolean"] + }, + "is_protected": { + "type": ["null", "boolean"] + }, + "is_scim": { + "type": ["null", "boolean"] + } + }, + "type": "object" + }, + "objs_user": { + "items": [ + { + "additionalProperties": false, + "description": "user object for non enterprise type", + "properties": { + "color": { + "pattern": "^[a-fA-F0-9]{6}$", + "type": "string" + }, + "deleted": { + "type": "boolean" + }, + "enterprise_user": { + "$ref": "#/definitions/objs_enterprise_user" + }, + "has_2fa": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "is_admin": { + "type": "boolean" + }, + "is_app_user": { + "type": "boolean" + }, + "is_bot": { + "type": "boolean" + }, + "is_external": { + "type": "boolean" + }, + "is_forgotten": { + "type": "boolean" + }, + "is_invited_user": { + "type": "boolean" + }, + "is_owner": { + "type": "boolean" + }, + "is_primary_owner": { + "type": "boolean" + }, + "is_restricted": { + "type": "boolean" + }, + "is_stranger": { + "type": "boolean" + }, + "is_ultra_restricted": { + "type": "boolean" + }, + "locale": { + "type": "string" + }, + "name": { + "type": "string" + }, + "presence": { + "type": "string" + }, + "profile": { + "$ref": "#/definitions/objs_user_profile" + }, + "real_name": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "team_id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "team_profile": { + "additionalProperties": false, + "properties": { + "fields": { + "items": { + "$ref": "#/definitions/objs_team_profile_field" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": ["fields"], + "type": "object" + }, + "two_factor_type": { + "type": "string" + }, + "tz": { + "items": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "tz_label": { + "type": "string" + }, + "tz_offset": { + "type": "number" + }, + "updated": { + "type": "number" + } + }, + "required": [ + "id", + "name", + "profile", + "is_bot", + "updated", + "is_app_user" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "enterprise user", + "properties": { + "color": { + "description": "refercing to bug: https://jira.tinyspeck.com/browse/EVALUE-1559", + "pattern": "^([a-fA-F0-9]{6})?$", + "type": "string" + }, + "deleted": { + "type": "boolean" + }, + "enterprise_user": { + "$ref": "#/definitions/objs_enterprise_user" + }, + "has_2fa": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "is_admin": { + "type": "boolean" + }, + "is_app_user": { + "type": "boolean" + }, + "is_bot": { + "type": "boolean" + }, + "is_external": { + "type": "boolean" + }, + "is_forgotten": { + "type": "boolean" + }, + "is_owner": { + "type": "boolean" + }, + "is_primary_owner": { + "type": "boolean" + }, + "is_restricted": { + "type": "boolean" + }, + "is_stranger": { + "type": "boolean" + }, + "is_ultra_restricted": { + "type": "boolean" + }, + "locale": { + "type": "string" + }, + "name": { + "type": "string" + }, + "presence": { + "type": "string" + }, + "profile": { + "$ref": "#/definitions/objs_user_profile" + }, + "real_name": { + "type": "string" + }, + "team_id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "team_profile": { + "additionalProperties": false, + "properties": { + "fields": { + "items": { + "$ref": "#/definitions/objs_team_profile_field" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": ["fields"], + "type": "object" + }, + "teams": { + "items": { + "$ref": "#/definitions/defs_workspace_id" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "two_factor_type": { + "type": "string" + }, + "tz": { + "items": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "tz_label": { + "type": "string" + }, + "tz_offset": { + "type": "number" + }, + "updated": { + "type": "number" + } + }, + "required": [ + "id", + "name", + "profile", + "is_bot", + "updated", + "is_app_user" + ], + "type": "object" + } + ] + }, + "objs_user_profile": { + "additionalProperties": false, + "properties": { + "always_active": { + "type": "boolean" + }, + "api_app_id": { + "$ref": "#/definitions/defs_optional_app_id" + }, + "avatar_hash": { + "type": "string" + }, + "bot_id": { + "$ref": "#/definitions/defs_bot_id" + }, + "display_name": { + "type": "string" + }, + "display_name_normalized": { + "type": "string" + }, + "email": { + "format": "email", + "type": ["null", "string"] + }, + "fields": { + "items": { + "type": "object" + }, + "type": ["object", "null", "array"] + }, + "first_name": { + "type": ["null", "string"] + }, + "guest_expiration_ts": { + "type": ["null", "integer"] + }, + "guest_invited_by": { + "type": ["null", "string"] + }, + "image_1024": { + "format": "uri", + "type": ["null", "string"] + }, + "image_192": { + "format": "uri", + "type": ["null", "string"] + }, + "image_24": { + "format": "uri", + "type": ["null", "string"] + }, + "image_32": { + "format": "uri", + "type": ["null", "string"] + }, + "image_48": { + "format": "uri", + "type": ["null", "string"] + }, + "image_512": { + "format": "uri", + "type": ["null", "string"] + }, + "image_72": { + "format": "uri", + "type": ["null", "string"] + }, + "image_original": { + "format": "uri", + "type": ["null", "string"] + }, + "is_app_user": { + "type": "boolean" + }, + "is_custom_image": { + "type": "boolean" + }, + "is_restricted": { + "type": ["null", "boolean"] + }, + "is_ultra_restricted": { + "type": ["null", "boolean"] + }, + "last_avatar_image_hash": { + "type": "string" + }, + "last_name": { + "type": ["null", "string"] + }, + "memberships_count": { + "type": "integer" + }, + "name": { + "type": ["null", "string"] + }, + "phone": { + "type": "string" + }, + "pronouns": { + "type": "string" + }, + "real_name": { + "type": "string" + }, + "real_name_normalized": { + "type": "string" + }, + "skype": { + "type": "string" + }, + "status_default_emoji": { + "type": "string" + }, + "status_default_text": { + "type": "string" + }, + "status_default_text_canonical": { + "type": ["null", "string"] + }, + "status_emoji": { + "type": "string" + }, + "status_expiration": { + "type": "integer" + }, + "status_text": { + "type": "string" + }, + "status_text_canonical": { + "type": ["null", "string"] + }, + "team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "title": { + "type": "string" + }, + "updated": { + "type": "integer" + }, + "user_id": { + "type": "string" + }, + "username": { + "type": ["null", "string"] + } + }, + "required": [ + "real_name", + "display_name", + "avatar_hash", + "real_name_normalized", + "display_name_normalized", + "title", + "phone", + "skype", + "status_text", + "status_emoji", + "fields" + ], + "title": "User profile object", + "type": "object" + }, + "objs_user_profile_short": { + "additionalProperties": false, + "properties": { + "avatar_hash": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "display_name_normalized": { + "type": "string" + }, + "first_name": { + "type": ["string", "null"] + }, + "image_72": { + "format": "uri", + "type": "string" + }, + "is_restricted": { + "type": "boolean" + }, + "is_ultra_restricted": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "real_name": { + "type": "string" + }, + "real_name_normalized": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/defs_workspace_id" + } + }, + "required": [ + "avatar_hash", + "image_72", + "first_name", + "real_name", + "display_name", + "team", + "name", + "is_restricted", + "is_ultra_restricted" + ], + "type": "object" + } + }, + "externalDocs": { + "description": "Learn more about the Slack Web API", + "url": "https://api.slack.com/web" + }, + "host": "slack.com", + "info": { + "contact": { + "name": "Slack developer relations", + "url": "https://api.slack.com/support" + }, + "description": "One way to interact with the Slack platform is its HTTP RPC-based Web API, a collection of methods requiring OAuth 2.0-based user, bot, or workspace tokens blessed with related OAuth scopes.", + "title": "Slack Web API", + "version": "1.7.0" + }, + "paths": { + "/conversations.list": { + "get": { + "consumes": ["application/x-www-form-urlencoded"], + "description": "Lists all channels in a Slack team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.list" + }, + "operationId": "conversations_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Set to `true` to exclude archived channels from the list", + "in": "query", + "name": "exclude_archived", + "type": "boolean" + }, + { + "description": "Mix and match channel types by providing a comma-separated list of any combination of `public_channel`, `private_channel`, `mpim`, `im`", + "in": "query", + "name": "types", + "type": "string" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached. Must be an integer no larger than 1000.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": ["application/json"], + "responses": { + "200": { + "description": "Typical success response with only public channels", + "examples": { + "application/json": { + "channels": [ + { + "created": 1449252889, + "creator": "U012A3CDE", + "id": "C012AB3CD", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": true, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "general", + "name_normalized": "general", + "num_members": 4, + "pending_shared": [], + "previous_names": [], + "purpose": { + "creator": "", + "last_set": 0, + "value": "This channel is for team-wide communication and announcements. All team members are in this channel." + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "Company-wide announcements and work-based matters" + }, + "unlinked": 0 + }, + { + "created": 1449252889, + "creator": "U061F7AUR", + "id": "C061EG9T2", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": false, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "random", + "name_normalized": "random", + "num_members": 4, + "pending_shared": [], + "previous_names": [], + "purpose": { + "creator": "", + "last_set": 0, + "value": "A place for non-work-related flimflam, faffing, hodge-podge or jibber-jabber you'd prefer to keep out of more focused work-related channels." + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "Non-work banter and water cooler conversation" + }, + "unlinked": 0 + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "dGVhbTpDMDYxRkE1UEI=" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.list method", + "properties": { + "channels": { + "items": { + "$ref": "#/definitions/objs_conversation" + }, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "response_metadata": { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string" + } + }, + "required": ["next_cursor"], + "type": "object" + } + }, + "required": ["ok", "channels"], + "title": "conversations.list success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "missing_scope", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": ["ok", "error"], + "title": "conversations.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:read", + "groups:read", + "im:read", + "mpim:read" + ] + } + ], + "tags": ["conversations"] + } + } + }, + "schemes": ["https"], + "securityDefinitions": { + "slackAuth": { + "authorizationUrl": "https://slack.com/oauth/authorize", + "flow": "accessCode", + "scopes": { + "admin": "admin" + }, + "tokenUrl": "https://slack.com/api/oauth.access", + "type": "oauth2" + } + }, + "swagger": "2.0", + "tags": [] +} diff --git a/apps/integrations/src/core/schemas/types.ts b/apps/integrations/src/core/schemas/types.ts new file mode 100644 index 000000000..14b31a388 --- /dev/null +++ b/apps/integrations/src/core/schemas/types.ts @@ -0,0 +1,3 @@ +import { Schema } from "@cfworker/json-schema"; + +export type JSONSchema = Schema; diff --git a/apps/integrations/src/core/schemas/validate.ts b/apps/integrations/src/core/schemas/validate.ts new file mode 100644 index 000000000..1597d10da --- /dev/null +++ b/apps/integrations/src/core/schemas/validate.ts @@ -0,0 +1,22 @@ +import { Validator } from "@cfworker/json-schema"; +import { JSONSchema } from "./types"; + +export function validate(data: any, schema?: JSONSchema) { + if (!schema) { + return { + success: true as const, + }; + } + const validator = new Validator(schema); + const result = validator.validate(data); + if (!result.valid) { + return { + success: false as const, + errors: result.errors, + }; + } + + return { + success: true as const, + }; +} diff --git a/apps/integrations/src/core/service/types.ts b/apps/integrations/src/core/service/types.ts new file mode 100644 index 000000000..c006e2105 --- /dev/null +++ b/apps/integrations/src/core/service/types.ts @@ -0,0 +1,11 @@ +import { Action } from "core/action/types"; +import { IntegrationAuthentication } from "core/authentication/types"; +import { Endpoint } from "core/endpoint/types"; + +export type Service = { + name: string; + service: string; + version: string; + authentication: IntegrationAuthentication; + actions: Record; +}; diff --git a/apps/integrations/src/generators/combineSchemas.test.ts b/apps/integrations/src/generators/combineSchemas.test.ts new file mode 100644 index 000000000..db5c25eba --- /dev/null +++ b/apps/integrations/src/generators/combineSchemas.test.ts @@ -0,0 +1,106 @@ +import { EndpointSpec } from "core/endpoint/types"; +import { JSONSchema } from "core/schemas/types"; +import { expect, test } from "vitest"; +import { createInputSchema } from "./combineSchemas"; + +test("create input schema when only a body schema", async () => { + try { + const schema: JSONSchema = { + type: "object", + required: ["channel"], + properties: { + as_user: { + type: "string", + description: + "Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [authorship](#authorship) below.", + }, + attachments: { + type: "string", + description: + "A JSON-based array of structured attachments, presented as a URL-encoded string.", + }, + channel: { + type: "string", + description: + "Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details.", + }, + }, + }; + + const inputSchema = createInputSchema({ body: schema }); + expect(inputSchema).toEqual(schema); + } catch (e: any) { + console.error(JSON.stringify(e.errors, null, 2)); + expect(e).toEqual(null); + } +}); + +test("combine input body and parameters into a schema", async () => { + try { + const bodySchema: JSONSchema = { + type: "object", + required: ["channel"], + properties: { + as_user: { + type: "string", + description: + "Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [authorship](#authorship) below.", + }, + attachments: { + type: "string", + description: + "A JSON-based array of structured attachments, presented as a URL-encoded string.", + }, + channel: { + type: "string", + description: + "Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details.", + }, + }, + }; + const parameters: EndpointSpec["parameters"] = [ + { + name: "limit", + description: "The maximum number of items to return.", + in: "path", + required: true, + schema: { + type: "integer", + description: "The maximum number of items to return.", + }, + }, + ]; + + const inputSchema = createInputSchema({ body: bodySchema, parameters }); + expect(inputSchema).toMatchInlineSnapshot(` + { + "properties": { + "as_user": { + "description": "Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [authorship](#authorship) below.", + "type": "string", + }, + "attachments": { + "description": "A JSON-based array of structured attachments, presented as a URL-encoded string.", + "type": "string", + }, + "channel": { + "description": "Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details.", + "type": "string", + }, + "limit": { + "description": "The maximum number of items to return.", + "type": "integer", + }, + }, + "required": [ + "channel", + "limit", + ], + "type": "object", + } + `); + } catch (e: any) { + console.error(JSON.stringify(e.errors, null, 2)); + expect(e).toEqual(null); + } +}); diff --git a/apps/integrations/src/generators/combineSchemas.ts b/apps/integrations/src/generators/combineSchemas.ts new file mode 100644 index 000000000..898bd2544 --- /dev/null +++ b/apps/integrations/src/generators/combineSchemas.ts @@ -0,0 +1,77 @@ +import { Action } from "core/action/types"; +import { JSONSchema } from "core/schemas/types"; + +export function generateInputOutputSchemas( + spec: Action["spec"], + name: string +): { + input: JSONSchema | undefined; + output: JSONSchema; +} { + const inputSchema = createInputSchema(spec.input); + if (inputSchema) inputSchema.title = `${name}Input`; + + const outputSchema = createSuccessfulOutputSchema(spec.output); + outputSchema.title = `${name}Output`; + + return { + input: inputSchema, + output: outputSchema, + }; +} + +export function createInputSchema( + spec: Action["spec"]["input"] +): JSONSchema | undefined { + let inputSchema: JSONSchema | undefined = spec.body; + + if (spec.parameters && spec.parameters.length > 0) { + if (!inputSchema) { + inputSchema = { + type: "object", + properties: {}, + }; + } + + inputSchema = { + type: "object", + properties: { + ...inputSchema.properties, + ...Object.fromEntries( + spec.parameters.map((p) => [ + p.name, + { ...p.schema, description: p.description }, + ]) + ), + }, + required: [ + ...(inputSchema.required ?? []), + ...spec.parameters.filter((p) => p.required).map((p) => p.name), + ], + }; + } + + return inputSchema; +} + +export function createSuccessfulOutputSchema( + spec: Action["spec"]["output"] +): JSONSchema { + //combine all "success" output schemas into a union + const outputSuccessSchemas = Object.values(spec.responses).flatMap((s) => + s.flatMap((r) => (r.success ? r.schema : [])) + ); + return outputSuccessSchemas.length === 1 + ? outputSuccessSchemas[0] + : createDiscriminatedUnionSchema(`Output`, outputSuccessSchemas); +} + +function createDiscriminatedUnionSchema( + name: string, + schemas: JSONSchema[] +): JSONSchema { + return { + $id: name, + oneOf: schemas, + }; +} diff --git a/apps/integrations/src/generators/generateTypes.test.ts b/apps/integrations/src/generators/generateTypes.test.ts new file mode 100644 index 000000000..9f67b96ee --- /dev/null +++ b/apps/integrations/src/generators/generateTypes.test.ts @@ -0,0 +1,119 @@ +import { expect, test } from "vitest"; +import { getTypesFromSchema as generateTypesFromSchema } from "./generateTypes"; + +test("simple schema type generation", async () => { + try { + const schema = { + type: "object", + properties: { + channel: { + type: "string", + description: "ID of conversation to join", + }, + }, + required: ["channel"], + }; + + const data = await generateTypesFromSchema(schema, "Input"); + expect(data).toMatchInlineSnapshot(` + "export interface Input { + /** + * ID of conversation to join + */ + channel: string; + } + " + `); + } catch (e: any) { + console.error(JSON.stringify(e.errors, null, 2)); + expect(e).toEqual(null); + } +}); + +test("advanced schema type generation", async () => { + try { + const schema = { + type: "object", + properties: { + channel: { + type: "string", + }, + message: { + type: "object", + properties: { + attachments: { + type: "array", + items: { + type: "object", + properties: { + fallback: { + type: "string", + }, + id: { + type: "number", + }, + text: { + type: "string", + }, + }, + required: ["fallback", "id", "text"], + }, + }, + bot_id: { + type: "string", + }, + subtype: { + type: "string", + }, + text: { + type: "string", + }, + ts: { + type: "string", + }, + type: { + type: "string", + }, + user: { + type: "string", + }, + }, + required: ["bot_id", "text", "ts", "type"], + }, + ok: { + type: "boolean", + }, + ts: { + type: "string", + }, + }, + required: ["channel", "message", "ok", "ts"], + }; + + const data = await generateTypesFromSchema(schema, "Input"); + expect(data).toMatchInlineSnapshot(` + "export interface Input { + channel: string; + message: { + attachments?: { + fallback: string; + id: number; + text: string; + }[]; + bot_id: string; + subtype?: string; + text: string; + ts: string; + type: string; + user?: string; + }; + ok: boolean; + ts: string; + } + " + `); + } catch (e: any) { + console.error(JSON.stringify(e.errors, null, 2)); + expect(e).toEqual(null); + } +}); diff --git a/apps/integrations/src/generators/generateTypes.ts b/apps/integrations/src/generators/generateTypes.ts new file mode 100644 index 000000000..44656e140 --- /dev/null +++ b/apps/integrations/src/generators/generateTypes.ts @@ -0,0 +1,9 @@ +import { compile } from "json-schema-to-typescript"; + +export async function getTypesFromSchema(schema: any, name: string) { + const ts = await compile(schema, name, { + additionalProperties: false, + bannerComment: "", + }); + return ts; +} diff --git a/apps/integrations/src/integrations/catalog.ts b/apps/integrations/src/integrations/catalog.ts new file mode 100644 index 000000000..59020d14a --- /dev/null +++ b/apps/integrations/src/integrations/catalog.ts @@ -0,0 +1,8 @@ +import { Catalog } from "core/catalog"; +import { slack } from "./slack"; + +export const catalog: Catalog = { + services: { + slack, + }, +}; diff --git a/apps/integrations/src/integrations/slack/actions/actions.ts b/apps/integrations/src/integrations/slack/actions/actions.ts new file mode 100644 index 000000000..26bcc1e6d --- /dev/null +++ b/apps/integrations/src/integrations/slack/actions/actions.ts @@ -0,0 +1,146 @@ +import { makeRequestAction } from "core/action/simpleAction"; +import { Action } from "core/action/types"; +import { + combineSecurityScopes, + makeInputSpec, + makeOutputSpec, +} from "core/action/utilities"; +import { CacheService } from "core/cache/types"; +import { RequestData } from "core/request/types"; +import endpoints from "../endpoints/endpoints"; + +export const conversationsList: Action = makeRequestAction( + endpoints.conversationsList +); + +export const chatPostMessage: Action = { + name: endpoints.chatPostMessage.spec.endpointSpec.metadata.name, + description: endpoints.chatPostMessage.spec.endpointSpec.metadata.description, + path: endpoints.chatPostMessage.spec.endpointSpec.path, + method: endpoints.chatPostMessage.spec.endpointSpec.method, + spec: { + input: { + ...makeInputSpec(endpoints.chatPostMessage), + security: combineSecurityScopes([ + endpoints.chatPostMessage.spec.endpointSpec.security, + endpoints.conversationsList.spec.endpointSpec.security, + endpoints.conversationsJoin.spec.endpointSpec.security, + ]), + }, + output: makeOutputSpec(endpoints.chatPostMessage), + }, + action: async (data, cache, metadata) => { + //get channel id + const channelId = await getChannelId({ + channel: data.body.channel, + credentials: data.credentials, + cache, + }); + + if (!channelId) { + return { + success: false, + status: 404, + body: { + ok: false, + error: "channel_not_found", + }, + }; + } + + const postMessageBody = { + ...data.body, + channel: channelId, + }; + + //todo add extra passed in metadata to the metadata property + // + + const postResponse = await endpoints.chatPostMessage.request({ + parameters: data.parameters, + body: postMessageBody, + credentials: data.credentials, + }); + + //success + if (postResponse.success) return postResponse; + + //if the bot isn't a member of the channel we want to invite + if (postResponse.body?.error !== "not_in_channel") return postResponse; + + //join the bot to the channel + const joinResponse = await endpoints.conversationsJoin.request({ + body: { + channel: channelId, + }, + credentials: data.credentials, + }); + + //if we can't join the channel, return the error + if (!joinResponse.success) { + return { + success: false, + status: 400, + body: { + ok: false, + error: `failed to join channel: ${joinResponse.body?.error}`, + }, + }; + } + + //try again now we've joined the channel + return await endpoints.chatPostMessage.request({ + parameters: data.parameters, + body: postMessageBody, + credentials: data.credentials, + }); + }, +}; + +async function getChannelId({ + channel, + credentials, + cache, +}: { + channel: string; + credentials: RequestData["credentials"]; + cache?: CacheService; +}): Promise { + if (channel.startsWith("#")) { + channel = channel.substring(1); + } + + const cachedChannelId = await cache?.get(channel); + if (cachedChannelId) { + return cachedChannelId; + } + + try { + const data = await endpoints.conversationsList.request({ + parameters: { + limit: 1000, + }, + credentials, + }); + + if (!data.success) { + return undefined; + } + + //lookup by name or id + const match = data.body.channels.find( + (channelData: any) => + channelData.name === channel || channelData.id === channel + ); + if (!match) { + return undefined; + } + + //cache for 24 hours + await cache?.set(channel, match.id, 60 * 60 * 24); + return match.id; + } catch (e: any) { + console.error(JSON.stringify(e, null, 2)); + return undefined; + } +} diff --git a/apps/integrations/src/integrations/slack/authentication.ts b/apps/integrations/src/integrations/slack/authentication.ts new file mode 100644 index 000000000..0bb4f4fa1 --- /dev/null +++ b/apps/integrations/src/integrations/slack/authentication.ts @@ -0,0 +1,84 @@ +import { IntegrationAuthentication } from "core/authentication/types"; + +export const authentication: IntegrationAuthentication = { + slackAuth: { + type: "oauth2", + placement: { + in: "header", + type: "bearer", + key: "Authorization", + }, + authorizationUrl: "https://slack.com/oauth/authorize", + tokenUrl: "https://slack.com/api/oauth.access", + flow: "accessCode", + scopes: { + admin: "admin", + "admin.apps:read": "admin.apps:read", + "admin.apps:write": "admin.apps:write", + "admin.conversations:read": "admin.conversations:read", + "admin.conversations:write": "admin.conversations:write", + "admin.invites:read": "admin.invites:read", + "admin.invites:write": "admin.invites:write", + "admin.teams:read": "admin.teams:read", + "admin.teams:write": "admin.teams:write", + "admin.usergroups:read": "admin.usergroups:read", + "admin.usergroups:write": "admin.usergroups:write", + "admin.users:read": "admin.users:read", + "admin.users:write": "admin.users:write", + "authorizations:read": "authorizations:read", + bot: "Bot user scope", + "calls:read": "calls:read", + "calls:write": "calls:write", + "channels:history": "channels:history", + "channels:manage": "channels:manage", + "channels:read": "channels:read", + "channels:write": "channels:write", + "chat:write": "chat:write", + "chat:write:bot": "Author messages as a bot", + "chat:write:user": "Author messages as a user", + "conversations:history": "conversations:history", + "conversations:read": "conversations:read", + "conversations:write": "conversations:write", + "dnd:read": "dnd:read", + "dnd:write": "dnd:write", + "emoji:read": "emoji:read", + "files:read": "files:read", + "files:write:user": "files:write:user", + "groups:history": "groups:history", + "groups:read": "groups:read", + "groups:write": "groups:write", + "identity.basic": "identity.basic", + "im:history": "im:history", + "im:read": "im:read", + "im:write": "im:write", + "links:write": "links:write", + "mpim:history": "mpim:history", + "mpim:read": "mpim:read", + "mpim:write": "mpim:write", + none: "No scope required", + "pins:read": "pins:read", + "pins:write": "pins:write", + "reactions:read": "reactions:read", + "reactions:write": "reactions:write", + "reminders:read": "reminders:read", + "reminders:write": "reminders:write", + "remote_files:read": "remote_files:read", + "remote_files:share": "remote_files:share", + "remote_files:write": "remote_files:write", + "rtm:stream": "rtm:stream", + "search:read": "search:read", + "stars:read": "stars:read", + "stars:write": "stars:write", + "team:read": "team:read", + "tokens.basic": "tokens.basic", + "usergroups:read": "usergroups:read", + "usergroups:write": "usergroups:write", + "users.profile:read": "users.profile:read", + "users.profile:write": "users.profile:write", + "users:read": "users:read", + "users:read.email": "users:read.email", + "users:write": "users:write", + "workflow.steps:execute": "workflow.steps:execute", + }, + }, +}; diff --git a/apps/integrations/src/integrations/slack/endpoints/endpoints.ts b/apps/integrations/src/integrations/slack/endpoints/endpoints.ts new file mode 100644 index 000000000..ef2d691b9 --- /dev/null +++ b/apps/integrations/src/integrations/slack/endpoints/endpoints.ts @@ -0,0 +1,8 @@ +import { makeEndpoints } from "core/endpoint/endpoint"; +import { authentication } from "../authentication"; +import * as specs from "./specs"; + +const baseUrl = "https://slack.com/api"; + +const endpoints = makeEndpoints(baseUrl, authentication, specs); +export default endpoints; diff --git a/apps/integrations/src/integrations/slack/endpoints/schemas/slack_web_openapi_v2.json b/apps/integrations/src/integrations/slack/endpoints/schemas/slack_web_openapi_v2.json new file mode 100644 index 000000000..72c5dfb43 --- /dev/null +++ b/apps/integrations/src/integrations/slack/endpoints/schemas/slack_web_openapi_v2.json @@ -0,0 +1,27441 @@ +{ + "basePath": "/api", + "definitions": { + "blocks": { + "description": "This is a very loose definition, in the future, we'll populate this with deeper schema in this definition namespace.", + "items": { + "additionalProperties": true, + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "title": "Block Kit blocks", + "type": "array" + }, + "defs_app_id": { + "pattern": "^A[A-Z0-9]{1,}$", + "title": "App ID", + "type": "string" + }, + "defs_bot_id": { + "pattern": "^B[A-Z0-9]{8,}$", + "title": "Bot User ID", + "type": "string" + }, + "defs_channel": { + "pattern": "^[CGD][A-Z0-9]{8,}$", + "title": "Channel-like conversation ID", + "type": "string" + }, + "defs_channel_id": { + "pattern": "^[C][A-Z0-9]{2,}$", + "title": "Channel ID", + "type": "string" + }, + "defs_channel_name": { + "title": "Name of a channel", + "type": "string" + }, + "defs_comment_id": { + "pattern": "^Fc[A-Z0-9]{8,}$", + "title": "File Comment ID", + "type": "string" + }, + "defs_dm_id": { + "pattern": "^[D][A-Z0-9]{8,}$", + "title": "Direct Message Channel ID", + "type": "string" + }, + "defs_enterprise_id": { + "pattern": "^[E][A-Z0-9]{8,}$", + "title": "Enterprise ID", + "type": "string" + }, + "defs_enterprise_name": { + "title": "Name of the enterprise org", + "type": "string" + }, + "defs_enterprise_user_id": { + "pattern": "^[WU][A-Z0-9]{8,}$", + "title": "Enterprise User ID", + "type": "string" + }, + "defs_file_id": { + "pattern": "^[F][A-Z0-9]{8,}$", + "title": "File ID", + "type": "string" + }, + "defs_group_id": { + "pattern": "^[G][A-Z0-9]{8,}$", + "title": "Private Channel ID", + "type": "string" + }, + "defs_ok_false": { + "enum": [ + false + ], + "title": "default failure response", + "type": "boolean" + }, + "defs_ok_true": { + "enum": [ + true + ], + "title": "default success response", + "type": "boolean" + }, + "defs_optional_app_id": { + "pattern": "^(A[A-Z0-9]{1,})?$", + "title": "App ID or empty string", + "type": "string" + }, + "defs_pinned_info": { + "additionalProperties": false, + "title": "Info for a pinned item", + "type": "object" + }, + "defs_reminder_id": { + "pattern": "^Rm[A-Z0-9]{8,}$", + "title": "Reminder ID", + "type": "string" + }, + "defs_subteam_id": { + "pattern": "^S[A-Z0-9]{2,}$", + "title": "Subteam ID", + "type": "string" + }, + "defs_team": { + "pattern": "^[T][A-Z0-9]{2,}$", + "title": "Team ID", + "type": "string" + }, + "defs_topic_purpose_creator": { + "pattern": "^[UW][A-Z0-9]{8,}$|^$", + "title": "User ID or empty string, used for topic and purpose creation", + "type": "string" + }, + "defs_ts": { + "pattern": "^\\d{10}\\.\\d{6}$", + "title": "Timestamp in format 0123456789.012345", + "type": "string" + }, + "defs_user_id": { + "pattern": "^[UW][A-Z0-9]{2,}$", + "title": "User ID", + "type": "string" + }, + "defs_workspace_id": { + "pattern": "^[TE][A-Z0-9]{8,}$", + "title": "Team or Enterprise ID", + "type": "string" + }, + "objs_bot_profile": { + "additionalProperties": false, + "properties": { + "app_id": { + "$ref": "#/definitions/defs_app_id" + }, + "deleted": { + "type": "boolean" + }, + "icons": { + "additionalProperties": false, + "properties": { + "image_36": { + "format": "uri", + "type": "string" + }, + "image_48": { + "format": "uri", + "type": "string" + }, + "image_72": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "image_36", + "image_48", + "image_72" + ], + "type": "object" + }, + "id": { + "$ref": "#/definitions/defs_bot_id" + }, + "name": { + "type": "string" + }, + "team_id": { + "$ref": "#/definitions/defs_team" + }, + "updated": { + "type": "integer" + } + }, + "required": [ + "id", + "deleted", + "name", + "updated", + "app_id", + "icons", + "team_id" + ], + "title": "Bot Profile Object", + "type": "object" + }, + "objs_channel": { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "created": { + "type": "integer" + }, + "creator": { + "$ref": "#/definitions/defs_user_id" + }, + "id": { + "$ref": "#/definitions/defs_channel_id" + }, + "is_archived": { + "type": "boolean" + }, + "is_channel": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_general": { + "type": "boolean" + }, + "is_member": { + "type": "boolean" + }, + "is_moved": { + "type": "integer" + }, + "is_mpim": { + "type": "boolean" + }, + "is_non_threadable": { + "type": "boolean" + }, + "is_org_shared": { + "type": "boolean" + }, + "is_pending_ext_shared": { + "type": "boolean" + }, + "is_private": { + "type": "boolean" + }, + "is_read_only": { + "type": "boolean" + }, + "is_shared": { + "type": "boolean" + }, + "is_thread_only": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "items": [ + { + "$ref": "#/definitions/objs_message" + }, + { + "type": "null" + } + ] + }, + "members": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "name": { + "type": "string" + }, + "name_normalized": { + "type": "string" + }, + "num_members": { + "type": "integer" + }, + "pending_shared": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "previous_names": { + "items": { + "$ref": "#/definitions/defs_channel_name" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "priority": { + "type": "number" + }, + "purpose": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "creator", + "last_set" + ], + "type": "object" + }, + "topic": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "creator", + "last_set" + ], + "type": "object" + }, + "unlinked": { + "title": "Field to determine whether a channel has ever been shared/disconnected in the past", + "type": "integer" + }, + "unread_count": { + "type": "integer" + }, + "unread_count_display": { + "type": "integer" + } + }, + "required": [ + "id", + "name", + "created", + "creator", + "is_channel", + "is_org_shared", + "is_private", + "is_mpim", + "is_shared", + "name_normalized", + "members", + "topic", + "purpose" + ], + "title": "Channel Object", + "type": "object" + }, + "objs_comment": { + "additionalProperties": false, + "properties": { + "comment": { + "type": "string" + }, + "created": { + "type": "integer" + }, + "id": { + "$ref": "#/definitions/defs_comment_id" + }, + "is_intro": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "num_stars": { + "type": "integer" + }, + "pinned_info": { + "$ref": "#/definitions/defs_pinned_info" + }, + "pinned_to": { + "items": { + "$ref": "#/definitions/defs_channel" + }, + "type": "array" + }, + "reactions": { + "items": { + "$ref": "#/definitions/objs_reaction" + }, + "type": "array" + }, + "timestamp": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": [ + "id", + "created", + "timestamp", + "user", + "is_intro", + "comment" + ], + "title": "File Comment Object", + "type": "object" + }, + "objs_comments": { + "items": {}, + "title": "file comments object", + "type": "array" + }, + "objs_conversation": { + "items": [ + { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "connected_team_ids": { + "items": { + "$ref": "#/definitions/defs_workspace_id" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "conversation_host_id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "created": { + "type": "integer" + }, + "creator": { + "$ref": "#/definitions/defs_user_id" + }, + "display_counts": { + "additionalProperties": false, + "properties": { + "display_counts": { + "type": "integer" + }, + "guest_counts": { + "type": "integer" + } + }, + "required": [ + "display_counts", + "guest_counts" + ], + "type": "object" + }, + "enterprise_id": { + "$ref": "#/definitions/defs_enterprise_id" + }, + "has_pins": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_channel" + }, + "internal_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "is_archived": { + "type": "boolean" + }, + "is_channel": { + "type": "boolean" + }, + "is_ext_shared": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_general": { + "type": "boolean" + }, + "is_global_shared": { + "type": "boolean" + }, + "is_group": { + "type": "boolean" + }, + "is_im": { + "type": "boolean" + }, + "is_member": { + "type": "boolean" + }, + "is_moved": { + "type": "integer" + }, + "is_mpim": { + "enum": [ + false + ], + "type": "boolean" + }, + "is_non_threadable": { + "type": "boolean" + }, + "is_open": { + "type": "boolean" + }, + "is_org_default": { + "type": "boolean" + }, + "is_org_mandatory": { + "type": "boolean" + }, + "is_org_shared": { + "type": "boolean" + }, + "is_pending_ext_shared": { + "type": "boolean" + }, + "is_private": { + "type": "boolean" + }, + "is_read_only": { + "type": "boolean" + }, + "is_shared": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "is_thread_only": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "items": [ + { + "$ref": "#/definitions/objs_message" + }, + { + "type": "null" + } + ] + }, + "members": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "name": { + "type": "string" + }, + "name_normalized": { + "type": "string" + }, + "num_members": { + "type": "integer" + }, + "parent_conversation": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "type": "null" + } + ] + }, + "pending_connected_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "pending_shared": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "pin_count": { + "type": "integer" + }, + "previous_names": { + "items": { + "$ref": "#/definitions/defs_channel_name" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "priority": { + "type": "number" + }, + "purpose": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "creator", + "last_set" + ], + "type": "object" + }, + "shared_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "shares": { + "items": { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "is_active": { + "type": "boolean" + }, + "team": { + "$ref": "#/definitions/objs_team" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": [ + "team", + "user", + "is_active" + ], + "type": "object" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "timezone_count": { + "type": "integer" + }, + "topic": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "creator", + "last_set" + ], + "type": "object" + }, + "unlinked": { + "title": "Field to determine whether a channel has ever been shared/disconnected in the past", + "type": "integer" + }, + "unread_count": { + "type": "integer" + }, + "unread_count_display": { + "type": "integer" + }, + "use_case": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "name", + "created", + "creator", + "is_archived", + "is_channel", + "is_general", + "is_mpim", + "is_group", + "is_org_shared", + "is_im", + "is_shared", + "is_private", + "name_normalized", + "topic", + "purpose" + ], + "title": "Conversation object", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "connected_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "conversation_host_id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "created": { + "type": "integer" + }, + "creator": { + "$ref": "#/definitions/defs_user_id" + }, + "display_counts": { + "additionalProperties": false, + "properties": { + "display_counts": { + "type": "integer" + }, + "guest_counts": { + "type": "integer" + } + }, + "required": [ + "display_counts", + "guest_counts" + ], + "type": "object" + }, + "id": { + "$ref": "#/definitions/defs_channel" + }, + "internal_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "is_archived": { + "type": "boolean" + }, + "is_channel": { + "type": "boolean" + }, + "is_ext_shared": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_general": { + "type": "boolean" + }, + "is_group": { + "type": "boolean" + }, + "is_im": { + "type": "boolean" + }, + "is_member": { + "type": "boolean" + }, + "is_moved": { + "type": "integer" + }, + "is_mpim": { + "enum": [ + true + ], + "type": "boolean" + }, + "is_non_threadable": { + "type": "boolean" + }, + "is_open": { + "type": "boolean" + }, + "is_org_shared": { + "type": "boolean" + }, + "is_pending_ext_shared": { + "type": "boolean" + }, + "is_private": { + "type": "boolean" + }, + "is_read_only": { + "type": "boolean" + }, + "is_shared": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "is_thread_only": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "items": [ + { + "$ref": "#/definitions/objs_message" + }, + { + "type": "null" + } + ] + }, + "members": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "name": { + "type": "string" + }, + "name_normalized": { + "type": "string" + }, + "num_members": { + "type": "integer" + }, + "parent_conversation": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "type": "null" + } + ] + }, + "pending_connected_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "pending_shared": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "pin_count": { + "type": "integer" + }, + "previous_names": { + "items": { + "$ref": "#/definitions/defs_channel_name" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "priority": { + "type": "number" + }, + "purpose": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "creator", + "last_set" + ], + "type": "object" + }, + "shared_team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "shares": { + "items": { + "additionalProperties": false, + "properties": { + "accepted_user": { + "$ref": "#/definitions/defs_user_id" + }, + "is_active": { + "type": "boolean" + }, + "team": { + "$ref": "#/definitions/objs_team" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": [ + "team", + "user", + "is_active" + ], + "type": "object" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "timezone_count": { + "type": "integer" + }, + "topic": { + "additionalProperties": false, + "properties": { + "creator": { + "$ref": "#/definitions/defs_topic_purpose_creator" + }, + "last_set": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value", + "creator", + "last_set" + ], + "type": "object" + }, + "unlinked": { + "title": "Field to determine whether a channel has ever been shared/disconnected in the past", + "type": "integer" + }, + "unread_count": { + "type": "integer" + }, + "unread_count_display": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "name", + "created", + "creator", + "is_archived", + "is_channel", + "is_general", + "is_mpim", + "is_group", + "is_org_shared", + "is_im", + "is_shared", + "is_private", + "name_normalized", + "topic", + "purpose" + ], + "title": "Conversation MPIM Object", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "created": { + "type": "integer" + }, + "has_pins": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_dm_id" + }, + "is_archived": { + "type": "boolean" + }, + "is_ext_shared": { + "type": "boolean" + }, + "is_frozen": { + "type": "boolean" + }, + "is_im": { + "type": "boolean" + }, + "is_open": { + "type": "boolean" + }, + "is_org_shared": { + "type": "boolean" + }, + "is_shared": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "is_user_deleted": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "items": [ + { + "$ref": "#/definitions/objs_message" + }, + { + "type": "null" + } + ] + }, + "parent_conversation": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "type": "null" + } + ] + }, + "pin_count": { + "type": "integer" + }, + "priority": { + "type": "number" + }, + "shares": { + "items": { + "additionalProperties": false, + "properties": { + "date_create": { + "type": "integer" + }, + "id": { + "$ref": "#/definitions/defs_team" + }, + "is_active": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/objs_team" + } + }, + "required": [ + "id", + "name", + "team", + "date_create", + "is_active" + ], + "type": "object" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "unread_count": { + "type": "integer" + }, + "unread_count_display": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "version": { + "type": "integer" + } + }, + "required": [ + "id", + "created", + "is_im", + "is_org_shared", + "user", + "priority" + ], + "title": "Conversation IM Channel Object from conversations.* methods", + "type": "object" + } + ] + }, + "objs_enterprise_user": { + "additionalProperties": false, + "properties": { + "enterprise_id": { + "$ref": "#/definitions/defs_enterprise_id" + }, + "enterprise_name": { + "$ref": "#/definitions/defs_enterprise_name" + }, + "id": { + "$ref": "#/definitions/defs_enterprise_user_id" + }, + "is_admin": { + "type": "boolean" + }, + "is_owner": { + "type": "boolean" + }, + "teams": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "id", + "enterprise_id", + "enterprise_name", + "is_admin", + "is_owner", + "teams" + ], + "type": "object" + }, + "objs_external_org_migrations": { + "properties": { + "current": { + "items": { + "properties": { + "date_started": { + "type": "integer" + }, + "team_id": { + "type": "string" + } + }, + "required": [ + "team_id", + "date_started" + ], + "type": "object" + }, + "type": "array" + }, + "date_updated": { + "type": "integer" + } + }, + "required": [ + "date_updated", + "current" + ], + "title": "External Org Migrations", + "type": "object" + }, + "objs_file": { + "additionalProperties": false, + "properties": { + "channels": { + "items": { + "$ref": "#/definitions/defs_channel_id" + }, + "type": "array", + "uniqueItems": true + }, + "comments_count": { + "type": "integer" + }, + "created": { + "type": "integer" + }, + "date_delete": { + "type": "integer" + }, + "display_as_bot": { + "type": "boolean" + }, + "editable": { + "type": "boolean" + }, + "editor": { + "$ref": "#/definitions/defs_user_id" + }, + "external_id": { + "type": "string" + }, + "external_type": { + "type": "string" + }, + "external_url": { + "format": "uri", + "type": "string" + }, + "filetype": { + "type": "string" + }, + "groups": { + "items": { + "$ref": "#/definitions/defs_group_id" + }, + "type": "array", + "uniqueItems": true + }, + "has_rich_preview": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_file_id" + }, + "image_exif_rotation": { + "type": "integer" + }, + "ims": { + "items": { + "$ref": "#/definitions/defs_dm_id" + }, + "type": "array", + "uniqueItems": true + }, + "is_external": { + "type": "boolean" + }, + "is_public": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "is_tombstoned": { + "type": "boolean" + }, + "last_editor": { + "$ref": "#/definitions/defs_user_id" + }, + "mimetype": { + "type": "string" + }, + "mode": { + "type": "string" + }, + "name": { + "type": "string" + }, + "non_owner_editable": { + "type": "boolean" + }, + "num_stars": { + "type": "integer" + }, + "original_h": { + "type": "integer" + }, + "original_w": { + "type": "integer" + }, + "permalink": { + "format": "uri", + "type": "string" + }, + "permalink_public": { + "format": "uri", + "type": "string" + }, + "pinned_info": { + "$ref": "#/definitions/defs_pinned_info" + }, + "pinned_to": { + "items": { + "$ref": "#/definitions/defs_channel" + }, + "type": "array" + }, + "pretty_type": { + "type": "string" + }, + "preview": { + "type": "string" + }, + "public_url_shared": { + "type": "boolean" + }, + "reactions": { + "items": { + "$ref": "#/definitions/objs_reaction" + }, + "type": "array" + }, + "shares": { + "additionalProperties": false, + "properties": { + "private": { + "additionalProperties": false + }, + "public": { + "additionalProperties": false + } + }, + "type": "object" + }, + "size": { + "type": "integer" + }, + "source_team": { + "$ref": "#/definitions/defs_team" + }, + "state": { + "type": "string" + }, + "thumb_1024": { + "format": "uri", + "type": "string" + }, + "thumb_1024_h": { + "type": "integer" + }, + "thumb_1024_w": { + "type": "integer" + }, + "thumb_160": { + "format": "uri", + "type": "string" + }, + "thumb_360": { + "format": "uri", + "type": "string" + }, + "thumb_360_h": { + "type": "integer" + }, + "thumb_360_w": { + "type": "integer" + }, + "thumb_480": { + "format": "uri", + "type": "string" + }, + "thumb_480_h": { + "type": "integer" + }, + "thumb_480_w": { + "type": "integer" + }, + "thumb_64": { + "format": "uri", + "type": "string" + }, + "thumb_720": { + "format": "uri", + "type": "string" + }, + "thumb_720_h": { + "type": "integer" + }, + "thumb_720_w": { + "type": "integer" + }, + "thumb_80": { + "format": "uri", + "type": "string" + }, + "thumb_800": { + "format": "uri", + "type": "string" + }, + "thumb_800_h": { + "type": "integer" + }, + "thumb_800_w": { + "type": "integer" + }, + "thumb_960": { + "format": "uri", + "type": "string" + }, + "thumb_960_h": { + "type": "integer" + }, + "thumb_960_w": { + "type": "integer" + }, + "thumb_tiny": { + "type": "string" + }, + "timestamp": { + "type": "integer" + }, + "title": { + "type": "string" + }, + "updated": { + "type": "integer" + }, + "url_private": { + "format": "uri", + "type": "string" + }, + "url_private_download": { + "format": "uri", + "type": "string" + }, + "user": { + "type": "string" + }, + "user_team": { + "$ref": "#/definitions/defs_team" + }, + "username": { + "type": "string" + } + }, + "title": "file object", + "type": "object" + }, + "objs_icon": { + "properties": { + "image_102": { + "type": "string" + }, + "image_132": { + "type": "string" + }, + "image_230": { + "type": "string" + }, + "image_34": { + "type": "string" + }, + "image_44": { + "type": "string" + }, + "image_68": { + "type": "string" + }, + "image_88": { + "type": "string" + }, + "image_default": { + "type": "boolean" + } + }, + "type": "object" + }, + "objs_message": { + "additionalProperties": false, + "properties": { + "attachments": { + "items": { + "additionalProperties": false, + "properties": { + "fallback": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "image_bytes": { + "type": "integer" + }, + "image_height": { + "type": "integer" + }, + "image_url": { + "type": "string" + }, + "image_width": { + "type": "integer" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "blocks": { + "$ref": "#/definitions/blocks" + }, + "bot_id": { + "items": [ + { + "$ref": "#/definitions/defs_bot_id" + }, + { + "title": "Nil bot_id set when display_as_bot is false", + "type": "null" + } + ] + }, + "bot_profile": { + "$ref": "#/definitions/objs_bot_profile" + }, + "client_msg_id": { + "type": "string" + }, + "comment": { + "$ref": "#/definitions/objs_comment" + }, + "display_as_bot": { + "type": "boolean" + }, + "file": { + "$ref": "#/definitions/objs_file" + }, + "files": { + "items": { + "$ref": "#/definitions/objs_file" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "icons": { + "additionalProperties": false, + "properties": { + "emoji": { + "type": "string" + }, + "image_64": { + "format": "uri", + "type": "string" + } + }, + "type": "object" + }, + "inviter": { + "$ref": "#/definitions/defs_user_id" + }, + "is_delayed_message": { + "type": "boolean" + }, + "is_intro": { + "type": "boolean" + }, + "is_starred": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest_reply": { + "$ref": "#/definitions/defs_ts" + }, + "name": { + "type": "string" + }, + "old_name": { + "type": "string" + }, + "parent_user_id": { + "$ref": "#/definitions/defs_user_id" + }, + "permalink": { + "format": "uri", + "type": "string" + }, + "pinned_to": { + "items": { + "$ref": "#/definitions/defs_channel" + }, + "type": "array" + }, + "purpose": { + "type": "string" + }, + "reactions": { + "items": { + "$ref": "#/definitions/objs_reaction" + }, + "type": "array" + }, + "reply_count": { + "type": "integer" + }, + "reply_users": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "reply_users_count": { + "type": "integer" + }, + "source_team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "subscribed": { + "type": "boolean" + }, + "subtype": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "text": { + "type": "string" + }, + "thread_ts": { + "$ref": "#/definitions/defs_ts" + }, + "topic": { + "type": "string" + }, + "ts": { + "$ref": "#/definitions/defs_ts" + }, + "type": { + "type": "string" + }, + "unread_count": { + "type": "integer" + }, + "upload": { + "type": "boolean" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "user_profile": { + "$ref": "#/definitions/objs_user_profile_short" + }, + "user_team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "username": { + "type": "string" + } + }, + "required": [ + "text", + "type", + "ts" + ], + "title": "Message object", + "type": "object" + }, + "objs_paging": { + "additionalProperties": false, + "properties": { + "count": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "pages": { + "type": "integer" + }, + "per_page": { + "type": "integer" + }, + "spill": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "required": [ + "page", + "total" + ], + "title": "paging object", + "type": "object" + }, + "objs_primary_owner": { + "properties": { + "email": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "required": [ + "id", + "email" + ], + "type": "object" + }, + "objs_reaction": { + "additionalProperties": true, + "properties": { + "count": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "users": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "type": "array" + } + }, + "required": [ + "name", + "users", + "count" + ], + "title": "Reaction object", + "type": "object" + }, + "objs_reminder": { + "additionalProperties": false, + "properties": { + "complete_ts": { + "type": "integer" + }, + "creator": { + "$ref": "#/definitions/defs_user_id" + }, + "id": { + "$ref": "#/definitions/defs_reminder_id" + }, + "recurring": { + "type": "boolean" + }, + "text": { + "type": "string" + }, + "time": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": [ + "id", + "creator", + "user", + "text", + "recurring" + ], + "type": "object" + }, + "objs_resources": { + "additionalProperties": false, + "properties": { + "excluded_ids": { + "items": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "$ref": "#/definitions/defs_team" + } + ] + }, + "type": "array" + }, + "ids": { + "items": { + "items": [ + { + "$ref": "#/definitions/defs_channel" + }, + { + "$ref": "#/definitions/defs_team" + } + ] + }, + "type": "array" + }, + "wildcard": { + "type": "boolean" + } + }, + "required": [ + "ids" + ], + "title": "resources in info from apps.permissions.info", + "type": "object" + }, + "objs_response_metadata": { + "items": [ + { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string" + } + }, + "required": [ + "next_cursor" + ], + "title": "new paging style", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "messages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "warnings": { + "items": { + "enum": [ + "method_deprecated" + ], + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "messages", + "warnings" + ], + "title": "deprecation_warning", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "messages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "next_cursor": { + "type": "string" + }, + "warnings": { + "items": { + "enum": [ + "method_deprecated" + ], + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "messages", + "warnings", + "next_cursor" + ], + "title": "deprecation_warning and paging style together", + "type": "object" + } + ] + }, + "objs_scopes": { + "items": { + "title": "Named OAuth scopes", + "type": "string", + "x-examples": [ + "chat:write", + "im:history", + "im:read" + ] + }, + "type": "array" + }, + "objs_subteam": { + "additionalProperties": false, + "properties": { + "auto_provision": { + "type": "boolean" + }, + "auto_type": { + "items": [ + { + "type": "null" + }, + { + "enum": [ + "owner", + "admin" + ], + "type": "string" + } + ] + }, + "channel_count": { + "type": "integer" + }, + "created_by": { + "$ref": "#/definitions/defs_user_id" + }, + "date_create": { + "type": "integer" + }, + "date_delete": { + "type": "integer" + }, + "date_update": { + "type": "integer" + }, + "deleted_by": { + "items": [ + { + "type": "null" + }, + { + "$ref": "#/definitions/defs_user_id" + } + ] + }, + "description": { + "type": "string" + }, + "enterprise_subteam_id": { + "type": "string" + }, + "handle": { + "type": "string" + }, + "id": { + "$ref": "#/definitions/defs_subteam_id" + }, + "is_external": { + "type": "boolean" + }, + "is_subteam": { + "type": "boolean" + }, + "is_usergroup": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "prefs": { + "additionalProperties": false, + "properties": { + "channels": { + "items": { + "$ref": "#/definitions/defs_channel_id" + }, + "type": "array" + }, + "groups": { + "items": { + "$ref": "#/definitions/defs_group_id" + }, + "type": "array" + } + }, + "required": [ + "channels", + "groups" + ], + "type": "object" + }, + "team_id": { + "$ref": "#/definitions/defs_team" + }, + "updated_by": { + "$ref": "#/definitions/defs_user_id" + }, + "user_count": { + "type": "integer" + }, + "users": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "type": "array" + } + }, + "required": [ + "id", + "team_id", + "is_usergroup", + "is_subteam", + "name", + "description", + "handle", + "is_external", + "date_create", + "date_update", + "date_delete", + "auto_type", + "auto_provision", + "enterprise_subteam_id", + "created_by", + "updated_by", + "deleted_by", + "prefs" + ], + "title": "Subteam/Usergroup Object", + "type": "object" + }, + "objs_team": { + "additionalProperties": false, + "properties": { + "archived": { + "type": "boolean" + }, + "avatar_base_url": { + "format": "uri", + "type": "string" + }, + "created": { + "type": "integer" + }, + "date_create": { + "type": "integer" + }, + "deleted": { + "type": "boolean" + }, + "description": { + "type": [ + "null", + "string" + ] + }, + "discoverable": { + "items": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "domain": { + "type": "string" + }, + "email_domain": { + "type": "string" + }, + "enterprise_id": { + "$ref": "#/definitions/defs_enterprise_id" + }, + "enterprise_name": { + "$ref": "#/definitions/defs_enterprise_name" + }, + "external_org_migrations": { + "$ref": "#/definitions/objs_external_org_migrations" + }, + "has_compliance_export": { + "type": "boolean" + }, + "icon": { + "$ref": "#/definitions/objs_icon" + }, + "id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "is_assigned": { + "type": "boolean" + }, + "is_enterprise": { + "type": "integer" + }, + "is_over_storage_limit": { + "type": "boolean" + }, + "limit_ts": { + "type": "integer" + }, + "locale": { + "type": "string" + }, + "messages_count": { + "type": "integer" + }, + "msg_edit_window_mins": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "over_integrations_limit": { + "type": "boolean" + }, + "over_storage_limit": { + "type": "boolean" + }, + "pay_prod_cur": { + "type": "string" + }, + "plan": { + "enum": [ + "", + "std", + "plus", + "compliance", + "enterprise" + ], + "type": "string" + }, + "primary_owner": { + "$ref": "#/definitions/objs_primary_owner" + }, + "sso_provider": { + "properties": { + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "id", + "name", + "domain", + "email_domain", + "icon" + ], + "title": "Team Object", + "type": "object" + }, + "objs_team_profile_field": { + "additionalProperties": false, + "properties": { + "field_name": { + "type": [ + "null", + "string" + ] + }, + "hint": { + "type": "string" + }, + "id": { + "pattern": "^X[a-zA-Z0-9]{9,}$", + "type": "string" + }, + "is_hidden": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "options": { + "items": [ + { + "type": "null" + }, + { + "$ref": "#/definitions/objs_team_profile_field_option" + } + ] + }, + "ordering": { + "type": "number" + }, + "possible_values": { + "items": { + "type": "string" + }, + "type": [ + "null", + "array" + ] + }, + "type": { + "enum": [ + "text", + "date", + "link", + "mailto", + "options_list", + "user" + ], + "type": "string" + } + }, + "required": [ + "id", + "ordering", + "label", + "hint", + "type" + ], + "type": "object" + }, + "objs_team_profile_field_option": { + "additionalProperties": false, + "properties": { + "is_custom": { + "type": [ + "null", + "boolean" + ] + }, + "is_multiple_entry": { + "type": [ + "null", + "boolean" + ] + }, + "is_protected": { + "type": [ + "null", + "boolean" + ] + }, + "is_scim": { + "type": [ + "null", + "boolean" + ] + } + }, + "type": "object" + }, + "objs_user": { + "items": [ + { + "additionalProperties": false, + "description": "user object for non enterprise type", + "properties": { + "color": { + "pattern": "^[a-fA-F0-9]{6}$", + "type": "string" + }, + "deleted": { + "type": "boolean" + }, + "enterprise_user": { + "$ref": "#/definitions/objs_enterprise_user" + }, + "has_2fa": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "is_admin": { + "type": "boolean" + }, + "is_app_user": { + "type": "boolean" + }, + "is_bot": { + "type": "boolean" + }, + "is_external": { + "type": "boolean" + }, + "is_forgotten": { + "type": "boolean" + }, + "is_invited_user": { + "type": "boolean" + }, + "is_owner": { + "type": "boolean" + }, + "is_primary_owner": { + "type": "boolean" + }, + "is_restricted": { + "type": "boolean" + }, + "is_stranger": { + "type": "boolean" + }, + "is_ultra_restricted": { + "type": "boolean" + }, + "locale": { + "type": "string" + }, + "name": { + "type": "string" + }, + "presence": { + "type": "string" + }, + "profile": { + "$ref": "#/definitions/objs_user_profile" + }, + "real_name": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "team_id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "team_profile": { + "additionalProperties": false, + "properties": { + "fields": { + "items": { + "$ref": "#/definitions/objs_team_profile_field" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "fields" + ], + "type": "object" + }, + "two_factor_type": { + "type": "string" + }, + "tz": { + "items": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "tz_label": { + "type": "string" + }, + "tz_offset": { + "type": "number" + }, + "updated": { + "type": "number" + } + }, + "required": [ + "id", + "name", + "profile", + "is_bot", + "updated", + "is_app_user" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "enterprise user", + "properties": { + "color": { + "description": "refercing to bug: https://jira.tinyspeck.com/browse/EVALUE-1559", + "pattern": "^([a-fA-F0-9]{6})?$", + "type": "string" + }, + "deleted": { + "type": "boolean" + }, + "enterprise_user": { + "$ref": "#/definitions/objs_enterprise_user" + }, + "has_2fa": { + "type": "boolean" + }, + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "is_admin": { + "type": "boolean" + }, + "is_app_user": { + "type": "boolean" + }, + "is_bot": { + "type": "boolean" + }, + "is_external": { + "type": "boolean" + }, + "is_forgotten": { + "type": "boolean" + }, + "is_owner": { + "type": "boolean" + }, + "is_primary_owner": { + "type": "boolean" + }, + "is_restricted": { + "type": "boolean" + }, + "is_stranger": { + "type": "boolean" + }, + "is_ultra_restricted": { + "type": "boolean" + }, + "locale": { + "type": "string" + }, + "name": { + "type": "string" + }, + "presence": { + "type": "string" + }, + "profile": { + "$ref": "#/definitions/objs_user_profile" + }, + "real_name": { + "type": "string" + }, + "team_id": { + "$ref": "#/definitions/defs_workspace_id" + }, + "team_profile": { + "additionalProperties": false, + "properties": { + "fields": { + "items": { + "$ref": "#/definitions/objs_team_profile_field" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "fields" + ], + "type": "object" + }, + "teams": { + "items": { + "$ref": "#/definitions/defs_workspace_id" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "two_factor_type": { + "type": "string" + }, + "tz": { + "items": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "tz_label": { + "type": "string" + }, + "tz_offset": { + "type": "number" + }, + "updated": { + "type": "number" + } + }, + "required": [ + "id", + "name", + "profile", + "is_bot", + "updated", + "is_app_user" + ], + "type": "object" + } + ] + }, + "objs_user_profile": { + "additionalProperties": false, + "properties": { + "always_active": { + "type": "boolean" + }, + "api_app_id": { + "$ref": "#/definitions/defs_optional_app_id" + }, + "avatar_hash": { + "type": "string" + }, + "bot_id": { + "$ref": "#/definitions/defs_bot_id" + }, + "display_name": { + "type": "string" + }, + "display_name_normalized": { + "type": "string" + }, + "email": { + "format": "email", + "type": [ + "null", + "string" + ] + }, + "fields": { + "items": { + "type": "object" + }, + "type": [ + "object", + "null", + "array" + ] + }, + "first_name": { + "type": [ + "null", + "string" + ] + }, + "guest_expiration_ts": { + "type": [ + "null", + "integer" + ] + }, + "guest_invited_by": { + "type": [ + "null", + "string" + ] + }, + "image_1024": { + "format": "uri", + "type": [ + "null", + "string" + ] + }, + "image_192": { + "format": "uri", + "type": [ + "null", + "string" + ] + }, + "image_24": { + "format": "uri", + "type": [ + "null", + "string" + ] + }, + "image_32": { + "format": "uri", + "type": [ + "null", + "string" + ] + }, + "image_48": { + "format": "uri", + "type": [ + "null", + "string" + ] + }, + "image_512": { + "format": "uri", + "type": [ + "null", + "string" + ] + }, + "image_72": { + "format": "uri", + "type": [ + "null", + "string" + ] + }, + "image_original": { + "format": "uri", + "type": [ + "null", + "string" + ] + }, + "is_app_user": { + "type": "boolean" + }, + "is_custom_image": { + "type": "boolean" + }, + "is_restricted": { + "type": [ + "null", + "boolean" + ] + }, + "is_ultra_restricted": { + "type": [ + "null", + "boolean" + ] + }, + "last_avatar_image_hash": { + "type": "string" + }, + "last_name": { + "type": [ + "null", + "string" + ] + }, + "memberships_count": { + "type": "integer" + }, + "name": { + "type": [ + "null", + "string" + ] + }, + "phone": { + "type": "string" + }, + "pronouns": { + "type": "string" + }, + "real_name": { + "type": "string" + }, + "real_name_normalized": { + "type": "string" + }, + "skype": { + "type": "string" + }, + "status_default_emoji": { + "type": "string" + }, + "status_default_text": { + "type": "string" + }, + "status_default_text_canonical": { + "type": [ + "null", + "string" + ] + }, + "status_emoji": { + "type": "string" + }, + "status_expiration": { + "type": "integer" + }, + "status_text": { + "type": "string" + }, + "status_text_canonical": { + "type": [ + "null", + "string" + ] + }, + "team": { + "$ref": "#/definitions/defs_workspace_id" + }, + "title": { + "type": "string" + }, + "updated": { + "type": "integer" + }, + "user_id": { + "type": "string" + }, + "username": { + "type": [ + "null", + "string" + ] + } + }, + "required": [ + "real_name", + "display_name", + "avatar_hash", + "real_name_normalized", + "display_name_normalized", + "title", + "phone", + "skype", + "status_text", + "status_emoji", + "fields" + ], + "title": "User profile object", + "type": "object" + }, + "objs_user_profile_short": { + "additionalProperties": false, + "properties": { + "avatar_hash": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "display_name_normalized": { + "type": "string" + }, + "first_name": { + "type": [ + "string", + "null" + ] + }, + "image_72": { + "format": "uri", + "type": "string" + }, + "is_restricted": { + "type": "boolean" + }, + "is_ultra_restricted": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "real_name": { + "type": "string" + }, + "real_name_normalized": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/defs_workspace_id" + } + }, + "required": [ + "avatar_hash", + "image_72", + "first_name", + "real_name", + "display_name", + "team", + "name", + "is_restricted", + "is_ultra_restricted" + ], + "type": "object" + } + }, + "externalDocs": { + "description": "Learn more about the Slack Web API", + "url": "https://api.slack.com/web" + }, + "host": "slack.com", + "info": { + "contact": { + "name": "Slack developer relations", + "url": "https://api.slack.com/support" + }, + "description": "One way to interact with the Slack platform is its HTTP RPC-based Web API, a collection of methods requiring OAuth 2.0-based user, bot, or workspace tokens blessed with related OAuth scopes.", + "title": "Slack Web API", + "version": "1.7.0" + }, + "paths": { + "/admin.apps.approve": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Approve an app for installation on a workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.apps.approve" + }, + "operationId": "admin_apps_approve", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.apps:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The id of the app to approve.", + "in": "formData", + "name": "app_id", + "type": "string" + }, + { + "description": "The id of the request to approve.", + "in": "formData", + "name": "request_id", + "type": "string" + }, + { + "in": "formData", + "name": "team_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.apps:write" + ] + } + ], + "tags": [ + "admin.apps", + "admin" + ] + } + }, + "/admin.apps.approved.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List approved apps for an org or workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.apps.approved.list" + }, + "operationId": "admin_apps_approved_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.apps:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The maximum number of items to return. Must be between 1 - 1000 both inclusive.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "in": "query", + "name": "team_id", + "type": "string" + }, + { + "in": "query", + "name": "enterprise_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "approved_apps": [ + { + "app": { + "additional_info": "", + "app_directory_url": "https://myteam.enterprise.slack.com/apps/A0W7UKG8E-my-test-app", + "app_homepage_url": "https://www.slack.com", + "description": "test app", + "help_url": "https://www.slack.com", + "icons": { + "image_1024": "https://3026743124446w96_2bd4ea1ad1f89a23c242_1024.png", + "image_128": "https://30267341249446w6_2bd4ea1ad1f89a23c242_128.png", + "image_192": "https://30267431249446w6_2bd4ea1ad1f89a23c242_192.png", + "image_32": "https://302674312496446w_2bd4ea1ad1f89a23c242_32.png", + "image_36": "https://302674312496446w_2bd4ea1ad1f89a23c242_36.png", + "image_48": "https://302674312496446w_2bd4ea1ad1f89a23c242_48.png", + "image_512": "https://30267431249446w6_2bd4ea1ad1f89a23c242_512.png", + "image_64": "https://302674312496446w_2bd4ea1ad1f89a23c242_64.png", + "image_72": "https://302674312496446w_2bd4ea1ad1f89a23c242_72.png", + "image_96": "https://302674312496446w_2bd4ea1ad1f89a23c242_96.png", + "image_original": "https://302674446w12496_2bd4ea1ad1f89a23c242_original.png" + }, + "id": "A0W7UKG8E", + "is_app_directory_approved": false, + "is_internal": false, + "name": "My Test App", + "privacy_policy_url": "https://www.slack.com" + }, + "date_updated": 1574296707, + "last_resolved_by": { + "actor_id": "W0G82F4FD", + "actor_type": "user" + }, + "scopes": [ + { + "description": "Add the ability for people to direct message or mention @my_test_app", + "is_sensitive": true, + "name": "bot", + "token_type": "bot" + } + ] + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.apps:read" + ] + } + ], + "tags": [ + "admin.apps.approved", + "admin" + ] + } + }, + "/admin.apps.requests.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List app requests for a team/workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.apps.requests.list" + }, + "operationId": "admin_apps_requests_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.apps:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The maximum number of items to return. Must be between 1 - 1000 both inclusive.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "in": "query", + "name": "team_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "app_requests": [ + { + "app": { + "additional_info": "", + "app_directory_url": "https://acmecorp.slack.com/apps/A061BL8RQ0-test-app", + "app_homepage_url": "", + "description": "", + "help_url": "", + "icons": { + "image_1024": "/cdn/15258203/img/testapp/service_1024.png", + "image_128": "/cdn/157258203/img/testapp/service_128.png", + "image_192": "/cdn/157258203/img/testapp/service_192.png", + "image_32": "/cdn/157658203/img/testapp/service_32.png", + "image_36": "/cdn/157658203/img/testapp/service_36.png", + "image_48": "/cdn/157658203/img/testapp/service_48.png", + "image_512": "/cdn/15758203/img/testapp/service_512.png", + "image_64": "/cdn/157658203/img/testapp/service_64.png", + "image_72": "/cdn/157658203/img/testapp/service_72.png", + "image_96": "/cdn/157658203/img/testapp/service_96.png" + }, + "id": "A061BL8RQ0", + "is_app_directory_approved": true, + "is_internal": false, + "name": "Test App", + "privacy_policy_url": "https://testapp.com/privacy" + }, + "date_created": 1578956327, + "id": "Ar0XJGFLMLS", + "message": "test test again", + "previous_resolution": null, + "scopes": [ + { + "description": "Post messages to specific channels in Slack", + "is_sensitive": false, + "name": "incoming-webhook", + "token_type": "user" + } + ], + "team": { + "domain": "acmecorp", + "id": "T0M94LNUCR", + "name": "Acme Corp" + }, + "user": { + "email": "janedoe@example.com", + "id": "W08RA9G5HR", + "name": "Jane Doe" + } + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "missing_scope", + "needed": "admin.apps:read", + "ok": false, + "provided": "read,client,admin,identify,post,apps" + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.apps:read" + ] + } + ], + "tags": [ + "admin.apps.requests", + "admin" + ] + } + }, + "/admin.apps.restrict": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Restrict an app for installation on a workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.apps.restrict" + }, + "operationId": "admin_apps_restrict", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.apps:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The id of the app to restrict.", + "in": "formData", + "name": "app_id", + "type": "string" + }, + { + "description": "The id of the request to restrict.", + "in": "formData", + "name": "request_id", + "type": "string" + }, + { + "in": "formData", + "name": "team_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.apps:write" + ] + } + ], + "tags": [ + "admin.apps", + "admin" + ] + } + }, + "/admin.apps.restricted.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List restricted apps for an org or workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.apps.restricted.list" + }, + "operationId": "admin_apps_restricted_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.apps:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The maximum number of items to return. Must be between 1 - 1000 both inclusive.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "in": "query", + "name": "team_id", + "type": "string" + }, + { + "in": "query", + "name": "enterprise_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "response_metadata": { + "next_cursor": "" + }, + "restricted_apps": [ + { + "app": { + "additional_info": "", + "app_directory_url": "https://myteam.enterprise.slack.com/apps/A0FDLP8M2L-my-test-app", + "app_homepage_url": "https://example.com", + "description": "A fun test app for Slack", + "help_url": "https://example.com", + "icons": { + "image_1024": "https://1433265338rl878408_eb57dbc818daa4ba15d6_1024.png", + "image_128": "https://4332653438rl87808_eb57dbc818daa4ba15d6_128.png", + "image_192": "https://4332653438rl87808_eb57dbc818daa4ba15d6_192.png", + "image_32": "https://143326534038rl8788_eb57dbc818daa4ba15d6_32.png", + "image_36": "https://143326534038rl8788_eb57dbc818daa4ba15d6_36.png", + "image_48": "https://143326534038rl8788_eb57dbc818daa4ba15d6_48.png", + "image_512": "https://4332653438rl87808_eb57dbc818daa4ba15d6_512.png", + "image_64": "https://143326534038rl8788_eb57dbc818daa4ba15d6_64.png", + "image_72": "https://143326534038rl8788_eb57dbc818daa4ba15d6_72.png", + "image_96": "https://143326534038rl8788_eb57dbc818daa4ba15d6_96.png", + "image_original": "https://143338rl8782653408_eb57dbc818daa4ba15d6_original.png" + }, + "id": "A0FDLP8M2L", + "is_app_directory_approved": true, + "is_internal": false, + "name": "My Test App", + "privacy_policy_url": "https://example.com" + }, + "date_updated": 1574296721, + "last_resolved_by": { + "actor_id": "W0G82LMFD", + "actor_type": "user" + }, + "scopes": [ + { + "description": "Upload, edit, and delete files on the user\u201fs behalf", + "is_sensitive": true, + "name": "files:write:user", + "token_type": "user" + } + ] + } + ] + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.apps:read" + ] + } + ], + "tags": [ + "admin.apps.restricted", + "admin" + ] + } + }, + "/admin.conversations.archive": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Archive a public or private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.archive" + }, + "operationId": "admin_conversations_archive", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to archive.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.archive", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.archive schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.archive", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "channel_not_found", + "channel_type_not_supported", + "default_org_wide_channel", + "already_archived", + "cant_archive_general", + "restricted_action", + "could_not_archive_channel" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.archive error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.convertToPrivate": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Convert a public channel to a private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.convertToPrivate" + }, + "operationId": "admin_conversations_convertToPrivate", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to convert to private.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.convertToPrivate", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.convertToPrivate schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.convertToPrivate", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "restricted_action", + "name_taken", + "channel_not_found", + "channel_type_not_supported", + "default_org_wide_channel", + "method_not_supported_for_channel_type", + "could_not_convert_channel", + "external_channel_migrating" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.convertToPrivate error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.create": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Create a public or private channel-based conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.create" + }, + "operationId": "admin_conversations_create", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Name of the public or private channel to create.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + }, + { + "description": "Description of the public or private channel to create.", + "in": "formData", + "name": "description", + "type": "string" + }, + { + "description": "When `true`, creates a private channel instead of a public channel", + "in": "formData", + "name": "is_private", + "required": true, + "type": "boolean" + }, + { + "description": "When `true`, the channel will be available org-wide. Note: if the channel is not `org_wide=true`, you must specify a `team_id` for this channel", + "in": "formData", + "name": "org_wide", + "type": "boolean" + }, + { + "description": "The workspace to create the channel in. Note: this argument is required unless you set `org_wide=true`.", + "in": "formData", + "name": "team_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel_id": "C12345", + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.create", + "properties": { + "channel_id": { + "$ref": "#/definitions/defs_channel_id" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.create schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.create", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "name_taken", + "restricted_action", + "team_not_found", + "invalid_team", + "invalid_name", + "could_not_create_channel", + "team_id_or_org_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.create error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.delete": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Delete a public or private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.delete" + }, + "operationId": "admin_conversations_delete", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to delete.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.delete", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.delete schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.delete", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "not_an_admin", + "channel_not_found", + "channel_type_not_supported", + "default_org_wide_channel", + "restricted_action", + "could_not_delete_channel", + "missing_scope" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.delete error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.disconnectShared": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Disconnect a connected channel from one or more workspaces.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.disconnectShared" + }, + "operationId": "admin_conversations_disconnectShared", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to be disconnected from some workspaces.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + }, + { + "description": "The team to be removed from the channel. Currently only a single team id can be specified.", + "in": "formData", + "name": "leaving_team_ids", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.disconnectShared", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.rename schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.disconnectShared", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "not_an_admin", + "not_an_enterprise", + "channel_not_found", + "not_supported", + "team_not_found", + "restricted_action", + "missing_scope", + "leaving_team_not_in_channel", + "no_teams_to_disconnect", + "leaving_team_required", + "cannot_kick_team", + "cannot_kick_home_team" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.disconnectShared error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.ekm.listOriginalConnectedChannelInfo": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List all disconnected channels\u2014i.e., channels that were once connected to other workspaces and then disconnected\u2014and the corresponding original channel IDs for key revocation with EKM.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.ekm.listOriginalConnectedChannelInfo" + }, + "operationId": "admin_conversations_ekm_listOriginalConnectedChannelInfo", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "A comma-separated list of channels to filter to.", + "in": "query", + "name": "channel_ids", + "type": "string" + }, + { + "description": "A comma-separated list of the workspaces to which the channels you would like returned belong.", + "in": "query", + "name": "team_ids", + "type": "string" + }, + { + "description": "The maximum number of items to return. Must be between 1 - 1000 both inclusive.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channels": [ + { + "id": "string", + "internal_team_ids": "array", + "original_connected_channel_id": "string", + "original_connected_host_id": "string" + } + ], + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:read" + ] + } + ], + "tags": [ + "admin.conversations.ekm", + "admin" + ] + } + }, + "/admin.conversations.getConversationPrefs": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Get conversation preferences for a public or private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.getConversationPrefs" + }, + "operationId": "admin_conversations_getConversationPrefs", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to get preferences for.", + "in": "query", + "name": "channel_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.getConversationPrefs", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "prefs": { + "properties": { + "can_thread": { + "properties": { + "type": { + "items": { + "type": "string" + }, + "type": "array" + }, + "user": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "who_can_post": { + "properties": { + "type": { + "items": { + "type": "string" + }, + "type": "array" + }, + "user": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.getConversationPrefs schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.getConversationPrefs", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "not_an_admin", + "not_an_enterprise", + "restricted_action", + "missing_scope", + "channel_not_found", + "channel_type_not_supported", + "could_not_get_conversation_prefs" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.unarchive error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:read" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.getTeams": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Get all the workspaces a given public or private channel is connected to within this Enterprise org.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.getTeams" + }, + "operationId": "admin_conversations_getTeams", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to determine connected workspaces within the organization for.", + "in": "query", + "name": "channel_id", + "required": true, + "type": "string" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The maximum number of items to return. Must be between 1 - 1000 both inclusive.", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "teams": [ + "T1234", + "T5678" + ] + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.getTeams", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "response_metadata": { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string" + } + }, + "required": [ + "next_cursor" + ], + "type": "object" + }, + "team_ids": { + "items": { + "$ref": "#/definitions/defs_team" + }, + "type": "array" + } + }, + "required": [ + "ok", + "team_ids" + ], + "title": "admin.conversations.getTeams schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.getTeams", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "channel_not_found", + "channel_type_not_supported", + "unsupported_team_type", + "restricted_action", + "could_not_get_teams", + "invalid_cursor", + "invalid_limit" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.getTeams error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:read" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.invite": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Invite a user to a public or private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.invite" + }, + "operationId": "admin_conversations_invite", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The users to invite.", + "in": "formData", + "name": "user_ids", + "required": true, + "type": "string" + }, + { + "description": "The channel that the users will be invited to.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.invite", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.invite schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "Schema for error response from admin.conversations.invite", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "channel_not_found", + "channel_type_not_supported", + "default_org_wide_channel", + "restricted_action", + "user_must_be_admin", + "failed_for_some_users" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.invite error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.rename": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Rename a public or private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.rename" + }, + "operationId": "admin_conversations_rename", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to rename.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + }, + { + "in": "formData", + "name": "name", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.rename", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.rename schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.rename", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "channel_not_found", + "channel_type_not_supported", + "restricted_action", + "could_not_rename_channel", + "default_org_wide_channel", + "name_taken" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.unarchive error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.restrictAccess.addGroup": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Add an allowlist of IDP groups for accessing a channel", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.restrictAccess.addGroup" + }, + "operationId": "admin_conversations_restrictAccess_addGroup", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The workspace where the channel exists. This argument is required for channels only tied to one workspace, and optional for channels that are shared across an organization.", + "in": "formData", + "name": "team_id", + "type": "string" + }, + { + "description": "The [IDP Group](https://slack.com/help/articles/115001435788-Connect-identity-provider-groups-to-your-Enterprise-Grid-org) ID to be an allowlist for the private channel.", + "in": "formData", + "name": "group_id", + "required": true, + "type": "string" + }, + { + "description": "The channel to link this group to.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations.restrictAccess", + "admin" + ] + } + }, + "/admin.conversations.restrictAccess.listGroups": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List all IDP Groups linked to a channel", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.restrictAccess.listGroups" + }, + "operationId": "admin_conversations_restrictAccess_listGroups", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "channel_id", + "required": true, + "type": "string" + }, + { + "description": "The workspace where the channel exists. This argument is required for channels only tied to one workspace, and optional for channels that are shared across an organization.", + "in": "query", + "name": "team_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "group_ids": [ + "YOUR_GROUP_ID" + ], + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:read" + ] + } + ], + "tags": [ + "admin.conversations.restrictAccess", + "admin" + ] + } + }, + "/admin.conversations.restrictAccess.removeGroup": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Remove a linked IDP group linked from a private channel", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.restrictAccess.removeGroup" + }, + "operationId": "admin_conversations_restrictAccess_removeGroup", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The workspace where the channel exists. This argument is required for channels only tied to one workspace, and optional for channels that are shared across an organization.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The [IDP Group](https://slack.com/help/articles/115001435788-Connect-identity-provider-groups-to-your-Enterprise-Grid-org) ID to remove from the private channel.", + "in": "formData", + "name": "group_id", + "required": true, + "type": "string" + }, + { + "description": "The channel to remove the linked group from.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations.restrictAccess", + "admin" + ] + } + }, + "/admin.conversations.search": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Search for public or private channels in an Enterprise organization.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.search" + }, + "operationId": "admin_conversations_search", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Comma separated string of team IDs, signifying the workspaces to search through.", + "in": "query", + "name": "team_ids", + "type": "string" + }, + { + "description": "Name of the the channel to query by.", + "in": "query", + "name": "query", + "type": "string" + }, + { + "description": "Maximum number of items to be returned. Must be between 1 - 20 both inclusive. Default is 10.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The type of channel to include or exclude in the search. For example `private` will search private channels, while `private_exclude` will exclude them. For a full list of types, check the [Types section](#types).", + "in": "query", + "name": "search_channel_types", + "type": "string" + }, + { + "description": "Possible values are `relevant` (search ranking based on what we think is closest), `name` (alphabetical), `member_count` (number of users in the channel), and `created` (date channel was created). You can optionally pair this with the `sort_dir` arg to change how it is sorted ", + "in": "query", + "name": "sort", + "type": "string" + }, + { + "description": "Sort direction. Possible values are `asc` for ascending order like (1, 2, 3) or (a, b, c), and `desc` for descending order like (3, 2, 1) or (c, b, a)", + "in": "query", + "name": "sort_dir", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channels": [ + { + "created": 1449252889, + "creator": "U012A3CDE", + "id": "C012AB3CD", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": true, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "general", + "name_normalized": "general", + "num_members": 4, + "pending_shared": [], + "previous_names": [], + "purpose": { + "creator": "", + "last_set": 0, + "value": "This channel is for team-wide communication and announcements. All team members are in this channel." + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "Company-wide announcements and work-based matters" + }, + "unlinked": 0 + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "dGVhbTpDMDYxRkE1UEI=" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.search", + "properties": { + "channels": { + "items": { + "$ref": "#/definitions/objs_channel" + }, + "type": "array" + }, + "next_cursor": { + "type": "string" + } + }, + "required": [ + "channels", + "next_cursor" + ], + "title": "admin.conversations.search schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "not_an_enterprise", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.search", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "not_an_admin", + "not_an_enterprise", + "team_not_found", + "not_allowed", + "invalid_auth", + "invalid_cursor", + "invalid_search_channel_type", + "invalid_sort", + "invalid_sort_dir" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.search error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:read" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.setConversationPrefs": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set the posting permissions for a public or private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.setConversationPrefs" + }, + "operationId": "admin_conversations_setConversationPrefs", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to set the prefs for", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + }, + { + "description": "The prefs for this channel in a stringified JSON format.", + "in": "formData", + "name": "prefs", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.setConversationPrefs", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.setConversationPrefs schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.setConversationPrefs", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "not_an_admin", + "channel_not_found", + "channel_type_not_supported", + "restricted_action", + "missing_scope", + "could_not_set_channel_pref", + "default_org_wide_channel" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.setConversationPrefs error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.setTeams": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set the workspaces in an Enterprise grid org that connect to a public or private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.setTeams" + }, + "operationId": "admin_conversations_setTeams", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The encoded `channel_id` to add or remove to workspaces.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + }, + { + "description": "The workspace to which the channel belongs. Omit this argument if the channel is a cross-workspace shared channel.", + "in": "formData", + "name": "team_id", + "type": "string" + }, + { + "description": "A comma-separated list of workspaces to which the channel should be shared. Not required if the channel is being shared org-wide.", + "in": "formData", + "name": "target_team_ids", + "type": "string" + }, + { + "description": "True if channel has to be converted to an org channel", + "in": "formData", + "name": "org_channel", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.conversations.unarchive": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Unarchive a public or private channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.conversations.unarchive" + }, + "operationId": "admin_conversations_unarchive", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.conversations:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The channel to unarchive.", + "in": "formData", + "name": "channel_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of admin.conversations.unarchive", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "admin.conversations.unarchive schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from admin.conversations.unarchive", + "properties": { + "error": { + "enum": [ + "feature_not_enabled", + "channel_not_found", + "channel_not_archived", + "channel_type_not_supported", + "restricted_action", + "could_not_unarchive_channel", + "default_org_wide_channel", + "missing_scope" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "admin.conversations.unarchive error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.conversations:write" + ] + } + ], + "tags": [ + "admin.conversations", + "admin" + ] + } + }, + "/admin.emoji.add": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Add an emoji.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.emoji.add" + }, + "operationId": "admin_emoji_add", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The name of the emoji to be removed. Colons (`:myemoji:`) around the value are not required, although they may be included.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + }, + { + "description": "The URL of a file to use as an image for the emoji. Square images under 128KB and with transparent backgrounds work best.", + "in": "formData", + "name": "url", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.emoji", + "admin" + ] + } + }, + "/admin.emoji.addAlias": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Add an emoji alias.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.emoji.addAlias" + }, + "operationId": "admin_emoji_addAlias", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The name of the emoji to be aliased. Colons (`:myemoji:`) around the value are not required, although they may be included.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + }, + { + "description": "The alias of the emoji.", + "in": "formData", + "name": "alias_for", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.emoji", + "admin" + ] + } + }, + "/admin.emoji.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List emoji for an Enterprise Grid organization.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.emoji.list" + }, + "operationId": "admin_emoji_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The maximum number of items to return. Must be between 1 - 1000 both inclusive.", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "cache_ts": "1575283387.000000", + "categories": [ + { + "emoji_names": [ + "grinning", + "grin", + "joy", + "etc etc ..." + ], + "name": "Smileys & People" + } + ], + "categories_version": "5", + "emoji": { + "black_square": "alias:black_large_square", + "bowtie": "https://emoji.slack-edge.com/T9TK3CUKW/bowtie/f3ec6f2bb0.png", + "cubimal_chick": "https://emoji.slack-edge.com/T9TK3CUKW/cubimal_chick/85961c43d7.png", + "dusty_stick": "https://emoji.slack-edge.com/T9TK3CUKW/dusty_stick/6177a62312.png", + "glitch_crab": "https://emoji.slack-edge.com/T9TK3CUKW/glitch_crab/db049f1f9c.png", + "piggy": "https://emoji.slack-edge.com/T9TK3CUKW/piggy/b7762ee8cd.png", + "pride": "https://emoji.slack-edge.com/T9TK3CUKW/pride/56b1bd3388.png", + "shipit": "alias:squirrel", + "simple_smile": { + "apple": "https://a.slack-edge.com/80588/img/emoji_2017_12_06/apple/simple_smile.png", + "google": "https://a.slack-edge.com/80588/img/emoji_2017_12_06/google/simple_smile.png" + }, + "slack": "https://emoji.slack-edge.com/T9TK3CUKW/slack/7d462d2443.png", + "slack_call": "https://emoji.slack-edge.com/T9TK3CUKW/slack_call/b81fffd6dd.png", + "squirrel": "https://emoji.slack-edge.com/T9TK3CUKW/squirrel/465f40c0e0.png", + "thumbsup_all": "https://emoji.slack-edge.com/T9TK3CUKW/thumbsup_all/50096a1020.gif", + "white_square": "alias:white_large_square" + }, + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:read" + ] + } + ], + "tags": [ + "admin.emoji", + "admin" + ] + } + }, + "/admin.emoji.remove": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Remove an emoji across an Enterprise Grid organization", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.emoji.remove" + }, + "operationId": "admin_emoji_remove", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The name of the emoji to be removed. Colons (`:myemoji:`) around the value are not required, although they may be included.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.emoji", + "admin" + ] + } + }, + "/admin.emoji.rename": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Rename an emoji.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.emoji.rename" + }, + "operationId": "admin_emoji_rename", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The name of the emoji to be renamed. Colons (`:myemoji:`) around the value are not required, although they may be included.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + }, + { + "description": "The new name of the emoji.", + "in": "formData", + "name": "new_name", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.emoji", + "admin" + ] + } + }, + "/admin.inviteRequests.approve": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Approve a workspace invite request.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.inviteRequests.approve" + }, + "operationId": "admin_inviteRequests_approve", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.invites:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace where the invite request was made.", + "in": "formData", + "name": "team_id", + "type": "string" + }, + { + "description": "ID of the request to invite.", + "in": "formData", + "name": "invite_request_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.invites:write" + ] + } + ], + "tags": [ + "admin.inviteRequests", + "admin" + ] + } + }, + "/admin.inviteRequests.approved.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "List all approved workspace invite requests.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.inviteRequests.approved.list" + }, + "operationId": "admin_inviteRequests_approved_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.invites:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace where the invite requests were made.", + "in": "query", + "name": "team_id", + "type": "string" + }, + { + "description": "Value of the `next_cursor` field sent as part of the previous API response", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The number of results that will be returned by the API on each invocation. Must be between 1 - 1000, both inclusive", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.invites:read" + ] + } + ], + "tags": [ + "admin.inviteRequests.approved", + "admin" + ] + } + }, + "/admin.inviteRequests.denied.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "List all denied workspace invite requests.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.inviteRequests.denied.list" + }, + "operationId": "admin_inviteRequests_denied_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.invites:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace where the invite requests were made.", + "in": "query", + "name": "team_id", + "type": "string" + }, + { + "description": "Value of the `next_cursor` field sent as part of the previous api response", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The number of results that will be returned by the API on each invocation. Must be between 1 - 1000 both inclusive", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.invites:read" + ] + } + ], + "tags": [ + "admin.inviteRequests.denied", + "admin" + ] + } + }, + "/admin.inviteRequests.deny": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Deny a workspace invite request.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.inviteRequests.deny" + }, + "operationId": "admin_inviteRequests_deny", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.invites:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace where the invite request was made.", + "in": "formData", + "name": "team_id", + "type": "string" + }, + { + "description": "ID of the request to invite.", + "in": "formData", + "name": "invite_request_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.invites:write" + ] + } + ], + "tags": [ + "admin.inviteRequests", + "admin" + ] + } + }, + "/admin.inviteRequests.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "List all pending workspace invite requests.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.inviteRequests.list" + }, + "operationId": "admin_inviteRequests_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.invites:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace where the invite requests were made.", + "in": "query", + "name": "team_id", + "type": "string" + }, + { + "description": "Value of the `next_cursor` field sent as part of the previous API response", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The number of results that will be returned by the API on each invocation. Must be between 1 - 1000, both inclusive", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.invites:read" + ] + } + ], + "tags": [ + "admin.inviteRequests", + "admin" + ] + } + }, + "/admin.teams.admins.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List all of the admins on a given workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.admins.list" + }, + "operationId": "admin_teams_admins_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The maximum number of items to return.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "in": "query", + "name": "team_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "admin_ids": [ + "U1234" + ], + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:read" + ] + } + ], + "tags": [ + "admin.teams.admins", + "admin" + ] + } + }, + "/admin.teams.create": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Create an Enterprise team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.create" + }, + "operationId": "admin_teams_create", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Team domain (for example, slacksoftballteam).", + "in": "formData", + "name": "team_domain", + "required": true, + "type": "string" + }, + { + "description": "Team name (for example, Slack Softball Team).", + "in": "formData", + "name": "team_name", + "required": true, + "type": "string" + }, + { + "description": "Description for the team.", + "in": "formData", + "name": "team_description", + "type": "string" + }, + { + "description": "Who can join the team. A team's discoverability can be `open`, `closed`, `invite_only`, or `unlisted`.", + "in": "formData", + "name": "team_discoverability", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "team": "T12345" + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.teams", + "admin" + ] + } + }, + "/admin.teams.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "List all teams on an Enterprise organization", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.list" + }, + "operationId": "admin_teams_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The maximum number of items to return. Must be between 1 - 100 both inclusive.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "teams": [ + { + "discoverability": "hidden", + "id": "T1234", + "name": "My Team", + "primary_owner": { + "email": "bront@slack.com", + "user_id": "W1234" + }, + "team_url": "https://subarachnoid.slack.com/" + } + ] + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:read" + ] + } + ], + "tags": [ + "admin.teams", + "admin" + ] + } + }, + "/admin.teams.owners.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List all of the owners on a given workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.owners.list" + }, + "operationId": "admin_teams_owners_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The maximum number of items to return. Must be between 1 - 1000 both inclusive.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "owner_ids": [ + "U1234" + ] + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:read" + ] + } + ], + "tags": [ + "admin.teams.owners", + "admin" + ] + } + }, + "/admin.teams.settings.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Fetch information about settings in a workspace", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.settings.info" + }, + "operationId": "admin_teams_settings_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "team_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "team": { + "default_channels": "array", + "domain": "string", + "email_domain": "string", + "enterprise_id": "string", + "enterprise_name": "string", + "icon": "array", + "id": "string", + "name": "string" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:read" + ] + } + ], + "tags": [ + "admin.teams.settings", + "admin" + ] + } + }, + "/admin.teams.settings.setDefaultChannels": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Set the default channels of a workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.settings.setDefaultChannels" + }, + "operationId": "admin_teams_settings_setDefaultChannels", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace to set the default channel for.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "An array of channel IDs.", + "in": "formData", + "name": "channel_ids", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.teams.settings", + "admin" + ] + } + }, + "/admin.teams.settings.setDescription": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set the description of a given workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.settings.setDescription" + }, + "operationId": "admin_teams_settings_setDescription", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace to set the description for.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The new description for the workspace.", + "in": "formData", + "name": "description", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.teams.settings", + "admin" + ] + } + }, + "/admin.teams.settings.setDiscoverability": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "An API method that allows admins to set the discoverability of a given workspace", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.settings.setDiscoverability" + }, + "operationId": "admin_teams_settings_setDiscoverability", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID of the workspace to set discoverability on.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "This workspace's discovery setting. It must be set to one of `open`, `invite_only`, `closed`, or `unlisted`.", + "in": "formData", + "name": "discoverability", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.teams.settings", + "admin" + ] + } + }, + "/admin.teams.settings.setIcon": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Sets the icon of a workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.settings.setIcon" + }, + "operationId": "admin_teams_settings_setIcon", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Image URL for the icon", + "in": "formData", + "name": "image_url", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace to set the icon for.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.teams.settings", + "admin" + ] + } + }, + "/admin.teams.settings.setName": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set the name of a given workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.teams.settings.setName" + }, + "operationId": "admin_teams_settings_setName", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID for the workspace to set the name for.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The new name of the workspace.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.teams.settings", + "admin" + ] + } + }, + "/admin.usergroups.addChannels": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Add one or more default channels to an IDP group.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.usergroups.addChannels" + }, + "operationId": "admin_usergroups_addChannels", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.usergroups:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID of the IDP group to add default channels for.", + "in": "formData", + "name": "usergroup_id", + "required": true, + "type": "string" + }, + { + "description": "The workspace to add default channels in.", + "in": "formData", + "name": "team_id", + "type": "string" + }, + { + "description": "Comma separated string of channel IDs.", + "in": "formData", + "name": "channel_ids", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response if the token provided is not associated with an Org Admin or Owner", + "examples": { + "application/json": { + "error": "not_an_admin", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.usergroups:write" + ] + } + ], + "tags": [ + "admin.usergroups", + "admin" + ] + } + }, + "/admin.usergroups.addTeams": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Associate one or more default workspaces with an organization-wide IDP group.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.usergroups.addTeams" + }, + "operationId": "admin_usergroups_addTeams", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.teams:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "An encoded usergroup (IDP Group) ID.", + "in": "formData", + "name": "usergroup_id", + "required": true, + "type": "string" + }, + { + "description": "A comma separated list of encoded team (workspace) IDs. Each workspace *MUST* belong to the organization associated with the token.", + "in": "formData", + "name": "team_ids", + "required": true, + "type": "string" + }, + { + "description": "When `true`, this method automatically creates new workspace accounts for the IDP group members.", + "in": "formData", + "name": "auto_provision", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.teams:write" + ] + } + ], + "tags": [ + "admin.usergroups", + "admin" + ] + } + }, + "/admin.usergroups.listChannels": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "List the channels linked to an org-level IDP group (user group).", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.usergroups.listChannels" + }, + "operationId": "admin_usergroups_listChannels", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.usergroups:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID of the IDP group to list default channels for.", + "in": "query", + "name": "usergroup_id", + "required": true, + "type": "string" + }, + { + "description": "ID of the the workspace.", + "in": "query", + "name": "team_id", + "type": "string" + }, + { + "description": "Flag to include or exclude the count of members per channel.", + "in": "query", + "name": "include_num_members", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channels": [ + { + "id": "C024BE91L", + "name": "fun", + "num_members": 34, + "team_id": "T024BE911" + }, + { + "id": "C024BE91K", + "name": "more fun", + "team_id": "T024BE912" + }, + { + "id": "C024BE91M", + "is_redacted": true, + "name": "public-channel", + "num_members": 34, + "team_id": "T024BE911" + }, + { + "id": "C024BE91N", + "name": "some more fun", + "team_id": "T024BE921" + } + ], + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response if the token provided is not associated with an Org Admin or Owner", + "examples": { + "application/json": { + "error": "not_an_admin", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.usergroups:read" + ] + } + ], + "tags": [ + "admin.usergroups", + "admin" + ] + } + }, + "/admin.usergroups.removeChannels": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Remove one or more default channels from an org-level IDP group (user group).", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.usergroups.removeChannels" + }, + "operationId": "admin_usergroups_removeChannels", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.usergroups:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID of the IDP Group", + "in": "formData", + "name": "usergroup_id", + "required": true, + "type": "string" + }, + { + "description": "Comma-separated string of channel IDs", + "in": "formData", + "name": "channel_ids", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response if the token provided is not associated with an Org Admin or Owner", + "examples": { + "application/json": { + "error": "not_an_admin", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.usergroups:write" + ] + } + ], + "tags": [ + "admin.usergroups", + "admin" + ] + } + }, + "/admin.users.assign": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Add an Enterprise user to a workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.assign" + }, + "operationId": "admin_users_assign", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID (`T1234`) of the workspace.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The ID of the user to add to the workspace.", + "in": "formData", + "name": "user_id", + "required": true, + "type": "string" + }, + { + "description": "True if user should be added to the workspace as a guest.", + "in": "formData", + "name": "is_restricted", + "type": "boolean" + }, + { + "description": "True if user should be added to the workspace as a single-channel guest.", + "in": "formData", + "name": "is_ultra_restricted", + "type": "boolean" + }, + { + "description": "Comma separated values of channel IDs to add user in the new workspace.", + "in": "formData", + "name": "channel_ids", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users", + "admin" + ] + } + }, + "/admin.users.invite": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Invite a user to a workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.invite" + }, + "operationId": "admin_users_invite", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID (`T1234`) of the workspace.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The email address of the person to invite.", + "in": "formData", + "name": "email", + "required": true, + "type": "string" + }, + { + "description": "A comma-separated list of `channel_id`s for this user to join. At least one channel is required.", + "in": "formData", + "name": "channel_ids", + "required": true, + "type": "string" + }, + { + "description": "An optional message to send to the user in the invite email.", + "in": "formData", + "name": "custom_message", + "type": "string" + }, + { + "description": "Full name of the user.", + "in": "formData", + "name": "real_name", + "type": "string" + }, + { + "description": "Allow this invite to be resent in the future if a user has not signed up yet. (default: false)", + "in": "formData", + "name": "resend", + "type": "boolean" + }, + { + "description": "Is this user a multi-channel guest user? (default: false)", + "in": "formData", + "name": "is_restricted", + "type": "boolean" + }, + { + "description": "Is this user a single channel guest user? (default: false)", + "in": "formData", + "name": "is_ultra_restricted", + "type": "boolean" + }, + { + "description": "Timestamp when guest account should be disabled. Only include this timestamp if you are inviting a guest user and you want their account to expire on a certain date.", + "in": "formData", + "name": "guest_expiration_ts", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users", + "admin" + ] + } + }, + "/admin.users.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "List users on a workspace", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.list" + }, + "operationId": "admin_users_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID (`T1234`) of the workspace.", + "in": "query", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "Set `cursor` to `next_cursor` returned by the previous call to list items in the next page.", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "Limit for how many users to be retrieved per page", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "users": [ + { + "email": "bront@slack.com", + "id": "T1234", + "is_admin": false, + "is_bot": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false + } + ] + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:read" + ] + } + ], + "tags": [ + "admin.users", + "admin" + ] + } + }, + "/admin.users.remove": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Remove a user from a workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.remove" + }, + "operationId": "admin_users_remove", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID (`T1234`) of the workspace.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The ID of the user to remove.", + "in": "formData", + "name": "user_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users", + "admin" + ] + } + }, + "/admin.users.session.invalidate": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Invalidate a single session for a user by session_id", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.session.invalidate" + }, + "operationId": "admin_users_session_invalidate", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "ID of the team that the session belongs to", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "in": "formData", + "name": "session_id", + "required": true, + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users.session", + "admin" + ] + } + }, + "/admin.users.session.reset": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Wipes all valid sessions on all devices for a given user", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.session.reset" + }, + "operationId": "admin_users_session_reset", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID of the user to wipe sessions for", + "in": "formData", + "name": "user_id", + "required": true, + "type": "string" + }, + { + "description": "Only expire mobile sessions (default: false)", + "in": "formData", + "name": "mobile_only", + "type": "boolean" + }, + { + "description": "Only expire web sessions (default: false)", + "in": "formData", + "name": "web_only", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users.session", + "admin" + ] + } + }, + "/admin.users.setAdmin": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set an existing guest, regular user, or owner to be an admin user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.setAdmin" + }, + "operationId": "admin_users_setAdmin", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID (`T1234`) of the workspace.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The ID of the user to designate as an admin.", + "in": "formData", + "name": "user_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users", + "admin" + ] + } + }, + "/admin.users.setExpiration": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set an expiration for a guest user", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.setExpiration" + }, + "operationId": "admin_users_setExpiration", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID (`T1234`) of the workspace.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The ID of the user to set an expiration for.", + "in": "formData", + "name": "user_id", + "required": true, + "type": "string" + }, + { + "description": "Timestamp when guest account should be disabled.", + "in": "formData", + "name": "expiration_ts", + "required": true, + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users", + "admin" + ] + } + }, + "/admin.users.setOwner": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set an existing guest, regular user, or admin user to be a workspace owner.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.setOwner" + }, + "operationId": "admin_users_setOwner", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID (`T1234`) of the workspace.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "Id of the user to promote to owner.", + "in": "formData", + "name": "user_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users", + "admin" + ] + } + }, + "/admin.users.setRegular": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set an existing guest user, admin user, or owner to be a regular user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/admin.users.setRegular" + }, + "operationId": "admin_users_setRegular", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin.users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID (`T1234`) of the workspace.", + "in": "formData", + "name": "team_id", + "required": true, + "type": "string" + }, + { + "description": "The ID of the user to designate as a regular user.", + "in": "formData", + "name": "user_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin.users:write" + ] + } + ], + "tags": [ + "admin.users", + "admin" + ] + } + }, + "/api.test": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Checks API calling code.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/api.test" + }, + "operationId": "api_test", + "parameters": [ + { + "description": "Error response to return", + "in": "query", + "name": "error", + "type": "string" + }, + { + "description": "example property to return", + "in": "query", + "name": "foo", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Standard success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": { + "type": "object" + }, + "description": "Schema for successful response api.test method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "api.test success schema", + "type": "object" + } + }, + "default": { + "description": "Artificial error response", + "examples": { + "application/json": { + "args": { + "error": "my_error" + }, + "error": "my_error", + "ok": false + } + }, + "schema": { + "additionalProperties": { + "type": "object" + }, + "description": "Schema for error response api.test method", + "properties": { + "error": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "api.test error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "api" + ] + } + }, + "/apps.event.authorizations.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Get a list of authorizations for the given event context. Each authorization represents an app installation that the event is visible to.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/apps.event.authorizations.list" + }, + "operationId": "apps_event_authorizations_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `authorizations:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "event_context", + "required": true, + "type": "string" + }, + { + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "authorizations": { + "enterprise_id": "string", + "is_bot": "string", + "team_id": "string", + "user_id": "string" + }, + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "authorizations:read" + ] + } + ], + "tags": [ + "apps.event.authorizations", + "apps" + ] + } + }, + "/apps.permissions.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Returns list of permissions this app has on a team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/apps.permissions.info" + }, + "operationId": "apps_permissions_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Standard success response when used with a user token", + "examples": { + "application/json": { + "info": { + "app_home": { + "resources": { + "ids": [ + "D0C0NU1Q8", + "D0BH95DLH" + ] + }, + "scopes": [ + "chat:write", + "im:history", + "im:read" + ] + }, + "channel": { + "resources": { + "excluded_ids": [], + "ids": [ + "C061FA5PB" + ], + "wildcard": false + }, + "scopes": [ + "channels:read" + ] + }, + "group": { + "resources": { + "ids": [] + }, + "scopes": [] + }, + "im": { + "resources": { + "ids": [] + }, + "scopes": [] + }, + "mpim": { + "resources": { + "ids": [] + }, + "scopes": [] + }, + "team": { + "resources": { + "ids": [] + }, + "scopes": [] + } + }, + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from apps.permissions.info method", + "properties": { + "info": { + "properties": { + "app_home": { + "properties": { + "resources": { + "$ref": "#/definitions/objs_resources" + }, + "scopes": { + "$ref": "#/definitions/objs_scopes" + } + }, + "type": "object" + }, + "channel": { + "properties": { + "resources": { + "$ref": "#/definitions/objs_resources" + }, + "scopes": { + "$ref": "#/definitions/objs_scopes" + } + }, + "type": "object" + }, + "group": { + "properties": { + "resources": { + "$ref": "#/definitions/objs_resources" + }, + "scopes": { + "$ref": "#/definitions/objs_scopes" + } + }, + "type": "object" + }, + "im": { + "properties": { + "resources": { + "$ref": "#/definitions/objs_resources" + }, + "scopes": { + "$ref": "#/definitions/objs_scopes" + } + }, + "type": "object" + }, + "mpim": { + "properties": { + "resources": { + "$ref": "#/definitions/objs_resources" + }, + "scopes": { + "$ref": "#/definitions/objs_scopes" + } + }, + "type": "object" + }, + "team": { + "properties": { + "resources": { + "$ref": "#/definitions/objs_resources" + }, + "scopes": { + "$ref": "#/definitions/objs_scopes" + } + }, + "required": [ + "scopes", + "resources" + ], + "type": "object" + } + }, + "required": [ + "team", + "channel", + "group", + "mpim", + "im", + "app_home" + ], + "type": "object" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "info" + ], + "title": "apps.permissions.info schema", + "type": "object" + } + }, + "default": { + "description": "Standard failure response when used with an invalid token", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from apps.permissions.info method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "apps.permissions.info error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "apps.permissions", + "apps" + ] + } + }, + "/apps.permissions.request": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Allows an app to request additional scopes", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/apps.permissions.request" + }, + "operationId": "apps_permissions_request", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "A comma separated list of scopes to request for", + "in": "query", + "name": "scopes", + "required": true, + "type": "string" + }, + { + "description": "Token used to trigger the permissions API", + "in": "query", + "name": "trigger_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Standard success response when used with a user token", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from apps.permissions.request method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "apps.permissions.request schema", + "type": "object" + } + }, + "default": { + "description": "Standard failure response when trigger_id is invalid", + "examples": { + "application/json": { + "error": "invalid_trigger_id", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from apps.permissions.request method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "invalid_trigger", + "trigger_exchanged", + "invalid_scope", + "invalid_user", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "apps.permissions.request error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "apps.permissions", + "apps" + ] + } + }, + "/apps.permissions.resources.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Returns list of resource grants this app has on a team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/apps.permissions.resources.list" + }, + "operationId": "apps_permissions_resources_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The maximum number of items to return.", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical successful paginated response", + "examples": { + "application/json": { + "ok": true, + "resources": [ + { + "id": "T0DES3UAN", + "type": "team" + }, + { + "id": "D024BFF1M", + "type": "app_home" + }, + { + "id": "C024BE91L", + "type": "channel" + } + ], + "response_metadata": { + "next_cursor": "dGVhbTpDMUg5UkVTR0w=" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "Schema for successful response apps.permissions.resources.list method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "resources": { + "items": { + "properties": { + "id": { + "title": "An ID for a resource", + "type": "string", + "x-examples": [ + "T0DES3UAN", + "C0ABC1ABC" + ] + }, + "type": { + "title": "The type of resource the `id` corresponds to", + "type": "string", + "x-examples": [ + "team", + "channel", + "mpim" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "response_metadata": { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string", + "x-examples": [ + "dGVhbTpDMUg5UkVTR0w=" + ] + } + }, + "required": [ + "next_cursor" + ], + "type": "object" + } + }, + "required": [ + "ok", + "resources" + ], + "title": "apps.permissions.resources.list success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_cursor", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from apps.permissions.resources.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "invalid_cursor", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "apps.permissions.resources.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "apps.permissions.resources", + "apps" + ] + } + }, + "/apps.permissions.scopes.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Returns list of scopes this app has on a team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/apps.permissions.scopes.list" + }, + "operationId": "apps_permissions_scopes_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical successful paginated response", + "examples": { + "application/json": { + "ok": true, + "scopes": { + "app_home": [ + "chat:write", + "im:history", + "im:read" + ], + "channel": [ + "channels:history", + "chat:write" + ], + "group": [ + "chat:write" + ], + "im": [ + "chat:write" + ], + "mpim": [ + "chat:write" + ], + "team": [ + "users:read" + ], + "user": [] + } + } + }, + "schema": { + "additionalProperties": true, + "description": "Schema for successful response api.permissions.scopes.list method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "scopes": { + "additionalProperties": true, + "properties": { + "app_home": { + "$ref": "#/definitions/objs_scopes" + }, + "channel": { + "$ref": "#/definitions/objs_scopes" + }, + "group": { + "$ref": "#/definitions/objs_scopes" + }, + "im": { + "$ref": "#/definitions/objs_scopes" + }, + "mpim": { + "$ref": "#/definitions/objs_scopes" + }, + "team": { + "$ref": "#/definitions/objs_scopes" + }, + "user": { + "$ref": "#/definitions/objs_scopes" + } + }, + "type": "object" + } + }, + "required": [ + "ok", + "scopes" + ], + "title": "api.permissions.scopes.list success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from apps.permissions.scopes.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "apps.permissions.scopes.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "apps.permissions.scopes", + "apps" + ] + } + }, + "/apps.permissions.users.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Returns list of user grants and corresponding scopes this app has on a team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/apps.permissions.users.list" + }, + "operationId": "apps_permissions_users_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The maximum number of items to return.", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical successful paginated response", + "examples": { + "application/json": { + "ok": true, + "resources": [ + { + "id": "U0DES3UAN", + "scopes": [ + "dnd:write:user", + "reminders:write:user" + ] + }, + { + "id": "U024BFF1M", + "scopes": [ + "reminders:write:user" + ] + } + ], + "response_metadata": { + "next_cursor": "dGVhbTdPMUg5UkFTT0w=" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_cursor", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "apps.permissions.users", + "apps" + ] + } + }, + "/apps.permissions.users.request": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Enables an app to trigger a permissions modal to grant an app access to a user access scope.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/apps.permissions.users.request" + }, + "operationId": "apps_permissions_users_request", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "A comma separated list of user scopes to request for", + "in": "query", + "name": "scopes", + "required": true, + "type": "string" + }, + { + "description": "Token used to trigger the request", + "in": "query", + "name": "trigger_id", + "required": true, + "type": "string" + }, + { + "description": "The user this scope is being requested for", + "in": "query", + "name": "user", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Standard success response when used with a user token", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Standard failure response when trigger_id is invalid", + "examples": { + "application/json": { + "error": "invalid_trigger_id", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "apps.permissions.users", + "apps" + ] + } + }, + "/apps.uninstall": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Uninstalls your app from a workspace.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/apps.uninstall" + }, + "operationId": "apps_uninstall", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Issued when you created your application.", + "in": "query", + "name": "client_id", + "type": "string" + }, + { + "description": "Issued when you created your application.", + "in": "query", + "name": "client_secret", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from apps.uninstall method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "apps.uninstall schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from apps.uninstall method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "invalid_client_id", + "bad_client_secret", + "client_id_token_mismatch", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "apps.uninstall error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "apps" + ] + } + }, + "/auth.revoke": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Revokes a token.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/auth.revoke" + }, + "operationId": "auth_revoke", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Setting this parameter to `1` triggers a _testing mode_ where the specified token will not actually be revoked.", + "in": "query", + "name": "test", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "revoked": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from auth.revoke method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "revoked": { + "type": "boolean" + } + }, + "required": [ + "ok", + "revoked" + ], + "title": "auth.revoke schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from auth.revoke method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "auth.revoke error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "auth" + ] + } + }, + "/auth.test": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Checks authentication & identity.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/auth.test" + }, + "operationId": "auth_test", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Standard success response when used with a user token", + "examples": { + "application/json": { + "ok": true, + "team": "Subarachnoid Workspace", + "team_id": "T12345678", + "url": "https://subarachnoid.slack.com/", + "user": "grace", + "user_id": "W12345678" + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response auth.test method", + "properties": { + "bot_id": { + "$ref": "#/definitions/defs_bot_id" + }, + "is_enterprise_install": { + "type": "boolean" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "team": { + "type": "string" + }, + "team_id": { + "$ref": "#/definitions/defs_team" + }, + "url": { + "type": "string" + }, + "user": { + "type": "string" + }, + "user_id": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": [ + "ok", + "url", + "team", + "user", + "team_id", + "user_id" + ], + "title": "auth.test success schema", + "type": "object" + } + }, + "default": { + "description": "Standard failure response when used with an invalid token", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response auth.test method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "token_revoked", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "auth.test error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "auth" + ] + } + }, + "/bots.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets information about a bot user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/bots.info" + }, + "operationId": "bots_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Bot user to get info on", + "in": "query", + "name": "bot", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "When successful, returns bot info by bot ID.", + "examples": { + "application/json": { + "bot": { + "app_id": "A161CLERW", + "deleted": false, + "icons": { + "image_36": "https://...", + "image_48": "https://...", + "image_72": "https://..." + }, + "id": "B061F7JD2", + "name": "beforebot", + "updated": 1449272004, + "user_id": "U012ABCDEF" + }, + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from bots.info method", + "properties": { + "bot": { + "additionalProperties": false, + "properties": { + "app_id": { + "$ref": "#/definitions/defs_app_id" + }, + "deleted": { + "type": "boolean" + }, + "icons": { + "additionalProperties": false, + "properties": { + "image_36": { + "format": "uri", + "type": "string" + }, + "image_48": { + "format": "uri", + "type": "string" + }, + "image_72": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "image_36", + "image_48", + "image_72" + ], + "type": "object" + }, + "id": { + "$ref": "#/definitions/defs_bot_id" + }, + "name": { + "type": "string" + }, + "updated": { + "type": "integer" + }, + "user_id": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": [ + "id", + "deleted", + "name", + "updated", + "app_id", + "icons" + ], + "type": "object" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "bot" + ], + "title": "bots.info schema", + "type": "object" + } + }, + "default": { + "description": "When no bot can be found, it returns an error.", + "examples": { + "application/json": { + "error": "bot_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from bots.info method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "bot_not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "bots.info error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users:read" + ] + } + ], + "tags": [ + "bots" + ] + } + }, + "/calls.add": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Registers a new Call.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/calls.add" + }, + "operationId": "calls_add", + "parameters": [ + { + "description": "Authentication token. Requires scope: `calls:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "An ID supplied by the 3rd-party Call provider. It must be unique across all Calls from that service.", + "in": "formData", + "name": "external_unique_id", + "required": true, + "type": "string" + }, + { + "description": "An optional, human-readable ID supplied by the 3rd-party Call provider. If supplied, this ID will be displayed in the Call object.", + "in": "formData", + "name": "external_display_id", + "type": "string" + }, + { + "description": "The URL required for a client to join the Call.", + "in": "formData", + "name": "join_url", + "required": true, + "type": "string" + }, + { + "description": "When supplied, available Slack clients will attempt to directly launch the 3rd-party Call with this URL.", + "in": "formData", + "name": "desktop_app_join_url", + "type": "string" + }, + { + "description": "Call start time in UTC UNIX timestamp format", + "in": "formData", + "name": "date_start", + "type": "integer" + }, + { + "description": "The name of the Call.", + "in": "formData", + "name": "title", + "type": "string" + }, + { + "description": "The valid Slack user ID of the user who created this Call. When this method is called with a user token, the `created_by` field is optional and defaults to the authed user of the token. Otherwise, the field is required.", + "in": "formData", + "name": "created_by", + "type": "string" + }, + { + "description": "The list of users to register as participants in the Call. [Read more on how to specify users here](/apis/calls#users).", + "in": "formData", + "name": "users", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "calls:write" + ] + } + ], + "tags": [ + "calls" + ] + } + }, + "/calls.end": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Ends a Call.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/calls.end" + }, + "operationId": "calls_end", + "parameters": [ + { + "description": "Authentication token. Requires scope: `calls:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "`id` returned when registering the call using the [`calls.add`](/methods/calls.add) method.", + "in": "formData", + "name": "id", + "required": true, + "type": "string" + }, + { + "description": "Call duration in seconds", + "in": "formData", + "name": "duration", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "calls:write" + ] + } + ], + "tags": [ + "calls" + ] + } + }, + "/calls.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Returns information about a Call.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/calls.info" + }, + "operationId": "calls_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `calls:read`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "`id` of the Call returned by the [`calls.add`](/methods/calls.add) method.", + "in": "query", + "name": "id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "calls:read" + ] + } + ], + "tags": [ + "calls" + ] + } + }, + "/calls.participants.add": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Registers new participants added to a Call.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/calls.participants.add" + }, + "operationId": "calls_participants_add", + "parameters": [ + { + "description": "Authentication token. Requires scope: `calls:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "`id` returned by the [`calls.add`](/methods/calls.add) method.", + "in": "formData", + "name": "id", + "required": true, + "type": "string" + }, + { + "description": "The list of users to add as participants in the Call. [Read more on how to specify users here](/apis/calls#users).", + "in": "formData", + "name": "users", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "calls:write" + ] + } + ], + "tags": [ + "calls.participants", + "calls" + ] + } + }, + "/calls.participants.remove": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Registers participants removed from a Call.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/calls.participants.remove" + }, + "operationId": "calls_participants_remove", + "parameters": [ + { + "description": "Authentication token. Requires scope: `calls:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "`id` returned by the [`calls.add`](/methods/calls.add) method.", + "in": "formData", + "name": "id", + "required": true, + "type": "string" + }, + { + "description": "The list of users to remove as participants in the Call. [Read more on how to specify users here](/apis/calls#users).", + "in": "formData", + "name": "users", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "calls:write" + ] + } + ], + "tags": [ + "calls.participants", + "calls" + ] + } + }, + "/calls.update": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Updates information about a Call.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/calls.update" + }, + "operationId": "calls_update", + "parameters": [ + { + "description": "Authentication token. Requires scope: `calls:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "`id` returned by the [`calls.add`](/methods/calls.add) method.", + "in": "formData", + "name": "id", + "required": true, + "type": "string" + }, + { + "description": "The name of the Call.", + "in": "formData", + "name": "title", + "type": "string" + }, + { + "description": "The URL required for a client to join the Call.", + "in": "formData", + "name": "join_url", + "type": "string" + }, + { + "description": "When supplied, available Slack clients will attempt to directly launch the 3rd-party Call with this URL.", + "in": "formData", + "name": "desktop_app_join_url", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "calls:write" + ] + } + ], + "tags": [ + "calls" + ] + } + }, + "/chat.delete": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Deletes a message.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.delete" + }, + "operationId": "chat_delete", + "parameters": [ + { + "description": "Authentication token. Requires scope: `chat:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Timestamp of the message to be deleted.", + "in": "formData", + "name": "ts", + "type": "number" + }, + { + "description": "Channel containing the message to be deleted.", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "Pass true to delete the message as the authed user with `chat:write:user` scope. [Bot users](/bot-users) in this context are considered authed users. If unused or false, the message will be deleted with `chat:write:bot` scope.", + "in": "formData", + "name": "as_user", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel": "C024BE91L", + "ok": true, + "ts": "1401383885.000061" + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of chat.delete method", + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "ts": { + "$ref": "#/definitions/defs_ts" + } + }, + "required": [ + "ok", + "channel", + "ts" + ], + "title": "chat.delete success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "message_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from chat.delete method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "message_not_found", + "channel_not_found", + "cant_delete_message", + "compliance_exports_prevent_deletion", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.delete error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "chat:write:user", + "chat:write:bot" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/chat.deleteScheduledMessage": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Deletes a pending scheduled message from the queue.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.deleteScheduledMessage" + }, + "operationId": "chat_deleteScheduledMessage", + "parameters": [ + { + "description": "Authentication token. Requires scope: `chat:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Pass true to delete the message as the authed user with `chat:write:user` scope. [Bot users](/bot-users) in this context are considered authed users. If unused or false, the message will be deleted with `chat:write:bot` scope.", + "in": "formData", + "name": "as_user", + "type": "boolean" + }, + { + "description": "The channel the scheduled_message is posting to", + "in": "formData", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "`scheduled_message_id` returned from call to chat.scheduleMessage", + "in": "formData", + "name": "scheduled_message_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from chat.deleteScheduledMessage method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "chat.deleteScheduledMessage schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response if no message is found", + "examples": { + "application/json": { + "error": "invalid_scheduled_message_id", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from chat.deleteScheduledMessage method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "invalid_scheduled_message_id", + "channel_not_found", + "bad_token", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "ekm_access_denied", + "missing_scope", + "invalid_arguments", + "invalid_arg_name", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.deleteScheduledMessage error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "chat:write:user", + "chat:write:bot" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/chat.getPermalink": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieve a permalink URL for a specific extant message", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.getPermalink" + }, + "operationId": "chat_getPermalink", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The ID of the conversation or channel containing the message", + "in": "query", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "A message's `ts` value, uniquely identifying it within a channel", + "in": "query", + "name": "message_ts", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Standard success response", + "examples": { + "application/json": { + "channel": "C1H9RESGA", + "ok": true, + "permalink": "https://ghostbusters.slack.com/archives/C1H9RESGA/p135854651500008" + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response chat.getPermalink", + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "permalink": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "ok", + "channel", + "permalink" + ], + "title": "chat.getPermalink success schema", + "type": "object" + } + }, + "default": { + "description": "Error response when channel cannot be found", + "examples": { + "application/json": { + "error": "channel_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from chat.getPermalink method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "channel_not_found", + "message_not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.getPermalink error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/chat.meMessage": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Share a me message into a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.meMessage" + }, + "operationId": "chat_meMessage", + "parameters": [ + { + "description": "Authentication token. Requires scope: `chat:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Channel to send message to. Can be a public channel, private group or IM channel. Can be an encoded ID, or a name.", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "Text of the message to send.", + "in": "formData", + "name": "text", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel": "C024BE7LR", + "ok": true, + "ts": "1417671948.000006" + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from chat.meMessage method", + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "ts": { + "$ref": "#/definitions/defs_ts" + } + }, + "required": [ + "ok" + ], + "title": "chat.meMessage schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from chat.meMessage method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "channel_not_found", + "not_in_channel", + "is_archived", + "msg_too_long", + "no_text", + "rate_limited", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.meMessage error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "chat:write:user", + "chat:write:bot" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/chat.postEphemeral": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Sends an ephemeral message to a user in a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.postEphemeral" + }, + "operationId": "chat_postEphemeral", + "parameters": [ + { + "description": "Authentication token. Requires scope: `chat:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Pass true to post the message as the authed user. Defaults to true if the chat:write:bot scope is not included. Otherwise, defaults to false.", + "in": "formData", + "name": "as_user", + "type": "boolean" + }, + { + "description": "A JSON-based array of structured attachments, presented as a URL-encoded string.", + "in": "formData", + "name": "attachments", + "type": "string" + }, + { + "description": "A JSON-based array of structured blocks, presented as a URL-encoded string.", + "in": "formData", + "name": "blocks", + "type": "string" + }, + { + "description": "Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name.", + "in": "formData", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "Emoji to use as the icon for this message. Overrides `icon_url`. Must be used in conjunction with `as_user` set to `false`, otherwise ignored. See [authorship](#authorship) below.", + "in": "formData", + "name": "icon_emoji", + "type": "string" + }, + { + "description": "URL to an image to use as the icon for this message. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.", + "in": "formData", + "name": "icon_url", + "type": "string" + }, + { + "description": "Find and link channel names and usernames.", + "in": "formData", + "name": "link_names", + "type": "boolean" + }, + { + "description": "Change how messages are treated. Defaults to `none`. See [below](#formatting).", + "in": "formData", + "name": "parse", + "type": "string" + }, + { + "description": "How this field works and whether it is required depends on other fields you use in your API call. [See below](#text_usage) for more detail.", + "in": "formData", + "name": "text", + "type": "string" + }, + { + "description": "Provide another message's `ts` value to post this message in a thread. Avoid using a reply's `ts` value; use its parent's value instead. Ephemeral messages in threads are only shown if there is already an active thread.", + "in": "formData", + "name": "thread_ts", + "type": "string" + }, + { + "description": "`id` of the user who will receive the ephemeral message. The user should be in the channel specified by the `channel` argument.", + "in": "formData", + "name": "user", + "required": true, + "type": "string" + }, + { + "description": "Set your bot's user name. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.", + "in": "formData", + "name": "username", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "message_ts": "1502210682.580145", + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from chat.postEphemeral method", + "properties": { + "message_ts": { + "$ref": "#/definitions/defs_ts" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "message_ts" + ], + "title": "chat.postEphemeral success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "user_not_in_channel", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from chat.postEphemeral method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "channel_not_found", + "is_archived", + "msg_too_long", + "no_text", + "restricted_action", + "too_many_attachments", + "user_not_in_channel", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.postEphemeral error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "chat:write:user", + "chat:write:bot" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/chat.postMessage": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Sends a message to a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.postMessage" + }, + "operationId": "chat_postMessage", + "parameters": [ + { + "description": "Authentication token. Requires scope: `chat:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [authorship](#authorship) below.", + "in": "formData", + "name": "as_user", + "type": "string" + }, + { + "description": "A JSON-based array of structured attachments, presented as a URL-encoded string.", + "in": "formData", + "name": "attachments", + "type": "string" + }, + { + "description": "A JSON-based array of structured blocks, presented as a URL-encoded string.", + "in": "formData", + "name": "blocks", + "type": "string" + }, + { + "description": "Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details.", + "in": "formData", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "Emoji to use as the icon for this message. Overrides `icon_url`. Must be used in conjunction with `as_user` set to `false`, otherwise ignored. See [authorship](#authorship) below.", + "in": "formData", + "name": "icon_emoji", + "type": "string" + }, + { + "description": "URL to an image to use as the icon for this message. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.", + "in": "formData", + "name": "icon_url", + "type": "string" + }, + { + "description": "Find and link channel names and usernames.", + "in": "formData", + "name": "link_names", + "type": "boolean" + }, + { + "description": "Disable Slack markup parsing by setting to `false`. Enabled by default.", + "in": "formData", + "name": "mrkdwn", + "type": "boolean" + }, + { + "description": "Change how messages are treated. Defaults to `none`. See [below](#formatting).", + "in": "formData", + "name": "parse", + "type": "string" + }, + { + "description": "Used in conjunction with `thread_ts` and indicates whether reply should be made visible to everyone in the channel or conversation. Defaults to `false`.", + "in": "formData", + "name": "reply_broadcast", + "type": "boolean" + }, + { + "description": "How this field works and whether it is required depends on other fields you use in your API call. [See below](#text_usage) for more detail.", + "in": "formData", + "name": "text", + "type": "string" + }, + { + "description": "Provide another message's `ts` value to make this message a reply. Avoid using a reply's `ts` value; use its parent instead.", + "in": "formData", + "name": "thread_ts", + "type": "string" + }, + { + "description": "Pass true to enable unfurling of primarily text-based content.", + "in": "formData", + "name": "unfurl_links", + "type": "boolean" + }, + { + "description": "Pass false to disable unfurling of media content.", + "in": "formData", + "name": "unfurl_media", + "type": "boolean" + }, + { + "description": "Set your bot's user name. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.", + "in": "formData", + "name": "username", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel": "C1H9RESGL", + "message": { + "attachments": [ + { + "fallback": "This is an attachment's fallback", + "id": 1, + "text": "This is an attachment" + } + ], + "bot_id": "B19LU7CSY", + "subtype": "bot_message", + "text": "Here's a message for you", + "ts": "1503435956.000247", + "type": "message", + "username": "ecto1" + }, + "ok": true, + "ts": "1503435956.000247" + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of chat.postMessage method", + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "message": { + "$ref": "#/definitions/objs_message" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "ts": { + "$ref": "#/definitions/defs_ts" + } + }, + "required": [ + "ok", + "channel", + "ts", + "message" + ], + "title": "chat.postMessage success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response if too many attachments are included", + "examples": { + "application/json": { + "error": "too_many_attachments", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response chat.postMessage method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "channel_not_found", + "not_in_channel", + "is_archived", + "msg_too_long", + "no_text", + "too_many_attachments", + "rate_limited", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.postMessage error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "chat:write:user", + "chat:write:bot" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/chat.scheduleMessage": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Schedules a message to be sent to a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.scheduleMessage" + }, + "operationId": "chat_scheduleMessage", + "parameters": [ + { + "description": "Authentication token. Requires scope: `chat:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Channel, private group, or DM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details.", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "How this field works and whether it is required depends on other fields you use in your API call. [See below](#text_usage) for more detail.", + "in": "formData", + "name": "text", + "type": "string" + }, + { + "description": "Unix EPOCH timestamp of time in future to send the message.", + "in": "formData", + "name": "post_at", + "type": "string" + }, + { + "description": "Change how messages are treated. Defaults to `none`. See [chat.postMessage](chat.postMessage#formatting).", + "in": "formData", + "name": "parse", + "type": "string" + }, + { + "description": "Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [chat.postMessage](chat.postMessage#authorship).", + "in": "formData", + "name": "as_user", + "type": "boolean" + }, + { + "description": "Find and link channel names and usernames.", + "in": "formData", + "name": "link_names", + "type": "boolean" + }, + { + "description": "A JSON-based array of structured attachments, presented as a URL-encoded string.", + "in": "formData", + "name": "attachments", + "type": "string" + }, + { + "description": "A JSON-based array of structured blocks, presented as a URL-encoded string.", + "in": "formData", + "name": "blocks", + "type": "string" + }, + { + "description": "Pass true to enable unfurling of primarily text-based content.", + "in": "formData", + "name": "unfurl_links", + "type": "boolean" + }, + { + "description": "Pass false to disable unfurling of media content.", + "in": "formData", + "name": "unfurl_media", + "type": "boolean" + }, + { + "description": "Provide another message's `ts` value to make this message a reply. Avoid using a reply's `ts` value; use its parent instead.", + "in": "formData", + "name": "thread_ts", + "type": "number" + }, + { + "description": "Used in conjunction with `thread_ts` and indicates whether reply should be made visible to everyone in the channel or conversation. Defaults to `false`.", + "in": "formData", + "name": "reply_broadcast", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel": "C1H9RESGL", + "message": { + "attachments": [ + { + "fallback": "This is an attachment's fallback", + "id": 1, + "text": "This is an attachment" + } + ], + "bot_id": "B19LU7CSY", + "subtype": "bot_message", + "text": "Here's a message for you in the future", + "type": "delayed_message", + "username": "ecto1" + }, + "ok": true, + "post_at": "1562180400", + "scheduled_message_id": "Q1298393284" + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of chat.scheduleMessage method", + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "message": { + "additionalProperties": false, + "properties": { + "bot_id": { + "$ref": "#/definitions/defs_bot_id" + }, + "bot_profile": { + "$ref": "#/definitions/objs_bot_profile" + }, + "team": { + "$ref": "#/definitions/defs_team" + }, + "text": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "username": { + "type": "string" + } + }, + "required": [ + "type", + "text", + "bot_id", + "user", + "team" + ], + "type": "object" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "post_at": { + "pattern": "^\\d{10}$", + "type": "integer" + }, + "scheduled_message_id": { + "pattern": "^[Q][A-Z0-9]{8,}$", + "title": "Scheduled Message ID", + "type": "string" + } + }, + "required": [ + "ok", + "channel", + "post_at", + "scheduled_message_id", + "message" + ], + "title": "chat.scheduleMessage success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response if the `post_at` is invalid (ex. in the past or too far into the future)", + "examples": { + "application/json": { + "error": "time_in_past", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response chat.scheduleMessage method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "invalid_time", + "time_in_past", + "time_too_far", + "channel_not_found", + "not_in_channel", + "is_archived", + "msg_too_long", + "no_text", + "restricted_action", + "restricted_action_read_only_channel", + "restricted_action_thread_only_channel", + "restricted_action_non_threadable_channel", + "too_many_attachments", + "rate_limited", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "ekm_access_denied", + "missing_scope", + "invalid_arguments", + "invalid_arg_name", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.scheduleMessage error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "chat:write:user", + "chat:write:bot" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/chat.scheduledMessages.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Returns a list of scheduled messages.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.scheduledMessages.list" + }, + "operationId": "chat_scheduledMessages_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "The channel of the scheduled messages", + "in": "query", + "name": "channel", + "type": "string" + }, + { + "description": "A UNIX timestamp of the latest value in the time range", + "in": "query", + "name": "latest", + "type": "number" + }, + { + "description": "A UNIX timestamp of the oldest value in the time range", + "in": "query", + "name": "oldest", + "type": "number" + }, + { + "description": "Maximum number of original entries to return.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "For pagination purposes, this is the `cursor` value returned from a previous call to `chat.scheduledmessages.list` indicating where you want to start this call from.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "response_metadata": { + "next_cursor": "" + }, + "scheduled_messages": [ + { + "channel_id": "C1H9RESGL", + "date_created": 1551891734, + "id": 1298393284, + "post_at": 1551991428, + "text": "Here's a message for you in the future" + } + ] + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from chat.scheduledMessages.list method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "response_metadata": { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string" + } + }, + "required": [ + "next_cursor" + ], + "type": "object" + }, + "scheduled_messages": { + "items": { + "additionalProperties": false, + "properties": { + "channel_id": { + "$ref": "#/definitions/defs_channel_id" + }, + "date_created": { + "pattern": "^\\d{10}$", + "type": "integer" + }, + "id": { + "pattern": "^[Q][A-Z0-9]{8,}$", + "type": "string" + }, + "post_at": { + "pattern": "^\\d{10}$", + "type": "integer" + }, + "text": { + "type": "string" + } + }, + "required": [ + "id", + "channel_id", + "post_at", + "date_created" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "ok", + "scheduled_messages", + "response_metadata" + ], + "title": "chat.scheduledMessages.list schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response if the channel passed is invalid", + "examples": { + "application/json": { + "error": "invalid_channel", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from chat.scheduledMessages.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "invalid_channel", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "ekm_access_denied", + "missing_scope", + "invalid_arguments", + "invalid_arg_name", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.scheduledMessages.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "chat.scheduledMessages", + "chat" + ] + } + }, + "/chat.unfurl": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Provide custom unfurl behavior for user-posted URLs", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.unfurl" + }, + "operationId": "chat_unfurl", + "parameters": [ + { + "description": "Authentication token. Requires scope: `links:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Channel ID of the message", + "in": "formData", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "Timestamp of the message to add unfurl behavior to.", + "in": "formData", + "name": "ts", + "required": true, + "type": "string" + }, + { + "description": "URL-encoded JSON map with keys set to URLs featured in the the message, pointing to their unfurl blocks or message attachments.", + "in": "formData", + "name": "unfurls", + "type": "string" + }, + { + "description": "Provide a simply-formatted string to send as an ephemeral message to the user as invitation to authenticate further and enable full unfurling behavior", + "in": "formData", + "name": "user_auth_message", + "type": "string" + }, + { + "description": "Set to `true` or `1` to indicate the user must install your Slack app to trigger unfurls for this domain", + "in": "formData", + "name": "user_auth_required", + "type": "boolean" + }, + { + "description": "Send users to this custom URL where they will complete authentication in your app to fully trigger unfurling. Value should be properly URL-encoded.", + "in": "formData", + "name": "user_auth_url", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical, minimal success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from chat.unfurl method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "chat.unfurl success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "cannot_unfurl_url", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from chat.unfurl method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "cannot_unfurl_url", + "cannot_find_service", + "missing_unfurls", + "cannot_prompt", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.unfurl error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "links:write" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/chat.update": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Updates a message.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/chat.update" + }, + "operationId": "chat_update", + "parameters": [ + { + "description": "Authentication token. Requires scope: `chat:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Pass true to update the message as the authed user. [Bot users](/bot-users) in this context are considered authed users.", + "in": "formData", + "name": "as_user", + "type": "string" + }, + { + "description": "A JSON-based array of structured attachments, presented as a URL-encoded string. This field is required when not presenting `text`. If you don't include this field, the message's previous `attachments` will be retained. To remove previous `attachments`, include an empty array for this field.", + "in": "formData", + "name": "attachments", + "type": "string" + }, + { + "description": "A JSON-based array of [structured blocks](/block-kit/building), presented as a URL-encoded string. If you don't include this field, the message's previous `blocks` will be retained. To remove previous `blocks`, include an empty array for this field.", + "in": "formData", + "name": "blocks", + "type": "string" + }, + { + "description": "Channel containing the message to be updated.", + "in": "formData", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "Find and link channel names and usernames. Defaults to `none`. If you do not specify a value for this field, the original value set for the message will be overwritten with the default, `none`.", + "in": "formData", + "name": "link_names", + "type": "string" + }, + { + "description": "Change how messages are treated. Defaults to `client`, unlike `chat.postMessage`. Accepts either `none` or `full`. If you do not specify a value for this field, the original value set for the message will be overwritten with the default, `client`.", + "in": "formData", + "name": "parse", + "type": "string" + }, + { + "description": "New text for the message, using the [default formatting rules](/reference/surfaces/formatting). It's not required when presenting `blocks` or `attachments`.", + "in": "formData", + "name": "text", + "type": "string" + }, + { + "description": "Timestamp of the message to be updated.", + "in": "formData", + "name": "ts", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel": "C024BE91L", + "message": { + "text": "Updated text you carefully authored", + "user": "U34567890" + }, + "ok": true, + "text": "Updated text you carefully authored", + "ts": "1401383885.000061" + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response of chat.update method", + "properties": { + "channel": { + "type": "string" + }, + "message": { + "properties": { + "attachments": { + "items": { + "type": "object" + }, + "type": "array" + }, + "blocks": { + "type": "object" + }, + "text": { + "type": "string" + } + }, + "required": [ + "text" + ], + "title": "Message object", + "type": "object" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "text": { + "type": "string" + }, + "ts": { + "type": "string" + } + }, + "required": [ + "ok", + "channel", + "ts", + "text", + "message" + ], + "title": "chat.update success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "cant_update_message", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response chat.update method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "message_not_found", + "cant_update_message", + "channel_not_found", + "edit_window_closed", + "msg_too_long", + "too_many_attachments", + "rate_limited", + "no_text", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "request_timeout", + "invalid_json", + "json_not_object", + "upgrade_required", + "fatal_error", + "is_inactive" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "chat.update error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "chat:write:user", + "chat:write:bot" + ] + } + ], + "tags": [ + "chat" + ] + } + }, + "/conversations.archive": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Archives a conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.archive" + }, + "operationId": "conversations_archive", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "ID of conversation to archive", + "in": "formData", + "name": "channel", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response conversations.archive method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "conversations.archive success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "channel_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.archive method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "not_supported", + "channel_not_found", + "already_archived", + "cant_archive_general", + "restricted_action", + "not_authed", + "invalid_auth", + "account_inactive", + "user_is_bot", + "user_is_restricted", + "user_is_ultra_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "team_added_to_org", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.archive error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.close": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Closes a direct message or multi-person direct message.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.close" + }, + "operationId": "conversations_close", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Conversation to close.", + "in": "formData", + "name": "channel", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response conversations.close method", + "properties": { + "already_closed": { + "type": "boolean" + }, + "no_op": { + "type": "boolean" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "conversations.close success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "channel_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.close method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "channel_not_found", + "user_does_not_own_channel", + "missing_scope", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.close error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.create": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Initiates a public or private channel-based conversation", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.create" + }, + "operationId": "conversations_create", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Name of the public or private channel to create", + "in": "formData", + "name": "name", + "type": "string" + }, + { + "description": "Create a private channel instead of a public one", + "in": "formData", + "name": "is_private", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "If successful, the command returns a rather stark [conversation object](/types/conversation)", + "examples": { + "application/json": { + "channel": { + "created": 1504554479, + "creator": "U0123456", + "id": "C0EAQDV4Z", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": false, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "last_read": "0000000000.000000", + "latest": null, + "name": "endeavor", + "name_normalized": "endeavor", + "pending_shared": [], + "previous_names": [], + "priority": 0, + "purpose": { + "creator": "", + "last_set": 0, + "value": "" + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "" + }, + "unlinked": 0, + "unread_count": 0, + "unread_count_display": 0 + }, + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response conversations.create method", + "properties": { + "channel": { + "$ref": "#/definitions/objs_conversation" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "channel" + ], + "title": "conversations.create success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response when name already in use", + "examples": { + "application/json": { + "error": "name_taken", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.create method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "detail": { + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "name_taken", + "restricted_action", + "no_channel", + "invalid_name_required", + "invalid_name_punctuation", + "invalid_name_maxlength", + "invalid_name_specials", + "invalid_name", + "not_authed", + "invalid_auth", + "account_inactive", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.create error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.history": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Fetches a conversation's history of messages and events.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.history" + }, + "operationId": "conversations_history", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:history`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Conversation ID to fetch history for.", + "in": "query", + "name": "channel", + "type": "string" + }, + { + "description": "End of time range of messages to include in results.", + "in": "query", + "name": "latest", + "type": "number" + }, + { + "description": "Start of time range of messages to include in results.", + "in": "query", + "name": "oldest", + "type": "number" + }, + { + "description": "Include messages with latest or oldest timestamp in results only when either timestamp is specified.", + "in": "query", + "name": "inclusive", + "type": "boolean" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the users list hasn't been reached.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response containing a channel's messages", + "examples": { + "application/json": { + "has_more": true, + "messages": [ + { + "text": "I find you punny and would like to smell your nose letter", + "ts": "1512085950.000216", + "type": "message", + "user": "U012AB3CDE" + }, + { + "text": "What, you want to smell my shoes better?", + "ts": "1512104434.000490", + "type": "message", + "user": "U061F7AUR" + } + ], + "ok": true, + "pin_count": 0, + "response_metadata": { + "next_cursor": "bmV4dF90czoxNTEyMDg1ODYxMDAwNTQz" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.history method", + "properties": { + "channel_actions_count": { + "type": "integer" + }, + "channel_actions_ts": { + "items": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "has_more": { + "type": "boolean" + }, + "messages": { + "items": { + "$ref": "#/definitions/objs_message" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "pin_count": { + "type": "integer" + } + }, + "required": [ + "ok", + "messages", + "has_more", + "pin_count", + "channel_actions_ts", + "channel_actions_count" + ], + "title": "conversations.history success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "channel_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.history method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "missing_scope", + "channel_not_found", + "invalid_ts_latest", + "invalid_ts_oldest", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.history error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:history", + "groups:history", + "im:history", + "mpim:history" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieve information about a conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.info" + }, + "operationId": "conversations_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Conversation ID to learn more about", + "in": "query", + "name": "channel", + "type": "string" + }, + { + "description": "Set this to `true` to receive the locale for this conversation. Defaults to `false`", + "in": "query", + "name": "include_locale", + "type": "boolean" + }, + { + "description": "Set to `true` to include the member count for the specified conversation. Defaults to `false`", + "in": "query", + "name": "include_num_members", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response for a public channel. (Also, a response from a private channel and a multi-party IM is very similar to this example.)", + "examples": { + "application/json": { + "channel": { + "created": 1449252889, + "creator": "W012A3BCD", + "id": "C012AB3CD", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": true, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_read_only": false, + "is_shared": false, + "last_read": "1502126650.228446", + "locale": "en-US", + "name": "general", + "name_normalized": "general", + "parent_conversation": null, + "pending_shared": [], + "previous_names": [ + "specifics", + "abstractions", + "etc" + ], + "purpose": { + "creator": "W012A3BCD", + "last_set": 1449709364, + "value": "This part of the workspace is for fun. Make fun here." + }, + "topic": { + "creator": "W012A3BCD", + "last_set": 1449709364, + "value": "For public discussion of generalities" + }, + "unlinked": 0 + }, + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response conversations.info", + "properties": { + "channel": { + "$ref": "#/definitions/objs_conversation" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "channel" + ], + "title": "conversations.info success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response when a channel cannot be found", + "examples": { + "application/json": { + "error": "channel_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.info method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "missing_scope", + "channel_not_found", + "team_added_to_org", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.info error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:read", + "groups:read", + "im:read", + "mpim:read" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.invite": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Invites users to a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.invite" + }, + "operationId": "conversations_invite", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "The ID of the public or private channel to invite user(s) to.", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "A comma separated list of user IDs. Up to 1000 users may be listed.", + "in": "formData", + "name": "users", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response when an invitation is extended", + "examples": { + "application/json": { + "channel": { + "created": 1449252889, + "creator": "W012A3BCD", + "id": "C012AB3CD", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": true, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_read_only": false, + "is_shared": false, + "last_read": "1502126650.228446", + "locale": "en-US", + "name": "general", + "name_normalized": "general", + "num_members": 23, + "pending_shared": [], + "previous_names": [ + "specifics", + "abstractions", + "etc" + ], + "purpose": { + "creator": "W012A3BCD", + "last_set": 1449709364, + "value": "This part of the workspace is for fun. Make fun here." + }, + "topic": { + "creator": "W012A3BCD", + "last_set": 1449709364, + "value": "For public discussion of generalities" + }, + "unlinked": 0 + }, + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.invite method", + "properties": { + "channel": { + "$ref": "#/definitions/objs_conversation" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "channel" + ], + "title": "conversations.invite error schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response when an invite is attempted on a conversation type that does not support it", + "examples": { + "application/json": { + "error": "method_not_supported_for_channel_type", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.invite method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "user_not_found", + "no_user", + "cant_invite_self", + "not_in_channel", + "already_in_channel", + "is_archived", + "cant_invite", + "too_many_users", + "ura_max_channels", + "not_authed", + "invalid_auth", + "account_inactive", + "user_is_bot", + "user_is_restricted", + "user_is_ultra_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "team_added_to_org", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "errors": { + "items": { + "additionalProperties": false, + "properties": { + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "user_not_found", + "no_user", + "cant_invite_self", + "not_in_channel", + "already_in_channel", + "is_archived", + "cant_invite", + "too_many_users", + "ura_max_channels", + "not_authed", + "invalid_auth", + "account_inactive", + "user_is_bot", + "user_is_restricted", + "user_is_ultra_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "team_added_to_org", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": [ + "ok", + "error" + ], + "type": "object" + }, + "minItems": 1, + "title": "errors is returned when an error associates an user", + "type": "array", + "uniqueItems": true + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok" + ], + "title": "conversations.invite error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.join": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Joins an existing conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.join" + }, + "operationId": "conversations_join", + "parameters": [ + { + "description": "Authentication token. Requires scope: `channels:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "ID of conversation to join", + "in": "formData", + "name": "channel", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel": { + "created": 1449252889, + "creator": "U061F7AUR", + "id": "C061EG9SL", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": true, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "general", + "name_normalized": "general", + "pending_shared": [], + "previous_names": [], + "purpose": { + "creator": "", + "last_set": 0, + "value": "For widget discussion" + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "Which widget do you worry about?" + }, + "unlinked": 0 + }, + "ok": true, + "response_metadata": { + "warnings": [ + "already_in_channel" + ] + }, + "warning": "already_in_channel" + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.join method", + "properties": { + "channel": { + "$ref": "#/definitions/objs_conversation" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "response_metadata": { + "properties": { + "warnings": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "title": "Response metadata", + "type": "object" + }, + "warning": { + "type": "string" + } + }, + "required": [ + "ok", + "channel" + ], + "title": "conversations.join success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response if the conversation is archived and cannot be joined", + "examples": { + "application/json": { + "error": "is_archived", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.join method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "is_archived", + "not_authed", + "invalid_auth", + "account_inactive", + "user_is_bot", + "user_is_restricted", + "user_is_ultra_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "team_added_to_org", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.join error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.kick": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Removes a user from a conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.kick" + }, + "operationId": "conversations_kick", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "ID of conversation to remove user from.", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "User ID to be removed.", + "in": "formData", + "name": "user", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response conversations.kick method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "conversations.kick success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response when you attempt to kick yourself from a channel", + "examples": { + "application/json": { + "error": "cant_kick_self", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response conversations.kick method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "user_not_found", + "cant_kick_self", + "not_in_channel", + "cant_kick_from_general", + "restricted_action", + "not_authed", + "invalid_auth", + "account_inactive", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.kick error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.leave": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Leaves a conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.leave" + }, + "operationId": "conversations_leave", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Conversation to leave", + "in": "formData", + "name": "channel", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.leave method", + "properties": { + "not_in_channel": { + "enum": [ + true + ], + "type": "boolean" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "conversations.leave success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response when attempting to leave a workspace's \"general\" channel", + "examples": { + "application/json": { + "error": "cant_leave_general", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.leave method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "last_member", + "missing_scope", + "channel_not_found", + "is_archived", + "cant_leave_general", + "not_authed", + "invalid_auth", + "account_inactive", + "user_is_bot", + "user_is_restricted", + "user_is_ultra_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "team_added_to_org", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.leave error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Lists all channels in a Slack team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.list" + }, + "operationId": "conversations_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Set to `true` to exclude archived channels from the list", + "in": "query", + "name": "exclude_archived", + "type": "boolean" + }, + { + "description": "Mix and match channel types by providing a comma-separated list of any combination of `public_channel`, `private_channel`, `mpim`, `im`", + "in": "query", + "name": "types", + "type": "string" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached. Must be an integer no larger than 1000.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response with only public channels", + "examples": { + "application/json": { + "channels": [ + { + "created": 1449252889, + "creator": "U012A3CDE", + "id": "C012AB3CD", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": true, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "general", + "name_normalized": "general", + "num_members": 4, + "pending_shared": [], + "previous_names": [], + "purpose": { + "creator": "", + "last_set": 0, + "value": "This channel is for team-wide communication and announcements. All team members are in this channel." + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "Company-wide announcements and work-based matters" + }, + "unlinked": 0 + }, + { + "created": 1449252889, + "creator": "U061F7AUR", + "id": "C061EG9T2", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": false, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "random", + "name_normalized": "random", + "num_members": 4, + "pending_shared": [], + "previous_names": [], + "purpose": { + "creator": "", + "last_set": 0, + "value": "A place for non-work-related flimflam, faffing, hodge-podge or jibber-jabber you'd prefer to keep out of more focused work-related channels." + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "Non-work banter and water cooler conversation" + }, + "unlinked": 0 + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "dGVhbTpDMDYxRkE1UEI=" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.list method", + "properties": { + "channels": { + "items": { + "$ref": "#/definitions/objs_conversation" + }, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "response_metadata": { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string" + } + }, + "required": [ + "next_cursor" + ], + "type": "object" + } + }, + "required": [ + "ok", + "channels" + ], + "title": "conversations.list success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "missing_scope", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:read", + "groups:read", + "im:read", + "mpim:read" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.mark": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Sets the read cursor in a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.mark" + }, + "operationId": "conversations_mark", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Channel or conversation to set the read cursor for.", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "Unique identifier of message you want marked as most recently seen in this conversation.", + "in": "formData", + "name": "ts", + "type": "number" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response conversations.mark method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "conversations.mark success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.mark method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "invalid_timestamp", + "not_in_channel", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "not_allowed_token_type" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.mark error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.members": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieve members of a conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.members" + }, + "operationId": "conversations_members", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "ID of the conversation to retrieve members for", + "in": "query", + "name": "channel", + "type": "string" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the users list hasn't been reached.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical paginated success response", + "examples": { + "application/json": { + "members": [ + "U023BECGF", + "U061F7AUR", + "W012A3CDE" + ], + "ok": true, + "response_metadata": { + "next_cursor": "e3VzZXJfaWQ6IFcxMjM0NTY3fQ==" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response conversations.members method", + "properties": { + "members": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "response_metadata": { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string" + } + }, + "required": [ + "next_cursor" + ], + "type": "object" + } + }, + "required": [ + "ok", + "members", + "response_metadata" + ], + "title": "conversations.members success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response when an invalid cursor is provided", + "examples": { + "application/json": { + "error": "invalid_cursor", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response conversations.members method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "channel_not_found", + "invalid_limit", + "invalid_cursor", + "fetch_members_failed", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.members error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:read", + "groups:read", + "im:read", + "mpim:read" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.open": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Opens or resumes a direct message or multi-person direct message.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.open" + }, + "operationId": "conversations_open", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Resume a conversation by supplying an `im` or `mpim`'s ID. Or provide the `users` field instead.", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "Comma separated lists of users. If only one user is included, this creates a 1:1 DM. The ordering of the users is preserved whenever a multi-person direct message is returned. Supply a `channel` when not supplying `users`.", + "in": "formData", + "name": "users", + "type": "string" + }, + { + "description": "Boolean, indicates you want the full IM channel definition in the response.", + "in": "formData", + "name": "return_im", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel": { + "id": "D069C7QFK" + }, + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.open method when opening channels, ims, mpims", + "properties": { + "already_open": { + "type": "boolean" + }, + "channel": { + "items": [ + { + "$ref": "#/definitions/objs_conversation" + }, + { + "additionalProperties": false, + "properties": { + "created": { + "type": "string" + }, + "id": { + "$ref": "#/definitions/defs_dm_id" + }, + "is_im": { + "type": "boolean" + }, + "is_open": { + "type": "boolean" + }, + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest": { + "$ref": "#/definitions/objs_message" + }, + "unread_count": { + "type": "number" + }, + "unread_count_display": { + "type": "number" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + } + }, + "required": [ + "id" + ], + "type": "object" + } + ] + }, + "no_op": { + "type": "boolean" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "channel" + ], + "title": "conversations.open success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "channel_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.open method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "user_not_found", + "user_not_visible", + "user_disabled", + "users_list_not_supplied", + "not_enough_users", + "too_many_users", + "invalid_user_combination", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "channel_not_found" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.open error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.rename": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Renames a conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.rename" + }, + "operationId": "conversations_rename", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "ID of conversation to rename", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "New name for conversation.", + "in": "formData", + "name": "name", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "channel": { + "created": 1449252889, + "creator": "W012A3BCD", + "id": "C012AB3CD", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": true, + "is_group": false, + "is_im": false, + "is_member": true, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_read_only": false, + "is_shared": false, + "last_read": "1502126650.228446", + "locale": "en-US", + "name": "general", + "name_normalized": "general", + "num_members": 23, + "pending_shared": [], + "previous_names": [ + "specifics", + "abstractions", + "etc" + ], + "purpose": { + "creator": "W012A3BCD", + "last_set": 1449709364, + "value": "This part of the workspace is for fun. Make fun here." + }, + "topic": { + "creator": "W012A3BCD", + "last_set": 1449709364, + "value": "For public discussion of generalities" + }, + "unlinked": 0 + }, + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.rename method", + "properties": { + "channel": { + "$ref": "#/definitions/objs_conversation" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "channel" + ], + "title": "conversations.rename success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response when the calling user is not a member of the conversation", + "examples": { + "application/json": { + "error": "not_in_channel", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.rename method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "user_is_restricted", + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "not_in_channel", + "not_authorized", + "invalid_name", + "name_taken", + "invalid_name_required", + "invalid_name_punctuation", + "invalid_name_maxlength", + "invalid_name_specials", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.rename error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.replies": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieve a thread of messages posted to a conversation", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.replies" + }, + "operationId": "conversations_replies", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:history`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Conversation ID to fetch thread from.", + "in": "query", + "name": "channel", + "type": "string" + }, + { + "description": "Unique identifier of a thread's parent message. `ts` must be the timestamp of an existing message with 0 or more replies. If there are no replies then just the single message referenced by `ts` will return - it is just an ordinary, unthreaded message.", + "in": "query", + "name": "ts", + "type": "number" + }, + { + "description": "End of time range of messages to include in results.", + "in": "query", + "name": "latest", + "type": "number" + }, + { + "description": "Start of time range of messages to include in results.", + "in": "query", + "name": "oldest", + "type": "number" + }, + { + "description": "Include messages with latest or oldest timestamp in results only when either timestamp is specified.", + "in": "query", + "name": "inclusive", + "type": "boolean" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the users list hasn't been reached.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "has_more": true, + "messages": [ + { + "last_read": "1484678597.521003", + "reply_count": 3, + "subscribed": true, + "text": "island", + "thread_ts": "1482960137.003543", + "ts": "1482960137.003543", + "type": "message", + "unread_count": 0, + "user": "U061F7AUR" + }, + { + "parent_user_id": "U061F7AUR", + "text": "one island", + "thread_ts": "1482960137.003543", + "ts": "1483037603.017503", + "type": "message", + "user": "U061F7AUR" + }, + { + "parent_user_id": "U061F7AUR", + "text": "two island", + "thread_ts": "1482960137.003543", + "ts": "1483051909.018632", + "type": "message", + "user": "U061F7AUR" + }, + { + "parent_user_id": "U061F7AUR", + "text": "three for the land", + "thread_ts": "1482960137.003543", + "ts": "1483125339.020269", + "type": "message", + "user": "U061F7AUR" + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "bmV4dF90czoxNDg0Njc4MjkwNTE3MDkx" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.replies method", + "properties": { + "has_more": { + "type": "boolean" + }, + "messages": { + "items": { + "items": [ + { + "additionalProperties": false, + "properties": { + "last_read": { + "$ref": "#/definitions/defs_ts" + }, + "latest_reply": { + "$ref": "#/definitions/defs_ts" + }, + "reply_count": { + "type": "integer" + }, + "reply_users": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "type": "array", + "uniqueItems": true + }, + "reply_users_count": { + "type": "integer" + }, + "source_team": { + "$ref": "#/definitions/defs_team" + }, + "subscribed": { + "type": "boolean" + }, + "team": { + "$ref": "#/definitions/defs_team" + }, + "text": { + "type": "string" + }, + "thread_ts": { + "$ref": "#/definitions/defs_ts" + }, + "ts": { + "$ref": "#/definitions/defs_ts" + }, + "type": { + "type": "string" + }, + "unread_count": { + "type": "integer" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "user_profile": { + "$ref": "#/definitions/objs_user_profile_short" + }, + "user_team": { + "$ref": "#/definitions/defs_team" + } + }, + "required": [ + "type", + "user", + "text", + "thread_ts", + "reply_count", + "subscribed", + "ts" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "is_starred": { + "type": "boolean" + }, + "parent_user_id": { + "$ref": "#/definitions/defs_user_id" + }, + "source_team": { + "$ref": "#/definitions/defs_team" + }, + "team": { + "$ref": "#/definitions/defs_team" + }, + "text": { + "type": "string" + }, + "thread_ts": { + "$ref": "#/definitions/defs_ts" + }, + "ts": { + "$ref": "#/definitions/defs_ts" + }, + "type": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/defs_user_id" + }, + "user_profile": { + "$ref": "#/definitions/objs_user_profile_short" + }, + "user_team": { + "$ref": "#/definitions/defs_team" + } + }, + "required": [ + "type", + "user", + "text", + "thread_ts", + "parent_user_id", + "ts" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "messages" + ], + "title": "conversations.replies success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "thread_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.replies method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "missing_scope", + "channel_not_found", + "thread_not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.replies error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:history", + "groups:history", + "im:history", + "mpim:history" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.setPurpose": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Sets the purpose for a conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.setPurpose" + }, + "operationId": "conversations_setPurpose", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Conversation to set the purpose of", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "A new, specialer purpose", + "in": "formData", + "name": "purpose", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.setPurpose method", + "properties": { + "channel": { + "$ref": "#/definitions/objs_conversation" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "channel" + ], + "title": "conversations.setPurpose success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.setPurpose method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "not_in_channel", + "is_archived", + "too_long", + "user_is_restricted", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.setPurpose error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.setTopic": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Sets the topic for a conversation.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.setTopic" + }, + "operationId": "conversations_setTopic", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "Conversation to set the topic of", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "The new topic string. Does not support formatting or linkification.", + "in": "formData", + "name": "topic", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.setTopic method", + "properties": { + "channel": { + "$ref": "#/definitions/objs_conversation" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "channel" + ], + "title": "conversations.setTopic success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.setTopic method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "not_in_channel", + "is_archived", + "too_long", + "user_is_restricted", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.setTopic error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/conversations.unarchive": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Reverses conversation archival.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/conversations.unarchive" + }, + "operationId": "conversations_unarchive", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "ID of conversation to unarchive", + "in": "formData", + "name": "channel", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from conversations.unarchive method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "conversations.unarchive success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "channel_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from conversations.unarchive method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "channel_not_found", + "not_archived", + "not_authed", + "invalid_auth", + "account_inactive", + "user_is_bot", + "user_is_restricted", + "user_is_ultra_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "team_added_to_org", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "needed": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "provided": { + "type": "string" + } + }, + "required": [ + "ok", + "error" + ], + "title": "conversations.unarchive error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:write", + "groups:write", + "im:write", + "mpim:write" + ] + } + ], + "tags": [ + "conversations" + ] + } + }, + "/dialog.open": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Open a dialog with a user", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/dialog.open" + }, + "operationId": "dialog_open", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The dialog definition. This must be a JSON-encoded string.", + "in": "query", + "name": "dialog", + "required": true, + "type": "string" + }, + { + "description": "Exchange a trigger to post to the user.", + "in": "query", + "name": "trigger_id", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response is quite minimal.", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from dialog.open method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "dialog.open schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response, before getting to any possible validation errors.", + "examples": { + "application/json": { + "error": "missing_trigger", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from dialog.open method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "validation_errors", + "missing_trigger", + "missing_dialog", + "trigger_exchanged", + "trigger_expired", + "invalid_trigger", + "app_missing_action_url", + "cannot_create_dialog", + "failed_sending_dialog", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "dialog.open error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "dialog" + ] + } + }, + "/dnd.endDnd": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Ends the current user's Do Not Disturb session immediately.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/dnd.endDnd" + }, + "operationId": "dnd_endDnd", + "parameters": [ + { + "description": "Authentication token. Requires scope: `dnd:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from dnd.endDnd method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "dnd.endDnd schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from dnd.endDnd method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "unknown_error", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "dnd.endDnd error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "dnd:write" + ] + } + ], + "tags": [ + "dnd" + ] + } + }, + "/dnd.endSnooze": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Ends the current user's snooze mode immediately.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/dnd.endSnooze" + }, + "operationId": "dnd_endSnooze", + "parameters": [ + { + "description": "Authentication token. Requires scope: `dnd:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from dnd.endSnooze method", + "properties": { + "dnd_enabled": { + "type": "boolean" + }, + "next_dnd_end_ts": { + "type": "integer" + }, + "next_dnd_start_ts": { + "type": "integer" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "snooze_enabled": { + "type": "boolean" + } + }, + "required": [ + "ok", + "dnd_enabled", + "next_dnd_start_ts", + "next_dnd_end_ts", + "snooze_enabled" + ], + "title": "dnd.endSnooze schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from dnd.endSnooze method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "snooze_not_active", + "snooze_end_failed", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "dnd.endSnooze error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "dnd:write" + ] + } + ], + "tags": [ + "dnd" + ] + } + }, + "/dnd.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieves a user's current Do Not Disturb status.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/dnd.info" + }, + "operationId": "dnd_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `dnd:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "User to fetch status for (defaults to current user)", + "in": "query", + "name": "user", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from dnd.info method", + "properties": { + "dnd_enabled": { + "type": "boolean" + }, + "next_dnd_end_ts": { + "type": "integer" + }, + "next_dnd_start_ts": { + "type": "integer" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "snooze_enabled": { + "type": "boolean" + }, + "snooze_endtime": { + "type": "integer" + }, + "snooze_remaining": { + "type": "integer" + } + }, + "required": [ + "ok", + "dnd_enabled", + "next_dnd_start_ts", + "next_dnd_end_ts" + ], + "title": "dnd.info schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from dnd.info method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "user_not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "dnd.info error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "dnd:read" + ] + } + ], + "tags": [ + "dnd" + ] + } + }, + "/dnd.setSnooze": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Turns on Do Not Disturb mode for the current user, or changes its duration.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/dnd.setSnooze" + }, + "operationId": "dnd_setSnooze", + "parameters": [ + { + "description": "Authentication token. Requires scope: `dnd:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Number of minutes, from now, to snooze until.", + "in": "formData", + "name": "num_minutes", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from dnd.setSnooze method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "snooze_enabled": { + "type": "boolean" + }, + "snooze_endtime": { + "type": "integer" + }, + "snooze_remaining": { + "type": "integer" + } + }, + "required": [ + "ok", + "snooze_enabled", + "snooze_endtime", + "snooze_remaining" + ], + "title": "dnd.setSnooze schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from dnd.setSnooze method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "missing_duration", + "snooze_failed", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "too_long", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "dnd.setSnooze error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "dnd:write" + ] + } + ], + "tags": [ + "dnd" + ] + } + }, + "/dnd.teamInfo": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieves the Do Not Disturb status for up to 50 users on a team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/dnd.teamInfo" + }, + "operationId": "dnd_teamInfo", + "parameters": [ + { + "description": "Authentication token. Requires scope: `dnd:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Comma-separated list of users to fetch Do Not Disturb status for", + "in": "query", + "name": "users", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "users": { + "U023BECGF": { + "dnd_enabled": true, + "next_dnd_end_ts": 1450423800, + "next_dnd_start_ts": 1450387800 + }, + "W058CJVAA": { + "dnd_enabled": false, + "next_dnd_end_ts": 1, + "next_dnd_start_ts": 1 + } + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "dnd:read" + ] + } + ], + "tags": [ + "dnd" + ] + } + }, + "/emoji.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Lists custom emoji for a team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/emoji.list" + }, + "operationId": "emoji_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `emoji:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "emoji:read" + ] + } + ], + "tags": [ + "emoji" + ] + } + }, + "/files.comments.delete": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Deletes an existing comment on a file.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.comments.delete" + }, + "operationId": "files_comments_delete", + "parameters": [ + { + "description": "Authentication token. Requires scope: `files:write:user`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "File to delete a comment from.", + "in": "formData", + "name": "file", + "type": "string" + }, + { + "description": "The comment to delete.", + "in": "formData", + "name": "id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Standard success response is very simple", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response files.comments.delete method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "files.comments.delete schema", + "type": "object" + } + }, + "default": { + "description": "Standard failure response when used with an invalid token", + "examples": { + "application/json": { + "error": "file_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response files.comments.delete method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "cant_delete", + "comment_not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "files.comments.delete error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "files:write:user" + ] + } + ], + "tags": [ + "files.comments", + "files" + ] + } + }, + "/files.delete": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Deletes a file.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.delete" + }, + "operationId": "files_delete", + "parameters": [ + { + "description": "Authentication token. Requires scope: `files:write:user`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "ID of file to delete.", + "in": "formData", + "name": "file", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response files.delete method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "files.delete schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response files.delete method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "file_not_found", + "file_deleted", + "cant_delete_file", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "files.delete error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "files:write:user" + ] + } + ], + "tags": [ + "files" + ] + } + }, + "/files.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets information about a file.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.info" + }, + "operationId": "files_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `files:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Specify a file by providing its ID.", + "in": "query", + "name": "file", + "type": "string" + }, + { + "in": "query", + "name": "count", + "type": "string" + }, + { + "in": "query", + "name": "page", + "type": "string" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Parameter for pagination. File comments are paginated for a single file. Set `cursor` equal to the `next_cursor` attribute returned by the previous request's `response_metadata`. This parameter is optional, but pagination is mandatory: the default value simply fetches the first \"page\" of the collection of comments. See [pagination](/docs/pagination) for more details.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "comments": [], + "file": { + "channels": [ + "C0T8SE4AU" + ], + "comments_count": 0, + "created": 1531763342, + "deanimate_gif": "https://.../tedair_deanimate_gif.png", + "display_as_bot": false, + "editable": false, + "external_type": "", + "filetype": "gif", + "groups": [], + "has_rich_preview": false, + "id": "F0S43PZDF", + "image_exif_rotation": 1, + "ims": [], + "is_external": false, + "is_public": true, + "is_starred": false, + "mimetype": "image/gif", + "mode": "hosted", + "name": "tedair.gif", + "original_h": 226, + "original_w": 176, + "permalink": "https://.../tedair.gif", + "permalink_public": "https://.../...", + "pjpeg": "https://.../tedair_pjpeg.jpg", + "pretty_type": "GIF", + "public_url_shared": false, + "shares": { + "public": { + "C0T8SE4AU": [ + { + "channel_name": "file-under", + "latest_reply": "1531763348.000001", + "reply_count": 1, + "reply_users": [ + "U061F7AUR" + ], + "reply_users_count": 1, + "team_id": "T061EG9R6", + "thread_ts": "1531763273.000015", + "ts": "1531763348.000001" + } + ] + } + }, + "size": 137531, + "thumb_160": "https://.../tedair_=_160.png", + "thumb_360": "https://.../tedair_360.png", + "thumb_360_gif": "https://.../tedair_360.gif", + "thumb_360_h": 226, + "thumb_360_w": 176, + "thumb_64": "https://.../tedair_64.png", + "thumb_80": "https://.../tedair_80.png", + "timestamp": 1531763342, + "title": "tedair.gif", + "url_private": "https://.../tedair.gif", + "url_private_download": "https://.../tedair.gif", + "user": "U061F7AUR", + "username": "" + }, + "ok": true, + "response_metadata": { + "next_cursor": "dGVhbTpDMUg5UkVTR0w=" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from files.info method", + "properties": { + "comments": { + "$ref": "#/definitions/objs_comments" + }, + "content_html": { + "type": "null" + }, + "editor": { + "$ref": "#/definitions/defs_user_id" + }, + "file": { + "$ref": "#/definitions/objs_file" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "paging": { + "$ref": "#/definitions/objs_paging" + }, + "response_metadata": { + "$ref": "#/definitions/objs_response_metadata" + } + }, + "required": [ + "ok", + "file", + "comments" + ], + "title": "files.info schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from files.info method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "file_not_found", + "file_deleted", + "timezone_count_failed", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "files.info error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "files:read" + ] + } + ], + "tags": [ + "files" + ] + } + }, + "/files.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List for a team, in a channel, or from a user with applied filters.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.list" + }, + "operationId": "files_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `files:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Filter files created by a single user.", + "in": "query", + "name": "user", + "type": "string" + }, + { + "description": "Filter files appearing in a specific channel, indicated by its ID.", + "in": "query", + "name": "channel", + "type": "string" + }, + { + "description": "Filter files created after this timestamp (inclusive).", + "in": "query", + "name": "ts_from", + "type": "number" + }, + { + "description": "Filter files created before this timestamp (inclusive).", + "in": "query", + "name": "ts_to", + "type": "number" + }, + { + "description": "Filter files by type ([see below](#file_types)). You can pass multiple values in the types argument, like `types=spaces,snippets`.The default value is `all`, which does not filter the list.", + "in": "query", + "name": "types", + "type": "string" + }, + { + "in": "query", + "name": "count", + "type": "string" + }, + { + "in": "query", + "name": "page", + "type": "string" + }, + { + "description": "Show truncated file info for files hidden due to being too old, and the team who owns the file being over the file limit.", + "in": "query", + "name": "show_files_hidden_by_limit", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "files": [ + { + "channels": [ + "C0T8SE4AU" + ], + "comments_count": 0, + "created": 1531763254, + "deanimate_gif": "https://.../billair_deanimate_gif.png", + "display_as_bot": false, + "editable": false, + "external_type": "", + "filetype": "gif", + "groups": [], + "id": "F0S43P1CZ", + "image_exif_rotation": 1, + "ims": [], + "is_external": false, + "is_public": true, + "mimetype": "image/gif", + "mode": "hosted", + "name": "billair.gif", + "original_h": 226, + "original_w": 176, + "permalink": "https://.../billair.gif", + "permalink_public": "https://.../...", + "pjpeg": "https://.../billair_pjpeg.jpg", + "pretty_type": "GIF", + "public_url_shared": false, + "size": 144538, + "thumb_160": "https://.../billair_=_160.png", + "thumb_360": "https://.../billair_360.png", + "thumb_360_gif": "https://.../billair_360.gif", + "thumb_360_h": 226, + "thumb_360_w": 176, + "thumb_64": "https://.../billair_64.png", + "thumb_80": "https://.../billair_80.png", + "timestamp": 1531763254, + "title": "billair.gif", + "url_private": "https://.../billair.gif", + "url_private_download": "https://.../billair.gif", + "user": "U061F7AUR", + "username": "" + }, + { + "channels": [ + "C0T8SE4AU" + ], + "comments_count": 0, + "created": 1531763342, + "deanimate_gif": "https://.../tedair_deanimate_gif.png", + "display_as_bot": false, + "editable": false, + "external_type": "", + "filetype": "gif", + "groups": [], + "id": "F0S43PZDF", + "image_exif_rotation": 1, + "ims": [], + "is_external": false, + "is_public": true, + "mimetype": "image/gif", + "mode": "hosted", + "name": "tedair.gif", + "original_h": 226, + "original_w": 176, + "permalink": "https://.../tedair.gif", + "permalink_public": "https://.../...", + "pjpeg": "https://.../tedair_pjpeg.jpg", + "pretty_type": "GIF", + "public_url_shared": false, + "size": 137531, + "thumb_160": "https://.../tedair_=_160.png", + "thumb_360": "https://.../tedair_360.png", + "thumb_360_gif": "https://.../tedair_360.gif", + "thumb_360_h": 226, + "thumb_360_w": 176, + "thumb_64": "https://.../tedair_64.png", + "thumb_80": "https://.../tedair_80.png", + "timestamp": 1531763342, + "title": "tedair.gif", + "url_private": "https://.../tedair.gif", + "url_private_download": "https://.../tedair.gif", + "user": "U061F7AUR", + "username": "" + } + ], + "ok": true, + "paging": { + "count": 100, + "page": 1, + "pages": 1, + "total": 2 + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from files.list method", + "properties": { + "files": { + "items": { + "$ref": "#/definitions/objs_file" + }, + "minItems": 0, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "paging": { + "$ref": "#/definitions/objs_paging" + } + }, + "required": [ + "ok", + "files", + "paging" + ], + "title": "files.list schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from files.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "user_not_found", + "unknown_type", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "files.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "files:read" + ] + } + ], + "tags": [ + "files" + ] + } + }, + "/files.remote.add": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Adds a file from a remote service", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.remote.add" + }, + "operationId": "files_remote_add", + "parameters": [ + { + "description": "Authentication token. Requires scope: `remote_files:write`", + "in": "formData", + "name": "token", + "type": "string" + }, + { + "description": "Creator defined GUID for the file.", + "in": "formData", + "name": "external_id", + "type": "string" + }, + { + "description": "Title of the file being shared.", + "in": "formData", + "name": "title", + "type": "string" + }, + { + "description": "type of file", + "in": "formData", + "name": "filetype", + "type": "string" + }, + { + "description": "URL of the remote file.", + "in": "formData", + "name": "external_url", + "type": "string" + }, + { + "description": "Preview of the document via `multipart/form-data`.", + "in": "formData", + "name": "preview_image", + "type": "string" + }, + { + "description": "A text file (txt, pdf, doc, etc.) containing textual search terms that are used to improve discovery of the remote file.", + "in": "formData", + "name": "indexable_file_contents", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "remote_files:write" + ] + } + ], + "tags": [ + "files.remote", + "files" + ] + } + }, + "/files.remote.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieve information about a remote file added to Slack", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.remote.info" + }, + "operationId": "files_remote_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `remote_files:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Specify a file by providing its ID.", + "in": "query", + "name": "file", + "type": "string" + }, + { + "description": "Creator defined GUID for the file.", + "in": "query", + "name": "external_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "remote_files:read" + ] + } + ], + "tags": [ + "files.remote", + "files" + ] + } + }, + "/files.remote.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieve information about a remote file added to Slack", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.remote.list" + }, + "operationId": "files_remote_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `remote_files:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Filter files appearing in a specific channel, indicated by its ID.", + "in": "query", + "name": "channel", + "type": "string" + }, + { + "description": "Filter files created after this timestamp (inclusive).", + "in": "query", + "name": "ts_from", + "type": "number" + }, + { + "description": "Filter files created before this timestamp (inclusive).", + "in": "query", + "name": "ts_to", + "type": "number" + }, + { + "description": "The maximum number of items to return.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "remote_files:read" + ] + } + ], + "tags": [ + "files.remote", + "files" + ] + } + }, + "/files.remote.remove": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Remove a remote file.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.remote.remove" + }, + "operationId": "files_remote_remove", + "parameters": [ + { + "description": "Authentication token. Requires scope: `remote_files:write`", + "in": "formData", + "name": "token", + "type": "string" + }, + { + "description": "Specify a file by providing its ID.", + "in": "formData", + "name": "file", + "type": "string" + }, + { + "description": "Creator defined GUID for the file.", + "in": "formData", + "name": "external_id", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "remote_files:write" + ] + } + ], + "tags": [ + "files.remote", + "files" + ] + } + }, + "/files.remote.share": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Share a remote file into a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.remote.share" + }, + "operationId": "files_remote_share", + "parameters": [ + { + "description": "Authentication token. Requires scope: `remote_files:share`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Specify a file registered with Slack by providing its ID. Either this field or `external_id` or both are required.", + "in": "query", + "name": "file", + "type": "string" + }, + { + "description": "The globally unique identifier (GUID) for the file, as set by the app registering the file with Slack. Either this field or `file` or both are required.", + "in": "query", + "name": "external_id", + "type": "string" + }, + { + "description": "Comma-separated list of channel IDs where the file will be shared.", + "in": "query", + "name": "channels", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "remote_files:share" + ] + } + ], + "tags": [ + "files.remote", + "files" + ] + } + }, + "/files.remote.update": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Updates an existing remote file.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.remote.update" + }, + "operationId": "files_remote_update", + "parameters": [ + { + "description": "Authentication token. Requires scope: `remote_files:write`", + "in": "formData", + "name": "token", + "type": "string" + }, + { + "description": "Specify a file by providing its ID.", + "in": "formData", + "name": "file", + "type": "string" + }, + { + "description": "Creator defined GUID for the file.", + "in": "formData", + "name": "external_id", + "type": "string" + }, + { + "description": "Title of the file being shared.", + "in": "formData", + "name": "title", + "type": "string" + }, + { + "description": "type of file", + "in": "formData", + "name": "filetype", + "type": "string" + }, + { + "description": "URL of the remote file.", + "in": "formData", + "name": "external_url", + "type": "string" + }, + { + "description": "Preview of the document via `multipart/form-data`.", + "in": "formData", + "name": "preview_image", + "type": "string" + }, + { + "description": "File containing contents that can be used to improve searchability for the remote file.", + "in": "formData", + "name": "indexable_file_contents", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "remote_files:write" + ] + } + ], + "tags": [ + "files.remote", + "files" + ] + } + }, + "/files.revokePublicURL": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Revokes public/external sharing access for a file", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.revokePublicURL" + }, + "operationId": "files_revokePublicURL", + "parameters": [ + { + "description": "Authentication token. Requires scope: `files:write:user`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "File to revoke", + "in": "formData", + "name": "file", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from files.revokePublicURL method", + "properties": { + "file": { + "$ref": "#/definitions/objs_file" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "file" + ], + "title": "files.revokePublicURL schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from files.revokePublicURL method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "file_not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "files.revokePublicURL error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "files:write:user" + ] + } + ], + "tags": [ + "files" + ] + } + }, + "/files.sharedPublicURL": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Enables a file for public/external sharing.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.sharedPublicURL" + }, + "operationId": "files_sharedPublicURL", + "parameters": [ + { + "description": "Authentication token. Requires scope: `files:write:user`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "File to share", + "in": "formData", + "name": "file", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from files.sharedPublicURL method", + "properties": { + "file": { + "$ref": "#/definitions/objs_file" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "file" + ], + "title": "files.sharedPublicURL schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from files.sharedPublicURL method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "file_not_found", + "not_allowed", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "files.sharedPublicURL error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "files:write:user" + ] + } + ], + "tags": [ + "files" + ] + } + }, + "/files.upload": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Uploads or creates a file.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/files.upload" + }, + "operationId": "files_upload", + "parameters": [ + { + "description": "Authentication token. Requires scope: `files:write:user`", + "in": "formData", + "name": "token", + "type": "string" + }, + { + "description": "File contents via `multipart/form-data`. If omitting this parameter, you must submit `content`.", + "in": "formData", + "name": "file", + "type": "string" + }, + { + "description": "File contents via a POST variable. If omitting this parameter, you must provide a `file`.", + "in": "formData", + "name": "content", + "type": "string" + }, + { + "description": "A [file type](/types/file#file_types) identifier.", + "in": "formData", + "name": "filetype", + "type": "string" + }, + { + "description": "Filename of file.", + "in": "formData", + "name": "filename", + "type": "string" + }, + { + "description": "Title of file.", + "in": "formData", + "name": "title", + "type": "string" + }, + { + "description": "The message text introducing the file in specified `channels`.", + "in": "formData", + "name": "initial_comment", + "type": "string" + }, + { + "description": "Comma-separated list of channel names or IDs where the file will be shared.", + "in": "formData", + "name": "channels", + "type": "string" + }, + { + "description": "Provide another message's `ts` value to upload this file as a reply. Never use a reply's `ts` value; use its parent instead.", + "in": "formData", + "name": "thread_ts", + "type": "number" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Success response after uploading a file to a channel with an initial message", + "examples": { + "application/json": { + "file": { + "channels": [], + "comments_count": 0, + "created": 1532293501, + "display_as_bot": false, + "editable": false, + "external_type": "", + "filetype": "gif", + "groups": [], + "has_rich_preview": false, + "id": "F0TD00400", + "image_exif_rotation": 1, + "ims": [ + "D0L4B9P0Q" + ], + "is_external": false, + "is_public": false, + "is_starred": false, + "mimetype": "image/jpeg", + "mode": "hosted", + "name": "dramacat.gif", + "original_h": 366, + "original_w": 526, + "permalink": "https://.../dramacat.gif", + "permalink_public": "https://.../More-Path-Components", + "pretty_type": "JPEG", + "public_url_shared": false, + "shares": { + "private": { + "D0L4B9P0Q": [ + { + "reply_count": 0, + "reply_users": [], + "reply_users_count": 0, + "ts": "1532293503.000001" + } + ] + } + }, + "size": 43518, + "thumb_160": "https://.../dramacat_160.gif", + "thumb_360": "https://.../dramacat_360.gif", + "thumb_360_h": 250, + "thumb_360_w": 360, + "thumb_480": "https://.../dramacat_480.gif", + "thumb_480_h": 334, + "thumb_480_w": 480, + "thumb_64": "https://.../dramacat_64.gif", + "thumb_80": "https://.../dramacat_80.gif", + "timestamp": 1532293501, + "title": "dramacat", + "url_private": "https://.../dramacat.gif", + "url_private_download": "https://.../dramacat.gif", + "user": "U0L4B9NSU", + "username": "" + }, + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response files.upload method", + "properties": { + "file": { + "$ref": "#/definitions/objs_file" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "file" + ], + "title": "files.upload schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response files.upload method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "posting_to_general_channel_denied", + "invalid_channel", + "file_uploads_disabled", + "file_uploads_except_images_disabled", + "storage_limit_reached", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "files.upload error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "files:write:user" + ] + } + ], + "tags": [ + "files" + ] + } + }, + "/migration.exchange": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "For Enterprise Grid workspaces, map local user IDs to global user IDs", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/migration.exchange" + }, + "operationId": "migration_exchange", + "parameters": [ + { + "description": "Authentication token. Requires scope: `tokens.basic`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "A comma-separated list of user ids, up to 400 per request", + "in": "query", + "name": "users", + "required": true, + "type": "string" + }, + { + "description": "Specify team_id starts with `T` in case of Org Token", + "in": "query", + "name": "team_id", + "type": "string" + }, + { + "description": "Specify `true` to convert `W` global user IDs to workspace-specific `U` IDs. Defaults to `false`.", + "in": "query", + "name": "to_old", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response when mappings exist for the specified user IDs", + "examples": { + "application/json": { + "enterprise_id": "E1KQTNXE1", + "invalid_user_ids": [ + "U21ABZZXX" + ], + "ok": true, + "team_id": "T1KR7PE1W", + "user_id_map": { + "U06UBSUN5": "W06M56XJM", + "U06UBSVB3": "W06PUUDLY", + "U06UBSVDX": "W06PUUDMW", + "U06UEB62U": "W06PTT6GH", + "W06UAZ65Q": "W06UAZ65Q" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "Schema for successful response from migration.exchange method", + "properties": { + "enterprise_id": { + "title": "The enterprise grid organization ID containing the workspace/team.", + "type": "string" + }, + "invalid_user_ids": { + "items": { + "type": "string" + }, + "title": "A list of User IDs that cannot be mapped or found", + "type": "array" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "team_id": { + "$ref": "#/definitions/defs_team" + }, + "user_id_map": { + "additionalProperties": true, + "title": "A mapping of provided user IDs with mapped user IDs", + "type": "object" + } + }, + "required": [ + "ok", + "team_id", + "enterprise_id" + ], + "title": "migration.exchange success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response when there are no mappings to provide", + "examples": { + "application/json": { + "error": "not_enterprise_team", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from migration.exchange method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_enterprise_team", + "too_many_users", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "migration.exchange error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "tokens.basic" + ] + } + ], + "tags": [ + "migration" + ] + } + }, + "/oauth.access": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Exchanges a temporary OAuth verifier code for an access token.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/oauth.access" + }, + "operationId": "oauth_access", + "parameters": [ + { + "description": "Issued when you created your application.", + "in": "query", + "name": "client_id", + "type": "string" + }, + { + "description": "Issued when you created your application.", + "in": "query", + "name": "client_secret", + "type": "string" + }, + { + "description": "The `code` param returned via the OAuth callback.", + "in": "query", + "name": "code", + "type": "string" + }, + { + "description": "This must match the originally submitted URI (if one was sent).", + "in": "query", + "name": "redirect_uri", + "type": "string" + }, + { + "description": "Request the user to add your app only to a single channel. Only valid with a [legacy workspace app](https://api.slack.com/legacy-workspace-apps).", + "in": "query", + "name": "single_channel", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Successful user token negotiation for a single scope", + "examples": { + "application/json": { + "access_token": "xoxp-XXXXXXXX-XXXXXXXX-XXXXX", + "enterprise_id": null, + "scope": "groups:write", + "team_id": "TXXXXXXXXX", + "team_name": "Wyld Stallyns LLC" + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_client_id", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "oauth" + ] + } + }, + "/oauth.token": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Exchanges a temporary OAuth verifier code for a workspace token.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/oauth.token" + }, + "operationId": "oauth_token", + "parameters": [ + { + "description": "Issued when you created your application.", + "in": "query", + "name": "client_id", + "type": "string" + }, + { + "description": "Issued when you created your application.", + "in": "query", + "name": "client_secret", + "type": "string" + }, + { + "description": "The `code` param returned via the OAuth callback.", + "in": "query", + "name": "code", + "type": "string" + }, + { + "description": "This must match the originally submitted URI (if one was sent).", + "in": "query", + "name": "redirect_uri", + "type": "string" + }, + { + "description": "Request the user to add your app only to a single channel.", + "in": "query", + "name": "single_channel", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Success example using a workspace app produces a very different kind of response", + "examples": { + "application/json": { + "access_token": "xoxa-access-token-string", + "app_id": "A012345678", + "app_user_id": "U0AB12ABC", + "authorizing_user_id": "U0HTT3Q0G", + "installer_user_id": "U061F7AUR", + "ok": true, + "permissions": [ + { + "resource_id": 0, + "resource_type": "channel", + "scopes": [ + "channels:read", + "chat:write:user" + ] + } + ], + "single_channel_id": "C061EG9T2", + "team_id": "T061EG9Z9", + "team_name": "Subarachnoid Workspace", + "token_type": "app" + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_client_id", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "oauth" + ] + } + }, + "/oauth.v2.access": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Exchanges a temporary OAuth verifier code for an access token.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/oauth.v2.access" + }, + "operationId": "oauth_v2_access", + "parameters": [ + { + "description": "Issued when you created your application.", + "in": "query", + "name": "client_id", + "type": "string" + }, + { + "description": "Issued when you created your application.", + "in": "query", + "name": "client_secret", + "type": "string" + }, + { + "description": "The `code` param returned via the OAuth callback.", + "in": "query", + "name": "code", + "required": true, + "type": "string" + }, + { + "description": "This must match the originally submitted URI (if one was sent).", + "in": "query", + "name": "redirect_uri", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Successful token request with scopes for both a bot user and a user token", + "examples": { + "application/json": { + "access_token": "xoxb-17653672481-19874698323-pdFZKVeTuE8sk7oOcBrzbqgy", + "app_id": "A0KRD7HC3", + "authed_user": { + "access_token": "xoxp-1234", + "id": "U1234", + "scope": "chat:write", + "token_type": "user" + }, + "bot_user_id": "U0KRQLJ9H", + "enterprise": { + "id": "E12345678", + "name": "slack-sports" + }, + "ok": true, + "scope": "commands,incoming-webhook", + "team": { + "id": "T9TK3CUKW", + "name": "Slack Softball Team" + }, + "token_type": "bot" + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_client_id", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "oauth.v2", + "oauth" + ] + } + }, + "/pins.add": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Pins an item to a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/pins.add" + }, + "operationId": "pins_add", + "parameters": [ + { + "description": "Authentication token. Requires scope: `pins:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Channel to pin the item in.", + "in": "formData", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "Timestamp of the message to pin.", + "in": "formData", + "name": "timestamp", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from pins.add method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "pins.add schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "channel_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from pins.add method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "bad_timestamp", + "message_not_found", + "channel_not_found", + "no_item_specified", + "already_pinned", + "permission_denied", + "file_not_shared", + "not_pinnable", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "pins.add error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "pins:write" + ] + } + ], + "tags": [ + "pins" + ] + } + }, + "/pins.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Lists items pinned to a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/pins.list" + }, + "operationId": "pins_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `pins:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Channel to get pinned items for.", + "in": "query", + "name": "channel", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "items": [ + { + "channel": "C2U86NC6H", + "created": 1508881078, + "created_by": "U2U85N1RZ", + "message": { + "permalink": "https://hitchhikers.slack.com/archives/C2U86NC6H/p1508197641000151", + "pinned_to": [ + "C2U86NC6H" + ], + "text": "What is the meaning of life?", + "ts": "1508197641.000151", + "type": "message", + "user": "U2U85N1RZ" + }, + "type": "message" + }, + { + "channel": "C2U86NC6H", + "created": 1508880991, + "created_by": "U2U85N1RZ", + "message": { + "permalink": "https://hitchhikers.slack.com/archives/C2U86NC6H/p1508284197000015", + "pinned_to": [ + "C2U86NC6H" + ], + "text": "The meaning of life, the universe, and everything is 42.", + "ts": "1503289197.000015", + "type": "message", + "user": "U2U85N1RZ" + }, + "type": "message" + } + ], + "ok": true + } + }, + "schema": { + "description": "Schema for successful response from pins.list method", + "items": [ + { + "additionalProperties": false, + "properties": { + "items": { + "items": [ + { + "additionalProperties": false, + "properties": { + "created": { + "type": "integer" + }, + "created_by": { + "$ref": "#/definitions/defs_user_id" + }, + "file": { + "$ref": "#/definitions/objs_file" + }, + "type": { + "enum": [ + "file" + ], + "type": "string" + } + }, + "title": "File Pin", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "created": { + "type": "integer" + }, + "created_by": { + "$ref": "#/definitions/defs_user_id" + }, + "message": { + "$ref": "#/definitions/objs_message" + }, + "type": { + "enum": [ + "message" + ], + "type": "string" + } + }, + "title": "Message Pin", + "type": "object" + } + ], + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "items" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "count": { + "type": "integer" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok", + "count" + ], + "type": "object" + } + ], + "title": "pins.list success schema" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from pins.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "channel_not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "pins.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "pins:read" + ] + } + ], + "tags": [ + "pins" + ] + } + }, + "/pins.remove": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Un-pins an item from a channel.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/pins.remove" + }, + "operationId": "pins_remove", + "parameters": [ + { + "description": "Authentication token. Requires scope: `pins:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Channel where the item is pinned to.", + "in": "formData", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "Timestamp of the message to un-pin.", + "in": "formData", + "name": "timestamp", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from pins.remove method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "pins.remove schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "no_pin", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from pins.remove method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "bad_timestamp", + "file_not_found", + "file_comment_not_found", + "message_not_found", + "no_item_specified", + "not_pinned", + "permission_denied", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_typ", + "missing_post_typ", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeou", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "pins.remove error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "pins:write" + ] + } + ], + "tags": [ + "pins" + ] + } + }, + "/reactions.add": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Adds a reaction to an item.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reactions.add" + }, + "operationId": "reactions_add", + "parameters": [ + { + "description": "Channel where the message to add reaction to was posted.", + "in": "formData", + "name": "channel", + "required": true, + "type": "string" + }, + { + "description": "Reaction (emoji) name.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + }, + { + "description": "Timestamp of the message to add reaction to.", + "in": "formData", + "name": "timestamp", + "required": true, + "type": "string" + }, + { + "description": "Authentication token. Requires scope: `reactions:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from reactions.add method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "reactions.add schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "already_reacted", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reactions.add method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "bad_timestamp", + "message_not_found", + "no_item_specified", + "invalid_name", + "already_reacted", + "too_many_emoji", + "too_many_reactions", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reactions.add error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reactions:write" + ] + } + ], + "tags": [ + "reactions" + ] + } + }, + "/reactions.get": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets reactions for an item.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reactions.get" + }, + "operationId": "reactions_get", + "parameters": [ + { + "description": "Authentication token. Requires scope: `reactions:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Channel where the message to get reactions for was posted.", + "in": "query", + "name": "channel", + "type": "string" + }, + { + "description": "File to get reactions for.", + "in": "query", + "name": "file", + "type": "string" + }, + { + "description": "File comment to get reactions for.", + "in": "query", + "name": "file_comment", + "type": "string" + }, + { + "description": "If true always return the complete reaction list.", + "in": "query", + "name": "full", + "type": "boolean" + }, + { + "description": "Timestamp of the message to get reactions for.", + "in": "query", + "name": "timestamp", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "file": { + "channels": [ + "C2U7V2YA2" + ], + "comments_count": 1, + "created": 1507850315, + "groups": [], + "id": "F7H0D7ZA4", + "ims": [], + "name": "computer.gif", + "reactions": [ + { + "count": 1, + "name": "stuck_out_tongue_winking_eye", + "users": [ + "U2U85N1RV" + ] + } + ], + "timestamp": 1507850315, + "title": "computer.gif", + "user": "U2U85N1RV" + }, + "ok": true, + "type": "file" + } + }, + "schema": { + "description": "Schema for successful response from reactions.get method", + "items": [ + { + "additionalProperties": false, + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "message": { + "$ref": "#/definitions/objs_message" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "type": { + "enum": [ + "message" + ], + "type": "string" + } + }, + "required": [ + "ok", + "type", + "channel", + "message" + ] + }, + { + "additionalProperties": false, + "properties": { + "file": { + "$ref": "#/definitions/objs_file" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "type": { + "enum": [ + "file" + ], + "type": "string" + } + }, + "required": [ + "ok", + "type", + "file" + ] + }, + { + "additionalProperties": false, + "properties": { + "comment": { + "$ref": "#/definitions/objs_comment" + }, + "file": { + "$ref": "#/definitions/objs_file" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "type": { + "enum": [ + "file_comment" + ], + "type": "string" + } + }, + "required": [ + "ok", + "type", + "file", + "comment" + ] + } + ], + "title": "reactions.get success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reactions.get method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "bad_timestamp", + "file_not_found", + "file_comment_not_found", + "message_not_found", + "no_item_specified", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reactions.get error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reactions:read" + ] + } + ], + "tags": [ + "reactions" + ] + } + }, + "/reactions.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Lists reactions made by a user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reactions.list" + }, + "operationId": "reactions_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `reactions:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Show reactions made by this user. Defaults to the authed user.", + "in": "query", + "name": "user", + "type": "string" + }, + { + "description": "If true always return the complete reaction list.", + "in": "query", + "name": "full", + "type": "boolean" + }, + { + "in": "query", + "name": "count", + "type": "integer" + }, + { + "in": "query", + "name": "page", + "type": "integer" + }, + { + "description": "Parameter for pagination. Set `cursor` equal to the `next_cursor` attribute returned by the previous request's `response_metadata`. This parameter is optional, but pagination is mandatory: the default value simply fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more details.", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached.", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "items": [ + { + "channel": "C3UKJTQAC", + "message": { + "bot_id": "B4VLRLMKJ", + "reactions": [ + { + "count": 1, + "name": "robot_face", + "users": [ + "U2U85N1RV" + ] + } + ], + "subtype": "bot_message", + "text": "Hello from Python! :tada:", + "ts": "1507849573.000090", + "username": "Shipit Notifications" + }, + "type": "message" + }, + { + "comment": { + "comment": "This is a file comment", + "created": 1508286096, + "id": "Fc7LP08P1U", + "reactions": [ + { + "count": 1, + "name": "white_check_mark", + "users": [ + "U2U85N1RV" + ] + } + ], + "timestamp": 1508286096, + "type": "file_comment", + "user": "U2U85N1RV" + }, + "file": { + "channels": [ + "C2U7V2YA2" + ], + "comments_count": 1, + "created": 1507850315, + "reactions": [ + { + "count": 1, + "name": "stuck_out_tongue_winking_eye", + "users": [ + "U2U85N1RV" + ] + } + ], + "title": "computer.gif", + "user": "U2U85N1RV", + "username": "" + } + }, + { + "file": { + "channels": [ + "C2U7V2YA2" + ], + "comments_count": 1, + "created": 1507850315, + "id": "F7H0D7ZA4", + "name": "computer.gif", + "reactions": [ + { + "count": 1, + "name": "stuck_out_tongue_winking_eye", + "users": [ + "U2U85N1RV" + ] + } + ], + "size": 1639034, + "title": "computer.gif", + "user": "U2U85N1RV", + "username": "" + }, + "type": "file" + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "dGVhbTpDMUg5UkVTR0w=" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from reactions.list method", + "properties": { + "items": { + "items": { + "items": [ + { + "additionalProperties": false, + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "message": { + "$ref": "#/definitions/objs_message" + }, + "type": { + "enum": [ + "message" + ], + "type": "string" + } + }, + "required": [ + "type", + "channel", + "message" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "file": { + "$ref": "#/definitions/objs_file" + }, + "type": { + "enum": [ + "file" + ], + "type": "string" + } + }, + "required": [ + "type", + "file" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "comment": { + "$ref": "#/definitions/objs_comment" + }, + "file": { + "$ref": "#/definitions/objs_file" + }, + "type": { + "enum": [ + "file_comment" + ], + "type": "string" + } + }, + "required": [ + "type", + "file", + "comment" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "paging": { + "$ref": "#/definitions/objs_paging" + }, + "response_metadata": { + "$ref": "#/definitions/objs_response_metadata" + } + }, + "required": [ + "ok", + "items" + ], + "title": "reactions.list schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reactions.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "user_not_found", + "not_authed", + "invalid_auth", + "account_inactiv", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reactions.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reactions:read" + ] + } + ], + "tags": [ + "reactions" + ] + } + }, + "/reactions.remove": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Removes a reaction from an item.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reactions.remove" + }, + "operationId": "reactions_remove", + "parameters": [ + { + "description": "Authentication token. Requires scope: `reactions:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Reaction (emoji) name.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + }, + { + "description": "File to remove reaction from.", + "in": "formData", + "name": "file", + "type": "string" + }, + { + "description": "File comment to remove reaction from.", + "in": "formData", + "name": "file_comment", + "type": "string" + }, + { + "description": "Channel where the message to remove reaction from was posted.", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "Timestamp of the message to remove reaction from.", + "in": "formData", + "name": "timestamp", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from reactions.remove method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "reactions.remove schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "no_reaction", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reactions.remove method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "bad_timestamp", + "file_not_found", + "file_comment_not_found", + "message_not_found", + "no_item_specified", + "invalid_name", + "no_reaction", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reactions.remove error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reactions:write" + ] + } + ], + "tags": [ + "reactions" + ] + } + }, + "/reminders.add": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Creates a reminder.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reminders.add" + }, + "operationId": "reminders_add", + "parameters": [ + { + "description": "Authentication token. Requires scope: `reminders:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "The content of the reminder", + "in": "formData", + "name": "text", + "required": true, + "type": "string" + }, + { + "description": "When this reminder should happen: the Unix timestamp (up to five years from now), the number of seconds until the reminder (if within 24 hours), or a natural language description (Ex. \"in 15 minutes,\" or \"every Thursday\")", + "in": "formData", + "name": "time", + "required": true, + "type": "string" + }, + { + "description": "The user who will receive the reminder. If no user is specified, the reminder will go to user who created it.", + "in": "formData", + "name": "user", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from reminders.add method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "reminder": { + "$ref": "#/definitions/objs_reminder" + } + }, + "required": [ + "ok", + "reminder" + ], + "title": "reminders.add schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reminders.add method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "cannot_parse", + "user_not_found", + "cannot_add_bot", + "cannot_add_slackbot", + "cannot_add_others", + "cannot_add_others_recurring", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reminders.add error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reminders:write" + ] + } + ], + "tags": [ + "reminders" + ] + } + }, + "/reminders.complete": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Marks a reminder as complete.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reminders.complete" + }, + "operationId": "reminders_complete", + "parameters": [ + { + "description": "Authentication token. Requires scope: `reminders:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "The ID of the reminder to be marked as complete", + "in": "formData", + "name": "reminder", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from reminders.complete method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "reminders.complete schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reminders.complete method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_found", + "cannot_complete_recurring", + "cannot_complete_others", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reminders.complete error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reminders:write" + ] + } + ], + "tags": [ + "reminders" + ] + } + }, + "/reminders.delete": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Deletes a reminder.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reminders.delete" + }, + "operationId": "reminders_delete", + "parameters": [ + { + "description": "Authentication token. Requires scope: `reminders:write`", + "in": "header", + "name": "token", + "type": "string" + }, + { + "description": "The ID of the reminder", + "in": "formData", + "name": "reminder", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from reminders.delete method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "reminders.delete schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reminders.delete method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reminders.delete error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reminders:write" + ] + } + ], + "tags": [ + "reminders" + ] + } + }, + "/reminders.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets information about a reminder.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reminders.info" + }, + "operationId": "reminders_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `reminders:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "The ID of the reminder", + "in": "query", + "name": "reminder", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from reminders.info method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "reminder": { + "$ref": "#/definitions/objs_reminder" + } + }, + "required": [ + "ok", + "reminder" + ], + "title": "reminders.info schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reminders.info method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reminders.info error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reminders:read" + ] + } + ], + "tags": [ + "reminders" + ] + } + }, + "/reminders.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Lists all reminders created by or for a given user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/reminders.list" + }, + "operationId": "reminders_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `reminders:read`", + "in": "query", + "name": "token", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from reminders.list method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "reminders": { + "items": { + "$ref": "#/definitions/objs_reminder" + }, + "type": "array" + } + }, + "required": [ + "ok", + "reminders" + ], + "title": "reminders.list schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from reminders.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "reminders.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "reminders:read" + ] + } + ], + "tags": [ + "reminders" + ] + } + }, + "/rtm.connect": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Starts a Real Time Messaging session.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/rtm.connect" + }, + "operationId": "rtm_connect", + "parameters": [ + { + "description": "Authentication token. Requires scope: `rtm:stream`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Batch presence deliveries via subscription. Enabling changes the shape of `presence_change` events. See [batch presence](/docs/presence-and-status#batching).", + "in": "query", + "name": "batch_presence_aware", + "type": "boolean" + }, + { + "description": "Only deliver presence events when requested by subscription. See [presence subscriptions](/docs/presence-and-status#subscriptions).", + "in": "query", + "name": "presence_sub", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "self": { + "id": "U4X318ZMZ", + "name": "robotoverlord" + }, + "team": { + "domain": "slackdemo", + "id": "T2U81E2FP", + "name": "SlackDemo" + }, + "url": "wss://..." + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from rtm.connect method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "self": { + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + }, + "team": { + "additionalProperties": false, + "properties": { + "domain": { + "type": "string" + }, + "id": { + "$ref": "#/definitions/defs_team" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "domain" + ], + "type": "object" + }, + "url": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "ok", + "url", + "team", + "self" + ], + "title": "rtm.connect schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from rtm.connect method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "rtm.connect error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "rtm:stream" + ] + } + ], + "tags": [ + "rtm" + ] + } + }, + "/search.messages": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Searches for messages matching a query.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/search.messages" + }, + "operationId": "search_messages", + "parameters": [ + { + "description": "Authentication token. Requires scope: `search:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Pass the number of results you want per \"page\". Maximum of `100`.", + "in": "query", + "name": "count", + "type": "integer" + }, + { + "description": "Pass a value of `true` to enable query highlight markers (see below).", + "in": "query", + "name": "highlight", + "type": "boolean" + }, + { + "in": "query", + "name": "page", + "type": "integer" + }, + { + "description": "Search query.", + "in": "query", + "name": "query", + "required": true, + "type": "string" + }, + { + "description": "Return matches sorted by either `score` or `timestamp`.", + "in": "query", + "name": "sort", + "type": "string" + }, + { + "description": "Change sort direction to ascending (`asc`) or descending (`desc`).", + "in": "query", + "name": "sort_dir", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "messages": { + "matches": [ + { + "channel": { + "id": "C12345678", + "is_ext_shared": false, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "general", + "pending_shared": [] + }, + "iid": "cb64bdaa-c1e8-4631-8a91-0f78080113e9", + "permalink": "https://hitchhikers.slack.com/archives/C12345678/p1508284197000015", + "team": "T12345678", + "text": "The meaning of life the universe and everything is 42.", + "ts": "1508284197.000015", + "type": "message", + "user": "U2U85N1RV", + "username": "roach" + }, + { + "channel": { + "id": "C12345678", + "is_ext_shared": false, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "random", + "pending_shared": [] + }, + "iid": "9a00d3c9-bd2d-45b0-988b-6cff99ae2a90", + "permalink": "https://hitchhikers.slack.com/archives/C12345678/p1508795665000236", + "team": "T12345678", + "text": "The meaning of life the universe and everything is 101010", + "ts": "1508795665.000236", + "type": "message", + "user": "", + "username": "robot overlord" + } + ], + "pagination": { + "first": 1, + "last": 2, + "page": 1, + "page_count": 1, + "per_page": 20, + "total_count": 2 + }, + "paging": { + "count": 20, + "page": 1, + "pages": 1, + "total": 2 + }, + "total": 2 + }, + "ok": true, + "query": "The meaning of life the universe and everything" + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "No query passed", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "search:read" + ] + } + ], + "tags": [ + "search" + ] + } + }, + "/stars.add": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Adds a star to an item.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/stars.add" + }, + "operationId": "stars_add", + "parameters": [ + { + "description": "Authentication token. Requires scope: `stars:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Channel to add star to, or channel where the message to add star to was posted (used with `timestamp`).", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "File to add star to.", + "in": "formData", + "name": "file", + "type": "string" + }, + { + "description": "File comment to add star to.", + "in": "formData", + "name": "file_comment", + "type": "string" + }, + { + "description": "Timestamp of the message to add star to.", + "in": "formData", + "name": "timestamp", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from stars.add method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "stars.add schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from stars.add method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "bad_timestamp", + "message_not_found", + "file_not_found", + "file_comment_not_found", + "channel_not_found", + "no_item_specified", + "already_starred", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "stars.add error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "stars:write" + ] + } + ], + "tags": [ + "stars" + ] + } + }, + "/stars.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Lists stars for a user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/stars.list" + }, + "operationId": "stars_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `stars:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "in": "query", + "name": "count", + "type": "string" + }, + { + "in": "query", + "name": "page", + "type": "string" + }, + { + "description": "Parameter for pagination. Set `cursor` equal to the `next_cursor` attribute returned by the previous request's `response_metadata`. This parameter is optional, but pagination is mandatory: the default value simply fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more details.", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached.", + "in": "query", + "name": "limit", + "type": "integer" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from stars.list method", + "properties": { + "items": { + "items": { + "items": [ + { + "additionalProperties": false, + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "date_create": { + "type": "integer" + }, + "message": { + "$ref": "#/definitions/objs_message" + }, + "type": { + "enum": [ + "message" + ], + "type": "string" + } + }, + "required": [ + "type", + "channel", + "message", + "date_create" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "date_create": { + "type": "integer" + }, + "file": { + "$ref": "#/definitions/objs_file" + }, + "type": { + "enum": [ + "file" + ], + "type": "string" + } + }, + "required": [ + "type", + "file", + "date_create" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "comment": { + "$ref": "#/definitions/objs_comment" + }, + "date_create": { + "type": "integer" + }, + "file": { + "$ref": "#/definitions/objs_file" + }, + "type": { + "enum": [ + "file_comment" + ], + "type": "string" + } + }, + "required": [ + "type", + "file", + "comment", + "date_create" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "date_create": { + "type": "integer" + }, + "type": { + "enum": [ + "channel" + ], + "type": "string" + } + }, + "required": [ + "type", + "channel", + "date_create" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "channel": { + "$ref": "#/definitions/defs_dm_id" + }, + "date_create": { + "type": "integer" + }, + "type": { + "enum": [ + "im" + ], + "type": "string" + } + }, + "required": [ + "type", + "channel", + "date_create" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "channel": { + "$ref": "#/definitions/defs_group_id" + }, + "date_create": { + "type": "integer" + }, + "type": { + "enum": [ + "group" + ], + "type": "string" + } + }, + "required": [ + "type", + "channel", + "date_create" + ], + "type": "object" + } + ] + }, + "type": "array" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "paging": { + "$ref": "#/definitions/objs_paging" + } + }, + "required": [ + "ok", + "items" + ], + "title": "stars.list schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from stars.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "stars.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "stars:read" + ] + } + ], + "tags": [ + "stars" + ] + } + }, + "/stars.remove": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Removes a star from an item.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/stars.remove" + }, + "operationId": "stars_remove", + "parameters": [ + { + "description": "Authentication token. Requires scope: `stars:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Channel to remove star from, or channel where the message to remove star from was posted (used with `timestamp`).", + "in": "formData", + "name": "channel", + "type": "string" + }, + { + "description": "File to remove star from.", + "in": "formData", + "name": "file", + "type": "string" + }, + { + "description": "File comment to remove star from.", + "in": "formData", + "name": "file_comment", + "type": "string" + }, + { + "description": "Timestamp of the message to remove star from.", + "in": "formData", + "name": "timestamp", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from stars.remove method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "stars.remove schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from stars.remove method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "bad_timestamp", + "message_not_found", + "file_not_found", + "file_comment_not_found", + "channel_not_found", + "no_item_specified", + "not_starred", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "stars.remove error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "stars:write" + ] + } + ], + "tags": [ + "stars" + ] + } + }, + "/team.accessLogs": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets the access logs for the current team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/team.accessLogs" + }, + "operationId": "team_accessLogs", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "End of time range of logs to include in results (inclusive).", + "in": "query", + "name": "before", + "type": "string" + }, + { + "in": "query", + "name": "count", + "type": "string" + }, + { + "in": "query", + "name": "page", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "This response demonstrates pagination and two access log entries.", + "examples": { + "application/json": { + "logins": [ + { + "count": 1, + "country": "US", + "date_first": 1422922864, + "date_last": 1422922864, + "ip": "127.0.0.1", + "isp": "BigCo ISP", + "region": "CA", + "user_agent": "SlackWeb Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.35 Safari/537.36", + "user_id": "U45678", + "username": "alice" + }, + { + "count": 1, + "country": "US", + "date_first": 1422922493, + "date_last": 1422922493, + "ip": "127.0.0.1", + "isp": "BigCo ISP", + "region": "CA", + "user_agent": "SlackWeb Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4", + "user_id": "U12345", + "username": "white_rabbit" + } + ], + "ok": true, + "paging": { + "count": 100, + "page": 1, + "pages": 1, + "total": 2 + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from team.accessLogs method", + "properties": { + "logins": { + "items": { + "additionalProperties": false, + "properties": { + "count": { + "type": "integer" + }, + "country": { + "type": [ + "string", + "null" + ] + }, + "date_first": { + "type": "integer" + }, + "date_last": { + "type": "integer" + }, + "ip": { + "type": [ + "string", + "null" + ] + }, + "isp": { + "type": [ + "string", + "null" + ] + }, + "region": { + "type": [ + "string", + "null" + ] + }, + "user_agent": { + "type": "string" + }, + "user_id": { + "$ref": "#/definitions/defs_user_id" + }, + "username": { + "type": "string" + } + }, + "required": [ + "user_id", + "username", + "date_first", + "date_last", + "count", + "ip", + "user_agent", + "isp", + "country", + "region" + ], + "type": "object" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "paging": { + "$ref": "#/definitions/objs_paging" + } + }, + "required": [ + "ok", + "logins", + "paging" + ], + "title": "team.accessLogs schema", + "type": "object" + } + }, + "default": { + "description": "A workspace must be on a paid plan to use this method, otherwise the `paid_only` error is thrown:", + "examples": { + "application/json": { + "error": "paid_only", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from team.accessLogs method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "paid_only", + "over_pagination_limit", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "team.accessLogs error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin" + ] + } + ], + "tags": [ + "team" + ] + } + }, + "/team.billableInfo": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets billable users information for the current team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/team.billableInfo" + }, + "operationId": "team_billableInfo", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "A user to retrieve the billable information for. Defaults to all users.", + "in": "query", + "name": "user", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "billable_info": { + "U02UCPE1R": { + "billing_active": true + }, + "U02UEBSD2": { + "billing_active": true + }, + "U0632EWRW": { + "billing_active": false + } + }, + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin" + ] + } + ], + "tags": [ + "team" + ] + } + }, + "/team.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets information about the current team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/team.info" + }, + "operationId": "team_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `team:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Team to get info on, if omitted, will return information about the current team. Will only return team that the authenticated token is allowed to see through external shared channels", + "in": "query", + "name": "team", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "team": { + "domain": "example", + "email_domain": "example.com", + "enterprise_id": "E1234A12AB", + "enterprise_name": "Umbrella Corporation", + "icon": { + "image_102": "https://...", + "image_132": "https://...", + "image_34": "https://...", + "image_44": "https://...", + "image_68": "https://...", + "image_88": "https://...", + "image_default": true + }, + "id": "T12345", + "name": "My Team" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from team.info method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "team": { + "$ref": "#/definitions/objs_team" + } + }, + "required": [ + "ok", + "team" + ], + "title": "team.info schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from team.info method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "team.info error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "team:read" + ] + } + ], + "tags": [ + "team" + ] + } + }, + "/team.integrationLogs": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets the integration logs for the current team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/team.integrationLogs" + }, + "operationId": "team_integrationLogs", + "parameters": [ + { + "description": "Authentication token. Requires scope: `admin`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Filter logs to this Slack app. Defaults to all logs.", + "in": "query", + "name": "app_id", + "type": "string" + }, + { + "description": "Filter logs with this change type. Defaults to all logs.", + "in": "query", + "name": "change_type", + "type": "string" + }, + { + "in": "query", + "name": "count", + "type": "string" + }, + { + "in": "query", + "name": "page", + "type": "string" + }, + { + "description": "Filter logs to this service. Defaults to all logs.", + "in": "query", + "name": "service_id", + "type": "string" + }, + { + "description": "Filter logs generated by this user\u2019s actions. Defaults to all logs.", + "in": "query", + "name": "user", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from team.integrationLogs method", + "properties": { + "logs": { + "items": { + "additionalProperties": false, + "properties": { + "admin_app_id": { + "$ref": "#/definitions/defs_app_id" + }, + "app_id": { + "$ref": "#/definitions/defs_app_id" + }, + "app_type": { + "type": "string" + }, + "change_type": { + "type": "string" + }, + "channel": { + "$ref": "#/definitions/defs_channel" + }, + "date": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "service_id": { + "type": "string" + }, + "service_type": { + "type": "string" + }, + "user_id": { + "$ref": "#/definitions/defs_user_id" + }, + "user_name": { + "type": "string" + } + }, + "required": [ + "user_id", + "user_name", + "date", + "change_type", + "app_type", + "app_id", + "scope" + ], + "type": "object" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "paging": { + "$ref": "#/definitions/objs_paging" + } + }, + "required": [ + "ok", + "logs", + "paging" + ], + "title": "team.integrationLogs schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from team.integrationLogs method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "team.integrationLogs error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "admin" + ] + } + ], + "tags": [ + "team" + ] + } + }, + "/team.profile.get": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieve a team's profile.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/team.profile.get" + }, + "operationId": "team_profile_get", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users.profile:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Filter by visibility.", + "in": "query", + "name": "visibility", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "profile": { + "fields": [ + { + "hint": "Enter the extension to reach your desk", + "id": "Xf06054AAA", + "is_hidden": 1, + "label": "Phone extension", + "options": null, + "ordering": 0, + "possible_values": null, + "type": "text" + }, + { + "hint": "When you were born", + "id": "Xf06054BBB", + "label": "Date of birth", + "options": null, + "ordering": 1, + "possible_values": null, + "type": "date" + }, + { + "hint": "Enter a link to your Facebook profile", + "id": "Xf06054CCC", + "label": "Facebook", + "options": null, + "ordering": 2, + "possible_values": null, + "type": "link" + }, + { + "hint": "Hogwarts, obviously", + "id": "Xf06054DDD", + "label": "House", + "options": null, + "ordering": 3, + "possible_values": [ + "Gryffindor", + "Hufflepuff", + "Ravenclaw", + "Slytherin" + ], + "type": "options_list" + }, + { + "hint": "Office location (LDAP)", + "id": "Xf06054EEE", + "label": "Location", + "options": { + "is_protected": 1 + }, + "ordering": 4, + "possible_values": null, + "type": "text" + }, + { + "hint": "The boss", + "id": "Xf06054FFF", + "label": "Manager", + "options": null, + "ordering": 5, + "possible_values": null, + "type": "user" + } + ] + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from team.profile.get method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "profile": { + "additionalProperties": false, + "properties": { + "fields": { + "items": { + "$ref": "#/definitions/objs_team_profile_field" + }, + "type": "array", + "uniqueItems": true + } + }, + "required": [ + "fields" + ], + "type": "object" + } + }, + "required": [ + "ok", + "profile" + ], + "title": "team.profile.get success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from team.profile.get method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_typ", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeou", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "team.profile.get error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users.profile:read" + ] + } + ], + "tags": [ + "team.profile", + "team" + ] + } + }, + "/usergroups.create": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Create a User Group", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/usergroups.create" + }, + "operationId": "usergroups_create", + "parameters": [ + { + "description": "Authentication token. Requires scope: `usergroups:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "A comma separated string of encoded channel IDs for which the User Group uses as a default.", + "in": "formData", + "name": "channels", + "type": "string" + }, + { + "description": "A short description of the User Group.", + "in": "formData", + "name": "description", + "type": "string" + }, + { + "description": "A mention handle. Must be unique among channels, users and User Groups.", + "in": "formData", + "name": "handle", + "type": "string" + }, + { + "description": "Include the number of users in each User Group.", + "in": "formData", + "name": "include_count", + "type": "boolean" + }, + { + "description": "A name for the User Group. Must be unique among User Groups.", + "in": "formData", + "name": "name", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from usergroups.create method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "usergroup": { + "$ref": "#/definitions/objs_subteam" + } + }, + "required": [ + "ok", + "usergroup" + ], + "title": "usergroups.create schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from usergroups.create method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "permission_denied", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "usergroups.create error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "usergroups:write" + ] + } + ], + "tags": [ + "usergroups" + ] + } + }, + "/usergroups.disable": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Disable an existing User Group", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/usergroups.disable" + }, + "operationId": "usergroups_disable", + "parameters": [ + { + "description": "Authentication token. Requires scope: `usergroups:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Include the number of users in the User Group.", + "in": "formData", + "name": "include_count", + "type": "boolean" + }, + { + "description": "The encoded ID of the User Group to disable.", + "in": "formData", + "name": "usergroup", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from usergroups.disable method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "usergroup": { + "$ref": "#/definitions/objs_subteam" + } + }, + "required": [ + "ok", + "usergroup" + ], + "title": "usergroups.disable schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from usergroups.disable method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "permission_denied", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "usergroups.disable error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "usergroups:write" + ] + } + ], + "tags": [ + "usergroups" + ] + } + }, + "/usergroups.enable": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Enable a User Group", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/usergroups.enable" + }, + "operationId": "usergroups_enable", + "parameters": [ + { + "description": "Authentication token. Requires scope: `usergroups:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Include the number of users in the User Group.", + "in": "formData", + "name": "include_count", + "type": "boolean" + }, + { + "description": "The encoded ID of the User Group to enable.", + "in": "formData", + "name": "usergroup", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from usergroups.enable method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "usergroup": { + "$ref": "#/definitions/objs_subteam" + } + }, + "required": [ + "ok", + "usergroup" + ], + "title": "usergroups.enable schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from usergroups.enable method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_require", + "fatal_error", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "usergroups.enable error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "usergroups:write" + ] + } + ], + "tags": [ + "usergroups" + ] + } + }, + "/usergroups.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List all User Groups for a team", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/usergroups.list" + }, + "operationId": "usergroups_list", + "parameters": [ + { + "description": "Include the list of users for each User Group.", + "in": "query", + "name": "include_users", + "type": "boolean" + }, + { + "description": "Authentication token. Requires scope: `usergroups:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Include the number of users in each User Group.", + "in": "query", + "name": "include_count", + "type": "boolean" + }, + { + "description": "Include disabled User Groups.", + "in": "query", + "name": "include_disabled", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "usergroups": [ + { + "auto_type": "admin", + "created_by": "USLACKBOT", + "date_create": 1446598059, + "date_delete": 0, + "date_update": 1446670362, + "deleted_by": null, + "description": "A group of all Administrators on your team.", + "handle": "admins", + "id": "S0614TZR7", + "is_external": false, + "is_usergroup": true, + "name": "Team Admins", + "prefs": { + "channels": [], + "groups": [] + }, + "team_id": "T060RNRCH", + "updated_by": "U060RNRCZ", + "user_count": "2" + }, + { + "auto_type": "owner", + "created_by": "USLACKBOT", + "date_create": 1446678371, + "date_delete": 0, + "date_update": 1446678371, + "deleted_by": null, + "description": "A group of all Owners on your team.", + "handle": "owners", + "id": "S06158AV7", + "is_external": false, + "is_usergroup": true, + "name": "Team Owners", + "prefs": { + "channels": [], + "groups": [] + }, + "team_id": "T060RNRCH", + "updated_by": "USLACKBOT", + "user_count": "1" + }, + { + "auto_type": null, + "created_by": "U060RNRCZ", + "date_create": 1446746793, + "date_delete": 1446748865, + "date_update": 1446747767, + "deleted_by": null, + "description": "Marketing gurus, PR experts and product advocates.", + "handle": "marketing-team", + "id": "S0615G0KT", + "is_external": false, + "is_usergroup": true, + "name": "Marketing Team", + "prefs": { + "channels": [], + "groups": [] + }, + "team_id": "T060RNRCH", + "updated_by": "U060RNRCZ", + "user_count": "0" + } + ] + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from usergroups.list method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "usergroups": { + "items": { + "$ref": "#/definitions/objs_subteam" + }, + "type": "array" + } + }, + "required": [ + "ok", + "usergroups" + ], + "title": "usergroups.list schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from usergroups.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_require", + "fatal_error", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "usergroups.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "usergroups:read" + ] + } + ], + "tags": [ + "usergroups" + ] + } + }, + "/usergroups.update": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Update an existing User Group", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/usergroups.update" + }, + "operationId": "usergroups_update", + "parameters": [ + { + "description": "A mention handle. Must be unique among channels, users and User Groups.", + "in": "formData", + "name": "handle", + "type": "string" + }, + { + "description": "A short description of the User Group.", + "in": "formData", + "name": "description", + "type": "string" + }, + { + "description": "A comma separated string of encoded channel IDs for which the User Group uses as a default.", + "in": "formData", + "name": "channels", + "type": "string" + }, + { + "description": "Authentication token. Requires scope: `usergroups:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Include the number of users in the User Group.", + "in": "formData", + "name": "include_count", + "type": "boolean" + }, + { + "description": "The encoded ID of the User Group to update.", + "in": "formData", + "name": "usergroup", + "required": true, + "type": "string" + }, + { + "description": "A name for the User Group. Must be unique among User Groups.", + "in": "formData", + "name": "name", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "usergroup": { + "auto_type": null, + "created_by": "U060R4BJ4", + "date_create": 1447096577, + "date_delete": 0, + "date_update": 1447102109, + "deleted_by": null, + "description": "Marketing gurus, PR experts and product advocates.", + "handle": "marketing-team", + "id": "S0616NG6M", + "is_external": false, + "is_usergroup": true, + "name": "Marketing Team", + "prefs": { + "channels": [], + "groups": [] + }, + "team_id": "T060R4BHN", + "updated_by": "U060R4BJ4", + "user_count": 1, + "users": [ + "U060R4BJ4", + "U060RNRCZ" + ] + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from usergroups.update method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "usergroup": { + "$ref": "#/definitions/objs_subteam" + } + }, + "required": [ + "ok", + "usergroup" + ], + "title": "usergroups.update schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from usergroups.update method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "permission_denied", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_require", + "fatal_error", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "usergroups.update error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "usergroups:write" + ] + } + ], + "tags": [ + "usergroups" + ] + } + }, + "/usergroups.users.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List all users in a User Group", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/usergroups.users.list" + }, + "operationId": "usergroups_users_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `usergroups:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Allow results that involve disabled User Groups.", + "in": "query", + "name": "include_disabled", + "type": "boolean" + }, + { + "description": "The encoded ID of the User Group to update.", + "in": "query", + "name": "usergroup", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Standard success response when used with a user token", + "examples": { + "application/json": { + "ok": true, + "users": [ + "U060R4BJ4", + "W123A4BC5" + ] + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from usergroups.users.list method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "users": { + "items": { + "$ref": "#/definitions/defs_user_id" + }, + "type": "array" + } + }, + "required": [ + "ok", + "users" + ], + "title": "usergroups.users.list schema", + "type": "object" + } + }, + "default": { + "description": "Standard failure response when used with an invalid token", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from usergroups.users.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_require", + "fatal_error", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "usergroups.users.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "usergroups:read" + ] + } + ], + "tags": [ + "usergroups.users", + "usergroups" + ] + } + }, + "/usergroups.users.update": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Update the list of users for a User Group", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/usergroups.users.update" + }, + "operationId": "usergroups_users_update", + "parameters": [ + { + "description": "Authentication token. Requires scope: `usergroups:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Include the number of users in the User Group.", + "in": "formData", + "name": "include_count", + "type": "boolean" + }, + { + "description": "The encoded ID of the User Group to update.", + "in": "formData", + "name": "usergroup", + "required": true, + "type": "string" + }, + { + "description": "A comma separated string of encoded user IDs that represent the entire list of users for the User Group.", + "in": "formData", + "name": "users", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "usergroup": { + "auto_type": null, + "created_by": "U060R4BJ4", + "date_create": 1447096577, + "date_delete": 0, + "date_update": 1447102109, + "deleted_by": null, + "description": "Marketing gurus, PR experts and product advocates.", + "handle": "marketing-team", + "id": "S0616NG6M", + "is_external": false, + "is_usergroup": true, + "name": "Marketing Team", + "prefs": { + "channels": [], + "groups": [] + }, + "team_id": "T060R4BHN", + "updated_by": "U060R4BJ4", + "user_count": 1, + "users": [ + "U060R4BJ4", + "U060RNRCZ" + ] + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from usergroups.users.update method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "usergroup": { + "$ref": "#/definitions/objs_subteam" + } + }, + "required": [ + "ok", + "usergroup" + ], + "title": "usergroups.users.update schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from usergroups.users.update method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "permission_denied", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "user_is_restricted", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_require", + "fatal_error", + "missing_charset", + "superfluous_charset" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "usergroups.users.update error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "usergroups:write" + ] + } + ], + "tags": [ + "usergroups.users", + "usergroups" + ] + } + }, + "/users.conversations": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "List conversations the calling user may access.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.conversations" + }, + "operationId": "users_conversations", + "parameters": [ + { + "description": "Authentication token. Requires scope: `conversations:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "Browse conversations by a specific user ID's membership. Non-public channels are restricted to those where the calling user shares membership.", + "in": "query", + "name": "user", + "type": "string" + }, + { + "description": "Mix and match channel types by providing a comma-separated list of any combination of `public_channel`, `private_channel`, `mpim`, `im`", + "in": "query", + "name": "types", + "type": "string" + }, + { + "description": "Set to `true` to exclude archived channels from the list", + "in": "query", + "name": "exclude_archived", + "type": "boolean" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached. Must be an integer no larger than 1000.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response with only public channels. Note how `num_members` and `is_member` are not returned like typical `conversations` objects.", + "examples": { + "application/json": { + "channels": [ + { + "created": 1449252889, + "creator": "U012A3CDE", + "id": "C012AB3CD", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": true, + "is_group": false, + "is_im": false, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "general", + "name_normalized": "general", + "pending_shared": [], + "previous_names": [], + "purpose": { + "creator": "", + "last_set": 0, + "value": "This channel is for team-wide communication and announcements. All team members are in this channel." + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "Company-wide announcements and work-based matters" + }, + "unlinked": 0 + }, + { + "created": 1449252889, + "creator": "U061F7AUR", + "id": "C061EG9T2", + "is_archived": false, + "is_channel": true, + "is_ext_shared": false, + "is_general": false, + "is_group": false, + "is_im": false, + "is_mpim": false, + "is_org_shared": false, + "is_pending_ext_shared": false, + "is_private": false, + "is_shared": false, + "name": "random", + "name_normalized": "random", + "pending_shared": [], + "previous_names": [], + "purpose": { + "creator": "", + "last_set": 0, + "value": "A place for non-work-related flimflam, faffing, hodge-podge or jibber-jabber you'd prefer to keep out of more focused work-related channels." + }, + "topic": { + "creator": "", + "last_set": 0, + "value": "Non-work banter and water cooler conversation" + }, + "unlinked": 0 + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "dGVhbTpDMDYxRkE1UEI=" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "Schema for successful response from users.conversations method. Returned conversation objects do not include `num_members` or `is_member`", + "properties": { + "channels": { + "items": { + "$ref": "#/definitions/objs_conversation" + }, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "response_metadata": { + "additionalProperties": false, + "properties": { + "next_cursor": { + "type": "string" + } + }, + "required": [ + "next_cursor" + ], + "type": "object" + } + }, + "required": [ + "ok", + "channels" + ], + "title": "users.conversations success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.conversations method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "method_not_supported_for_channel_type", + "missing_scope", + "invalid_types", + "invalid_cursor", + "invalid_limit", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.conversations error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "channels:read", + "groups:read", + "im:read", + "mpim:read" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.deletePhoto": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Delete the user profile photo", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.deletePhoto" + }, + "operationId": "users_deletePhoto", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users.profile:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from users.deletePhoto method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "users.deletePhoto schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.deletePhoto method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.deletePhoto error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users.profile:write" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.getPresence": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets user presence information.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.getPresence" + }, + "operationId": "users_getPresence", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "User to get presence info on. Defaults to the authed user.", + "in": "query", + "name": "user", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "When requesting information for a different user, this method just returns the current presence (either `active` or `away`).", + "examples": { + "application/json": { + "ok": true, + "presence": "active" + } + }, + "schema": { + "additionalProperties": true, + "description": "Generated from users.getPresence with shasum e7251aec575d8863f9e0eb38663ae9dc26655f65", + "properties": { + "auto_away": { + "type": "boolean" + }, + "connection_count": { + "type": "integer" + }, + "last_activity": { + "type": "integer" + }, + "manual_away": { + "type": "boolean" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "online": { + "type": "boolean" + }, + "presence": { + "type": "string" + } + }, + "required": [ + "ok", + "presence" + ], + "title": "API method: users.getPresence", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": { + "type": "object" + }, + "description": "Schema for error response users.getPresence method", + "properties": { + "error": { + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.counts error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users:read" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.identity": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Get a user's identity.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.identity" + }, + "operationId": "users_identity", + "parameters": [ + { + "description": "Authentication token. Requires scope: `identity.basic`", + "in": "query", + "name": "token", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "You will receive at a minimum the following information:", + "examples": { + "application/json": { + "ok": true, + "team": { + "id": "T0G9PQBBK" + }, + "user": { + "id": "U0G9QF9C6", + "name": "Sonny Whether" + } + } + }, + "schema": { + "description": "Schema for successful response from users.identity method", + "items": [ + { + "additionalProperties": false, + "description": "Schema for 'identity.basic' scope", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "team": { + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/defs_team" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "user": { + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "id" + ], + "type": "object" + } + }, + "required": [ + "ok", + "user", + "team" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Schema for 'identity.basic,identity.email' scopes", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "team": { + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/defs_team" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "user": { + "additionalProperties": false, + "properties": { + "email": { + "format": "email", + "type": "string" + }, + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "id", + "email" + ], + "type": "object" + } + }, + "required": [ + "ok", + "user", + "team" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Schema for 'identity.basic,identity.avatar' scopes", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "team": { + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/defs_team" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "user": { + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "image_192": { + "format": "url", + "type": "string" + }, + "image_24": { + "format": "url", + "type": "string" + }, + "image_32": { + "format": "url", + "type": "string" + }, + "image_48": { + "format": "url", + "type": "string" + }, + "image_512": { + "format": "url", + "type": "string" + }, + "image_72": { + "format": "url", + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "id", + "image_24", + "image_32", + "image_48", + "image_72", + "image_192", + "image_512" + ], + "type": "object" + } + }, + "required": [ + "ok", + "user", + "team" + ], + "type": "object" + }, + { + "additionalProperties": false, + "description": "Schema for 'identity.basic,identity.team' scopes", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "team": { + "additionalProperties": false, + "properties": { + "domain": { + "type": "string" + }, + "id": { + "$ref": "#/definitions/defs_team" + }, + "image_102": { + "format": "url", + "type": "string" + }, + "image_132": { + "format": "url", + "type": "string" + }, + "image_230": { + "format": "url", + "type": "string" + }, + "image_34": { + "format": "url", + "type": "string" + }, + "image_44": { + "format": "url", + "type": "string" + }, + "image_68": { + "format": "url", + "type": "string" + }, + "image_88": { + "format": "url", + "type": "string" + }, + "image_default": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "domain", + "image_34", + "image_44", + "image_68", + "image_88", + "image_102", + "image_132", + "image_230", + "image_default" + ], + "type": "object" + }, + "user": { + "additionalProperties": false, + "properties": { + "id": { + "$ref": "#/definitions/defs_user_id" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "id" + ], + "type": "object" + } + }, + "required": [ + "ok", + "user", + "team" + ], + "type": "object" + } + ], + "title": "users.identity schema" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "account_inactive", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.identity method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.identity error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "identity.basic" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.info": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Gets information about a user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.info" + }, + "operationId": "users_info", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Set this to `true` to receive the locale for this user. Defaults to `false`", + "in": "query", + "name": "include_locale", + "type": "boolean" + }, + { + "description": "User to get info on", + "in": "query", + "name": "user", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "user": { + "color": "9f69e7", + "deleted": false, + "has_2fa": false, + "id": "W012A3CDE", + "is_admin": true, + "is_app_user": false, + "is_bot": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "name": "spengler", + "profile": { + "avatar_hash": "ge3b51ca72de", + "display_name": "spengler", + "display_name_normalized": "spengler", + "email": "spengler@ghostbusters.example.com", + "image_192": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_24": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_32": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_48": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_512": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_72": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_original": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "real_name": "Egon Spengler", + "real_name_normalized": "Egon Spengler", + "status_emoji": ":books:", + "status_text": "Print is dead", + "team": "T012AB3C4" + }, + "real_name": "Egon Spengler", + "team_id": "T012AB3C4", + "tz": "America/Los_Angeles", + "tz_label": "Pacific Daylight Time", + "tz_offset": -25200, + "updated": 1502138686 + } + } + }, + "schema": { + "additionalProperties": true, + "description": "Schema for successful response from users.info method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "user": { + "$ref": "#/definitions/objs_user" + } + }, + "required": [ + "ok", + "user" + ], + "title": "users.info success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "user_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.info method", + "properties": { + "callstack": { + "type": "string" + }, + "error": { + "enum": [ + "user_not_found", + "user_not_visible", + "not_authed", + "invalid_auth", + "account_inactive", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.info error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users:read" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.list": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Lists all users in a Slack team.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.list" + }, + "operationId": "users_list", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users:read`", + "in": "query", + "name": "token", + "type": "string" + }, + { + "description": "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the users list hasn't been reached. Providing no `limit` value will result in Slack attempting to deliver you the entire result set. If the collection is too large you may experience `limit_required` or HTTP 500 errors.", + "in": "query", + "name": "limit", + "type": "integer" + }, + { + "description": "Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first \"page\" of the collection. See [pagination](/docs/pagination) for more detail.", + "in": "query", + "name": "cursor", + "type": "string" + }, + { + "description": "Set this to `true` to receive the locale for users. Defaults to `false`", + "in": "query", + "name": "include_locale", + "type": "boolean" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "cache_ts": 1498777272, + "members": [ + { + "color": "9f69e7", + "deleted": false, + "has_2fa": false, + "id": "W012A3CDE", + "is_admin": true, + "is_app_user": false, + "is_bot": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "name": "spengler", + "profile": { + "avatar_hash": "ge3b51ca72de", + "display_name": "spengler", + "display_name_normalized": "spengler", + "email": "spengler@ghostbusters.example.com", + "image_192": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_24": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_32": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_48": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_512": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_72": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "real_name": "Egon Spengler", + "real_name_normalized": "Egon Spengler", + "status_emoji": ":books:", + "status_text": "Print is dead", + "team": "T012AB3C4" + }, + "real_name": "spengler", + "team_id": "T012AB3C4", + "tz": "America/Los_Angeles", + "tz_label": "Pacific Daylight Time", + "tz_offset": -25200, + "updated": 1502138686 + }, + { + "color": "9f69e7", + "deleted": false, + "has_2fa": false, + "id": "W07QCRPA4", + "is_admin": true, + "is_bot": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "name": "glinda", + "profile": { + "avatar_hash": "8fbdd10b41c6", + "display_name": "Glinda the Fairly Good", + "display_name_normalized": "Glinda the Fairly Good", + "email": "glenda@south.oz.coven", + "first_name": "Glinda", + "image_1024": "https://a.slack-edge.com...png", + "image_192": "https://a.slack-edge.com...png", + "image_24": "https://a.slack-edge.com...png", + "image_32": "https://a.slack-edge.com...png", + "image_48": "https://a.slack-edge.com...png", + "image_512": "https://a.slack-edge.com...png", + "image_72": "https://a.slack-edge.com...png", + "image_original": "https://a.slack-edge.com...png", + "last_name": "Southgood", + "phone": "", + "real_name": "Glinda Southgood", + "real_name_normalized": "Glinda Southgood", + "skype": "", + "title": "Glinda the Good" + }, + "real_name": "Glinda Southgood", + "team_id": "T0G9PQBBK", + "tz": "America/Los_Angeles", + "tz_label": "Pacific Daylight Time", + "tz_offset": -25200, + "updated": 1480527098 + } + ], + "ok": true, + "response_metadata": { + "next_cursor": "dXNlcjpVMEc5V0ZYTlo=" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from users.list method", + "properties": { + "cache_ts": { + "type": "integer" + }, + "members": { + "items": { + "$ref": "#/definitions/objs_user" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "response_metadata": { + "$ref": "#/definitions/objs_response_metadata" + } + }, + "required": [ + "ok", + "members", + "cache_ts" + ], + "title": "users.list schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_cursor", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.list method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "limit_required", + "invalid_cursor", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.list error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users:read" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.lookupByEmail": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Find a user with an email address.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.lookupByEmail" + }, + "operationId": "users_lookupByEmail", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users:read.email`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "An email address belonging to a user in the workspace", + "in": "query", + "name": "email", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "user": { + "color": "9f69e7", + "deleted": false, + "has_2fa": false, + "id": "W012A3CDE", + "is_admin": true, + "is_app_user": false, + "is_bot": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "name": "spengler", + "profile": { + "avatar_hash": "ge3b51ca72de", + "display_name": "spengler", + "display_name_normalized": "spengler", + "email": "spengler@ghostbusters.example.com", + "image_192": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_24": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_32": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_48": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_512": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_72": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "real_name": "Egon Spengler", + "real_name_normalized": "Egon Spengler", + "status_emoji": ":books:", + "status_text": "Print is dead", + "team": "T012AB3C4" + }, + "real_name": "Egon Spengler", + "team_id": "T012AB3C4", + "tz": "America/Los_Angeles", + "tz_label": "Pacific Daylight Time", + "tz_offset": -25200, + "updated": 1502138686 + } + } + }, + "schema": { + "additionalProperties": true, + "description": "Schema for successful response from users.lookupByEmail method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "user": { + "$ref": "#/definitions/objs_user" + } + }, + "required": [ + "ok", + "user" + ], + "title": "users.lookupByEmail success schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "users_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.lookupByEmail method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "users_not_found", + "enterprise_is_restricted", + "not_authed", + "invalid_auth", + "account_inactive", + "no_permission", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.lookupByEmail error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users:read.email" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.profile.get": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Retrieves a user's profile information.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.profile.get" + }, + "operationId": "users_profile_get", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users.profile:read`", + "in": "query", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Include labels for each ID in custom profile fields", + "in": "query", + "name": "include_labels", + "type": "boolean" + }, + { + "description": "User to retrieve profile info for", + "in": "query", + "name": "user", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "profile": { + "avatar_hash": "ge3b51ca72de", + "display_name": "spengler", + "display_name_normalized": "spengler", + "email": "spengler@ghostbusters.example.com", + "image_192": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_24": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_32": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_48": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_512": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_72": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_original": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "real_name": "Egon Spengler", + "real_name_normalized": "Egon Spengler", + "status_emoji": ":books:", + "status_expiration": 0, + "status_text": "Print is dead", + "team": "T012AB3C4" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from users.profile.get method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "profile": { + "$ref": "#/definitions/objs_user_profile" + } + }, + "required": [ + "ok", + "profile" + ], + "title": "users.profile.get schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "user_not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.profile.get method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "user_not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.profile.get error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users.profile:read" + ] + } + ], + "tags": [ + "users.profile", + "users" + ] + } + }, + "/users.profile.set": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Set the profile information for a user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.profile.set" + }, + "operationId": "users_profile_set", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users.profile:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Name of a single key to set. Usable only if `profile` is not passed.", + "in": "formData", + "name": "name", + "type": "string" + }, + { + "description": "Collection of key:value pairs presented as a URL-encoded JSON hash. At most 50 fields may be set. Each field name is limited to 255 characters.", + "in": "formData", + "name": "profile", + "type": "string" + }, + { + "description": "ID of user to change. This argument may only be specified by team admins on paid teams.", + "in": "formData", + "name": "user", + "type": "string" + }, + { + "description": "Value to set a single key to. Usable only if `profile` is not passed.", + "in": "formData", + "name": "value", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true, + "profile": { + "avatar_hash": "ge3b51ca72de", + "display_name": "spengler", + "display_name_normalized": "spengler", + "email": "spengler@ghostbusters.example.com", + "image_192": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_24": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_32": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_48": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_512": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "image_72": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg", + "real_name": "Egon Spengler", + "real_name_normalized": "Egon Spengler", + "status_emoji": ":books:", + "status_expiration": 0, + "status_text": "Print is dead", + "team": "T012AB3C4" + } + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from users.profile.set method", + "properties": { + "email_pending": { + "format": "email", + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "profile": { + "$ref": "#/definitions/objs_user_profile" + }, + "username": { + "type": "string" + } + }, + "required": [ + "ok", + "username", + "profile" + ], + "title": "users.profile.set schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_profile", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.profile.set method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "reserved_name", + "invalid_profile", + "profile_set_failed", + "not_admin", + "not_app_admin", + "cannot_update_admin_user", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.profile.set error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users.profile:write" + ] + } + ], + "tags": [ + "users.profile", + "users" + ] + } + }, + "/users.setActive": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Marked a user as active. Deprecated and non-functional.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.setActive" + }, + "operationId": "users_setActive", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from users.setActive method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "users.setActive schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.setActive method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "ekm_access_denied", + "missing_scope", + "invalid_arguments", + "invalid_arg_name", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "request_timeout", + "fatal_error", + "internal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.setActive error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users:write" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.setPhoto": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded" + ], + "description": "Set the user profile photo", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.setPhoto" + }, + "operationId": "users_setPhoto", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users.profile:write`", + "in": "formData", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Width/height of crop box (always square)", + "in": "formData", + "name": "crop_w", + "type": "string" + }, + { + "description": "X coordinate of top-left corner of crop box", + "in": "formData", + "name": "crop_x", + "type": "string" + }, + { + "description": "Y coordinate of top-left corner of crop box", + "in": "formData", + "name": "crop_y", + "type": "string" + }, + { + "description": "File contents via `multipart/form-data`.", + "in": "formData", + "name": "image", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from users.setPhoto method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + }, + "profile": { + "additionalProperties": false, + "properties": { + "avatar_hash": { + "pattern": "^[0-9a-f]{12}$", + "type": "string" + }, + "image_1024": { + "format": "uri", + "type": "string" + }, + "image_192": { + "format": "uri", + "type": "string" + }, + "image_24": { + "format": "uri", + "type": "string" + }, + "image_32": { + "format": "uri", + "type": "string" + }, + "image_48": { + "format": "uri", + "type": "string" + }, + "image_512": { + "format": "uri", + "type": "string" + }, + "image_72": { + "format": "uri", + "type": "string" + }, + "image_original": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "image_24", + "image_32", + "image_48", + "image_72", + "image_192", + "image_512", + "image_1024", + "image_original", + "avatar_hash" + ], + "type": "object" + } + }, + "required": [ + "ok", + "profile" + ], + "title": "users.setPhoto schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.setPhoto method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "debug_step": { + "description": "possibly DEV/QA only", + "type": "string" + }, + "dims": { + "description": "possibly DEV/QA only", + "type": "string" + }, + "error": { + "enum": [ + "bad_image", + "too_large", + "too_many_frames", + "not_found", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "user_is_bot", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + }, + "time_ident": { + "description": "possibly DEV/QA only", + "type": "integer" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.setPhoto error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users.profile:write" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/users.setPresence": { + "post": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Manually sets user presence.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/users.setPresence" + }, + "operationId": "users_setPresence", + "parameters": [ + { + "description": "Authentication token. Requires scope: `users:write`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Either `auto` or `away`", + "in": "formData", + "name": "presence", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for successful response from users.setPresence method", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "users.setPresence schema", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": false, + "description": "Schema for error response from users.setPresence method", + "properties": { + "callstack": { + "description": "Note: PHP callstack is only visible in dev/qa", + "type": "string" + }, + "error": { + "enum": [ + "invalid_presence", + "not_authed", + "invalid_auth", + "account_inactive", + "token_revoked", + "no_permission", + "org_login_required", + "invalid_arg_name", + "invalid_array_arg", + "invalid_charset", + "invalid_form_data", + "invalid_post_type", + "missing_post_type", + "team_added_to_org", + "invalid_json", + "json_not_object", + "request_timeout", + "upgrade_required", + "fatal_error" + ], + "type": "string" + }, + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok", + "error" + ], + "title": "users.setPresence error schema", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "users:write" + ] + } + ], + "tags": [ + "users" + ] + } + }, + "/views.open": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Open a view for a user.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/views.open" + }, + "operationId": "views_open", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Exchange a trigger to post to the user.", + "in": "query", + "name": "trigger_id", + "required": true, + "type": "string" + }, + { + "description": "A [view payload](/reference/surfaces/views). This must be a JSON-encoded string.", + "in": "query", + "name": "view", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response includes the opened view payload.", + "examples": { + "application/json": { + "ok": true, + "view": { + "app_id": "AA4928AQ", + "blocks": [ + { + "block_id": "a_block_id", + "element": { + "action_id": "an_action_id", + "type": "plain_text_input" + }, + "label": { + "emoji": true, + "text": "A simple label", + "type": "plain_text" + }, + "optional": false, + "type": "input" + } + ], + "bot_id": "BA13894H", + "callback_id": "identify_your_modals", + "clear_on_close": false, + "external_id": "", + "hash": "156772938.1827394", + "id": "VMHU10V25", + "notify_on_close": false, + "private_metadata": "Shh it is a secret", + "root_view_id": "VMHU10V25", + "state": { + "values": {} + }, + "submit": { + "text": "Create", + "type": "plain_text" + }, + "team_id": "T8N4K1JN", + "title": { + "text": "Quite a plain modal", + "type": "plain_text" + }, + "type": "modal" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response, before getting to any possible validation errors.", + "examples": { + "application/json": { + "error": "invalid_arguments", + "ok": false, + "response_metadata": { + "messages": [ + "invalid `trigger_id`" + ] + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "views" + ] + } + }, + "/views.publish": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Publish a static view for a User.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/views.publish" + }, + "operationId": "views_publish", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "`id` of the user you want publish a view to.", + "in": "query", + "name": "user_id", + "required": true, + "type": "string" + }, + { + "description": "A [view payload](/reference/surfaces/views). This must be a JSON-encoded string.", + "in": "query", + "name": "view", + "required": true, + "type": "string" + }, + { + "description": "A string that represents view state to protect against possible race conditions.", + "in": "query", + "name": "hash", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response includes the published view payload.", + "examples": { + "application/json": { + "ok": true, + "view": { + "app_id": "AA4928AQ", + "blocks": [ + { + "block_id": "2WGp9", + "text": { + "text": "A simple section with some sample sentence.", + "type": "mrkdwn", + "verbatim": false + }, + "type": "section" + } + ], + "bot_id": "BA13894H", + "callback_id": "identify_your_home_tab", + "clear_on_close": false, + "close": null, + "external_id": "", + "hash": "156772938.1827394", + "id": "VMHU10V25", + "notify_on_close": false, + "previous_view_id": null, + "private_metadata": "Shh it is a secret", + "root_view_id": "VMHU10V25", + "state": { + "values": {} + }, + "submit": null, + "team_id": "T8N4K1JN", + "type": "home" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response, before getting to any possible validation errors.", + "examples": { + "application/json": { + "error": "invalid_arguments", + "ok": false, + "response_metadata": { + "messages": [ + "invalid `user_id`" + ] + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "views" + ] + } + }, + "/views.push": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Push a view onto the stack of a root view.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/views.push" + }, + "operationId": "views_push", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Exchange a trigger to post to the user.", + "in": "query", + "name": "trigger_id", + "required": true, + "type": "string" + }, + { + "description": "A [view payload](/reference/surfaces/views). This must be a JSON-encoded string.", + "in": "query", + "name": "view", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response includes the pushed view payload.", + "examples": { + "application/json": { + "ok": true, + "view": { + "app_id": "AAD3351BQ", + "blocks": [ + { + "block_id": "edit_details", + "element": { + "action_id": "detail_input", + "type": "plain_text_input" + }, + "label": { + "text": "Edit details", + "type": "plain_text" + }, + "type": "input" + } + ], + "bot_id": "BADF7A34H", + "callback_id": "view_4", + "clear_on_close": true, + "close": { + "emoji": true, + "text": "Back", + "type": "plain_text" + }, + "external_id": "", + "hash": "1569362015.55b5e41b", + "id": "VNM522E2U", + "notify_on_close": false, + "previous_view_id": null, + "private_metadata": "", + "root_view_id": "VNN729E3U", + "state": { + "values": {} + }, + "submit": { + "emoji": true, + "text": "Save", + "type": "plain_text" + }, + "team_id": "T9M4RL1JM", + "title": { + "emoji": true, + "text": "Pushed Modal", + "type": "plain_text" + }, + "type": "modal" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response.", + "examples": { + "application/json": { + "error": "invalid_arguments", + "ok": false, + "response_metadata": { + "messages": [ + "missing required field: title" + ] + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "views" + ] + } + }, + "/views.update": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Update an existing view.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/views.update" + }, + "operationId": "views_update", + "parameters": [ + { + "description": "Authentication token. Requires scope: `none`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "A unique identifier of the view to be updated. Either `view_id` or `external_id` is required.", + "in": "query", + "name": "view_id", + "type": "string" + }, + { + "description": "A unique identifier of the view set by the developer. Must be unique for all views on a team. Max length of 255 characters. Either `view_id` or `external_id` is required.", + "in": "query", + "name": "external_id", + "type": "string" + }, + { + "description": "A [view object](/reference/surfaces/views). This must be a JSON-encoded string.", + "in": "query", + "name": "view", + "type": "string" + }, + { + "description": "A string that represents view state to protect against possible race conditions.", + "in": "query", + "name": "hash", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response includes the updated view payload.", + "examples": { + "application/json": { + "ok": true, + "view": { + "app_id": "AAD3351BQ", + "blocks": [ + { + "accessory": { + "action_id": "button_4", + "text": { + "text": "Click me", + "type": "plain_text" + }, + "type": "button" + }, + "block_id": "s_block", + "text": { + "emoji": true, + "text": "I am but an updated modal", + "type": "plain_text" + }, + "type": "section" + } + ], + "bot_id": "BADF7A34H", + "callback_id": "view_2", + "clear_on_close": true, + "close": { + "emoji": true, + "text": "Close", + "type": "plain_text" + }, + "external_id": "", + "hash": "1569262015.55b5e41b", + "id": "VNM522E2U", + "notify_on_close": false, + "previous_view_id": null, + "private_metadata": "", + "root_view_id": "VNN729E3U", + "state": { + "values": {} + }, + "submit": null, + "team_id": "T9M4RL1JM", + "title": { + "emoji": true, + "text": "Updated Modal", + "type": "plain_text" + }, + "type": "modal" + } + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response.", + "examples": { + "application/json": { + "error": "not_found", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "none" + ] + } + ], + "tags": [ + "views" + ] + } + }, + "/workflows.stepCompleted": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Indicate that an app's step in a workflow completed execution.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/workflows.stepCompleted" + }, + "operationId": "workflows_stepCompleted", + "parameters": [ + { + "description": "Authentication token. Requires scope: `workflow.steps:execute`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Context identifier that maps to the correct workflow step execution.", + "in": "query", + "name": "workflow_step_execute_id", + "required": true, + "type": "string" + }, + { + "description": "Key-value object of outputs from your step. Keys of this object reflect the configured `key` properties of your [`outputs`](/reference/workflows/workflow_step#output) array from your `workflow_step` object.", + "in": "query", + "name": "outputs", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "workflow.steps:execute" + ] + } + ], + "tags": [ + "workflows" + ] + } + }, + "/workflows.stepFailed": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Indicate that an app's step in a workflow failed to execute.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/workflows.stepFailed" + }, + "operationId": "workflows_stepFailed", + "parameters": [ + { + "description": "Authentication token. Requires scope: `workflow.steps:execute`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "Context identifier that maps to the correct workflow step execution.", + "in": "query", + "name": "workflow_step_execute_id", + "required": true, + "type": "string" + }, + { + "description": "A JSON-based object with a `message` property that should contain a human readable error message.", + "in": "query", + "name": "error", + "required": true, + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "workflow.steps:execute" + ] + } + ], + "tags": [ + "workflows" + ] + } + }, + "/workflows.updateStep": { + "get": { + "consumes": [ + "application/x-www-form-urlencoded", + "application/json" + ], + "description": "Update the configuration for a workflow extension step.", + "externalDocs": { + "description": "API method documentation", + "url": "https://api.slack.com/methods/workflows.updateStep" + }, + "operationId": "workflows_updateStep", + "parameters": [ + { + "description": "Authentication token. Requires scope: `workflow.steps:execute`", + "in": "header", + "name": "token", + "required": true, + "type": "string" + }, + { + "description": "A context identifier provided with `view_submission` payloads used to call back to `workflows.updateStep`.", + "in": "query", + "name": "workflow_step_edit_id", + "required": true, + "type": "string" + }, + { + "description": "A JSON key-value map of inputs required from a user during configuration. This is the data your app expects to receive when the workflow step starts. **Please note**: the embedded variable format is set and replaced by the workflow system. You cannot create custom variables that will be replaced at runtime. [Read more about variables in workflow steps here](/workflows/steps#variables).", + "in": "query", + "name": "inputs", + "type": "string" + }, + { + "description": "An JSON array of output objects used during step execution. This is the data your app agrees to provide when your workflow step was executed.", + "in": "query", + "name": "outputs", + "type": "string" + }, + { + "description": "An optional field that can be used to override the step name that is shown in the Workflow Builder.", + "in": "query", + "name": "step_name", + "type": "string" + }, + { + "description": "An optional field that can be used to override app image that is shown in the Workflow Builder.", + "in": "query", + "name": "step_image_url", + "type": "string" + } + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Typical success response", + "examples": { + "application/json": { + "ok": true + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_true" + } + }, + "required": [ + "ok" + ], + "title": "Default success template", + "type": "object" + } + }, + "default": { + "description": "Typical error response", + "examples": { + "application/json": { + "error": "invalid_auth", + "ok": false + } + }, + "schema": { + "additionalProperties": true, + "description": "This method either only returns a brief _not OK_ response or a verbose schema is not available for this method.", + "properties": { + "ok": { + "$ref": "#/definitions/defs_ok_false" + } + }, + "required": [ + "ok" + ], + "title": "Default error template", + "type": "object" + } + } + }, + "security": [ + { + "slackAuth": [ + "workflow.steps:execute" + ] + } + ], + "tags": [ + "workflows" + ] + } + } + }, + "schemes": [ + "https" + ], + "securityDefinitions": { + "slackAuth": { + "authorizationUrl": "https://slack.com/oauth/authorize", + "flow": "accessCode", + "scopes": { + "admin": "admin", + "admin.apps:read": "admin.apps:read", + "admin.apps:write": "admin.apps:write", + "admin.conversations:read": "admin.conversations:read", + "admin.conversations:write": "admin.conversations:write", + "admin.invites:read": "admin.invites:read", + "admin.invites:write": "admin.invites:write", + "admin.teams:read": "admin.teams:read", + "admin.teams:write": "admin.teams:write", + "admin.usergroups:read": "admin.usergroups:read", + "admin.usergroups:write": "admin.usergroups:write", + "admin.users:read": "admin.users:read", + "admin.users:write": "admin.users:write", + "authorizations:read": "authorizations:read", + "bot": "Bot user scope", + "calls:read": "calls:read", + "calls:write": "calls:write", + "channels:history": "channels:history", + "channels:manage": "channels:manage", + "channels:read": "channels:read", + "channels:write": "channels:write", + "chat:write": "chat:write", + "chat:write:bot": "Author messages as a bot", + "chat:write:user": "Author messages as a user", + "conversations:history": "conversations:history", + "conversations:read": "conversations:read", + "conversations:write": "conversations:write", + "dnd:read": "dnd:read", + "dnd:write": "dnd:write", + "emoji:read": "emoji:read", + "files:read": "files:read", + "files:write:user": "files:write:user", + "groups:history": "groups:history", + "groups:read": "groups:read", + "groups:write": "groups:write", + "identity.basic": "identity.basic", + "im:history": "im:history", + "im:read": "im:read", + "im:write": "im:write", + "links:write": "links:write", + "mpim:history": "mpim:history", + "mpim:read": "mpim:read", + "mpim:write": "mpim:write", + "none": "No scope required", + "pins:read": "pins:read", + "pins:write": "pins:write", + "reactions:read": "reactions:read", + "reactions:write": "reactions:write", + "reminders:read": "reminders:read", + "reminders:write": "reminders:write", + "remote_files:read": "remote_files:read", + "remote_files:share": "remote_files:share", + "remote_files:write": "remote_files:write", + "rtm:stream": "rtm:stream", + "search:read": "search:read", + "stars:read": "stars:read", + "stars:write": "stars:write", + "team:read": "team:read", + "tokens.basic": "tokens.basic", + "usergroups:read": "usergroups:read", + "usergroups:write": "usergroups:write", + "users.profile:read": "users.profile:read", + "users.profile:write": "users.profile:write", + "users:read": "users:read", + "users:read.email": "users:read.email", + "users:write": "users:write", + "workflow.steps:execute": "workflow.steps:execute" + }, + "tokenUrl": "https://slack.com/api/oauth.access", + "type": "oauth2" + } + }, + "swagger": "2.0", + "tags": [] +} \ No newline at end of file diff --git a/apps/integrations/src/integrations/slack/endpoints/schemas/spec.ts b/apps/integrations/src/integrations/slack/endpoints/schemas/spec.ts new file mode 100644 index 000000000..659523e8f --- /dev/null +++ b/apps/integrations/src/integrations/slack/endpoints/schemas/spec.ts @@ -0,0 +1,3 @@ +import { dereferenceSpec } from "core/schemas/schemaBuilder"; +import rawSpec from "./slack_web_openapi_v2.json"; +export const spec = dereferenceSpec(rawSpec); diff --git a/apps/integrations/src/integrations/slack/endpoints/specs.ts b/apps/integrations/src/integrations/slack/endpoints/specs.ts new file mode 100644 index 000000000..f5b03ab38 --- /dev/null +++ b/apps/integrations/src/integrations/slack/endpoints/specs.ts @@ -0,0 +1,350 @@ +import { EndpointSpec, EndpointSpecResponse } from "core/endpoint/types"; +import { schemaFromOpenApiSpecV2 } from "core/schemas/schemaBuilder"; +import { spec } from "./schemas/spec"; + +const errorResponse: EndpointSpecResponse = { + success: false, + name: "Error", + description: "200 error response", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + ok: { + type: "boolean", + enum: [false], + }, + error: { + type: "string", + }, + }, + required: ["ok", "error"], + }, +}; + +export const chatPostMessage: EndpointSpec = { + path: "/chat.postMessage", + method: "POST", + metadata: { + name: "postMessage", + description: "Post a message to a channel", + externalDocs: { + description: "API method documentation", + url: "https://api.slack.com/methods/chat.postMessage", + }, + tags: ["chat"], + }, + security: { + slackAuth: ["chat:write:user", "chat:write:bot"], + }, + request: { + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + body: { + schema: { + type: "object", + required: ["channel"], + properties: { + as_user: { + type: "string", + description: + "Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [authorship](#authorship) below.", + }, + attachments: { + type: "string", + description: + "A JSON-based array of structured attachments, presented as a URL-encoded string.", + }, + blocks: { + type: "string", + description: + "A JSON-based array of structured blocks, presented as a URL-encoded string.", + }, + channel: { + type: "string", + description: + "Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details.", + }, + icon_emoji: { + type: "string", + description: + "Emoji to use as the icon for this message. Overrides `icon_url`. Must be used in conjunction with `as_user` set to `false`, otherwise ignored. See [authorship](#authorship) below.", + }, + icon_url: { + type: "string", + description: + "URL to an image to use as the icon for this message. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.", + }, + link_names: { + type: "boolean", + description: "Find and link channel names and usernames.", + }, + mrkdwn: { + type: "boolean", + description: + "Disable Slack markup parsing by setting to `false`. Enabled by default.", + }, + parse: { + type: "string", + description: + "Change how messages are treated. Defaults to `none`. See [below](#formatting).", + }, + reply_broadcast: { + type: "boolean", + description: + "Used in conjunction with `thread_ts` and indicates whether reply should be made visible to everyone in the channel or conversation. Defaults to `false`.", + }, + text: { + type: "string", + description: + "How this field works and whether it is required depends on other fields you use in your API call. [See below](#text_usage) for more detail.", + }, + thread_ts: { + type: "string", + description: + "Provide another message's `ts` value to make this message a reply. Avoid using a reply's `ts` value; use its parent instead.", + }, + unfurl_links: { + type: "boolean", + description: + "Pass true to enable unfurling of primarily text-based content.", + }, + unfurl_media: { + type: "boolean", + description: "Pass false to disable unfurling of media content.", + }, + username: { + type: "string", + description: + "Set your bot's user name. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below.", + }, + }, + }, + }, + }, + responses: { + 200: [ + { + success: true, + name: "Success", + description: "Typical success response", + schema: { + type: "object", + properties: { + channel: { + description: "Channel ID where the message was posted", + type: "string", + }, + message: { + type: "object", + properties: { + attachments: { + type: "array", + items: { + type: "object", + properties: { + fallback: { + type: "string", + }, + id: { + type: "number", + }, + text: { + type: "string", + }, + }, + required: ["fallback", "id", "text"], + }, + }, + bot_id: { + type: "string", + }, + subtype: { + type: "string", + }, + text: { + type: "string", + }, + ts: { + type: "string", + }, + type: { + type: "string", + }, + user: { + type: "string", + }, + }, + required: ["bot_id", "text", "ts", "type"], + }, + ok: { + type: "boolean", + }, + ts: { + type: "string", + }, + }, + required: ["channel", "message", "ok", "ts"], + }, + }, + errorResponse, + ], + default: [ + { + success: false, + name: "Error", + description: + "Typical error response if too many attachments are included", + schema: { + description: "Schema for error response chat.postMessage method", + type: "object", + properties: { + error: { + type: "string", + }, + ok: { + type: "boolean", + }, + }, + required: ["error", "ok"], + }, + }, + ], + }, +}; + +export const conversationsList: EndpointSpec = { + path: "/conversations.list", + method: "GET", + metadata: { + name: "conversationsList", + description: "Lists all channels in a Slack team.", + externalDocs: { + description: "API method documentation", + url: "https://api.slack.com/methods/conversations.list", + }, + tags: ["conversations"], + }, + security: { + slackAuth: ["conversations:read"], + }, + parameters: [ + { + name: "exclude_archived", + in: "query", + description: "Set to `true` to exclude archived channels from the list", + schema: { + type: "boolean", + }, + }, + { + name: "types", + in: "query", + description: + "Mix and match channel types by providing a comma-separated list of any combination of `public_channel`, `private_channel`, `mpim`, `im`", + schema: { + type: "string", + }, + }, + { + name: "limit", + in: "query", + description: + "The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached. Must be an integer no larger than 1000.", + schema: { + type: "number", + }, + }, + { + name: "cursor", + in: "query", + description: + 'Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request\'s `response_metadata`. Default value fetches the first "page" of the collection. See [pagination](/docs/pagination) for more detail.', + schema: { + type: "string", + }, + }, + ], + request: {}, + responses: { + 200: [ + { + success: true, + name: "Success", + schema: schemaFromOpenApiSpecV2( + spec, + "/paths//conversations.list/get/responses/200/schema" + ), + }, + errorResponse, + ], + default: [ + { + success: false, + name: "Error", + schema: schemaFromOpenApiSpecV2( + spec, + "/paths//conversations.list/get/responses/default/schema" + ), + }, + ], + }, +}; + +export const conversationsJoin: EndpointSpec = { + path: "/conversations.join", + method: "POST", + metadata: { + name: "conversationsJoin", + description: "Joins an existing conversation.", + externalDocs: { + description: "API method documentation", + url: "https://api.slack.com/methods/conversations.join", + }, + tags: ["conversations"], + }, + security: { + slackAuth: ["channels:write"], + }, + request: { + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + body: { + schema: { + type: "object", + properties: { + channel: { + type: "string", + description: "ID of conversation to join", + }, + }, + required: ["channel"], + }, + }, + }, + responses: { + 200: [ + { + success: true, + name: "Success", + schema: schemaFromOpenApiSpecV2( + spec, + "/paths//conversations.join/post/responses/200/schema" + ), + }, + errorResponse, + ], + default: [ + { + success: false, + name: "Error", + schema: schemaFromOpenApiSpecV2( + spec, + "/paths//conversations.join/post/responses/default/schema" + ), + }, + ], + }, +}; diff --git a/apps/integrations/src/integrations/slack/index.ts b/apps/integrations/src/integrations/slack/index.ts new file mode 100644 index 000000000..8649a4f0b --- /dev/null +++ b/apps/integrations/src/integrations/slack/index.ts @@ -0,0 +1,11 @@ +import { Service } from "core/service/types"; +import { authentication } from "./authentication"; +import * as actions from "./actions/actions"; + +export const slack: Service = { + name: "Slack", + service: "slack", + version: "1.0.0", + authentication, + actions, +}; diff --git a/apps/integrations/src/integrations/slack/tests/actions.test.ts b/apps/integrations/src/integrations/slack/tests/actions.test.ts new file mode 100644 index 000000000..e2ed1bb98 --- /dev/null +++ b/apps/integrations/src/integrations/slack/tests/actions.test.ts @@ -0,0 +1,84 @@ +import { expect, test } from "vitest"; +import { chatPostMessage, conversationsList } from "../actions/actions"; + +test("/conversations.list success", async () => { + try { + const data = await conversationsList.action({ + parameters: { + limit: 3, + }, + credentials: { + type: "oauth2", + name: "slackAuth", + accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + scopes: ["conversations:read"], + }, + }); + + expect(data.success).toEqual(true); + expect(data.status).toEqual(200); + expect(data.body.ok).toEqual(true); + } catch (e: any) { + console.error(JSON.stringify(e.errors, null, 2)); + expect(e).toEqual(null); + } +}); + +test("/chat.postMessage success with name", async () => { + try { + const data = await chatPostMessage.action({ + body: { + channel: "test-integrations", + text: "Using the channel name", + }, + credentials: { + type: "oauth2", + name: "slackAuth", + accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + scopes: [ + "chat:write:user", + "chat:write:bot", + "conversations:read", + "channels:write", + ], + }, + }); + + expect(data.success).toEqual(true); + expect(data.status).toEqual(200); + expect(data.body.ok).toEqual(true); + expect(data.body.message.text).toEqual("Using the channel name"); + } catch (e: any) { + console.error(JSON.stringify(e, null, 2)); + expect(e).toEqual(null); + } +}); + +test("/chat.postMessage failed with bad name", async () => { + try { + const data = await chatPostMessage.action({ + body: { + channel: "this-channel-does-not-exist", + text: "Using the channel name", + }, + credentials: { + type: "oauth2", + name: "slackAuth", + accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + scopes: [ + "chat:write:user", + "chat:write:bot", + "conversations:read", + "channels:write", + ], + }, + }); + + expect(data.success).toEqual(false); + expect(data.body.ok).toEqual(false); + expect(data.body.error).toEqual("channel_not_found"); + } catch (e: any) { + console.error(JSON.stringify(e.errors, null, 2)); + expect(e).toEqual(null); + } +}); diff --git a/apps/integrations/src/integrations/slack/tests/endpoints.test.ts b/apps/integrations/src/integrations/slack/tests/endpoints.test.ts new file mode 100644 index 000000000..ee3e35864 --- /dev/null +++ b/apps/integrations/src/integrations/slack/tests/endpoints.test.ts @@ -0,0 +1,91 @@ +import { expect, test } from "vitest"; +import endpoints from "../endpoints/endpoints"; + +test("missing credentials", async () => { + try { + await endpoints.chatPostMessage.request({ + body: { + channel: "C04GWUTDC3W", + text: "This the Trigger.dev integrations test", + }, + }); + } catch (e: any) { + expect(e.type).toEqual("missing_credentials"); + } +}); + +test("/chat.postMessage success", async () => { + try { + const data = await endpoints.chatPostMessage.request({ + body: { + channel: "C04GWUTDC3W", + text: "This the Trigger.dev integrations test", + }, + credentials: { + type: "oauth2", + name: "slackAuth", + accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + scopes: ["chat:write:user", "chat:write:bot"], + }, + }); + + expect(data.success).toEqual(true); + expect(data.status).toEqual(200); + expect(data.body.ok).toEqual(true); + expect(data.body.channel).toEqual("C04GWUTDC3W"); + expect(data.body.message.text).toEqual( + "This the Trigger.dev integrations test" + ); + } catch (e: any) { + console.error(JSON.stringify(e.errors, null, 2)); + expect(e).toEqual(null); + } +}); + +test("/chat.postMessage bad channel", async () => { + try { + const data = await endpoints.chatPostMessage.request({ + body: { + channel: "C00AAAAAAAA", + text: "This channel doesn't exist, so message won't send", + }, + credentials: { + type: "oauth2", + name: "slackAuth", + accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + scopes: ["chat:write:user", "chat:write:bot"], + }, + }); + + expect(data.success).toEqual(false); + expect(data.status).toEqual(200); + expect(data.body.ok).toEqual(false); + expect(data.body.error).toEqual("channel_not_found"); + } catch (e: any) { + console.error(JSON.stringify(e, null, 2)); + expect(e).toEqual(null); + } +}); + +test("/conversations.list success", async () => { + try { + const data = await endpoints.conversationsList.request({ + parameters: { + limit: 3, + }, + credentials: { + type: "oauth2", + name: "slackAuth", + accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + scopes: ["conversations:read"], + }, + }); + + expect(data.success).toEqual(true); + expect(data.status).toEqual(200); + expect(data.body.ok).toEqual(true); + } catch (e: any) { + console.error(JSON.stringify(e.errors, null, 2)); + expect(e).toEqual(null); + } +}); diff --git a/apps/integrations/src/trigger/sdk/generate.ts b/apps/integrations/src/trigger/sdk/generate.ts new file mode 100644 index 000000000..4b4b7c871 --- /dev/null +++ b/apps/integrations/src/trigger/sdk/generate.ts @@ -0,0 +1,16 @@ +import { catalog } from "integrations/catalog"; +import { generateService } from "./generateService"; + +export async function generate() { + console.log("Generating SDKs..."); + + const allSdks = Object.values(catalog.services).map((service) => { + return generateService(service); + }); + + await Promise.all(allSdks); + + console.log(`Generated ${allSdks.length} SDKs`); +} + +generate(); diff --git a/apps/integrations/src/trigger/sdk/generateService.test.ts b/apps/integrations/src/trigger/sdk/generateService.test.ts new file mode 100644 index 000000000..0e3fac293 --- /dev/null +++ b/apps/integrations/src/trigger/sdk/generateService.test.ts @@ -0,0 +1,9 @@ +import { slack } from "integrations/slack"; +import { expect, test } from "vitest"; +import { generateService } from "./generateService"; + +test("generate simple service", async () => { + generateService(slack); + + expect(1).toEqual(1); +}); diff --git a/apps/integrations/src/trigger/sdk/generateService.ts b/apps/integrations/src/trigger/sdk/generateService.ts new file mode 100644 index 000000000..f8c73cb8e --- /dev/null +++ b/apps/integrations/src/trigger/sdk/generateService.ts @@ -0,0 +1,176 @@ +import { IndentationText, NewLineKind, Project, QuoteKind } from "ts-morph"; +import { Service } from "core/service/types"; +import fs from "fs/promises"; +import { generateInputOutputSchemas } from "generators/combineSchemas"; +import { getTypesFromSchema } from "generators/generateTypes"; +import { dirname } from "path"; +import rimraf from "rimraf"; + +const appDir = require.main ? dirname(require.main.filename) : process.cwd(); + +export async function generateService(service: Service) { + const basePath = `sdks/@trigger.dev/${service.service}`; + + //remove folder + const absolutePath = `${appDir}/${basePath}/`; + + console.log(`Removing ${absolutePath}...`); + rimraf.sync(absolutePath); + + console.log(`Generating SDK for ${service.service}...`); + + const project = new Project({ + manipulationSettings: { + indentationText: IndentationText.TwoSpaces, + newLineKind: NewLineKind.LineFeed, + quoteKind: QuoteKind.Double, + usePrefixAndSuffixTextForRename: false, + useTrailingCommas: true, + }, + }); + + try { + project.createDirectory(basePath); + await generateTemplatedFiles(project, basePath, service); + await generateFunctionsAndTypes(project, basePath, service); + await project.save(); + } catch (e) { + console.error(e); + } +} + +function toFriendlyTypeName(original: string) { + //convert the input string to TitleCase, strip out any non alpha characters and strip out spaces + return original + .replace(/([A-Z])/g, " $1") + .replace(/^./, function (str: string) { + return str.toUpperCase(); + }) + .replace(/[^a-zA-Z]/g, "") + .replace(/\s/g, ""); +} + +async function generateTemplatedFiles( + project: Project, + basePath: string, + service: Service +) { + await createFileAndReplaceVariables( + "package.json", + project, + basePath, + service + ); + await createFileAndReplaceVariables( + "tsconfig.json", + project, + basePath, + service + ); + await createFileAndReplaceVariables("README.md", project, basePath, service); + await createFileAndReplaceVariables( + "tsup.config.ts", + project, + basePath, + service + ); + return; +} + +async function createFileAndReplaceVariables( + filename: string, + project: Project, + basePath: string, + service: Service +) { + const originalText = await fs.readFile( + `src/trigger/sdk/templates/${filename}`, + { encoding: "utf-8" } + ); + + //replace any text that matches {service.[key]} with the value from the service object + const text = originalText.replace( + /{service.([a-zA-Z0-9]+)}/g, + (match: string, key: string) => { + return (service as any)[key] as string; + } + ); + + const file = project.createSourceFile(`${basePath}/${filename}`, text, { + overwrite: true, + }); + file.formatText(); + return; +} + +async function generateFunctionsAndTypes( + project: Project, + basePath: string, + service: Service +) { + const { actions } = service; + + const typeDefinitions: Record = {}; + const functions: Record = {}; + //loop through actions + for (const key in actions) { + const action = actions[key]; + + //generate schemas for input and output + const name = toFriendlyTypeName(action.name); + const schemas = generateInputOutputSchemas(action.spec, name); + + //generate types for input and output + const inputTypeName = `${name}Input`; + const inputType = await getTypesFromSchema(schemas.input, inputTypeName); + typeDefinitions[inputTypeName] = inputType; + const outputTypeName = `${name}Output`; + const outputType = await getTypesFromSchema(schemas.output, outputTypeName); + typeDefinitions[outputTypeName] = outputType; + + functions[action.name] = ` +${action.description ? `/** ${action.description} */` : ""} +export async function ${action.name}( + /** This key should be unique inside your workflow */ + key: string, + /** The params for this call */ + params: ${inputTypeName} +): Promise<${outputTypeName}> { + const run = getTriggerRun(); + + if (!run) { + throw new Error("Cannot call ${action.name} outside of a trigger run"); + } + + const output = await run.performRequest(key, { + version: "2", + service: "${service.service}", + endpoint: "${action.path}", + params, + }); + + return output; +} + `; + } + + const typesFile = project.createSourceFile( + `${basePath}/src/types.ts`, + Object.values(typeDefinitions).join("\n\n"), + { + overwrite: true, + } + ); + typesFile.formatText(); + + const functionsFile = project.createSourceFile( + `${basePath}/src/index.ts`, + `import { getTriggerRun } from "@trigger.dev/sdk"; + import { ${Object.keys(typeDefinitions).join(", ")} } from "./types"; + ${Object.values(functions).join("")}`, + { + overwrite: true, + } + ); + functionsFile.formatText(); +} diff --git a/apps/integrations/src/trigger/sdk/templates/README.md b/apps/integrations/src/trigger/sdk/templates/README.md new file mode 100644 index 000000000..8025206ae --- /dev/null +++ b/apps/integrations/src/trigger/sdk/templates/README.md @@ -0,0 +1,3 @@ +# Trigger.dev {service.name} integration + +View more documentation [here](https://docs.trigger.dev) diff --git a/apps/integrations/src/trigger/sdk/templates/package.json b/apps/integrations/src/trigger/sdk/templates/package.json new file mode 100644 index 000000000..62f203a32 --- /dev/null +++ b/apps/integrations/src/trigger/sdk/templates/package.json @@ -0,0 +1,33 @@ +{ + "name": "@trigger.dev/{service.service}", + "version": "{service.version}", + "description": "The official {service.name} integration for Trigger.dev", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "publishConfig": { + "access": "public" + }, + "files": [ + "dist/index.js", + "dist/index.d.ts", + "dist/index.js.map" + ], + "devDependencies": { + "@trigger.dev/sdk": "workspace:*", + "@types/debug": "^4.1.7", + "@types/node": "16", + "rimraf": "^3.0.2", + "tsup": "^6.5.0" + }, + "peerDependencies": { + "@trigger.dev/sdk": "workspace:*" + }, + "scripts": { + "clean": "rimraf dist", + "build": "npm run clean && npm run build:tsup", + "build:tsup": "tsup" + }, + "dependencies": { + "debug": "^4.3.4" + } +} diff --git a/apps/integrations/src/trigger/sdk/templates/tsconfig.json b/apps/integrations/src/trigger/sdk/templates/tsconfig.json new file mode 100644 index 000000000..bb3e70788 --- /dev/null +++ b/apps/integrations/src/trigger/sdk/templates/tsconfig.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Node 16", + "include": ["./src/**/*.ts", "tsup.config.ts"], + "compilerOptions": { + "module": "commonjs", + "target": "ES2021", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "lib": ["DOM", "DOM.Iterable", "ES2019"], + "paths": { + "@trigger.dev/sdk/*": ["../../packages/trigger-sdk/src/*"], + "@trigger.dev/sdk": ["../../packages/trigger-sdk/src/index"] + } + }, + "exclude": ["node_modules"] +} diff --git a/apps/integrations/src/trigger/sdk/templates/tsup.config.ts b/apps/integrations/src/trigger/sdk/templates/tsup.config.ts new file mode 100644 index 000000000..5fcec5da2 --- /dev/null +++ b/apps/integrations/src/trigger/sdk/templates/tsup.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from "tsup"; + +export default defineConfig([ + { + name: "main", + entry: ["./src/index.ts"], + outDir: "./dist", + platform: "node", + format: ["cjs"], + legacyOutput: true, + sourcemap: true, + clean: true, + bundle: true, + splitting: false, + dts: true, + treeshake: { + preset: "smallest", + }, + external: ["http", "https", "util", "events", "tty", "os", "timers"], + esbuildPlugins: [], + }, +]); diff --git a/apps/integrations/tsconfig.json b/apps/integrations/tsconfig.json new file mode 100644 index 000000000..dffbe401a --- /dev/null +++ b/apps/integrations/tsconfig.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Node 16", + "compilerOptions": { + "baseUrl": "./src", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "lib": ["DOM", "DOM.Iterable", "ES2019"], + "module": "commonjs", + "target": "ES2021", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["./src/**/*.ts", "./src/**/*.d.ts"], + "exclude": ["node_modules"] +} diff --git a/apps/integrations/vitest.config.ts b/apps/integrations/vitest.config.ts new file mode 100644 index 000000000..648225465 --- /dev/null +++ b/apps/integrations/vitest.config.ts @@ -0,0 +1,12 @@ +/// +/// + +import { defineConfig } from "vite"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig({ + plugins: [tsconfigPaths()], + test: { + globals: true, + }, +}); diff --git a/apps/webapp/package.json b/apps/webapp/package.json index a358cb8ef..aa28d7832 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -196,7 +196,7 @@ "typescript": "^4.8.4", "vite": "^3.1.4", "vite-tsconfig-paths": "^3.5.1", - "vitest": "^0.23.4" + "vitest": "^0.28.4" }, "engines": { "node": ">=16.0.0" diff --git a/package.json b/package.json index b0120b7cb..af6016a76 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,8 @@ "changeset:next": "changeset pre enter next", "changeset:normal": "changeset pre exit", "sentry-upload": "turbo run sentry-upload", - "clean:sourcemaps": "turbo run clean:sourcemaps" + "clean:sourcemaps": "turbo run clean:sourcemaps", + "generate-sdks": "turbo run generate-sdks" }, "devDependencies": { "@manypkg/cli": "^0.19.2", @@ -55,7 +56,10 @@ "prettier": "^2.5.1", "tailwindcss": "3.1.8", "tsx": "^3.7.1", - "turbo": "^1.5.5" + "turbo": "^1.5.5", + "vite": "^4.1.1", + "vite-tsconfig-paths": "^4.0.5", + "vitest": "^0.28.4" }, "packageManager": "pnpm@7.13.5", "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d6f262ed..ce948a4e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,6 +15,9 @@ importers: tailwindcss: 3.1.8 tsx: ^3.7.1 turbo: ^1.5.5 + vite: ^4.1.1 + vite-tsconfig-paths: ^4.0.5 + vitest: ^0.28.4 dependencies: '@changesets/cli': 2.26.0 devDependencies: @@ -28,6 +31,79 @@ importers: tailwindcss: 3.1.8_postcss@8.4.21 tsx: 3.12.2 turbo: 1.7.0 + vite: 4.1.1 + vite-tsconfig-paths: 4.0.5 + vitest: 0.28.5 + + apps/integrations: + specifiers: + '@cfworker/json-schema': ^1.12.5 + '@trigger.dev/sdk': ^0.2.13 + '@types/eslint': ^8.4.6 + '@types/json-pointer': ^1.0.31 + '@types/node': ^18.13.0 + '@typescript-eslint/eslint-plugin': ^5.51.0 + eslint: ^8.34.0 + eslint-config-prettier: ^8.5.0 + eslint-config-standard-with-typescript: ^34.0.0 + eslint-plugin-import: ^2.27.5 + eslint-plugin-n: ^15.6.1 + eslint-plugin-promise: ^6.1.1 + json-pointer: ^0.6.2 + json-schema-deref-sync: ^0.14.0 + json-schema-to-typescript: ^11.0.3 + node-fetch: ^3.3.0 + rimraf: ^4.1.2 + ts-morph: ^17.0.1 + tsup: ^6.6.2 + tsx: ^3.12.3 + typescript: ^4.9.5 + vite: ^4.1.1 + vite-tsconfig-paths: ^4.0.5 + vitest: ^0.28.4 + dependencies: + '@cfworker/json-schema': 1.12.5 + '@trigger.dev/sdk': 0.2.13 + json-pointer: 0.6.2 + json-schema-deref-sync: 0.14.0 + json-schema-to-typescript: 11.0.3 + node-fetch: 3.3.0 + devDependencies: + '@types/eslint': 8.4.10 + '@types/json-pointer': 1.0.31 + '@types/node': 18.13.0 + '@typescript-eslint/eslint-plugin': 5.51.0_bzepuo66bcyj4mepwnxofjvdli + eslint: 8.34.0 + eslint-config-prettier: 8.6.0_eslint@8.34.0 + eslint-config-standard-with-typescript: 34.0.0_xlnlhajfavmnhfjhhcrfaju6re + eslint-plugin-import: 2.27.5_zycheyzypw6s5ouujsf5akzhsy + eslint-plugin-n: 15.6.1_eslint@8.34.0 + eslint-plugin-promise: 6.1.1_eslint@8.34.0 + rimraf: 4.1.2 + ts-morph: 17.0.1 + tsup: 6.6.2_typescript@4.9.5 + tsx: 3.12.3 + typescript: 4.9.5 + vite: 4.1.1_@types+node@18.13.0 + vite-tsconfig-paths: 4.0.5_typescript@4.9.5 + vitest: 0.28.5 + + apps/integrations/src/trigger/sdk/templates: + specifiers: + '@trigger.dev/sdk': workspace:* + '@types/debug': ^4.1.7 + '@types/node': '16' + debug: ^4.3.4 + rimraf: ^3.0.2 + tsup: ^6.5.0 + dependencies: + debug: 4.3.4 + devDependencies: + '@trigger.dev/sdk': link:../../../../../../packages/trigger-sdk + '@types/debug': 4.1.7 + '@types/node': 16.18.11 + rimraf: 3.0.2 + tsup: 6.5.0 apps/webapp: specifiers: @@ -181,7 +257,7 @@ importers: ulid: ^2.3.0 vite: ^3.1.4 vite-tsconfig-paths: ^3.5.1 - vitest: ^0.23.4 + vitest: ^0.28.4 zod: ^3.20.2 zod-error: ^1.1.0 dependencies: @@ -338,7 +414,7 @@ importers: typescript: 4.9.4 vite: 3.2.5_@types+node@18.11.18 vite-tsconfig-paths: 3.6.0_vite@3.2.5 - vitest: 0.23.4_happy-dom@6.0.4 + vitest: 0.28.5_happy-dom@6.0.4 apps/wss: specifiers: @@ -659,7 +735,7 @@ importers: tsup: ^6.5.0 zod: ^3.20.2 dependencies: - '@react-email/render': 0.0.3 + '@react-email/render': 0.0.3_react@18.2.0 debug: 4.3.4 zod: 3.20.2 devDependencies: @@ -3349,6 +3425,15 @@ packages: to-fast-properties: 2.0.0 dev: true + /@bcherny/json-schema-ref-parser/9.0.9: + resolution: {integrity: sha512-vmEmnJCfpkLdas++9OYg6riIezTYqTHpqUTODJzHLzs5UnXujbOJW9VwcVCnyo1mVRt32FRr23iXBx/sX8YbeQ==} + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.11 + call-me-maybe: 1.0.2 + js-yaml: 4.1.0 + dev: false + /@bcoe/v8-coverage/0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -3649,6 +3734,7 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/trace-mapping': 0.3.9 + dev: true /@cush/relative/1.0.0: resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==} @@ -3697,6 +3783,13 @@ packages: '@esbuild-kit/core-utils': 3.0.0 get-tsconfig: 4.3.0 + /@esbuild-kit/cjs-loader/2.4.2: + resolution: {integrity: sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==} + dependencies: + '@esbuild-kit/core-utils': 3.0.0 + get-tsconfig: 4.4.0 + dev: true + /@esbuild-kit/core-utils/3.0.0: resolution: {integrity: sha512-TXmwH9EFS3DC2sI2YJWJBgHGhlteK0Xyu1VabwetMULfm3oYhbrsWV5yaSr2NTWZIgDGVLHbRf0inxbjXqAcmQ==} dependencies: @@ -3709,6 +3802,13 @@ packages: '@esbuild-kit/core-utils': 3.0.0 get-tsconfig: 4.3.0 + /@esbuild-kit/esm-loader/2.5.5: + resolution: {integrity: sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==} + dependencies: + '@esbuild-kit/core-utils': 3.0.0 + get-tsconfig: 4.4.0 + dev: true + /@esbuild-plugins/node-modules-polyfill/0.1.4_esbuild@0.16.3: resolution: {integrity: sha512-uZbcXi0zbmKC/050p3gJnne5Qdzw8vkXIv+c2BW0Lsc1ji1SkrxbKPUy5Efr0blbTu1SL8w4eyfpnSdPg3G0Qg==} peerDependencies: @@ -3727,6 +3827,15 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm/0.16.17: + resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm/0.16.3: resolution: {integrity: sha512-mueuEoh+s1eRbSJqq9KNBQwI4QhQV6sRXIfTyLXSHGMpyew61rOK4qY21uKbXl1iBoMb0AdL1deWFCQVlN2qHA==} engines: {node: '>=12'} @@ -3744,6 +3853,24 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm/0.17.8: + resolution: {integrity: sha512-0/rb91GYKhrtbeglJXOhAv9RuYimgI8h623TplY2X+vA4EXnk3Zj1fXZreJ0J3OJJu1bwmb0W7g+2cT/d8/l/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.16.17: + resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm64/0.16.3: resolution: {integrity: sha512-RolFVeinkeraDvN/OoRf1F/lP0KUfGNb5jxy/vkIMeRRChkrX/HTYN6TYZosRJs3a1+8wqpxAo5PI5hFmxyPRg==} engines: {node: '>=12'} @@ -3761,6 +3888,24 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm64/0.17.8: + resolution: {integrity: sha512-oa/N5j6v1svZQs7EIRPqR8f+Bf8g6HBDjD/xHC02radE/NjKHK7oQmtmLxPs1iVwYyvE+Kolo6lbpfEQ9xnhxQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.16.17: + resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64/0.16.3: resolution: {integrity: sha512-SFpTUcIT1bIJuCCBMCQWq1bL2gPTjWoLZdjmIhjdcQHaUfV41OQfho6Ici5uvvkMmZRXIUGpM3GxysP/EU7ifQ==} engines: {node: '>=12'} @@ -3778,6 +3923,24 @@ packages: requiresBuild: true optional: true + /@esbuild/android-x64/0.17.8: + resolution: {integrity: sha512-bTliMLqD7pTOoPg4zZkXqCDuzIUguEWLpeqkNfC41ODBHwoUgZ2w5JBeYimv4oP6TDVocoYmEhZrCLQTrH89bg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.16.17: + resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64/0.16.3: resolution: {integrity: sha512-DO8WykMyB+N9mIDfI/Hug70Dk1KipavlGAecxS3jDUwAbTpDXj0Lcwzw9svkhxfpCagDmpaTMgxWK8/C/XcXvw==} engines: {node: '>=12'} @@ -3795,6 +3958,24 @@ packages: requiresBuild: true optional: true + /@esbuild/darwin-arm64/0.17.8: + resolution: {integrity: sha512-ghAbV3ia2zybEefXRRm7+lx8J/rnupZT0gp9CaGy/3iolEXkJ6LYRq4IpQVI9zR97ID80KJVoUlo3LSeA/sMAg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.16.17: + resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64/0.16.3: resolution: {integrity: sha512-uEqZQ2omc6BvWqdCiyZ5+XmxuHEi1SPzpVxXCSSV2+Sh7sbXbpeNhHIeFrIpRjAs0lI1FmA1iIOxFozKBhKgRQ==} engines: {node: '>=12'} @@ -3812,6 +3993,24 @@ packages: requiresBuild: true optional: true + /@esbuild/darwin-x64/0.17.8: + resolution: {integrity: sha512-n5WOpyvZ9TIdv2V1K3/iIkkJeKmUpKaCTdun9buhGRWfH//osmUjlv4Z5mmWdPWind/VGcVxTHtLfLCOohsOXw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.16.17: + resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64/0.16.3: resolution: {integrity: sha512-nJansp3sSXakNkOD5i5mIz2Is/HjzIhFs49b1tjrPrpCmwgBmH9SSzhC/Z1UqlkivqMYkhfPwMw1dGFUuwmXhw==} engines: {node: '>=12'} @@ -3829,6 +4028,24 @@ packages: requiresBuild: true optional: true + /@esbuild/freebsd-arm64/0.17.8: + resolution: {integrity: sha512-a/SATTaOhPIPFWvHZDoZYgxaZRVHn0/LX1fHLGfZ6C13JqFUZ3K6SMD6/HCtwOQ8HnsNaEeokdiDSFLuizqv5A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.16.17: + resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64/0.16.3: resolution: {integrity: sha512-TfoDzLw+QHfc4a8aKtGSQ96Wa+6eimljjkq9HKR0rHlU83vw8aldMOUSJTUDxbcUdcgnJzPaX8/vGWm7vyV7ug==} engines: {node: '>=12'} @@ -3846,6 +4063,24 @@ packages: requiresBuild: true optional: true + /@esbuild/freebsd-x64/0.17.8: + resolution: {integrity: sha512-xpFJb08dfXr5+rZc4E+ooZmayBW6R3q59daCpKZ/cDU96/kvDM+vkYzNeTJCGd8rtO6fHWMq5Rcv/1cY6p6/0Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.16.17: + resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm/0.16.3: resolution: {integrity: sha512-VwswmSYwVAAq6LysV59Fyqk3UIjbhuc6wb3vEcJ7HEJUtFuLK9uXWuFoH1lulEbE4+5GjtHi3MHX+w1gNHdOWQ==} engines: {node: '>=12'} @@ -3863,6 +4098,24 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-arm/0.17.8: + resolution: {integrity: sha512-6Ij8gfuGszcEwZpi5jQIJCVIACLS8Tz2chnEBfYjlmMzVsfqBP1iGmHQPp7JSnZg5xxK9tjCc+pJ2WtAmPRFVA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.16.17: + resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64/0.16.3: resolution: {integrity: sha512-7I3RlsnxEFCHVZNBLb2w7unamgZ5sVwO0/ikE2GaYvYuUQs9Qte/w7TqWcXHtCwxvZx/2+F97ndiUQAWs47ZfQ==} engines: {node: '>=12'} @@ -3880,6 +4133,24 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-arm64/0.17.8: + resolution: {integrity: sha512-v3iwDQuDljLTxpsqQDl3fl/yihjPAyOguxuloON9kFHYwopeJEf1BkDXODzYyXEI19gisEsQlG1bM65YqKSIww==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.16.17: + resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32/0.16.3: resolution: {integrity: sha512-X8FDDxM9cqda2rJE+iblQhIMYY49LfvW4kaEjoFbTTQ4Go8G96Smj2w3BRTwA8IHGoi9dPOPGAX63dhuv19UqA==} engines: {node: '>=12'} @@ -3897,6 +4168,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-ia32/0.17.8: + resolution: {integrity: sha512-8svILYKhE5XetuFk/B6raFYIyIqydQi+GngEXJgdPdI7OMKUbSd7uzR02wSY4kb53xBrClLkhH4Xs8P61Q2BaA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64/0.15.18: resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} engines: {node: '>=12'} @@ -3905,6 +4185,15 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-loong64/0.16.17: + resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64/0.16.3: resolution: {integrity: sha512-hIbeejCOyO0X9ujfIIOKjBjNAs9XD/YdJ9JXAy1lHA+8UXuOqbFe4ErMCqMr8dhlMGBuvcQYGF7+kO7waj2KHw==} engines: {node: '>=12'} @@ -3922,6 +4211,24 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-loong64/0.17.8: + resolution: {integrity: sha512-B6FyMeRJeV0NpyEOYlm5qtQfxbdlgmiGdD+QsipzKfFky0K5HW5Td6dyK3L3ypu1eY4kOmo7wW0o94SBqlqBSA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.16.17: + resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el/0.16.3: resolution: {integrity: sha512-znFRzICT/V8VZQMt6rjb21MtAVJv/3dmKRMlohlShrbVXdBuOdDrGb+C2cZGQAR8RFyRe7HS6klmHq103WpmVw==} engines: {node: '>=12'} @@ -3939,6 +4246,24 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-mips64el/0.17.8: + resolution: {integrity: sha512-CCb67RKahNobjm/eeEqeD/oJfJlrWyw29fgiyB6vcgyq97YAf3gCOuP6qMShYSPXgnlZe/i4a8WFHBw6N8bYAA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.16.17: + resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64/0.16.3: resolution: {integrity: sha512-EV7LuEybxhXrVTDpbqWF2yehYRNz5e5p+u3oQUS2+ZFpknyi1NXxr8URk4ykR8Efm7iu04//4sBg249yNOwy5Q==} engines: {node: '>=12'} @@ -3956,6 +4281,24 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-ppc64/0.17.8: + resolution: {integrity: sha512-bytLJOi55y55+mGSdgwZ5qBm0K9WOCh0rx+vavVPx+gqLLhxtSFU0XbeYy/dsAAD6xECGEv4IQeFILaSS2auXw==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.16.17: + resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64/0.16.3: resolution: {integrity: sha512-uDxqFOcLzFIJ+r/pkTTSE9lsCEaV/Y6rMlQjUI9BkzASEChYL/aSQjZjchtEmdnVxDKETnUAmsaZ4pqK1eE5BQ==} engines: {node: '>=12'} @@ -3973,6 +4316,24 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-riscv64/0.17.8: + resolution: {integrity: sha512-2YpRyQJmKVBEHSBLa8kBAtbhucaclb6ex4wchfY0Tj3Kg39kpjeJ9vhRU7x4mUpq8ISLXRXH1L0dBYjAeqzZAw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.16.17: + resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x/0.16.3: resolution: {integrity: sha512-NbeREhzSxYwFhnCAQOQZmajsPYtX71Ufej3IQ8W2Gxskfz9DK58ENEju4SbpIj48VenktRASC52N5Fhyf/aliQ==} engines: {node: '>=12'} @@ -3990,6 +4351,24 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-s390x/0.17.8: + resolution: {integrity: sha512-QgbNY/V3IFXvNf11SS6exkpVcX0LJcob+0RWCgV9OiDAmVElnxciHIisoSix9uzYzScPmS6dJFbZULdSAEkQVw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.16.17: + resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64/0.16.3: resolution: {integrity: sha512-SDiG0nCixYO9JgpehoKgScwic7vXXndfasjnD5DLbp1xltANzqZ425l7LSdHynt19UWOcDjG9wJJzSElsPvk0w==} engines: {node: '>=12'} @@ -4007,6 +4386,24 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-x64/0.17.8: + resolution: {integrity: sha512-mM/9S0SbAFDBc4OPoyP6SEOo5324LpUxdpeIUUSrSTOfhHU9hEfqRngmKgqILqwx/0DVJBzeNW7HmLEWp9vcOA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.16.17: + resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64/0.16.3: resolution: {integrity: sha512-AzbsJqiHEq1I/tUvOfAzCY15h4/7Ivp3ff/o1GpP16n48JMNAtbW0qui2WCgoIZArEHD0SUQ95gvR0oSO7ZbdA==} engines: {node: '>=12'} @@ -4024,6 +4421,24 @@ packages: requiresBuild: true optional: true + /@esbuild/netbsd-x64/0.17.8: + resolution: {integrity: sha512-eKUYcWaWTaYr9zbj8GertdVtlt1DTS1gNBWov+iQfWuWyuu59YN6gSEJvFzC5ESJ4kMcKR0uqWThKUn5o8We6Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.16.17: + resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64/0.16.3: resolution: {integrity: sha512-gSABi8qHl8k3Cbi/4toAzHiykuBuWLZs43JomTcXkjMZVkp0gj3gg9mO+9HJW/8GB5H89RX/V0QP4JGL7YEEVg==} engines: {node: '>=12'} @@ -4041,6 +4456,24 @@ packages: requiresBuild: true optional: true + /@esbuild/openbsd-x64/0.17.8: + resolution: {integrity: sha512-Vc9J4dXOboDyMXKD0eCeW0SIeEzr8K9oTHJU+Ci1mZc5njPfhKAqkRt3B/fUNU7dP+mRyralPu8QUkiaQn7iIg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.16.17: + resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64/0.16.3: resolution: {integrity: sha512-SF9Kch5Ete4reovvRO6yNjMxrvlfT0F0Flm+NPoUw5Z4Q3r1d23LFTgaLwm3Cp0iGbrU/MoUI+ZqwCv5XJijCw==} engines: {node: '>=12'} @@ -4058,6 +4491,24 @@ packages: requiresBuild: true optional: true + /@esbuild/sunos-x64/0.17.8: + resolution: {integrity: sha512-0xvOTNuPXI7ft1LYUgiaXtpCEjp90RuBBYovdd2lqAFxje4sEucurg30M1WIm03+3jxByd3mfo+VUmPtRSVuOw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.16.17: + resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64/0.16.3: resolution: {integrity: sha512-u5aBonZIyGopAZyOnoPAA6fGsDeHByZ9CnEzyML9NqntK6D/xl5jteZUKm/p6nD09+v3pTM6TuUIqSPcChk5gg==} engines: {node: '>=12'} @@ -4075,6 +4526,24 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-arm64/0.17.8: + resolution: {integrity: sha512-G0JQwUI5WdEFEnYNKzklxtBheCPkuDdu1YrtRrjuQv30WsYbkkoixKxLLv8qhJmNI+ATEWquZe/N0d0rpr55Mg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.16.17: + resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32/0.16.3: resolution: {integrity: sha512-GlgVq1WpvOEhNioh74TKelwla9KDuAaLZrdxuuUgsP2vayxeLgVc+rbpIv0IYF4+tlIzq2vRhofV+KGLD+37EQ==} engines: {node: '>=12'} @@ -4092,6 +4561,24 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-ia32/0.17.8: + resolution: {integrity: sha512-Fqy63515xl20OHGFykjJsMnoIWS+38fqfg88ClvPXyDbLtgXal2DTlhb1TfTX34qWi3u4I7Cq563QcHpqgLx8w==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.16.17: + resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64/0.16.3: resolution: {integrity: sha512-5/JuTd8OWW8UzEtyf19fbrtMJENza+C9JoPIkvItgTBQ1FO2ZLvjbPO6Xs54vk0s5JB5QsfieUEshRQfu7ZHow==} engines: {node: '>=12'} @@ -4109,6 +4596,15 @@ packages: requiresBuild: true optional: true + /@esbuild/win32-x64/0.17.8: + resolution: {integrity: sha512-1iuezdyDNngPnz8rLRDO2C/ZZ/emJLb72OsZeqQ6gL6Avko/XCXZw+NuxBSNhBAP13Hie418V7VMt9et1FMvpg==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@eslint/eslintrc/1.4.1: resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4215,7 +4711,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.18 + '@types/node': 18.13.0 '@types/yargs': 17.0.19 chalk: 4.1.2 dev: true @@ -4240,6 +4736,7 @@ packages: /@jridgewell/resolve-uri/3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} + dev: true /@jridgewell/set-array/1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} @@ -4248,6 +4745,7 @@ packages: /@jridgewell/sourcemap-codec/1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true /@jridgewell/trace-mapping/0.3.17: resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} @@ -4261,6 +4759,11 @@ packages: dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@jsdevtools/ono/7.1.3: + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + dev: false /@jsonhero/fetch-hero/0.2.2: resolution: {integrity: sha512-wO+JrqBfQDTtrGbxmAilJFaBLxdfVdeT7lsi+OaTqAv4taCU7aUzsGeDEtYvNF84xo/tCKi8F+YHiXM6k7er9Q==} @@ -4653,16 +5156,6 @@ packages: react-dom: 18.2.0_react@18.2.0 dev: false - /@react-email/render/0.0.3: - resolution: {integrity: sha512-+4eOrLGdTCJjoJU3PunekErjo3PFnhSDFjVINBHrfJT+1wlVdhWfDo7hFdzXJx/JOOYqmnZTilU/umGLdRumKQ==} - engines: {node: '>=18.0.0'} - dependencies: - pretty: 2.0.0 - react-dom: 18.2.0 - transitivePeerDependencies: - - react - dev: false - /@react-email/render/0.0.3_react@18.2.0: resolution: {integrity: sha512-+4eOrLGdTCJjoJU3PunekErjo3PFnhSDFjVINBHrfJT+1wlVdhWfDo7hFdzXJx/JOOYqmnZTilU/umGLdRumKQ==} engines: {node: '>=18.0.0'} @@ -4778,13 +5271,13 @@ packages: '@babel/eslint-parser': 7.19.1_ucmnolur3r335ullwiyt3zl3pi '@babel/preset-react': 7.18.6_@babel+core@7.20.12 '@rushstack/eslint-patch': 1.2.0 - '@typescript-eslint/eslint-plugin': 5.48.1_3jon24igvnqaqexgwtxk6nkpse + '@typescript-eslint/eslint-plugin': 5.51.0_3jon24igvnqaqexgwtxk6nkpse '@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe eslint: 8.31.0 eslint-import-resolver-node: 0.3.6 - eslint-import-resolver-typescript: 3.5.3_hnftvkj7qg3s6bbigj4pr6djxy - eslint-plugin-import: 2.27.4_qdjeohovcytra7xto5vgmxssaq - eslint-plugin-jest: 26.9.0_ohsifnwenhmxgcp7mend4dnv74 + eslint-import-resolver-typescript: 3.5.3_vz4tyq5r7fh66imfi352lmrvhq + eslint-plugin-import: 2.27.5_qdjeohovcytra7xto5vgmxssaq + eslint-plugin-jest: 26.9.0_bmivh2yni5e5jzvpaprsey2s7a eslint-plugin-jest-dom: 4.0.3_eslint@8.31.0 eslint-plugin-jsx-a11y: 6.7.1_eslint@8.31.0 eslint-plugin-node: 11.1.0_eslint@8.31.0 @@ -5142,6 +5635,7 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true + dev: true optional: true /@swc/core-darwin-x64/1.3.26: @@ -5150,6 +5644,7 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true + dev: true optional: true /@swc/core-linux-arm-gnueabihf/1.3.26: @@ -5158,6 +5653,7 @@ packages: cpu: [arm] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-linux-arm64-gnu/1.3.26: @@ -5166,6 +5662,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-linux-arm64-musl/1.3.26: @@ -5174,6 +5671,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-linux-x64-gnu/1.3.26: @@ -5182,6 +5680,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-linux-x64-musl/1.3.26: @@ -5190,6 +5689,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: true optional: true /@swc/core-win32-arm64-msvc/1.3.26: @@ -5198,6 +5698,7 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true + dev: true optional: true /@swc/core-win32-ia32-msvc/1.3.26: @@ -5206,6 +5707,7 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true + dev: true optional: true /@swc/core-win32-x64-msvc/1.3.26: @@ -5214,6 +5716,7 @@ packages: cpu: [x64] os: [win32] requiresBuild: true + dev: true optional: true /@swc/core/1.3.26: @@ -5231,6 +5734,7 @@ packages: '@swc/core-win32-arm64-msvc': 1.3.26 '@swc/core-win32-ia32-msvc': 1.3.26 '@swc/core-win32-x64-msvc': 1.3.26 + dev: true /@swc/helpers/0.4.14: resolution: {integrity: sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==} @@ -5258,7 +5762,7 @@ packages: tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.1.8_aesdjsunmf4wiehhujt67my7tu + tailwindcss: 3.1.8_postcss@8.4.21 /@tailwindcss/typography/0.5.9_tailwindcss@3.1.8: resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==} @@ -5269,7 +5773,7 @@ packages: lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 postcss-selector-parser: 6.0.10 - tailwindcss: 3.1.8_aesdjsunmf4wiehhujt67my7tu + tailwindcss: 3.1.8_postcss@8.4.21 dev: true /@tanstack/react-table/8.7.6_biqbaboplfbrettd7655fr4n2y: @@ -5357,17 +5861,50 @@ packages: engines: {node: '>= 6'} dev: true + /@trigger.dev/sdk/0.2.13: + resolution: {integrity: sha512-dEc0Lvbl8TK5lenK5Y88yPPwS/p1LO30d0oWMG+IpWgf7QxzeJaMoG55f/CvrV15LdtvlAdT/q0D08K2ao8TYA==} + dependencies: + debug: 4.3.4 + evt: 2.4.13 + node-fetch: 2.6.7 + slug: 6.1.0 + ulid: 2.3.0 + uuid: 9.0.0 + ws: 8.12.0 + zod: 3.20.2 + zod-error: 1.1.0 + zod-to-json-schema: 3.20.2_zod@3.20.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: false + + /@ts-morph/common/0.18.1: + resolution: {integrity: sha512-RVE+zSRICWRsfrkAw5qCAK+4ZH9kwEFv5h0+/YeHTLieWP7F4wWq4JsKFuNWG+fYh/KF+8rAtgdj5zb2mm+DVA==} + dependencies: + fast-glob: 3.2.12 + minimatch: 5.1.2 + mkdirp: 1.0.4 + path-browserify: 1.0.1 + dev: true + /@tsconfig/node10/1.0.9: resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true /@tsconfig/node12/1.0.11: resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true /@tsconfig/node14/1.0.3: resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true /@tsconfig/node16/1.0.3: resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} + dev: true /@typeform/embed-react/2.14.1_react@18.2.0: resolution: {integrity: sha512-+lPZyk3ghPYNyUPabBhMuG6pCP9Bx3qkNAXfKnWq3VMG2A7WXbfVOq2MouaCBRv539kryR6DVnvSvpBewHaoug==} @@ -5403,7 +5940,7 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/cacheable-request/6.0.3: @@ -5411,7 +5948,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 18.11.18 + '@types/node': 18.13.0 '@types/responselike': 1.0.0 dev: true @@ -5434,13 +5971,13 @@ packages: /@types/concat-stream/1.6.1: resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/connect/3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/cookie/0.4.1: @@ -5482,7 +6019,7 @@ packages: /@types/express-serve-static-core/4.17.32: resolution: {integrity: sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 dev: true @@ -5499,14 +6036,14 @@ packages: /@types/form-data/0.0.33: resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/glob/7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 18.11.18 + '@types/node': 18.13.0 /@types/hast/2.3.4: resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} @@ -5555,13 +6092,16 @@ packages: resolution: {integrity: sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g==} dev: true + /@types/json-pointer/1.0.31: + resolution: {integrity: sha512-hTPul7Um6LqsHXHQpdkXTU7Oysjsf+9k4Yfmg6JhSKG/jj9QuQGyMUdj6trPH6WHiIdxw7nYSROgOxeFmCVK2w==} + dev: true + /@types/json-query/2.2.3: resolution: {integrity: sha512-ygE4p8lyKzTBo9LF2K/u6MHnxPxbHY6wGvwM7TdAKhbP3SvEf+Y9aeVWedDiP8SMIPowTl9R/6awQYjiUTHz2g==} dev: true /@types/json-schema/7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} - dev: true /@types/json5/0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} @@ -5570,12 +6110,11 @@ packages: /@types/keyv/3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/lodash/4.14.191: resolution: {integrity: sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==} - dev: true /@types/marked/4.0.8: resolution: {integrity: sha512-HVNzMT5QlWCOdeuBsgXP8EZzKUf0+AXzN+sLmjvaB3ZlLqO+e4u0uXrdw9ub69wBKFs+c6/pA4r9sy6cCDvImw==} @@ -5605,7 +6144,7 @@ packages: /@types/morgan/1.9.4: resolution: {integrity: sha512-cXoc4k+6+YAllH3ZHmx4hf7La1dzUk6keTR4bF4b4Sc0mZxU/zK4wO7l+ZzezXm/jkYj/qC+uYGZrarZdIVvyQ==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/ms/0.7.31: @@ -5615,7 +6154,7 @@ packages: /@types/node-fetch/2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 form-data: 3.0.1 dev: true @@ -5636,6 +6175,10 @@ packages: /@types/node/18.11.18: resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} + dev: true + + /@types/node/18.13.0: + resolution: {integrity: sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==} /@types/node/8.10.66: resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} @@ -5644,6 +6187,10 @@ packages: /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + /@types/prettier/2.7.2: + resolution: {integrity: sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==} + dev: false + /@types/prismjs/1.26.0: resolution: {integrity: sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==} dev: true @@ -5682,7 +6229,7 @@ packages: /@types/responselike/1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/scheduler/0.16.2: @@ -5699,13 +6246,13 @@ packages: resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==} dependencies: '@types/mime': 3.0.1 - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/set-cookie-parser/2.4.2: resolution: {integrity: sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/sinonjs__fake-timers/8.1.1: @@ -5728,7 +6275,7 @@ packages: resolution: {integrity: sha512-tLfnlJf6A5mB6ddqF159GqcDizfzbMUB1/DeT59/wBNqzRTNNKsaw79A/1TZ84X+f/EwWH8FeuSkjlCLyqS/zQ==} dependencies: '@types/cookiejar': 2.1.2 - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/supertest/2.0.12: @@ -5754,7 +6301,7 @@ packages: /@types/ws/8.5.4: resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/yargs-parser/21.0.0: @@ -5771,12 +6318,12 @@ packages: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true optional: true - /@typescript-eslint/eslint-plugin/5.48.1_3jon24igvnqaqexgwtxk6nkpse: - resolution: {integrity: sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ==} + /@typescript-eslint/eslint-plugin/5.51.0_3jon24igvnqaqexgwtxk6nkpse: + resolution: {integrity: sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -5787,11 +6334,12 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 5.48.1_iukboom6ndih5an6iafl45j2fe - '@typescript-eslint/scope-manager': 5.48.1 - '@typescript-eslint/type-utils': 5.48.1_iukboom6ndih5an6iafl45j2fe - '@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/type-utils': 5.51.0_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/utils': 5.51.0_iukboom6ndih5an6iafl45j2fe debug: 4.3.4 eslint: 8.31.0 + grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 regexpp: 3.2.0 @@ -5802,6 +6350,54 @@ packages: - supports-color dev: true + /@typescript-eslint/eslint-plugin/5.51.0_bzepuo66bcyj4mepwnxofjvdli: + resolution: {integrity: sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/parser': 5.48.1_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/type-utils': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/utils': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm + debug: 4.3.4 + eslint: 8.34.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.4 + natural-compare-lite: 1.4.0 + regexpp: 3.2.0 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.5 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser/5.48.1_7kw3g6rralp5ps6mg3uyzz6azm: + resolution: {integrity: sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.48.1 + '@typescript-eslint/types': 5.48.1 + '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.5 + debug: 4.3.4 + eslint: 8.34.0 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/parser/5.48.1_iukboom6ndih5an6iafl45j2fe: resolution: {integrity: sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5830,8 +6426,16 @@ packages: '@typescript-eslint/visitor-keys': 5.48.1 dev: true - /@typescript-eslint/type-utils/5.48.1_iukboom6ndih5an6iafl45j2fe: - resolution: {integrity: sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ==} + /@typescript-eslint/scope-manager/5.51.0: + resolution: {integrity: sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/visitor-keys': 5.51.0 + dev: true + + /@typescript-eslint/type-utils/5.51.0_7kw3g6rralp5ps6mg3uyzz6azm: + resolution: {integrity: sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -5840,8 +6444,28 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4 - '@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/typescript-estree': 5.51.0_typescript@4.9.5 + '@typescript-eslint/utils': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm + debug: 4.3.4 + eslint: 8.34.0 + tsutils: 3.21.0_typescript@4.9.5 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/type-utils/5.51.0_iukboom6ndih5an6iafl45j2fe: + resolution: {integrity: sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 5.51.0_typescript@4.9.4 + '@typescript-eslint/utils': 5.51.0_iukboom6ndih5an6iafl45j2fe debug: 4.3.4 eslint: 8.31.0 tsutils: 3.21.0_typescript@4.9.4 @@ -5855,6 +6479,11 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/types/5.51.0: + resolution: {integrity: sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + /@typescript-eslint/typescript-estree/5.48.1_typescript@4.9.4: resolution: {integrity: sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5876,17 +6505,100 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.48.1_iukboom6ndih5an6iafl45j2fe: - resolution: {integrity: sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA==} + /@typescript-eslint/typescript-estree/5.48.1_typescript@4.9.5: + resolution: {integrity: sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.48.1 + '@typescript-eslint/visitor-keys': 5.48.1 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.5 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/typescript-estree/5.51.0_typescript@4.9.4: + resolution: {integrity: sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/visitor-keys': 5.51.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.4 + typescript: 4.9.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/typescript-estree/5.51.0_typescript@4.9.5: + resolution: {integrity: sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/visitor-keys': 5.51.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@4.9.5 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils/5.51.0_7kw3g6rralp5ps6mg3uyzz6azm: + resolution: {integrity: sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.48.1 - '@typescript-eslint/types': 5.48.1 - '@typescript-eslint/typescript-estree': 5.48.1_typescript@4.9.4 + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/typescript-estree': 5.51.0_typescript@4.9.5 + eslint: 8.34.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.34.0 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/utils/5.51.0_iukboom6ndih5an6iafl45j2fe: + resolution: {integrity: sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@types/semver': 7.3.13 + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/typescript-estree': 5.51.0_typescript@4.9.4 eslint: 8.31.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@8.31.0 @@ -5904,6 +6616,14 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /@typescript-eslint/visitor-keys/5.51.0: + resolution: {integrity: sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.51.0 + eslint-visitor-keys: 3.3.0 + dev: true + /@uiw/codemirror-extensions-basic-setup/4.19.5_tbeldtdcrf45b35pezgkzq2u4e: resolution: {integrity: sha512-1zt7ZPJ01xKkSW/KDy0FZNga0bngN1fC594wCVG7FBi60ehfcAucpooQ+JSPScKXopxcb+ugPKZvVLzr9/OfzA==} peerDependencies: @@ -5991,7 +6711,7 @@ packages: '@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.20.12 '@vanilla-extract/babel-plugin-debug-ids': 1.0.1 '@vanilla-extract/css': 1.9.3 - esbuild: 0.16.4 + esbuild: 0.16.17 eval: 0.1.6 find-up: 5.0.0 javascript-stringify: 2.1.0 @@ -6043,6 +6763,38 @@ packages: - terser dev: true + /@vitest/expect/0.28.5: + resolution: {integrity: sha512-gqTZwoUTwepwGIatnw4UKpQfnoyV0Z9Czn9+Lo2/jLIt4/AXLTn+oVZxlQ7Ng8bzcNkR+3DqLJ08kNr8jRmdNQ==} + dependencies: + '@vitest/spy': 0.28.5 + '@vitest/utils': 0.28.5 + chai: 4.3.7 + dev: true + + /@vitest/runner/0.28.5: + resolution: {integrity: sha512-NKkHtLB+FGjpp5KmneQjTcPLWPTDfB7ie+MmF1PnUBf/tGe2OjGxWyB62ySYZ25EYp9krR5Bw0YPLS/VWh1QiA==} + dependencies: + '@vitest/utils': 0.28.5 + p-limit: 4.0.0 + pathe: 1.1.0 + dev: true + + /@vitest/spy/0.28.5: + resolution: {integrity: sha512-7if6rsHQr9zbmvxN7h+gGh2L9eIIErgf8nSKYDlg07HHimCxp4H6I/X/DPXktVPPLQfiZ1Cw2cbDIx9fSqDjGw==} + dependencies: + tinyspy: 1.0.2 + dev: true + + /@vitest/utils/0.28.5: + resolution: {integrity: sha512-UyZdYwdULlOa4LTUSwZ+Paz7nBHGTT72jKwdFSV4IjHF1xsokp+CabMdhjvVhYwkLfO88ylJT46YMilnkSARZA==} + dependencies: + cli-truncate: 3.1.0 + diff: 5.1.0 + loupe: 2.3.6 + picocolors: 1.0.0 + pretty-format: 27.5.1 + dev: true + /@web3-storage/multipart-parser/1.0.0: resolution: {integrity: sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw==} @@ -6081,6 +6833,14 @@ packages: acorn: 8.8.1 dev: true + /acorn-jsx/5.3.2_acorn@8.8.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.8.2 + dev: true + /acorn-node/1.8.2: resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} dependencies: @@ -6095,6 +6855,7 @@ packages: /acorn-walk/8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} + dev: true /acorn/7.4.1: resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} @@ -6105,6 +6866,13 @@ packages: resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} engines: {node: '>=0.4.0'} hasBin: true + dev: true + + /acorn/8.8.2: + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true /agent-base/6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -6168,6 +6936,11 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + /ansi-regex/6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + /ansi-styles/3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -6185,13 +6958,17 @@ packages: engines: {node: '>=10'} dev: true + /ansi-styles/6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + /ansicolors/0.3.2: resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} dev: true /any-promise/1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - dev: true /any/1.0.0: resolution: {integrity: sha512-eHlqaTpbeFyxHAo2H8XI566tY/m+lvRUTsFwBNtWP08qJe7bf16Oj5ab2coiuY9yTMvzFgjpWbuqQIFqH+yi+w==} @@ -6237,6 +7014,7 @@ packages: /arg/4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true /arg/5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} @@ -6248,7 +7026,6 @@ packages: /argparse/2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true /aria-query/5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} @@ -6748,6 +7525,12 @@ packages: resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} dev: true + /builtins/5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.3.8 + dev: true + /bundle-require/3.1.2_esbuild@0.15.18: resolution: {integrity: sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -6758,6 +7541,16 @@ packages: load-tsconfig: 0.2.3 dev: true + /bundle-require/4.0.1_esbuild@0.17.8: + resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.17' + dependencies: + esbuild: 0.17.8 + load-tsconfig: 0.2.3 + dev: true + /busboy/1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -6998,6 +7791,10 @@ packages: /chardet/0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + /charenc/0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + dev: false + /check-error/1.0.2: resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} dev: true @@ -7058,6 +7855,17 @@ packages: escape-string-regexp: 4.0.0 dev: true + /cli-color/2.0.3: + resolution: {integrity: sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==} + engines: {node: '>=0.10'} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-iterator: 2.0.3 + memoizee: 0.4.15 + timers-ext: 0.1.7 + dev: false + /cli-cursor/3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -7092,6 +7900,14 @@ packages: string-width: 4.2.3 dev: true + /cli-truncate/3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + slice-ansi: 5.0.0 + string-width: 5.1.2 + dev: true + /cli-ux/6.0.9: resolution: {integrity: sha512-0Ku29QLf+P6SeBNWM7zyoJ49eKKOjxZBZ4OH2aFeRtC0sNXU3ftdJxQPKJ1SJ+axX34I1NsfTFahpXdnxklZgA==} engines: {node: '>=12.0.0'} @@ -7167,6 +7983,11 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + /clone/2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + dev: false + /clsx/1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} @@ -7177,6 +7998,10 @@ packages: engines: {node: '>=0.10.0'} dev: false + /code-block-writer/11.0.3: + resolution: {integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==} + dev: true + /code-point-at/1.1.0: resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} engines: {node: '>=0.10.0'} @@ -7395,6 +8220,7 @@ packages: /create-require/1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true /crelt/1.0.5: resolution: {integrity: sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==} @@ -7446,6 +8272,10 @@ packages: shebang-command: 2.0.0 which: 2.0.2 + /crypt/0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + dev: false + /crypto-js/4.1.1: resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} dev: false @@ -7543,6 +8373,17 @@ packages: yauzl: 2.10.0 dev: true + /d/1.0.1: + resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} + dependencies: + es5-ext: 0.10.62 + type: 1.2.0 + dev: false + + /dag-map/1.0.2: + resolution: {integrity: sha512-+LSAiGFwQ9dRnRdOeaj7g47ZFJcOUPukAP8J3A3fuZ1g9Y44BG+P1sgApjLXTQPOzC4+7S9Wr8kXsfpINM4jpw==} + dev: false + /damerau-levenshtein/1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true @@ -7558,6 +8399,11 @@ packages: resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==} engines: {node: '>= 6'} + /data-uri-to-buffer/4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + dev: false + /date-fns/2.29.3: resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} engines: {node: '>=0.11'} @@ -7855,6 +8701,7 @@ packages: /diff/4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + dev: true /diff/5.1.0: resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} @@ -7944,6 +8791,10 @@ packages: stream-shift: 1.0.1 dev: true + /eastasianwidth/0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + /ecc-jsbn/0.1.2: resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} dependencies: @@ -8092,6 +8943,40 @@ packages: is-date-object: 1.0.5 is-symbol: 1.0.4 + /es5-ext/0.10.62: + resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} + engines: {node: '>=0.10'} + requiresBuild: true + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.3 + next-tick: 1.1.0 + dev: false + + /es6-iterator/2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-symbol: 3.1.3 + dev: false + + /es6-symbol/3.1.3: + resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} + dependencies: + d: 1.0.1 + ext: 1.7.0 + dev: false + + /es6-weak-map/2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-iterator: 2.0.3 + es6-symbol: 3.1.3 + dev: false + /esbuild-android-64/0.15.18: resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} engines: {node: '>=12'} @@ -8281,6 +9166,36 @@ packages: esbuild-windows-64: 0.15.18 esbuild-windows-arm64: 0.15.18 + /esbuild/0.16.17: + resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.16.17 + '@esbuild/android-arm64': 0.16.17 + '@esbuild/android-x64': 0.16.17 + '@esbuild/darwin-arm64': 0.16.17 + '@esbuild/darwin-x64': 0.16.17 + '@esbuild/freebsd-arm64': 0.16.17 + '@esbuild/freebsd-x64': 0.16.17 + '@esbuild/linux-arm': 0.16.17 + '@esbuild/linux-arm64': 0.16.17 + '@esbuild/linux-ia32': 0.16.17 + '@esbuild/linux-loong64': 0.16.17 + '@esbuild/linux-mips64el': 0.16.17 + '@esbuild/linux-ppc64': 0.16.17 + '@esbuild/linux-riscv64': 0.16.17 + '@esbuild/linux-s390x': 0.16.17 + '@esbuild/linux-x64': 0.16.17 + '@esbuild/netbsd-x64': 0.16.17 + '@esbuild/openbsd-x64': 0.16.17 + '@esbuild/sunos-x64': 0.16.17 + '@esbuild/win32-arm64': 0.16.17 + '@esbuild/win32-ia32': 0.16.17 + '@esbuild/win32-x64': 0.16.17 + dev: true + /esbuild/0.16.3: resolution: {integrity: sha512-71f7EjPWTiSguen8X/kxEpkAS7BFHwtQKisCDDV3Y4GLGWBaoSCyD5uXkaUew6JDzA9FEN1W23mdnSwW9kqCeg==} engines: {node: '>=12'} @@ -8340,6 +9255,36 @@ packages: '@esbuild/win32-ia32': 0.16.4 '@esbuild/win32-x64': 0.16.4 + /esbuild/0.17.8: + resolution: {integrity: sha512-g24ybC3fWhZddZK6R3uD2iF/RIPnRpwJAqLov6ouX3hMbY4+tKolP0VMF3zuIYCaXun+yHwS5IPQ91N2BT191g==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.8 + '@esbuild/android-arm64': 0.17.8 + '@esbuild/android-x64': 0.17.8 + '@esbuild/darwin-arm64': 0.17.8 + '@esbuild/darwin-x64': 0.17.8 + '@esbuild/freebsd-arm64': 0.17.8 + '@esbuild/freebsd-x64': 0.17.8 + '@esbuild/linux-arm': 0.17.8 + '@esbuild/linux-arm64': 0.17.8 + '@esbuild/linux-ia32': 0.17.8 + '@esbuild/linux-loong64': 0.17.8 + '@esbuild/linux-mips64el': 0.17.8 + '@esbuild/linux-ppc64': 0.17.8 + '@esbuild/linux-riscv64': 0.17.8 + '@esbuild/linux-s390x': 0.17.8 + '@esbuild/linux-x64': 0.17.8 + '@esbuild/netbsd-x64': 0.17.8 + '@esbuild/openbsd-x64': 0.17.8 + '@esbuild/sunos-x64': 0.17.8 + '@esbuild/win32-arm64': 0.17.8 + '@esbuild/win32-ia32': 0.17.8 + '@esbuild/win32-x64': 0.17.8 + dev: true + /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -8383,6 +9328,51 @@ packages: eslint: 8.31.0 dev: true + /eslint-config-prettier/8.6.0_eslint@8.34.0: + resolution: {integrity: sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.34.0 + dev: true + + /eslint-config-standard-with-typescript/34.0.0_xlnlhajfavmnhfjhhcrfaju6re: + resolution: {integrity: sha512-zhCsI4/A0rJ1ma8sf3RLXYc0gc7yPmdTWRVXMh9dtqeUx3yBQyALH0wosHhk1uQ9QyItynLdNOtcHKNw8G7lQw==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + eslint: ^8.0.1 + eslint-plugin-import: ^2.25.2 + eslint-plugin-n: ^15.0.0 + eslint-plugin-promise: ^6.0.0 + typescript: '*' + dependencies: + '@typescript-eslint/eslint-plugin': 5.51.0_bzepuo66bcyj4mepwnxofjvdli + '@typescript-eslint/parser': 5.48.1_7kw3g6rralp5ps6mg3uyzz6azm + eslint: 8.34.0 + eslint-config-standard: 17.0.0_rwq7hzy2vtlwiajbw6pmw3rkzy + eslint-plugin-import: 2.27.5_zycheyzypw6s5ouujsf5akzhsy + eslint-plugin-n: 15.6.1_eslint@8.34.0 + eslint-plugin-promise: 6.1.1_eslint@8.34.0 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-config-standard/17.0.0_rwq7hzy2vtlwiajbw6pmw3rkzy: + resolution: {integrity: sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==} + peerDependencies: + eslint: ^8.0.1 + eslint-plugin-import: ^2.25.2 + eslint-plugin-n: ^15.0.0 + eslint-plugin-promise: ^6.0.0 + dependencies: + eslint: 8.34.0 + eslint-plugin-import: 2.27.5_zycheyzypw6s5ouujsf5akzhsy + eslint-plugin-n: 15.6.1_eslint@8.34.0 + eslint-plugin-promise: 6.1.1_eslint@8.34.0 + dev: true + /eslint-config-turbo/0.0.7_eslint@8.31.0: resolution: {integrity: sha512-WbrGlyfs94rOXrhombi1wjIAYGdV2iosgJRndOZtmDQeq5GLTzYmBUCJQZWtLBEBUPCj96RxZ2OL7Cn+xv/Azg==} peerDependencies: @@ -8411,7 +9401,7 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript/3.5.3_hnftvkj7qg3s6bbigj4pr6djxy: + /eslint-import-resolver-typescript/3.5.3_vz4tyq5r7fh66imfi352lmrvhq: resolution: {integrity: sha512-njRcKYBc3isE42LaTcJNVANR3R99H9bAxBDMNDr2W7yq5gYPxbU3MkdhsQukxZ/Xg9C2vcyLlDsbKfRDg0QvCQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -8421,7 +9411,7 @@ packages: debug: 4.3.4 enhanced-resolve: 5.12.0 eslint: 8.31.0 - eslint-plugin-import: 2.27.4_qdjeohovcytra7xto5vgmxssaq + eslint-plugin-import: 2.27.5_qdjeohovcytra7xto5vgmxssaq get-tsconfig: 4.3.0 globby: 13.1.3 is-core-module: 2.11.0 @@ -8431,6 +9421,35 @@ packages: - supports-color dev: true + /eslint-module-utils/2.7.4_fqawsowff3yxll7f25e3byprdq: + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.48.1_7kw3g6rralp5ps6mg3uyzz6azm + debug: 3.2.7 + eslint: 8.34.0 + eslint-import-resolver-node: 0.3.7 + transitivePeerDependencies: + - supports-color + dev: true + /eslint-module-utils/2.7.4_sqt5xxn4ciiurbqrzlaarm6ama: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} @@ -8480,8 +9499,19 @@ packages: regexpp: 3.2.0 dev: true - /eslint-plugin-import/2.27.4_qdjeohovcytra7xto5vgmxssaq: - resolution: {integrity: sha512-Z1jVt1EGKia1X9CnBCkpAOhWy8FgQ7OmJ/IblEkT82yrFU/xJaxwujaTzLWqigewwynRQ9mmHfX9MtAfhxm0sA==} + /eslint-plugin-es/4.1.0_eslint@8.34.0: + resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + eslint: 8.34.0 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + dev: true + + /eslint-plugin-import/2.27.5_qdjeohovcytra7xto5vgmxssaq: + resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -8513,6 +9543,39 @@ packages: - supports-color dev: true + /eslint-plugin-import/2.27.5_zycheyzypw6s5ouujsf5akzhsy: + resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 5.48.1_7kw3g6rralp5ps6mg3uyzz6azm + array-includes: 3.1.6 + array.prototype.flat: 1.3.1 + array.prototype.flatmap: 1.3.1 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.34.0 + eslint-import-resolver-node: 0.3.7 + eslint-module-utils: 2.7.4_fqawsowff3yxll7f25e3byprdq + has: 1.0.3 + is-core-module: 2.11.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.1 + semver: 6.3.0 + tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-plugin-jest-dom/4.0.3_eslint@8.31.0: resolution: {integrity: sha512-9j+n8uj0+V0tmsoS7bYC7fLhQmIvjRqRYEcbDSi+TKPsTThLLXCyj5swMSSf/hTleeMktACnn+HFqXBr5gbcbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6', yarn: '>=1'} @@ -8525,7 +9588,7 @@ packages: requireindex: 1.2.0 dev: true - /eslint-plugin-jest/26.9.0_ohsifnwenhmxgcp7mend4dnv74: + /eslint-plugin-jest/26.9.0_bmivh2yni5e5jzvpaprsey2s7a: resolution: {integrity: sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -8538,8 +9601,8 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.48.1_3jon24igvnqaqexgwtxk6nkpse - '@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/eslint-plugin': 5.51.0_3jon24igvnqaqexgwtxk6nkpse + '@typescript-eslint/utils': 5.51.0_iukboom6ndih5an6iafl45j2fe eslint: 8.31.0 transitivePeerDependencies: - supports-color @@ -8571,6 +9634,23 @@ packages: semver: 6.3.0 dev: true + /eslint-plugin-n/15.6.1_eslint@8.34.0: + resolution: {integrity: sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==} + engines: {node: '>=12.22.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + builtins: 5.0.1 + eslint: 8.34.0 + eslint-plugin-es: 4.1.0_eslint@8.34.0 + eslint-utils: 3.0.0_eslint@8.34.0 + ignore: 5.2.4 + is-core-module: 2.11.0 + minimatch: 3.1.2 + resolve: 1.22.1 + semver: 7.3.8 + dev: true + /eslint-plugin-node/11.1.0_eslint@8.31.0: resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} @@ -8586,6 +9666,15 @@ packages: semver: 6.3.0 dev: true + /eslint-plugin-promise/6.1.1_eslint@8.34.0: + resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.34.0 + dev: true + /eslint-plugin-react-hooks/4.6.0_eslint@8.31.0: resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} @@ -8648,7 +9737,7 @@ packages: peerDependencies: eslint: ^7.5.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.48.1_iukboom6ndih5an6iafl45j2fe + '@typescript-eslint/utils': 5.51.0_iukboom6ndih5an6iafl45j2fe eslint: 8.31.0 transitivePeerDependencies: - supports-color @@ -8696,6 +9785,16 @@ packages: eslint-visitor-keys: 2.1.0 dev: true + /eslint-utils/3.0.0_eslint@8.34.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.34.0 + eslint-visitor-keys: 2.1.0 + dev: true + /eslint-visitor-keys/1.3.0: resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} engines: {node: '>=4'} @@ -8759,6 +9858,54 @@ packages: - supports-color dev: true + /eslint/8.34.0: + resolution: {integrity: sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint/eslintrc': 1.4.1 + '@humanwhocodes/config-array': 0.11.8 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-utils: 3.0.0_eslint@8.34.0 + eslint-visitor-keys: 3.3.0 + espree: 9.4.1 + esquery: 1.4.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.19.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.4 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-sdsl: 4.2.0 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + regexpp: 3.2.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + /espree/9.4.1: resolution: {integrity: sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -8861,6 +10008,13 @@ packages: require-like: 0.1.2 dev: true + /event-emitter/0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + dev: false + /event-stream/3.3.4: resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} dependencies: @@ -9011,6 +10165,12 @@ packages: transitivePeerDependencies: - supports-color + /ext/1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + dependencies: + type: 2.7.2 + dev: false + /extend-shallow/2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -9154,6 +10314,14 @@ packages: pend: 1.2.0 dev: true + /fetch-blob/3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.2.1 + dev: false + /fflate/0.4.8: resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} dev: false @@ -9278,6 +10446,10 @@ packages: for-in: 1.0.2 dev: false + /foreach/2.0.6: + resolution: {integrity: sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==} + dev: false + /foreground-child/2.0.0: resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} engines: {node: '>=8.0.0'} @@ -9335,6 +10507,13 @@ packages: engines: {node: '>=0.4.x'} dev: true + /formdata-polyfill/4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + dependencies: + fetch-blob: 3.2.0 + dev: false + /forwarded/0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -9514,6 +10693,11 @@ packages: engines: {node: '>=8'} dev: true + /get-stdin/8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + dev: false + /get-stream/4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} engines: {node: '>=6'} @@ -9542,6 +10726,10 @@ packages: /get-tsconfig/4.3.0: resolution: {integrity: sha512-YCcF28IqSay3fqpIu5y3Krg/utCBHBeoflkZyHj/QcqI2nrLPC3ZegS9CmIo+hJb8K7aiGsuUl7PwWVjNG2HQQ==} + /get-tsconfig/4.4.0: + resolution: {integrity: sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ==} + dev: true + /get-uri/3.0.2: resolution: {integrity: sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==} engines: {node: '>= 6'} @@ -9594,6 +10782,16 @@ packages: dependencies: is-glob: 4.0.3 + /glob-promise/4.2.2_glob@7.2.3: + resolution: {integrity: sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==} + engines: {node: '>=12'} + peerDependencies: + glob: ^7.1.6 + dependencies: + '@types/glob': 7.2.0 + glob: 7.2.3 + dev: false + /glob-regex/0.3.2: resolution: {integrity: sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==} dev: true @@ -10331,6 +11529,11 @@ packages: dependencies: is-plain-object: 2.0.4 + /is-extglob/1.0.0: + resolution: {integrity: sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==} + engines: {node: '>=0.10.0'} + dev: false + /is-extglob/2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -10346,12 +11549,24 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + /is-fullwidth-code-point/4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + /is-generator-function/1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 + /is-glob/2.0.1: + resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 1.0.0 + dev: false + /is-glob/3.1.0: resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} engines: {node: '>=0.10.0'} @@ -10385,6 +11600,13 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + /is-invalid-path/0.1.0: + resolution: {integrity: sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-glob: 2.0.1 + dev: false + /is-ip/3.1.0: resolution: {integrity: sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==} engines: {node: '>=8'} @@ -10458,6 +11680,10 @@ packages: dependencies: isobject: 3.0.1 + /is-promise/2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: false + /is-reference/3.0.1: resolution: {integrity: sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==} dependencies: @@ -10521,6 +11747,13 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + /is-valid-path/0.1.1: + resolution: {integrity: sha512-+kwPrVDu9Ms03L90Qaml+79+6DZHqHyRoANI6IsZJ/g8frhnfchDOBCa0RbQ6/kdHt5CS5OeIEyrYznNuVN+8A==} + engines: {node: '>=0.10.0'} + dependencies: + is-invalid-path: 0.1.0 + dev: false + /is-weakmap/2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} dev: true @@ -10678,7 +11911,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.18 + '@types/node': 18.13.0 chalk: 4.1.2 ci-info: 3.7.1 graceful-fs: 4.2.10 @@ -10742,7 +11975,6 @@ packages: hasBin: true dependencies: argparse: 2.0.1 - dev: true /jsbn/0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} @@ -10779,10 +12011,30 @@ packages: /json-parse-even-better-errors/2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + /json-pointer/0.6.2: + resolution: {integrity: sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==} + dependencies: + foreach: 2.0.6 + dev: false + /json-query/2.2.2: resolution: {integrity: sha512-y+IcVZSdqNmS4fO8t1uZF6RMMs0xh3SrTjJr9bp1X3+v0Q13+7Cyv12dSmKwDswp/H427BVtpkLWhGxYu3ZWRA==} dev: false + /json-schema-deref-sync/0.14.0: + resolution: {integrity: sha512-yGR1xmhdiD6R0MSrwWcFxQzAj5b3i5Gb/mt5tvQKgFMMeNe0KZYNEN/jWr7G+xn39Azqgcvk4ZKMs8dQl8e4wA==} + engines: {node: '>=6.0.0'} + dependencies: + clone: 2.1.2 + dag-map: 1.0.2 + is-valid-path: 0.1.1 + lodash: 4.17.21 + md5: 2.2.1 + memory-cache: 0.2.0 + traverse: 0.6.7 + valid-url: 1.0.9 + dev: false + /json-schema-faker/0.5.0-rcv.46: resolution: {integrity: sha512-Q+sGrxptZfezwm7M9W9VmHT9E8s5fWPCaRC4J2zUjb3CmDsxokiCBdHdS/psu91Tafc/ITv+GtIztGzUVT2zIg==} hasBin: true @@ -10800,6 +12052,27 @@ packages: ono: 4.0.11 dev: false + /json-schema-to-typescript/11.0.3: + resolution: {integrity: sha512-EaEE9Y4VZ8b9jW5zce5a9L3+p4C9AqgIRHbNVDJahfMnoKzcd4sDb98BLxLdQhJEuRAXyKLg4H66NKm80W8ilg==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + '@bcherny/json-schema-ref-parser': 9.0.9 + '@types/json-schema': 7.0.11 + '@types/lodash': 4.14.191 + '@types/prettier': 2.7.2 + cli-color: 2.0.3 + get-stdin: 8.0.0 + glob: 7.2.3 + glob-promise: 4.2.2_glob@7.2.3 + is-glob: 4.0.3 + lodash: 4.17.21 + minimist: 1.2.7 + mkdirp: 1.0.4 + mz: 2.7.0 + prettier: 2.8.2 + dev: false + /json-schema-traverse/0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true @@ -11182,6 +12455,12 @@ packages: engines: {node: '>=12'} dev: true + /lru-queue/0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + dependencies: + es5-ext: 0.10.62 + dev: false + /lru_map/0.3.3: resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} dev: false @@ -11217,6 +12496,7 @@ packages: /make-error/1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true /make-iterator/0.1.1: resolution: {integrity: sha512-s8tbTxYqrfcXYHAPxUecPxgBnWod7yFShdSOWiV17WRM87bBH2mzr24A4tpUDv9SqebaV6JsPApwKXnisMmMBA==} @@ -11281,6 +12561,14 @@ packages: remove-accents: 0.4.2 dev: false + /md5/2.2.1: + resolution: {integrity: sha512-PlGG4z5mBANDGCKsYQe0CaUYHdZYZt8ZPZLmEt+Urf0W4GlpTX4HescwHU+dc9+Z/G/vZKYZYFrwgm9VxK6QOQ==} + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + dev: false + /mdast-util-definitions/5.1.1: resolution: {integrity: sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==} dependencies: @@ -11413,6 +12701,23 @@ packages: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} + /memoizee/0.4.15: + resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-weak-map: 2.0.3 + event-emitter: 0.3.5 + is-promise: 2.2.2 + lru-queue: 0.1.0 + next-tick: 1.1.0 + timers-ext: 0.1.7 + dev: false + + /memory-cache/0.2.0: + resolution: {integrity: sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==} + dev: false + /memorystream/0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -11526,8 +12831,8 @@ packages: /micromark-extension-mdxjs/1.0.0: resolution: {integrity: sha512-TZZRZgeHvtgm+IhtgC2+uDMR7h8eTKF0QUX9YsgoL9+bADBpBY6SiLvWqnBlLbCEevITmTqmEuY3FoxMKVs1rQ==} dependencies: - acorn: 8.8.1 - acorn-jsx: 5.3.2_acorn@8.8.1 + acorn: 8.8.2 + acorn-jsx: 5.3.2_acorn@8.8.2 micromark-extension-mdx-expression: 1.0.3 micromark-extension-mdx-jsx: 1.0.3 micromark-extension-mdx-md: 1.0.0 @@ -11880,12 +13185,11 @@ packages: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true - dev: true /mlly/1.1.0: resolution: {integrity: sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==} dependencies: - acorn: 8.8.1 + acorn: 8.8.2 pathe: 1.1.0 pkg-types: 1.0.1 ufo: 1.0.1 @@ -11970,7 +13274,6 @@ packages: any-promise: 1.3.0 object-assign: 4.1.1 thenify-all: 1.6.0 - dev: true /nano-time/1.0.0: resolution: {integrity: sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==} @@ -12025,6 +13328,10 @@ packages: engines: {node: '>= 0.4.0'} dev: true + /next-tick/1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + dev: false + /nice-try/1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} dev: true @@ -12037,6 +13344,11 @@ packages: /node-addon-api/4.3.0: resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + /node-domexception/1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + dev: false + /node-fetch/2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -12048,6 +13360,15 @@ packages: dependencies: whatwg-url: 5.0.0 + /node-fetch/3.3.0: + resolution: {integrity: sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + dev: false + /node-releases/2.0.8: resolution: {integrity: sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==} dev: true @@ -12434,6 +13755,13 @@ packages: dependencies: yocto-queue: 0.1.0 + /p-limit/4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + /p-locate/4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -12586,6 +13914,10 @@ packages: cross-spawn: 6.0.5 dev: true + /path-browserify/1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: true + /path-dirname/1.0.2: resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} @@ -12776,6 +14108,7 @@ packages: postcss: 8.4.21 ts-node: 10.9.1_fodzh64fuekdilycyvke2qmf2e yaml: 1.10.2 + dev: true /postcss-load-config/3.1.4_postcss@8.4.21: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} @@ -12792,7 +14125,6 @@ packages: lilconfig: 2.0.6 postcss: 8.4.21 yaml: 1.10.2 - dev: true /postcss-modules-extract-imports/3.0.0_postcss@8.4.21: resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} @@ -13194,15 +14526,6 @@ packages: shallow-equal: 1.2.1 dev: false - /react-dom/18.2.0: - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} - peerDependencies: - react: ^18.2.0 - dependencies: - loose-envify: 1.4.0 - scheduler: 0.23.0 - dev: false - /react-dom/18.2.0_react@18.2.0: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -13813,6 +15136,12 @@ packages: dependencies: glob: 7.2.3 + /rimraf/4.1.2: + resolution: {integrity: sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==} + engines: {node: '>=14'} + hasBin: true + dev: true + /rollup-plugin-inject/3.0.2: resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. @@ -14047,6 +15376,10 @@ packages: get-intrinsic: 1.1.3 object-inspect: 1.12.2 + /siginfo/2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + /sigmund/1.0.1: resolution: {integrity: sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==} @@ -14091,6 +15424,14 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true + /slice-ansi/5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + /slug/6.1.0: resolution: {integrity: sha512-x6vLHCMasg4DR2LPiyFGI0gJJhywY6DTiGhCrOMzb3SOk/0JVLIaL4UhyFSHu04SD3uAavrKY/K3zZ3i6iRcgA==} dev: false @@ -14298,6 +15639,10 @@ packages: escape-string-regexp: 2.0.0 dev: true + /stackback/0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + /standard-as-callback/2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} dev: false @@ -14330,6 +15675,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + /std-env/3.3.2: + resolution: {integrity: sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==} + dev: true + /stream-combiner/0.0.4: resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} dependencies: @@ -14382,6 +15731,15 @@ packages: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + /string-width/5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.0.1 + dev: true + /string.prototype.matchall/4.0.8: resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} dependencies: @@ -14452,6 +15810,13 @@ packages: dependencies: ansi-regex: 5.0.1 + /strip-ansi/7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + /strip-bom/3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -14479,7 +15844,13 @@ packages: /strip-literal/0.4.2: resolution: {integrity: sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==} dependencies: - acorn: 8.8.1 + acorn: 8.8.2 + dev: true + + /strip-literal/1.0.1: + resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} + dependencies: + acorn: 8.8.2 dev: true /striptags/2.2.1: @@ -14601,6 +15972,7 @@ packages: resolve: 1.22.1 transitivePeerDependencies: - ts-node + dev: true /tailwindcss/3.1.8_postcss@8.4.21: resolution: {integrity: sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==} @@ -14633,7 +16005,6 @@ packages: resolve: 1.22.1 transitivePeerDependencies: - ts-node - dev: true /tapable/2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} @@ -14712,13 +16083,11 @@ packages: engines: {node: '>=0.8'} dependencies: thenify: 3.3.1 - dev: true /thenify/3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} dependencies: any-promise: 1.3.0 - dev: true /throttleit/1.0.0: resolution: {integrity: sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==} @@ -14735,6 +16104,13 @@ packages: xtend: 4.0.2 dev: true + /timers-ext/0.1.7: + resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} + dependencies: + es5-ext: 0.10.62 + next-tick: 1.1.0 + dev: false + /tiny-glob/0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} dependencies: @@ -14754,6 +16130,11 @@ packages: engines: {node: '>=14.0.0'} dev: true + /tinypool/0.3.1: + resolution: {integrity: sha512-zLA1ZXlstbU2rlpA4CIeVaqvWq41MTWqLY3FfsAXgC8+f7Pk7zroaJQxDgxn1xNudKW6Kmj4808rPFShUlIRmQ==} + engines: {node: '>=14.0.0'} + dev: true + /tinyspy/1.0.2: resolution: {integrity: sha512-bSGlgwLBYf7PnUsQ6WOc6SJ3pGOcd+d8AA6EUnLDDM0kWEstC1JIlSZA3UNliDXhd9ABoS7hiRBDCu+XP/sf1Q==} engines: {node: '>=14.0.0'} @@ -14845,6 +16226,10 @@ packages: /traverse/0.3.9: resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} + /traverse/0.6.7: + resolution: {integrity: sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==} + dev: false + /tree-kill/1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -14876,6 +16261,13 @@ packages: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true + /ts-morph/17.0.1: + resolution: {integrity: sha512-10PkHyXmrtsTvZSL+cqtJLTgFXkU43Gd0JCc0Rw6GchWbqKe0Rwgt1v3ouobTZwQzF1mGhDeAlWYBMGRV7y+3g==} + dependencies: + '@ts-morph/common': 0.18.1 + code-block-writer: 11.0.3 + dev: true + /ts-node/10.9.1_fodzh64fuekdilycyvke2qmf2e: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -14906,6 +16298,7 @@ packages: typescript: 4.9.4 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + dev: true /ts-toolbelt/9.6.0: resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} @@ -14915,6 +16308,30 @@ packages: resolution: {integrity: sha512-3IDBalvf6SyvHFS14UiwCWzqdSdo+Q0k2J7DZyJYaHW/iraW9DJpaBKDJpry3yQs3o/t/A+oGaRW3iVt2lKxzA==} dev: false + /tsconfck/2.0.2: + resolution: {integrity: sha512-H3DWlwKpow+GpVLm/2cpmok72pwRr1YFROV3YzAmvzfGFiC1zEM/mc9b7+1XnrxuXtEbhJ7xUSIqjPFbedp7aQ==} + engines: {node: ^14.13.1 || ^16 || >=18, pnpm: ^7.18.0} + hasBin: true + peerDependencies: + typescript: ^4.3.5 + peerDependenciesMeta: + typescript: + optional: true + dev: true + + /tsconfck/2.0.2_typescript@4.9.5: + resolution: {integrity: sha512-H3DWlwKpow+GpVLm/2cpmok72pwRr1YFROV3YzAmvzfGFiC1zEM/mc9b7+1XnrxuXtEbhJ7xUSIqjPFbedp7aQ==} + engines: {node: ^14.13.1 || ^16 || >=18, pnpm: ^7.18.0} + hasBin: true + peerDependencies: + typescript: ^4.3.5 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 4.9.5 + dev: true + /tsconfig-paths/3.14.1: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} dependencies: @@ -15010,6 +16427,42 @@ packages: - ts-node dev: true + /tsup/6.6.2_typescript@4.9.5: + resolution: {integrity: sha512-+yQ6SI4rVtp1+YpcYOePumJLEVQ896CDNRt9dJ2L/DeMnLf1+FTOCVw5eioLBH0xLdHgogO9NQ6vPNF5MfkSJw==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: ^4.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + dependencies: + bundle-require: 4.0.1_esbuild@0.17.8 + cac: 6.7.14 + chokidar: 3.5.3 + debug: 4.3.4 + esbuild: 0.17.8 + execa: 5.1.1 + globby: 11.1.0 + joycon: 3.1.1 + postcss-load-config: 3.1.4 + resolve-from: 5.0.0 + rollup: 3.10.0 + source-map: 0.8.0-beta.0 + sucrase: 3.29.0 + tree-kill: 1.2.2 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + /tsutils/3.21.0_typescript@4.9.4: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -15020,6 +16473,16 @@ packages: typescript: 4.9.4 dev: true + /tsutils/3.21.0_typescript@4.9.5: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + dev: true + /tsx/3.12.2: resolution: {integrity: sha512-ykAEkoBg30RXxeOMVeZwar+JH632dZn9EUJVyJwhfag62k6UO/dIyJEV58YuLF6e5BTdV/qmbQrpkWqjq9cUnQ==} hasBin: true @@ -15030,6 +16493,17 @@ packages: optionalDependencies: fsevents: 2.3.2 + /tsx/3.12.3: + resolution: {integrity: sha512-Wc5BFH1xccYTXaQob+lEcimkcb/Pq+0en2s+ruiX0VEIC80nV7/0s7XRahx8NnsoCnpCVUPz8wrqVSPi760LkA==} + hasBin: true + dependencies: + '@esbuild-kit/cjs-loader': 2.4.2 + '@esbuild-kit/core-utils': 3.0.0 + '@esbuild-kit/esm-loader': 2.5.5 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /tty-table/4.1.6: resolution: {integrity: sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==} engines: {node: '>=8.0.0'} @@ -15169,6 +16643,14 @@ packages: media-typer: 0.3.0 mime-types: 2.1.35 + /type/1.2.0: + resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} + dev: false + + /type/2.7.2: + resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} + dev: false + /typed-array-length/1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: @@ -15185,6 +16667,12 @@ packages: engines: {node: '>=4.2.0'} hasBin: true + /typescript/4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + /ufo/1.0.1: resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==} dev: true @@ -15491,6 +16979,7 @@ packages: /v8-compile-cache-lib/3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true /v8-to-istanbul/9.0.1: resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==} @@ -15501,6 +16990,10 @@ packages: convert-source-map: 1.9.0 dev: true + /valid-url/1.0.9: + resolution: {integrity: sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==} + dev: false + /validate-npm-package-license/3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -15549,6 +17042,29 @@ packages: vfile-message: 3.1.3 dev: true + /vite-node/0.28.5_@types+node@18.13.0: + resolution: {integrity: sha512-LmXb9saMGlrMZbXTvOveJKwMTBTNUH66c8rJnQ0ZPNX+myPEol64+szRzXtV5ORb0Hb/91yq+/D3oERoyAt6LA==} + engines: {node: '>=v14.16.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.1.0 + pathe: 1.1.0 + picocolors: 1.0.0 + source-map: 0.6.1 + source-map-support: 0.5.21 + vite: 4.1.1_@types+node@18.13.0 + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite-tsconfig-paths/3.6.0_vite@3.2.5: resolution: {integrity: sha512-UfsPYonxLqPD633X8cWcPFVuYzx/CMNHAjZTasYwX69sXpa4gNmQkR0XCjj82h7zhLGdTWagMjC1qfb9S+zv0A==} peerDependencies: @@ -15563,6 +17079,28 @@ packages: - supports-color dev: true + /vite-tsconfig-paths/4.0.5: + resolution: {integrity: sha512-/L/eHwySFYjwxoYt1WRJniuK/jPv+WGwgRGBYx3leciR5wBeqntQpUE6Js6+TJemChc+ter7fDBKieyEWDx4yQ==} + dependencies: + debug: 4.3.4 + globrex: 0.1.2 + tsconfck: 2.0.2 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /vite-tsconfig-paths/4.0.5_typescript@4.9.5: + resolution: {integrity: sha512-/L/eHwySFYjwxoYt1WRJniuK/jPv+WGwgRGBYx3leciR5wBeqntQpUE6Js6+TJemChc+ter7fDBKieyEWDx4yQ==} + dependencies: + debug: 4.3.4 + globrex: 0.1.2 + tsconfck: 2.0.2_typescript@4.9.5 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /vite/3.2.5_@types+node@18.11.18: resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -15597,6 +17135,107 @@ packages: fsevents: 2.3.2 dev: true + /vite/3.2.5_@types+node@18.13.0: + resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.13.0 + esbuild: 0.15.18 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 2.79.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite/4.1.1: + resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.16.17 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.10.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite/4.1.1_@types+node@18.13.0: + resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.13.0 + esbuild: 0.16.17 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.10.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /vitest/0.23.4_happy-dom@6.0.4: resolution: {integrity: sha512-iukBNWqQAv8EKDBUNntspLp9SfpaVFbmzmM0sNcnTxASQZMzRw3PsM6DMlsHiI+I6GeO5/sYDg3ecpC+SNFLrQ==} engines: {node: '>=v14.16.0'} @@ -15621,7 +17260,7 @@ packages: dependencies: '@types/chai': 4.3.4 '@types/chai-subset': 1.3.3 - '@types/node': 18.11.18 + '@types/node': 18.13.0 chai: 4.3.7 debug: 4.3.4 happy-dom: 6.0.4 @@ -15630,7 +17269,118 @@ packages: tinybench: 2.3.1 tinypool: 0.3.0 tinyspy: 1.0.2 - vite: 3.2.5_@types+node@18.11.18 + vite: 3.2.5_@types+node@18.13.0 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vitest/0.28.5: + resolution: {integrity: sha512-pyCQ+wcAOX7mKMcBNkzDwEHRGqQvHUl0XnoHR+3Pb1hytAHISgSxv9h0gUiSiYtISXUU3rMrKiKzFYDrI6ZIHA==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.4 + '@types/chai-subset': 1.3.3 + '@types/node': 18.13.0 + '@vitest/expect': 0.28.5 + '@vitest/runner': 0.28.5 + '@vitest/spy': 0.28.5 + '@vitest/utils': 0.28.5 + acorn: 8.8.2 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + debug: 4.3.4 + local-pkg: 0.4.2 + pathe: 1.1.0 + picocolors: 1.0.0 + source-map: 0.6.1 + std-env: 3.3.2 + strip-literal: 1.0.1 + tinybench: 2.3.1 + tinypool: 0.3.1 + tinyspy: 1.0.2 + vite: 4.1.1_@types+node@18.13.0 + vite-node: 0.28.5_@types+node@18.13.0 + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vitest/0.28.5_happy-dom@6.0.4: + resolution: {integrity: sha512-pyCQ+wcAOX7mKMcBNkzDwEHRGqQvHUl0XnoHR+3Pb1hytAHISgSxv9h0gUiSiYtISXUU3rMrKiKzFYDrI6ZIHA==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.4 + '@types/chai-subset': 1.3.3 + '@types/node': 18.13.0 + '@vitest/expect': 0.28.5 + '@vitest/runner': 0.28.5 + '@vitest/spy': 0.28.5 + '@vitest/utils': 0.28.5 + acorn: 8.8.1 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + debug: 4.3.4 + happy-dom: 6.0.4 + local-pkg: 0.4.2 + pathe: 1.1.0 + picocolors: 1.0.0 + source-map: 0.6.1 + std-env: 3.3.2 + strip-literal: 1.0.1 + tinybench: 2.3.1 + tinypool: 0.3.1 + tinyspy: 1.0.2 + vite: 4.1.1_@types+node@18.13.0 + vite-node: 0.28.5_@types+node@18.13.0 + why-is-node-running: 2.2.2 transitivePeerDependencies: - less - sass @@ -15645,7 +17395,7 @@ packages: engines: {node: '>=6.0'} hasBin: true dependencies: - acorn: 8.8.1 + acorn: 8.8.2 acorn-walk: 8.2.0 dev: true @@ -15776,6 +17526,15 @@ packages: dependencies: isexe: 2.0.0 + /why-is-node-running/2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + /wide-align/1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} dependencies: @@ -15972,11 +17731,17 @@ packages: /yn/3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} + dev: true /yocto-queue/0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + /yocto-queue/1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + /zod-error/1.1.0: resolution: {integrity: sha512-zZ0I9/eFQsaDqglBPOM5Y/kJzbTkoD6hNZGON/kcMe2WIfLse2DIwsZpLMfKwBmcciYaEg+DubtLMnAbZ4/rfA==} dependencies: diff --git a/turbo.json b/turbo.json index 0d7a43b80..3a81a47d9 100644 --- a/turbo.json +++ b/turbo.json @@ -82,6 +82,9 @@ }, "clean:sourcemaps": { "cache": false + }, + "generate-sdks": { + "cache": false } }, "globalDependencies": [".env"], diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 000000000..648225465 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,12 @@ +/// +/// + +import { defineConfig } from "vite"; +import tsconfigPaths from "vite-tsconfig-paths"; + +export default defineConfig({ + plugins: [tsconfigPaths()], + test: { + globals: true, + }, +}); From fbdc3c799d7c320941514267918222ca7e42bfdd Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 14:56:55 +0000 Subject: [PATCH 002/133] Created the generated-integrations folder with a Readme --- generated-integrations/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 generated-integrations/README.md diff --git a/generated-integrations/README.md b/generated-integrations/README.md new file mode 100644 index 000000000..b39459fc3 --- /dev/null +++ b/generated-integrations/README.md @@ -0,0 +1,3 @@ +# What are these integrations? + +These are auto-generated from apps/integrations by running `pnpm run generate-integrations` from the root folder on the monorepo. From 63486d21c42d912ea828535b5e3dc9c0fe4b4032 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 14:57:09 +0000 Subject: [PATCH 003/133] Renamed command to `generate-integrations` --- apps/integrations/package.json | 2 +- package.json | 2 +- turbo.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/integrations/package.json b/apps/integrations/package.json index e31521451..2768caac3 100644 --- a/apps/integrations/package.json +++ b/apps/integrations/package.json @@ -8,7 +8,7 @@ "test": "vitest", "lint": "eslint src/**", "lint-fix": "eslint --fix src/**", - "generate-sdks": "tsx src/trigger/sdk/generate.ts" + "generate-integrations": "tsx src/trigger/sdk/generate.ts" }, "dependencies": { "@cfworker/json-schema": "^1.12.5", diff --git a/package.json b/package.json index af6016a76..e013d8f44 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "changeset:normal": "changeset pre exit", "sentry-upload": "turbo run sentry-upload", "clean:sourcemaps": "turbo run clean:sourcemaps", - "generate-sdks": "turbo run generate-sdks" + "generate-integrations": "turbo run generate-integrations" }, "devDependencies": { "@manypkg/cli": "^0.19.2", diff --git a/turbo.json b/turbo.json index 3a81a47d9..9c50f3b53 100644 --- a/turbo.json +++ b/turbo.json @@ -83,7 +83,7 @@ "clean:sourcemaps": { "cache": false }, - "generate-sdks": { + "generate-integrations": { "cache": false } }, From 62ab7e098ddb554d09bbdf63b9dc4c501073bf44 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 15:03:02 +0000 Subject: [PATCH 004/133] Generate integrations in the correct folder --- .../src/trigger/sdk/generateService.ts | 14 +++++++------- turbo.json | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/integrations/src/trigger/sdk/generateService.ts b/apps/integrations/src/trigger/sdk/generateService.ts index f8c73cb8e..a4575838e 100644 --- a/apps/integrations/src/trigger/sdk/generateService.ts +++ b/apps/integrations/src/trigger/sdk/generateService.ts @@ -1,18 +1,18 @@ import { IndentationText, NewLineKind, Project, QuoteKind } from "ts-morph"; import { Service } from "core/service/types"; import fs from "fs/promises"; +import path from "path"; import { generateInputOutputSchemas } from "generators/combineSchemas"; import { getTypesFromSchema } from "generators/generateTypes"; -import { dirname } from "path"; import rimraf from "rimraf"; -const appDir = require.main ? dirname(require.main.filename) : process.cwd(); +const appDir = process.cwd(); export async function generateService(service: Service) { - const basePath = `sdks/@trigger.dev/${service.service}`; + const basePath = `generated-integrations/${service.service}`; //remove folder - const absolutePath = `${appDir}/${basePath}/`; + const absolutePath = path.join(appDir, "../..", basePath); console.log(`Removing ${absolutePath}...`); rimraf.sync(absolutePath); @@ -30,9 +30,9 @@ export async function generateService(service: Service) { }); try { - project.createDirectory(basePath); - await generateTemplatedFiles(project, basePath, service); - await generateFunctionsAndTypes(project, basePath, service); + project.createDirectory(absolutePath); + await generateTemplatedFiles(project, absolutePath, service); + await generateFunctionsAndTypes(project, absolutePath, service); await project.save(); } catch (e) { console.error(e); diff --git a/turbo.json b/turbo.json index 9c50f3b53..069e51f19 100644 --- a/turbo.json +++ b/turbo.json @@ -84,7 +84,8 @@ "cache": false }, "generate-integrations": { - "cache": false + "cache": false, + "outputs": ["generated-integrations/**"] } }, "globalDependencies": [".env"], From 3d5bbf899e7e6db0377750924935f1932a70a3be Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 15:54:36 +0000 Subject: [PATCH 005/133] Got integrations express server up and running --- apps/integrations/.eslintrc.json | 4 + apps/integrations/index.ts | 14 ++ apps/integrations/package.json | 15 +- apps/integrations/src/core/request/errors.ts | 6 +- .../src/core/request/requestEndpoint.ts | 4 +- apps/integrations/src/core/schemas/types.ts | 3 +- apps/integrations/src/index.ts | 14 ++ apps/integrations/tsconfig.json | 1 + pnpm-lock.yaml | 173 +++++++++++++++++- 9 files changed, 226 insertions(+), 8 deletions(-) create mode 100644 apps/integrations/index.ts create mode 100644 apps/integrations/src/index.ts diff --git a/apps/integrations/.eslintrc.json b/apps/integrations/.eslintrc.json index 3bc8ecb51..20c9ccfc7 100644 --- a/apps/integrations/.eslintrc.json +++ b/apps/integrations/.eslintrc.json @@ -4,6 +4,10 @@ "plugin:@typescript-eslint/recommended", "prettier" ], + "env": { + "node": true, + "commonjs": true + }, "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], "root": true, diff --git a/apps/integrations/index.ts b/apps/integrations/index.ts new file mode 100644 index 000000000..888ee022f --- /dev/null +++ b/apps/integrations/index.ts @@ -0,0 +1,14 @@ +import express, { Express, Request, Response } from "express"; +import dotenv from "dotenv"; +dotenv.config(); + +const app: Express = express(); +const port = process.env.PORT; + +app.get("/", (req: Request, res: Response) => { + res.send("Express + TypeScript Server"); +}); + +app.listen(port, () => { + console.log(`⚡️[server]: Server is running at http://localhost:${port}`); +}); diff --git a/apps/integrations/package.json b/apps/integrations/package.json index 2768caac3..c4147e34d 100644 --- a/apps/integrations/package.json +++ b/apps/integrations/package.json @@ -3,8 +3,11 @@ "name": "integrations", "version": "1.0.0", "description": "API integrations in a format that can be used to generate clients", - "main": "src/index.ts", + "main": "index.js", "scripts": { + "build": "npx tsc", + "start": "node dist/index.js", + "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"", "test": "vitest", "lint": "eslint src/**", "lint-fix": "eslint --fix src/**", @@ -13,22 +16,29 @@ "dependencies": { "@cfworker/json-schema": "^1.12.5", "@trigger.dev/sdk": "^0.2.13", + "dotenv": "^16.0.3", + "express": "^4.18.1", + "express-async-errors": "^3.1.1", "json-pointer": "^0.6.2", "json-schema-deref-sync": "^0.14.0", "json-schema-to-typescript": "^11.0.3", + "loglevel": "^1.8.1", "node-fetch": "^3.3.0" }, "devDependencies": { "@types/eslint": "^8.4.6", + "@types/express": "^4.17.13", "@types/json-pointer": "^1.0.31", "@types/node": "^18.13.0", "@typescript-eslint/eslint-plugin": "^5.51.0", + "concurrently": "^7.6.0", "eslint": "^8.34.0", "eslint-config-prettier": "^8.5.0", "eslint-config-standard-with-typescript": "^34.0.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-n": "^15.6.1", "eslint-plugin-promise": "^6.1.1", + "nodemon": "^2.0.19", "rimraf": "^4.1.2", "ts-morph": "^17.0.1", "tsup": "^6.6.2", @@ -37,5 +47,8 @@ "vite": "^4.1.1", "vite-tsconfig-paths": "^4.0.5", "vitest": "^0.28.4" + }, + "engines": { + "node": ">=16.0.0" } } diff --git a/apps/integrations/src/core/request/errors.ts b/apps/integrations/src/core/request/errors.ts index e326c4a34..ae04d0e57 100644 --- a/apps/integrations/src/core/request/errors.ts +++ b/apps/integrations/src/core/request/errors.ts @@ -1,4 +1,4 @@ -import { type ErrorObject } from "ajv"; +import { JSONSchemaError } from "core/schemas/types"; export type RequestError = | RequestBodyInvalid @@ -27,7 +27,7 @@ export interface ParametersInvalid { name: string; value: any; }; - errors: Array<{ name: string; errors: ErrorObject[] }>; + errors: Array<{ name: string; errors: JSONSchemaError[] }>; } export interface ExtraParametersError { @@ -54,7 +54,7 @@ export interface MissingResponseSpec { export interface ResponseBodyInvalid { type: "response_invalid"; - errors: Array<{ name: string; errors: ErrorObject[] }>; + errors: Array<{ name: string; errors: JSONSchemaError[] }>; status: number; body?: any; } diff --git a/apps/integrations/src/core/request/requestEndpoint.ts b/apps/integrations/src/core/request/requestEndpoint.ts index 01b2e8e47..e0ddb2e68 100644 --- a/apps/integrations/src/core/request/requestEndpoint.ts +++ b/apps/integrations/src/core/request/requestEndpoint.ts @@ -1,6 +1,6 @@ -import { type ErrorObject } from "ajv"; import { applyCredentials } from "core/authentication/credentials"; import { EndpointSpec, EndpointSpecResponse } from "core/endpoint/types"; +import { JSONSchemaError } from "core/schemas/types"; import { validate } from "core/schemas/validate"; import fetch, { type Response } from "node-fetch"; import { @@ -137,7 +137,7 @@ export async function requestEndpoint( } // start with the first spec and loop through them, if one succeeds then return that - const specErrors: Array<{ name: string; errors: ErrorObject[] }> = []; + const specErrors: Array<{ name: string; errors: JSONSchemaError[] }> = []; for (const spec of responseSpecs) { const responseValid = validate(json, spec.schema); if (responseValid.success) { diff --git a/apps/integrations/src/core/schemas/types.ts b/apps/integrations/src/core/schemas/types.ts index 14b31a388..b388dbd97 100644 --- a/apps/integrations/src/core/schemas/types.ts +++ b/apps/integrations/src/core/schemas/types.ts @@ -1,3 +1,4 @@ -import { Schema } from "@cfworker/json-schema"; +import { Schema, OutputUnit } from "@cfworker/json-schema"; export type JSONSchema = Schema; +export type JSONSchemaError = OutputUnit; diff --git a/apps/integrations/src/index.ts b/apps/integrations/src/index.ts new file mode 100644 index 000000000..2f0df80f5 --- /dev/null +++ b/apps/integrations/src/index.ts @@ -0,0 +1,14 @@ +import express, { Express, Request, Response } from "express"; +import dotenv from "dotenv"; +dotenv.config(); + +const app: Express = express(); +const port = process.env.PORT ?? 3006; + +app.get("/", (req: Request, res: Response) => { + res.send("Express + TypeScript Server"); +}); + +app.listen(port, () => { + console.log(`⚡️[server]: Server is running at http://localhost:${port}`); +}); diff --git a/apps/integrations/tsconfig.json b/apps/integrations/tsconfig.json index dffbe401a..0cdba6b3d 100644 --- a/apps/integrations/tsconfig.json +++ b/apps/integrations/tsconfig.json @@ -3,6 +3,7 @@ "display": "Node 16", "compilerOptions": { "baseUrl": "./src", + "outDir": "./dist", "experimentalDecorators": true, "emitDecoratorMetadata": true, "lib": ["DOM", "DOM.Iterable", "ES2019"], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce948a4e9..b1edd8d94 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,22 +37,34 @@ importers: apps/integrations: specifiers: + '@babel/cli': ^7.20.7 + '@babel/core': ^7.20.12 + '@babel/preset-env': ^7.20.2 + '@babel/preset-typescript': ^7.18.6 + '@babel/register': ^7.18.9 '@cfworker/json-schema': ^1.12.5 '@trigger.dev/sdk': ^0.2.13 '@types/eslint': ^8.4.6 + '@types/express': ^4.17.13 '@types/json-pointer': ^1.0.31 '@types/node': ^18.13.0 '@typescript-eslint/eslint-plugin': ^5.51.0 + concurrently: ^7.6.0 + dotenv: ^16.0.3 eslint: ^8.34.0 eslint-config-prettier: ^8.5.0 eslint-config-standard-with-typescript: ^34.0.0 eslint-plugin-import: ^2.27.5 eslint-plugin-n: ^15.6.1 eslint-plugin-promise: ^6.1.1 + express: ^4.18.1 + express-async-errors: ^3.1.1 json-pointer: ^0.6.2 json-schema-deref-sync: ^0.14.0 json-schema-to-typescript: ^11.0.3 + loglevel: ^1.8.1 node-fetch: ^3.3.0 + nodemon: ^2.0.19 rimraf: ^4.1.2 ts-morph: ^17.0.1 tsup: ^6.6.2 @@ -64,21 +76,33 @@ importers: dependencies: '@cfworker/json-schema': 1.12.5 '@trigger.dev/sdk': 0.2.13 + dotenv: 16.0.3 + express: 4.18.2 + express-async-errors: 3.1.1_express@4.18.2 json-pointer: 0.6.2 json-schema-deref-sync: 0.14.0 json-schema-to-typescript: 11.0.3 + loglevel: 1.8.1 node-fetch: 3.3.0 devDependencies: + '@babel/cli': 7.20.7_@babel+core@7.20.12 + '@babel/core': 7.20.12 + '@babel/preset-env': 7.20.2_@babel+core@7.20.12 + '@babel/preset-typescript': 7.18.6_@babel+core@7.20.12 + '@babel/register': 7.18.9_@babel+core@7.20.12 '@types/eslint': 8.4.10 + '@types/express': 4.17.15 '@types/json-pointer': 1.0.31 '@types/node': 18.13.0 '@typescript-eslint/eslint-plugin': 5.51.0_bzepuo66bcyj4mepwnxofjvdli + concurrently: 7.6.0 eslint: 8.34.0 eslint-config-prettier: 8.6.0_eslint@8.34.0 eslint-config-standard-with-typescript: 34.0.0_xlnlhajfavmnhfjhhcrfaju6re eslint-plugin-import: 2.27.5_zycheyzypw6s5ouujsf5akzhsy eslint-plugin-n: 15.6.1_eslint@8.34.0 eslint-plugin-promise: 6.1.1_eslint@8.34.0 + nodemon: 2.0.20 rimraf: 4.1.2 ts-morph: 17.0.1 tsup: 6.6.2_typescript@4.9.5 @@ -2146,6 +2170,26 @@ packages: tslib: 2.4.1 dev: false + /@babel/cli/7.20.7_@babel+core@7.20.12: + resolution: {integrity: sha512-WylgcELHB66WwQqItxNILsMlaTd8/SO6SgTTjMp4uCI7P4QyH1r3nqgFmO3BfM4AtfniHgFMH3EpYFj/zynBkQ==} + engines: {node: '>=6.9.0'} + hasBin: true + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + '@jridgewell/trace-mapping': 0.3.17 + commander: 4.1.1 + convert-source-map: 1.9.0 + fs-readdir-recursive: 1.1.0 + glob: 7.2.3 + make-dir: 2.1.0 + slash: 2.0.0 + optionalDependencies: + '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 + chokidar: 3.5.3 + dev: true + /@babel/code-frame/7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} @@ -3383,6 +3427,20 @@ packages: - supports-color dev: true + /@babel/register/7.18.9_@babel+core@7.20.12: + resolution: {integrity: sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.12 + clone-deep: 4.0.1 + find-cache-dir: 2.1.0 + make-dir: 2.1.0 + pirates: 4.0.5 + source-map-support: 0.5.21 + dev: true + /@babel/runtime/7.20.7: resolution: {integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==} engines: {node: '>=6.9.0'} @@ -4901,6 +4959,12 @@ packages: - debug dev: false + /@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3: + resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} + requiresBuild: true + dev: true + optional: true + /@nicolo-ribaudo/eslint-scope-5-internals/5.1.1-v1: resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} dependencies: @@ -7973,6 +8037,15 @@ packages: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + /clone-deep/4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + dev: true + /clone-response/1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} dependencies: @@ -8090,6 +8163,10 @@ packages: engines: {node: '>=4.0.0'} dev: true + /commondir/1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + /component-emitter/1.3.0: resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} @@ -8128,6 +8205,22 @@ packages: typedarray: 0.0.6 dev: true + /concurrently/7.6.0: + resolution: {integrity: sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw==} + engines: {node: ^12.20.0 || ^14.13.0 || >=16.0.0} + hasBin: true + dependencies: + chalk: 4.1.2 + date-fns: 2.29.3 + lodash: 4.17.21 + rxjs: 7.8.0 + shell-quote: 1.7.4 + spawn-command: 0.0.2-1 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.6.2 + dev: true + /condense-newlines/0.2.1: resolution: {integrity: sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==} engines: {node: '>=0.10.0'} @@ -8767,7 +8860,6 @@ packages: /dotenv/16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} - dev: true /duplexer/0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} @@ -10127,6 +10219,14 @@ packages: lazy-cache: 1.0.4 dev: false + /express-async-errors/3.1.1_express@4.18.2: + resolution: {integrity: sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==} + peerDependencies: + express: ^4.16.2 + dependencies: + express: 4.18.2 + dev: false + /express/4.18.2: resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} engines: {node: '>= 0.10.0'} @@ -10383,6 +10483,22 @@ packages: transitivePeerDependencies: - supports-color + /find-cache-dir/2.1.0: + resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} + engines: {node: '>=6'} + dependencies: + commondir: 1.0.1 + make-dir: 2.1.0 + pkg-dir: 3.0.0 + dev: true + + /find-up/3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: true + /find-up/4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -10583,6 +10699,10 @@ packages: minipass: 3.3.6 dev: true + /fs-readdir-recursive/1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + dev: true + /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -12329,6 +12449,14 @@ packages: lie: 3.1.1 dev: false + /locate-path/3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: true + /locate-path/5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -12400,6 +12528,11 @@ packages: wrap-ansi: 6.2.0 dev: true + /loglevel/1.8.1: + resolution: {integrity: sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==} + engines: {node: '>= 0.6.0'} + dev: false + /longest-streak/3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} dev: true @@ -12488,6 +12621,14 @@ packages: sourcemap-codec: 1.4.8 dev: true + /make-dir/2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + dependencies: + pify: 4.0.1 + semver: 5.7.1 + dev: true + /make-dir/3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -13762,6 +13903,13 @@ packages: yocto-queue: 1.0.0 dev: true + /p-locate/3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: true + /p-locate/4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -13921,6 +14069,11 @@ packages: /path-dirname/1.0.2: resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} + /path-exists/3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + /path-exists/4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -14028,6 +14181,13 @@ packages: engines: {node: '>= 6'} dev: true + /pkg-dir/3.0.0: + resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} + engines: {node: '>=6'} + dependencies: + find-up: 3.0.0 + dev: true + /pkg-dir/4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -15332,6 +15492,13 @@ packages: /setprototypeof/1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + /shallow-clone/3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + dependencies: + kind-of: 6.0.3 + dev: true + /shallow-equal/1.2.1: resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==} dev: false @@ -15570,6 +15737,10 @@ packages: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} dev: true + /spawn-command/0.0.2-1: + resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} + dev: true + /spawndamnit/2.0.0: resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} dependencies: From 76c660f16789c6ebb05621df9f9e3d4bc34b6524 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 16:10:04 +0000 Subject: [PATCH 006/133] eslint ignore build folder --- apps/integrations/.eslintrc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/integrations/.eslintrc.json b/apps/integrations/.eslintrc.json index 20c9ccfc7..10c3a7745 100644 --- a/apps/integrations/.eslintrc.json +++ b/apps/integrations/.eslintrc.json @@ -16,5 +16,6 @@ "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-unused-vars": "off", "no-console": "off" - } + }, + "ignorePatterns": ["**/dist/*.js"] } From 313a8c59cf4ec59397b214b6ebcc3faa3061a61e Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 16:14:31 +0000 Subject: [PATCH 007/133] First commit of WIP generated Slack SDK --- generated-integrations/slack/README.md | 3 + generated-integrations/slack/package.json | 33 ++ generated-integrations/slack/src/index.ts | 48 ++ generated-integrations/slack/src/types.ts | 616 ++++++++++++++++++++ generated-integrations/slack/tsconfig.json | 21 + generated-integrations/slack/tsup.config.ts | 22 + 6 files changed, 743 insertions(+) create mode 100644 generated-integrations/slack/README.md create mode 100644 generated-integrations/slack/package.json create mode 100644 generated-integrations/slack/src/index.ts create mode 100644 generated-integrations/slack/src/types.ts create mode 100644 generated-integrations/slack/tsconfig.json create mode 100644 generated-integrations/slack/tsup.config.ts diff --git a/generated-integrations/slack/README.md b/generated-integrations/slack/README.md new file mode 100644 index 000000000..03ea70c2c --- /dev/null +++ b/generated-integrations/slack/README.md @@ -0,0 +1,3 @@ +# Trigger.dev Slack integration + +View more documentation[here](https://docs.trigger.dev) diff --git a/generated-integrations/slack/package.json b/generated-integrations/slack/package.json new file mode 100644 index 000000000..d72fdd0fe --- /dev/null +++ b/generated-integrations/slack/package.json @@ -0,0 +1,33 @@ +{ + "name": "@trigger.dev/slack", + "version": "1.0.0", + "description": "The official Slack integration for Trigger.dev", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "publishConfig": { + "access": "public" + }, + "files": [ + "dist/index.js", + "dist/index.d.ts", + "dist/index.js.map" + ], + "devDependencies": { + "@trigger.dev/sdk": "workspace:*", + "@types/debug": "^4.1.7", + "@types/node": "16", + "rimraf": "^3.0.2", + "tsup": "^6.5.0" + }, + "peerDependencies": { + "@trigger.dev/sdk": "workspace:*" + }, + "scripts": { + "clean": "rimraf dist", + "build": "npm run clean && npm run build:tsup", + "build:tsup": "tsup" + }, + "dependencies": { + "debug": "^4.3.4" + } +} diff --git a/generated-integrations/slack/src/index.ts b/generated-integrations/slack/src/index.ts new file mode 100644 index 000000000..a1ee9bf4c --- /dev/null +++ b/generated-integrations/slack/src/index.ts @@ -0,0 +1,48 @@ +import { getTriggerRun } from "@trigger.dev/sdk"; +import { PostMessageInput, PostMessageOutput, ConversationsListInput, ConversationsListOutput } from "./types"; + +/** Post a message to a channel */ +export async function postMessage( + /** This key should be unique inside your workflow */ + key: string, + /** The params for this call */ + params: PostMessageInput +): Promise { + const run = getTriggerRun(); + + if (!run) { + throw new Error("Cannot call postMessage outside of a trigger run"); + } + + const output = await run.performRequest(key, { + version: "2", + service: "slack", + endpoint: "/chat.postMessage", + params, + }); + + return output; +} + +/** Lists all channels in a Slack team. */ +export async function conversationsList( + /** This key should be unique inside your workflow */ + key: string, + /** The params for this call */ + params: ConversationsListInput +): Promise { + const run = getTriggerRun(); + + if (!run) { + throw new Error("Cannot call conversationsList outside of a trigger run"); + } + + const output = await run.performRequest(key, { + version: "2", + service: "slack", + endpoint: "/conversations.list", + params, + }); + + return output; +} diff --git a/generated-integrations/slack/src/types.ts b/generated-integrations/slack/src/types.ts new file mode 100644 index 000000000..8554be601 --- /dev/null +++ b/generated-integrations/slack/src/types.ts @@ -0,0 +1,616 @@ +export interface PostMessageInput { + /** + * Pass true to post the message as the authed user, instead of as a bot. Defaults to false. See [authorship](#authorship) below. + */ + as_user?: string; + /** + * A JSON-based array of structured attachments, presented as a URL-encoded string. + */ + attachments?: string; + /** + * A JSON-based array of structured blocks, presented as a URL-encoded string. + */ + blocks?: string; + /** + * Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name. See [below](#channels) for more details. + */ + channel: string; + /** + * Emoji to use as the icon for this message. Overrides `icon_url`. Must be used in conjunction with `as_user` set to `false`, otherwise ignored. See [authorship](#authorship) below. + */ + icon_emoji?: string; + /** + * URL to an image to use as the icon for this message. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below. + */ + icon_url?: string; + /** + * Find and link channel names and usernames. + */ + link_names?: boolean; + /** + * Disable Slack markup parsing by setting to `false`. Enabled by default. + */ + mrkdwn?: boolean; + /** + * Change how messages are treated. Defaults to `none`. See [below](#formatting). + */ + parse?: string; + /** + * Used in conjunction with `thread_ts` and indicates whether reply should be made visible to everyone in the channel or conversation. Defaults to `false`. + */ + reply_broadcast?: boolean; + /** + * How this field works and whether it is required depends on other fields you use in your API call. [See below](#text_usage) for more detail. + */ + text?: string; + /** + * Provide another message's `ts` value to make this message a reply. Avoid using a reply's `ts` value; use its parent instead. + */ + thread_ts?: string; + /** + * Pass true to enable unfurling of primarily text-based content. + */ + unfurl_links?: boolean; + /** + * Pass false to disable unfurling of media content. + */ + unfurl_media?: boolean; + /** + * Set your bot's user name. Must be used in conjunction with `as_user` set to false, otherwise ignored. See [authorship](#authorship) below. + */ + username?: string; +} + + +export interface PostMessageOutput { + /** + * Channel ID where the message was posted + */ + channel: string; + message: { + attachments?: { + fallback: string; + id: number; + text: string; + }[]; + bot_id: string; + subtype?: string; + text: string; + ts: string; + type: string; + user?: string; + }; + ok: boolean; + ts: string; +} + + +export interface ConversationsListInput { + /** + * Set to `true` to exclude archived channels from the list + */ + exclude_archived?: boolean; + /** + * Mix and match channel types by providing a comma-separated list of any combination of `public_channel`, `private_channel`, `mpim`, `im` + */ + types?: string; + /** + * The maximum number of items to return. Fewer than the requested number of items may be returned, even if the end of the list hasn't been reached. Must be an integer no larger than 1000. + */ + limit?: number; + /** + * Paginate through collections of data by setting the `cursor` parameter to a `next_cursor` attribute returned by a previous request's `response_metadata`. Default value fetches the first "page" of the collection. See [pagination](/docs/pagination) for more detail. + */ + cursor?: string; +} + + +export type UserID = string; +export type TeamOrEnterpriseID = string; +export type EnterpriseID = string; +export type ChannelLikeConversationID = string; +export type TeamID = string; +export type TimestampInFormat0123456789012345 = string; +/** + * This is a very loose definition, in the future, we'll populate this with deeper schema in this definition namespace. + */ +export type BlockKitBlocks = { + type: string; + [k: string]: unknown; +}[]; +export type BotUserID = string; +export type NilBotIdSetWhenDisplayAsBotIsFalse = null; +export type AppID = string; +export type FileCommentID = string; +export type ChannelID = string; +export type PrivateChannelID = string; +export type FileID = string; +export type DirectMessageChannelID = string; +export type NameOfAChannel = string; +export type UserIDOrEmptyStringUsedForTopicAndPurposeCreation = string; +export type NameOfTheEnterpriseOrg = string; +export type FieldToDetermineWhetherAChannelHasEverBeenSharedDisconnectedInThePast = number; +export type FieldToDetermineWhetherAChannelHasEverBeenSharedDisconnectedInThePast1 = number; +export type DefaultSuccessResponse = true; + +/** + * Schema for successful response from conversations.list method + */ +export interface ConversationsListOutput { + channels: + | [] + | [ConversationObject] + | [ConversationObject, ConversationMPIMObject] + | [ConversationObject, ConversationMPIMObject, ConversationIMChannelObjectFromConversationsMethods][]; + ok: DefaultSuccessResponse; + response_metadata?: { + next_cursor: string; + }; +} +export interface ConversationObject { + accepted_user?: UserID; + /** + * @minItems 0 + */ + connected_team_ids?: TeamOrEnterpriseID[]; + conversation_host_id?: TeamOrEnterpriseID; + created: number; + creator: UserID; + display_counts?: { + display_counts: number; + guest_counts: number; + }; + enterprise_id?: EnterpriseID; + has_pins?: boolean; + id: ChannelLikeConversationID; + /** + * @minItems 0 + */ + internal_team_ids?: TeamID[]; + is_archived: boolean; + is_channel: boolean; + is_ext_shared?: boolean; + is_frozen?: boolean; + is_general: boolean; + is_global_shared?: boolean; + is_group: boolean; + is_im: boolean; + is_member?: boolean; + is_moved?: number; + is_mpim: false; + is_non_threadable?: boolean; + is_open?: boolean; + is_org_default?: boolean; + is_org_mandatory?: boolean; + is_org_shared: boolean; + is_pending_ext_shared?: boolean; + is_private: boolean; + is_read_only?: boolean; + is_shared: boolean; + is_starred?: boolean; + is_thread_only?: boolean; + last_read?: TimestampInFormat0123456789012345; + latest?: [] | [MessageObject] | [MessageObject, null]; + /** + * @minItems 0 + */ + members?: UserID[]; + name: string; + name_normalized: string; + num_members?: number; + parent_conversation?: [] | [ChannelLikeConversationID] | [ChannelLikeConversationID, null]; + /** + * @minItems 0 + */ + pending_connected_team_ids?: TeamID[]; + /** + * @minItems 0 + */ + pending_shared?: TeamID[]; + pin_count?: number; + /** + * @minItems 0 + */ + previous_names?: NameOfAChannel[]; + priority?: number; + purpose: { + creator: UserIDOrEmptyStringUsedForTopicAndPurposeCreation; + last_set: number; + value: string; + }; + /** + * @minItems 0 + */ + shared_team_ids?: TeamID[]; + /** + * @minItems 0 + */ + shares?: { + accepted_user?: UserID; + is_active: boolean; + team: TeamObject; + user: UserID; + }[]; + timezone_count?: number; + topic: { + creator: UserIDOrEmptyStringUsedForTopicAndPurposeCreation; + last_set: number; + value: string; + }; + unlinked?: FieldToDetermineWhetherAChannelHasEverBeenSharedDisconnectedInThePast; + unread_count?: number; + unread_count_display?: number; + use_case?: string; + user?: UserID; + version?: number; +} +export interface MessageObject { + /** + * @minItems 1 + */ + attachments?: [ + { + fallback?: string; + id: number; + image_bytes?: number; + image_height?: number; + image_url?: string; + image_width?: number; + }, + ...{ + fallback?: string; + id: number; + image_bytes?: number; + image_height?: number; + image_url?: string; + image_width?: number; + }[] + ]; + blocks?: BlockKitBlocks; + bot_id?: [] | [BotUserID] | [BotUserID, NilBotIdSetWhenDisplayAsBotIsFalse]; + bot_profile?: BotProfileObject; + client_msg_id?: string; + comment?: FileCommentObject; + display_as_bot?: boolean; + file?: FileObject; + /** + * @minItems 1 + */ + files?: [FileObject, ...FileObject[]]; + icons?: { + emoji?: string; + image_64?: string; + }; + inviter?: UserID; + is_delayed_message?: boolean; + is_intro?: boolean; + is_starred?: boolean; + last_read?: TimestampInFormat0123456789012345; + latest_reply?: TimestampInFormat0123456789012345; + name?: string; + old_name?: string; + parent_user_id?: UserID; + permalink?: string; + pinned_to?: ChannelLikeConversationID[]; + purpose?: string; + reactions?: ReactionObject[]; + reply_count?: number; + /** + * @minItems 1 + */ + reply_users?: [UserID, ...UserID[]]; + reply_users_count?: number; + source_team?: TeamOrEnterpriseID; + subscribed?: boolean; + subtype?: string; + team?: TeamOrEnterpriseID; + text: string; + thread_ts?: TimestampInFormat0123456789012345; + topic?: string; + ts: TimestampInFormat0123456789012345; + type: string; + unread_count?: number; + upload?: boolean; + user?: UserID; + user_profile?: { + avatar_hash: string; + display_name: string; + display_name_normalized?: string; + first_name: string | null; + image_72: string; + is_restricted: boolean; + is_ultra_restricted: boolean; + name: string; + real_name: string; + real_name_normalized?: string; + team: TeamOrEnterpriseID; + }; + user_team?: TeamOrEnterpriseID; + username?: string; +} +export interface BotProfileObject { + app_id: AppID; + deleted: boolean; + icons: { + image_36: string; + image_48: string; + image_72: string; + }; + id: BotUserID; + name: string; + team_id: TeamID; + updated: number; +} +export interface FileCommentObject { + comment: string; + created: number; + id: FileCommentID; + is_intro: boolean; + is_starred?: boolean; + num_stars?: number; + pinned_info?: InfoForAPinnedItem; + pinned_to?: ChannelLikeConversationID[]; + reactions?: ReactionObject[]; + timestamp: number; + user: UserID; +} +export interface InfoForAPinnedItem { } +export interface ReactionObject { + count: number; + name: string; + users: UserID[]; + [k: string]: unknown; +} +export interface FileObject { + channels?: ChannelID[]; + comments_count?: number; + created?: number; + date_delete?: number; + display_as_bot?: boolean; + editable?: boolean; + editor?: UserID; + external_id?: string; + external_type?: string; + external_url?: string; + filetype?: string; + groups?: PrivateChannelID[]; + has_rich_preview?: boolean; + id?: FileID; + image_exif_rotation?: number; + ims?: DirectMessageChannelID[]; + is_external?: boolean; + is_public?: boolean; + is_starred?: boolean; + is_tombstoned?: boolean; + last_editor?: UserID; + mimetype?: string; + mode?: string; + name?: string; + non_owner_editable?: boolean; + num_stars?: number; + original_h?: number; + original_w?: number; + permalink?: string; + permalink_public?: string; + pinned_info?: InfoForAPinnedItem; + pinned_to?: ChannelLikeConversationID[]; + pretty_type?: string; + preview?: string; + public_url_shared?: boolean; + reactions?: ReactionObject[]; + shares?: { + private?: {}; + public?: {}; + }; + size?: number; + source_team?: TeamID; + state?: string; + thumb_1024?: string; + thumb_1024_h?: number; + thumb_1024_w?: number; + thumb_160?: string; + thumb_360?: string; + thumb_360_h?: number; + thumb_360_w?: number; + thumb_480?: string; + thumb_480_h?: number; + thumb_480_w?: number; + thumb_64?: string; + thumb_720?: string; + thumb_720_h?: number; + thumb_720_w?: number; + thumb_80?: string; + thumb_800?: string; + thumb_800_h?: number; + thumb_800_w?: number; + thumb_960?: string; + thumb_960_h?: number; + thumb_960_w?: number; + thumb_tiny?: string; + timestamp?: number; + title?: string; + updated?: number; + url_private?: string; + url_private_download?: string; + user?: string; + user_team?: TeamID; + username?: string; +} +export interface TeamObject { + archived?: boolean; + avatar_base_url?: string; + created?: number; + date_create?: number; + deleted?: boolean; + description?: null | string; + discoverable?: [] | [null] | [null, string]; + domain: string; + email_domain: string; + enterprise_id?: EnterpriseID; + enterprise_name?: NameOfTheEnterpriseOrg; + external_org_migrations?: ExternalOrgMigrations; + has_compliance_export?: boolean; + icon: { + image_102?: string; + image_132?: string; + image_230?: string; + image_34?: string; + image_44?: string; + image_68?: string; + image_88?: string; + image_default?: boolean; + }; + id: TeamOrEnterpriseID; + is_assigned?: boolean; + is_enterprise?: number; + is_over_storage_limit?: boolean; + limit_ts?: number; + locale?: string; + messages_count?: number; + msg_edit_window_mins?: number; + name: string; + over_integrations_limit?: boolean; + over_storage_limit?: boolean; + pay_prod_cur?: string; + plan?: "" | "std" | "plus" | "compliance" | "enterprise"; + primary_owner?: { + email: string; + id: string; + }; + sso_provider?: { + label?: string; + name?: string; + type?: string; + }; +} +export interface ExternalOrgMigrations { + current: { + date_started: number; + team_id: string; + }[]; + date_updated: number; +} +export interface ConversationMPIMObject { + accepted_user?: UserID; + /** + * @minItems 0 + */ + connected_team_ids?: TeamID[]; + conversation_host_id?: TeamOrEnterpriseID; + created: number; + creator: UserID; + display_counts?: { + display_counts: number; + guest_counts: number; + }; + id: ChannelLikeConversationID; + /** + * @minItems 0 + */ + internal_team_ids?: TeamID[]; + is_archived: boolean; + is_channel: boolean; + is_ext_shared?: boolean; + is_frozen?: boolean; + is_general: boolean; + is_group: boolean; + is_im: boolean; + is_member?: boolean; + is_moved?: number; + is_mpim: true; + is_non_threadable?: boolean; + is_open?: boolean; + is_org_shared: boolean; + is_pending_ext_shared?: boolean; + is_private: boolean; + is_read_only?: boolean; + is_shared: boolean; + is_starred?: boolean; + is_thread_only?: boolean; + last_read?: TimestampInFormat0123456789012345; + latest?: [] | [MessageObject] | [MessageObject, null]; + /** + * @minItems 0 + */ + members?: UserID[]; + name: string; + name_normalized: string; + num_members?: number; + parent_conversation?: [] | [ChannelLikeConversationID] | [ChannelLikeConversationID, null]; + /** + * @minItems 0 + */ + pending_connected_team_ids?: TeamID[]; + /** + * @minItems 0 + */ + pending_shared?: TeamID[]; + pin_count?: number; + /** + * @minItems 0 + */ + previous_names?: NameOfAChannel[]; + priority?: number; + purpose: { + creator: UserIDOrEmptyStringUsedForTopicAndPurposeCreation; + last_set: number; + value: string; + }; + /** + * @minItems 0 + */ + shared_team_ids?: TeamID[]; + /** + * @minItems 0 + */ + shares?: { + accepted_user?: UserID; + is_active: boolean; + team: TeamObject; + user: UserID; + }[]; + timezone_count?: number; + topic: { + creator: UserIDOrEmptyStringUsedForTopicAndPurposeCreation; + last_set: number; + value: string; + }; + unlinked?: FieldToDetermineWhetherAChannelHasEverBeenSharedDisconnectedInThePast1; + unread_count?: number; + unread_count_display?: number; + user?: UserID; + version?: number; +} +export interface ConversationIMChannelObjectFromConversationsMethods { + created: number; + has_pins?: boolean; + id: DirectMessageChannelID; + is_archived?: boolean; + is_ext_shared?: boolean; + is_frozen?: boolean; + is_im: boolean; + is_open?: boolean; + is_org_shared: boolean; + is_shared?: boolean; + is_starred?: boolean; + is_user_deleted?: boolean; + last_read?: TimestampInFormat0123456789012345; + latest?: [] | [MessageObject] | [MessageObject, null]; + parent_conversation?: [] | [ChannelLikeConversationID] | [ChannelLikeConversationID, null]; + pin_count?: number; + priority: number; + /** + * @minItems 0 + */ + shares?: { + date_create: number; + id: TeamID; + is_active: boolean; + name: string; + team: TeamObject; + }[]; + unread_count?: number; + unread_count_display?: number; + user: UserID; + version?: number; +} diff --git a/generated-integrations/slack/tsconfig.json b/generated-integrations/slack/tsconfig.json new file mode 100644 index 000000000..bb3e70788 --- /dev/null +++ b/generated-integrations/slack/tsconfig.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Node 16", + "include": ["./src/**/*.ts", "tsup.config.ts"], + "compilerOptions": { + "module": "commonjs", + "target": "ES2021", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "lib": ["DOM", "DOM.Iterable", "ES2019"], + "paths": { + "@trigger.dev/sdk/*": ["../../packages/trigger-sdk/src/*"], + "@trigger.dev/sdk": ["../../packages/trigger-sdk/src/index"] + } + }, + "exclude": ["node_modules"] +} diff --git a/generated-integrations/slack/tsup.config.ts b/generated-integrations/slack/tsup.config.ts new file mode 100644 index 000000000..5fcec5da2 --- /dev/null +++ b/generated-integrations/slack/tsup.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from "tsup"; + +export default defineConfig([ + { + name: "main", + entry: ["./src/index.ts"], + outDir: "./dist", + platform: "node", + format: ["cjs"], + legacyOutput: true, + sourcemap: true, + clean: true, + bundle: true, + splitting: false, + dts: true, + treeshake: { + preset: "smallest", + }, + external: ["http", "https", "util", "events", "tty", "os", "timers"], + esbuildPlugins: [], + }, +]); From 9751531cc19c0e24cf92b29f2c0552c1212245a4 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 16:14:43 +0000 Subject: [PATCH 008/133] Watch mode working properly with the action endpoint --- apps/integrations/package.json | 6 +- apps/integrations/src/api/action/index.ts | 5 + apps/integrations/src/index.ts | 5 +- apps/integrations/tsup.config.ts | 22 ++++ pnpm-lock.yaml | 125 ---------------------- 5 files changed, 34 insertions(+), 129 deletions(-) create mode 100644 apps/integrations/src/api/action/index.ts create mode 100644 apps/integrations/tsup.config.ts diff --git a/apps/integrations/package.json b/apps/integrations/package.json index c4147e34d..f5cdee9ae 100644 --- a/apps/integrations/package.json +++ b/apps/integrations/package.json @@ -3,11 +3,11 @@ "name": "integrations", "version": "1.0.0", "description": "API integrations in a format that can be used to generate clients", - "main": "index.js", + "main": "./dist/index.js", "scripts": { - "build": "npx tsc", + "build": "tsup", "start": "node dist/index.js", - "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"", + "dev": "concurrently \"tsup --watch\" \"nodemon -q dist/index.js\"", "test": "vitest", "lint": "eslint src/**", "lint-fix": "eslint --fix src/**", diff --git a/apps/integrations/src/api/action/index.ts b/apps/integrations/src/api/action/index.ts new file mode 100644 index 000000000..b3554c684 --- /dev/null +++ b/apps/integrations/src/api/action/index.ts @@ -0,0 +1,5 @@ +import { Request, Response } from "express"; + +export function handleAction(req: Request, res: Response) { + res.send("Slack 3"); +} diff --git a/apps/integrations/src/index.ts b/apps/integrations/src/index.ts index 2f0df80f5..6c64c62f9 100644 --- a/apps/integrations/src/index.ts +++ b/apps/integrations/src/index.ts @@ -1,14 +1,17 @@ import express, { Express, Request, Response } from "express"; import dotenv from "dotenv"; +import { handleAction } from "api/action"; dotenv.config(); const app: Express = express(); const port = process.env.PORT ?? 3006; app.get("/", (req: Request, res: Response) => { - res.send("Express + TypeScript Server"); + res.send("Trigger.dev integrations service"); }); +app.post("/api/:service/action/:action", handleAction); + app.listen(port, () => { console.log(`⚡️[server]: Server is running at http://localhost:${port}`); }); diff --git a/apps/integrations/tsup.config.ts b/apps/integrations/tsup.config.ts new file mode 100644 index 000000000..5fcec5da2 --- /dev/null +++ b/apps/integrations/tsup.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from "tsup"; + +export default defineConfig([ + { + name: "main", + entry: ["./src/index.ts"], + outDir: "./dist", + platform: "node", + format: ["cjs"], + legacyOutput: true, + sourcemap: true, + clean: true, + bundle: true, + splitting: false, + dts: true, + treeshake: { + preset: "smallest", + }, + external: ["http", "https", "util", "events", "tty", "os", "timers"], + esbuildPlugins: [], + }, +]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1edd8d94..ece1710fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,11 +37,6 @@ importers: apps/integrations: specifiers: - '@babel/cli': ^7.20.7 - '@babel/core': ^7.20.12 - '@babel/preset-env': ^7.20.2 - '@babel/preset-typescript': ^7.18.6 - '@babel/register': ^7.18.9 '@cfworker/json-schema': ^1.12.5 '@trigger.dev/sdk': ^0.2.13 '@types/eslint': ^8.4.6 @@ -85,11 +80,6 @@ importers: loglevel: 1.8.1 node-fetch: 3.3.0 devDependencies: - '@babel/cli': 7.20.7_@babel+core@7.20.12 - '@babel/core': 7.20.12 - '@babel/preset-env': 7.20.2_@babel+core@7.20.12 - '@babel/preset-typescript': 7.18.6_@babel+core@7.20.12 - '@babel/register': 7.18.9_@babel+core@7.20.12 '@types/eslint': 8.4.10 '@types/express': 4.17.15 '@types/json-pointer': 1.0.31 @@ -2170,26 +2160,6 @@ packages: tslib: 2.4.1 dev: false - /@babel/cli/7.20.7_@babel+core@7.20.12: - resolution: {integrity: sha512-WylgcELHB66WwQqItxNILsMlaTd8/SO6SgTTjMp4uCI7P4QyH1r3nqgFmO3BfM4AtfniHgFMH3EpYFj/zynBkQ==} - engines: {node: '>=6.9.0'} - hasBin: true - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.12 - '@jridgewell/trace-mapping': 0.3.17 - commander: 4.1.1 - convert-source-map: 1.9.0 - fs-readdir-recursive: 1.1.0 - glob: 7.2.3 - make-dir: 2.1.0 - slash: 2.0.0 - optionalDependencies: - '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 - chokidar: 3.5.3 - dev: true - /@babel/code-frame/7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} @@ -3427,20 +3397,6 @@ packages: - supports-color dev: true - /@babel/register/7.18.9_@babel+core@7.20.12: - resolution: {integrity: sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.12 - clone-deep: 4.0.1 - find-cache-dir: 2.1.0 - make-dir: 2.1.0 - pirates: 4.0.5 - source-map-support: 0.5.21 - dev: true - /@babel/runtime/7.20.7: resolution: {integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==} engines: {node: '>=6.9.0'} @@ -4959,12 +4915,6 @@ packages: - debug dev: false - /@nicolo-ribaudo/chokidar-2/2.1.8-no-fsevents.3: - resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} - requiresBuild: true - dev: true - optional: true - /@nicolo-ribaudo/eslint-scope-5-internals/5.1.1-v1: resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} dependencies: @@ -8037,15 +7987,6 @@ packages: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - /clone-deep/4.0.1: - resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} - engines: {node: '>=6'} - dependencies: - is-plain-object: 2.0.4 - kind-of: 6.0.3 - shallow-clone: 3.0.1 - dev: true - /clone-response/1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} dependencies: @@ -8163,10 +8104,6 @@ packages: engines: {node: '>=4.0.0'} dev: true - /commondir/1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - dev: true - /component-emitter/1.3.0: resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} @@ -10483,22 +10420,6 @@ packages: transitivePeerDependencies: - supports-color - /find-cache-dir/2.1.0: - resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} - engines: {node: '>=6'} - dependencies: - commondir: 1.0.1 - make-dir: 2.1.0 - pkg-dir: 3.0.0 - dev: true - - /find-up/3.0.0: - resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} - engines: {node: '>=6'} - dependencies: - locate-path: 3.0.0 - dev: true - /find-up/4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -10699,10 +10620,6 @@ packages: minipass: 3.3.6 dev: true - /fs-readdir-recursive/1.1.0: - resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} - dev: true - /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -12449,14 +12366,6 @@ packages: lie: 3.1.1 dev: false - /locate-path/3.0.0: - resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} - engines: {node: '>=6'} - dependencies: - p-locate: 3.0.0 - path-exists: 3.0.0 - dev: true - /locate-path/5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -12621,14 +12530,6 @@ packages: sourcemap-codec: 1.4.8 dev: true - /make-dir/2.1.0: - resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} - engines: {node: '>=6'} - dependencies: - pify: 4.0.1 - semver: 5.7.1 - dev: true - /make-dir/3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -13903,13 +13804,6 @@ packages: yocto-queue: 1.0.0 dev: true - /p-locate/3.0.0: - resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} - engines: {node: '>=6'} - dependencies: - p-limit: 2.3.0 - dev: true - /p-locate/4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -14069,11 +13963,6 @@ packages: /path-dirname/1.0.2: resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} - /path-exists/3.0.0: - resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} - engines: {node: '>=4'} - dev: true - /path-exists/4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -14181,13 +14070,6 @@ packages: engines: {node: '>= 6'} dev: true - /pkg-dir/3.0.0: - resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} - engines: {node: '>=6'} - dependencies: - find-up: 3.0.0 - dev: true - /pkg-dir/4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -15492,13 +15374,6 @@ packages: /setprototypeof/1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - /shallow-clone/3.0.1: - resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} - engines: {node: '>=8'} - dependencies: - kind-of: 6.0.3 - dev: true - /shallow-equal/1.2.1: resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==} dev: false From 73fb0f3c0d4b5e985be969700629ec8a4252b67f Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 16:37:26 +0000 Subject: [PATCH 009/133] Added explicit returns types because tsup was complaining --- apps/integrations/src/core/action/utilities.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/integrations/src/core/action/utilities.ts b/apps/integrations/src/core/action/utilities.ts index 10b1aac84..82c43e6d9 100644 --- a/apps/integrations/src/core/action/utilities.ts +++ b/apps/integrations/src/core/action/utilities.ts @@ -1,6 +1,7 @@ import { Endpoint } from "core/endpoint/types"; +import { InputSpec, OutputSpec } from "./types"; -export function makeInputSpec(endpoint: Endpoint) { +export function makeInputSpec(endpoint: Endpoint): InputSpec { return { security: endpoint.spec.endpointSpec.security, parameters: endpoint.spec.endpointSpec.parameters, @@ -8,7 +9,7 @@ export function makeInputSpec(endpoint: Endpoint) { }; } -export function makeOutputSpec(endpoint: Endpoint) { +export function makeOutputSpec(endpoint: Endpoint): OutputSpec { return { responses: endpoint.spec.endpointSpec.responses, }; From 4d6963f0e7b7025ca24d3f1f5edac830e23574f7 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 16:37:41 +0000 Subject: [PATCH 010/133] Added target node16 to tsup --- apps/integrations/tsup.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/integrations/tsup.config.ts b/apps/integrations/tsup.config.ts index 5fcec5da2..737bc680d 100644 --- a/apps/integrations/tsup.config.ts +++ b/apps/integrations/tsup.config.ts @@ -6,6 +6,7 @@ export default defineConfig([ entry: ["./src/index.ts"], outDir: "./dist", platform: "node", + target: "node16", format: ["cjs"], legacyOutput: true, sourcemap: true, From 76a2c82d9f0adf9ea5c346aa4ac7d5252416cd81 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 17:59:17 +0000 Subject: [PATCH 011/133] Fixes for CommonJS in express and tests failing because of access token --- apps/integrations/.infisical.json | 1 + apps/integrations/package.json | 3 ++- apps/integrations/src/api/action/index.ts | 16 +++++++++++++++- .../src/core/request/requestEndpoint.ts | 17 +++++++++++------ apps/integrations/src/core/schemas/validate.ts | 9 +++++++-- .../integrations/slack/tests/actions.test.ts | 16 +++++++++++++--- .../integrations/slack/tests/endpoints.test.ts | 15 ++++++++++++--- apps/integrations/vitest.config.ts | 1 + pnpm-lock.yaml | 5 ++++- vitest.config.ts | 1 + 10 files changed, 67 insertions(+), 17 deletions(-) create mode 100755 apps/integrations/.infisical.json diff --git a/apps/integrations/.infisical.json b/apps/integrations/.infisical.json new file mode 100755 index 000000000..9b8146fb4 --- /dev/null +++ b/apps/integrations/.infisical.json @@ -0,0 +1 @@ +{ "workspaceId": "63ea6cff29733e58db1e6b80" } diff --git a/apps/integrations/package.json b/apps/integrations/package.json index f5cdee9ae..301e25a91 100644 --- a/apps/integrations/package.json +++ b/apps/integrations/package.json @@ -16,7 +16,6 @@ "dependencies": { "@cfworker/json-schema": "^1.12.5", "@trigger.dev/sdk": "^0.2.13", - "dotenv": "^16.0.3", "express": "^4.18.1", "express-async-errors": "^3.1.1", "json-pointer": "^0.6.2", @@ -32,6 +31,7 @@ "@types/node": "^18.13.0", "@typescript-eslint/eslint-plugin": "^5.51.0", "concurrently": "^7.6.0", + "dotenv": "^16.0.3", "eslint": "^8.34.0", "eslint-config-prettier": "^8.5.0", "eslint-config-standard-with-typescript": "^34.0.0", @@ -40,6 +40,7 @@ "eslint-plugin-promise": "^6.1.1", "nodemon": "^2.0.19", "rimraf": "^4.1.2", + "tiny-invariant": "^1.2.0", "ts-morph": "^17.0.1", "tsup": "^6.6.2", "tsx": "^3.12.3", diff --git a/apps/integrations/src/api/action/index.ts b/apps/integrations/src/api/action/index.ts index b3554c684..b1b3964e9 100644 --- a/apps/integrations/src/api/action/index.ts +++ b/apps/integrations/src/api/action/index.ts @@ -1,5 +1,19 @@ import { Request, Response } from "express"; +import { catalog } from "integrations/catalog"; export function handleAction(req: Request, res: Response) { - res.send("Slack 3"); + const { service, action } = req.params; + + const matchingService = Object.values(catalog.services).find( + (s) => s.service === service + ); + + if (!matchingService) { + res + .status(404) + .send(JSON.stringify({ service, error: "Service not found" })); + return; + } + + res.send(`${service}/${action}`); } diff --git a/apps/integrations/src/core/request/requestEndpoint.ts b/apps/integrations/src/core/request/requestEndpoint.ts index e0ddb2e68..eb0e66f8e 100644 --- a/apps/integrations/src/core/request/requestEndpoint.ts +++ b/apps/integrations/src/core/request/requestEndpoint.ts @@ -2,12 +2,12 @@ import { applyCredentials } from "core/authentication/credentials"; import { EndpointSpec, EndpointSpecResponse } from "core/endpoint/types"; import { JSONSchemaError } from "core/schemas/types"; import { validate } from "core/schemas/validate"; -import fetch, { type Response } from "node-fetch"; +import { type Response } from "node-fetch"; import { - RequestSpec, + FetchConfig, RequestData, RequestResponse, - FetchConfig, + RequestSpec, } from "./types"; export async function requestEndpoint( @@ -18,7 +18,7 @@ export async function requestEndpoint( let path = endpointSpec.path; // validate the request body - const requestValid = validate(body, request.body?.schema); + const requestValid = await validate(body, request.body?.schema); if (!requestValid.success) { throw { type: "request_body_invalid", @@ -49,7 +49,7 @@ export async function requestEndpoint( const element = parameters[name]; //validate the parameter against the schema - const valid = validate(element, parameter.schema); + const valid = await validate(element, parameter.schema); if (!valid.success) { throw { type: "parameter_invalid", @@ -121,6 +121,7 @@ export async function requestEndpoint( headers: fetchConfig.headers, body: fetchConfig.body, }; + const fetch = await getFetch(); const response = await fetch(fetchConfig.url, fetchObject); const json = await safeGetJson(response); @@ -139,7 +140,7 @@ export async function requestEndpoint( // start with the first spec and loop through them, if one succeeds then return that const specErrors: Array<{ name: string; errors: JSONSchemaError[] }> = []; for (const spec of responseSpecs) { - const responseValid = validate(json, spec.schema); + const responseValid = await validate(json, spec.schema); if (responseValid.success) { return { success: spec.success, @@ -162,6 +163,10 @@ export async function requestEndpoint( }; } +async function getFetch() { + return (await import("node-fetch")).default; +} + async function safeGetJson(response: Response) { try { return await response.json(); diff --git a/apps/integrations/src/core/schemas/validate.ts b/apps/integrations/src/core/schemas/validate.ts index 1597d10da..9d7806b1f 100644 --- a/apps/integrations/src/core/schemas/validate.ts +++ b/apps/integrations/src/core/schemas/validate.ts @@ -1,12 +1,12 @@ -import { Validator } from "@cfworker/json-schema"; import { JSONSchema } from "./types"; -export function validate(data: any, schema?: JSONSchema) { +export async function validate(data: any, schema?: JSONSchema) { if (!schema) { return { success: true as const, }; } + const Validator = await getValidator(); const validator = new Validator(schema); const result = validator.validate(data); if (!result.valid) { @@ -20,3 +20,8 @@ export function validate(data: any, schema?: JSONSchema) { success: true as const, }; } + +async function getValidator() { + const tool = await import("@cfworker/json-schema"); + return tool.Validator; +} diff --git a/apps/integrations/src/integrations/slack/tests/actions.test.ts b/apps/integrations/src/integrations/slack/tests/actions.test.ts index e2ed1bb98..2b9c0cea1 100644 --- a/apps/integrations/src/integrations/slack/tests/actions.test.ts +++ b/apps/integrations/src/integrations/slack/tests/actions.test.ts @@ -1,7 +1,11 @@ import { expect, test } from "vitest"; import { chatPostMessage, conversationsList } from "../actions/actions"; +const authToken = () => process.env.SLACK_TOKEN ?? ""; + test("/conversations.list success", async () => { + const accessToken = authToken(); + expect(accessToken).not.toEqual(""); try { const data = await conversationsList.action({ parameters: { @@ -10,7 +14,7 @@ test("/conversations.list success", async () => { credentials: { type: "oauth2", name: "slackAuth", - accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + accessToken, scopes: ["conversations:read"], }, }); @@ -25,6 +29,9 @@ test("/conversations.list success", async () => { }); test("/chat.postMessage success with name", async () => { + const accessToken = authToken(); + expect(accessToken).not.toEqual(""); + try { const data = await chatPostMessage.action({ body: { @@ -34,7 +41,7 @@ test("/chat.postMessage success with name", async () => { credentials: { type: "oauth2", name: "slackAuth", - accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + accessToken, scopes: [ "chat:write:user", "chat:write:bot", @@ -55,6 +62,9 @@ test("/chat.postMessage success with name", async () => { }); test("/chat.postMessage failed with bad name", async () => { + const accessToken = authToken(); + expect(accessToken).not.toEqual(""); + try { const data = await chatPostMessage.action({ body: { @@ -64,7 +74,7 @@ test("/chat.postMessage failed with bad name", async () => { credentials: { type: "oauth2", name: "slackAuth", - accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + accessToken, scopes: [ "chat:write:user", "chat:write:bot", diff --git a/apps/integrations/src/integrations/slack/tests/endpoints.test.ts b/apps/integrations/src/integrations/slack/tests/endpoints.test.ts index ee3e35864..b15fa26d9 100644 --- a/apps/integrations/src/integrations/slack/tests/endpoints.test.ts +++ b/apps/integrations/src/integrations/slack/tests/endpoints.test.ts @@ -1,5 +1,6 @@ import { expect, test } from "vitest"; import endpoints from "../endpoints/endpoints"; +const authToken = () => process.env.SLACK_TOKEN ?? ""; test("missing credentials", async () => { try { @@ -15,6 +16,9 @@ test("missing credentials", async () => { }); test("/chat.postMessage success", async () => { + const accessToken = authToken(); + expect(accessToken).not.toEqual(""); + try { const data = await endpoints.chatPostMessage.request({ body: { @@ -24,7 +28,7 @@ test("/chat.postMessage success", async () => { credentials: { type: "oauth2", name: "slackAuth", - accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + accessToken, scopes: ["chat:write:user", "chat:write:bot"], }, }); @@ -43,6 +47,8 @@ test("/chat.postMessage success", async () => { }); test("/chat.postMessage bad channel", async () => { + const accessToken = authToken(); + expect(accessToken).not.toEqual(""); try { const data = await endpoints.chatPostMessage.request({ body: { @@ -52,7 +58,7 @@ test("/chat.postMessage bad channel", async () => { credentials: { type: "oauth2", name: "slackAuth", - accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + accessToken, scopes: ["chat:write:user", "chat:write:bot"], }, }); @@ -68,6 +74,9 @@ test("/chat.postMessage bad channel", async () => { }); test("/conversations.list success", async () => { + const accessToken = authToken(); + expect(accessToken).not.toEqual(""); + try { const data = await endpoints.conversationsList.request({ parameters: { @@ -76,7 +85,7 @@ test("/conversations.list success", async () => { credentials: { type: "oauth2", name: "slackAuth", - accessToken: "xoxb-276370297397-4578980839603-5mrIOR6E5KQGhOwtAYTaMC2x", + accessToken, scopes: ["conversations:read"], }, }); diff --git a/apps/integrations/vitest.config.ts b/apps/integrations/vitest.config.ts index 648225465..53a757df2 100644 --- a/apps/integrations/vitest.config.ts +++ b/apps/integrations/vitest.config.ts @@ -8,5 +8,6 @@ export default defineConfig({ plugins: [tsconfigPaths()], test: { globals: true, + setupFiles: ["dotenv/config"], }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ece1710fd..4b08e1068 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,6 +61,7 @@ importers: node-fetch: ^3.3.0 nodemon: ^2.0.19 rimraf: ^4.1.2 + tiny-invariant: ^1.2.0 ts-morph: ^17.0.1 tsup: ^6.6.2 tsx: ^3.12.3 @@ -71,7 +72,6 @@ importers: dependencies: '@cfworker/json-schema': 1.12.5 '@trigger.dev/sdk': 0.2.13 - dotenv: 16.0.3 express: 4.18.2 express-async-errors: 3.1.1_express@4.18.2 json-pointer: 0.6.2 @@ -86,6 +86,7 @@ importers: '@types/node': 18.13.0 '@typescript-eslint/eslint-plugin': 5.51.0_bzepuo66bcyj4mepwnxofjvdli concurrently: 7.6.0 + dotenv: 16.0.3 eslint: 8.34.0 eslint-config-prettier: 8.6.0_eslint@8.34.0 eslint-config-standard-with-typescript: 34.0.0_xlnlhajfavmnhfjhhcrfaju6re @@ -94,6 +95,7 @@ importers: eslint-plugin-promise: 6.1.1_eslint@8.34.0 nodemon: 2.0.20 rimraf: 4.1.2 + tiny-invariant: 1.3.1 ts-morph: 17.0.1 tsup: 6.6.2_typescript@4.9.5 tsx: 3.12.3 @@ -8797,6 +8799,7 @@ packages: /dotenv/16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} + dev: true /duplexer/0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} diff --git a/vitest.config.ts b/vitest.config.ts index 648225465..53a757df2 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -8,5 +8,6 @@ export default defineConfig({ plugins: [tsconfigPaths()], test: { globals: true, + setupFiles: ["dotenv/config"], }, }); From 38f32f405f233663c53ea2118c7479d5e3ab9a96 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 18:24:36 +0000 Subject: [PATCH 012/133] Progress on action api endpoint --- apps/integrations/package.json | 3 +- apps/integrations/src/api/action/index.ts | 59 +++++++++++++++++-- .../src/core/authentication/types.ts | 58 ++++++++++-------- apps/integrations/src/index.ts | 2 + pnpm-lock.yaml | 2 + 5 files changed, 93 insertions(+), 31 deletions(-) diff --git a/apps/integrations/package.json b/apps/integrations/package.json index 301e25a91..e5698c845 100644 --- a/apps/integrations/package.json +++ b/apps/integrations/package.json @@ -22,7 +22,8 @@ "json-schema-deref-sync": "^0.14.0", "json-schema-to-typescript": "^11.0.3", "loglevel": "^1.8.1", - "node-fetch": "^3.3.0" + "node-fetch": "^3.3.0", + "zod": "^3.20.2" }, "devDependencies": { "@types/eslint": "^8.4.6", diff --git a/apps/integrations/src/api/action/index.ts b/apps/integrations/src/api/action/index.ts index b1b3964e9..4f134375a 100644 --- a/apps/integrations/src/api/action/index.ts +++ b/apps/integrations/src/api/action/index.ts @@ -1,7 +1,15 @@ +import { AuthCredentialsSchema } from "core/authentication/types"; import { Request, Response } from "express"; import { catalog } from "integrations/catalog"; +import { z } from "zod"; -export function handleAction(req: Request, res: Response) { +const bodySchema = z.object({ + parameters: z.record(z.string(), z.any()).optional(), + credentials: AuthCredentialsSchema.optional(), + body: z.any().optional(), +}); + +export async function handleAction(req: Request, res: Response) { const { service, action } = req.params; const matchingService = Object.values(catalog.services).find( @@ -9,11 +17,52 @@ export function handleAction(req: Request, res: Response) { ); if (!matchingService) { - res - .status(404) - .send(JSON.stringify({ service, error: "Service not found" })); + res.status(404).send( + JSON.stringify({ + success: false, + service, + error: { type: "missing_service", message: "Service not found" }, + }) + ); return; } - res.send(`${service}/${action}`); + const matchingAction = Object.values(matchingService.actions).find( + (a) => a.name === action + ); + + if (!matchingAction) { + res.status(404).send( + JSON.stringify({ + success: false, + service, + action, + error: { type: "missing_action", message: "Action not found" }, + }) + ); + return; + } + + console.log("body", req.body); + + const bodyResult = bodySchema.safeParse(req.body); + + if (!bodyResult.success) { + res.status(400).send( + JSON.stringify({ + success: false, + error: { type: "invalid_body", issues: bodyResult.error.issues }, + }) + ); + return; + } + + try { + const data = await matchingAction.action(bodyResult.data); + res.send(JSON.stringify(data)); + } catch (e: any) { + res + .status(500) + .send(JSON.stringify({ success: false, errors: e.toString() })); + } } diff --git a/apps/integrations/src/core/authentication/types.ts b/apps/integrations/src/core/authentication/types.ts index 0be657a1a..b21866ad7 100644 --- a/apps/integrations/src/core/authentication/types.ts +++ b/apps/integrations/src/core/authentication/types.ts @@ -1,39 +1,47 @@ -export type IntegrationAuthentication = Record< -string, -AuthenticationDefinition -> +import { z } from "zod"; -type AuthenticationDefinition = OAuth2 +export type IntegrationAuthentication = Record< + string, + AuthenticationDefinition +>; + +type AuthenticationDefinition = OAuth2; interface OAuth2 { type: "oauth2"; - placement: AuthenticationPlacement - authorizationUrl: string - tokenUrl: string + placement: AuthenticationPlacement; + authorizationUrl: string; + tokenUrl: string; flow: "accessCode" | "implicit" | "password" | "application"; - scopes: Record + scopes: Record; } -type AuthenticationPlacement = HeaderAuthentication +type AuthenticationPlacement = HeaderAuthentication; interface HeaderAuthentication { in: "header"; type: "basic" | "bearer"; - key: string + key: string; } -export type AuthCredentials = OAuth2Credentials | APIKeyCredentials +const OAuth2CredentialsSchema = z.object({ + type: z.literal("oauth2"), + name: z.string(), + accessToken: z.string(), + scopes: z.array(z.string()), +}); -interface OAuth2Credentials { - type: "oauth2"; - name: string - accessToken: string - scopes: string[] -} -interface APIKeyCredentials { - type: "api_key"; - name: string - api_key: string - additionalFields?: Record - scopes: string[] -} +const APIKeyCredentialsSchema = z.object({ + type: z.literal("api_key"), + name: z.string(), + api_key: z.string(), + additionalFields: z.record(z.string(), z.string()).optional(), + scopes: z.array(z.string()), +}); + +export const AuthCredentialsSchema = z.discriminatedUnion("type", [ + OAuth2CredentialsSchema, + APIKeyCredentialsSchema, +]); + +export type AuthCredentials = z.infer; diff --git a/apps/integrations/src/index.ts b/apps/integrations/src/index.ts index 6c64c62f9..0bd9712d2 100644 --- a/apps/integrations/src/index.ts +++ b/apps/integrations/src/index.ts @@ -6,6 +6,8 @@ dotenv.config(); const app: Express = express(); const port = process.env.PORT ?? 3006; +app.use(express.json()); + app.get("/", (req: Request, res: Response) => { res.send("Trigger.dev integrations service"); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4b08e1068..6cb808610 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,6 +69,7 @@ importers: vite: ^4.1.1 vite-tsconfig-paths: ^4.0.5 vitest: ^0.28.4 + zod: ^3.20.2 dependencies: '@cfworker/json-schema': 1.12.5 '@trigger.dev/sdk': 0.2.13 @@ -79,6 +80,7 @@ importers: json-schema-to-typescript: 11.0.3 loglevel: 1.8.1 node-fetch: 3.3.0 + zod: 3.20.2 devDependencies: '@types/eslint': 8.4.10 '@types/express': 4.17.15 From 027f0210dcdde9796638fb1e5ecfa3157ab0bab5 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 21:44:18 +0000 Subject: [PATCH 013/133] The input is validated and results are coming back! --- .vscode/launch.json | 7 ++ apps/integrations/src/api/action/index.ts | 18 ++- apps/integrations/src/core/request/errors.ts | 10 +- .../src/core/request/requestEndpoint.ts | 6 + .../src/core/validation/inputs.ts | 109 ++++++++++++++++++ 5 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 apps/integrations/src/core/validation/inputs.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index e14f2c5d1..caf5c0a36 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,6 +11,13 @@ "type": "node-terminal", "cwd": "${workspaceFolder}" }, + { + "command": "pnpm run dev --filter integrations", + "name": "Run integrations", + "request": "launch", + "type": "node-terminal", + "cwd": "${workspaceFolder}" + }, { "type": "chrome", "request": "launch", diff --git a/apps/integrations/src/api/action/index.ts b/apps/integrations/src/api/action/index.ts index 4f134375a..303a6819f 100644 --- a/apps/integrations/src/api/action/index.ts +++ b/apps/integrations/src/api/action/index.ts @@ -1,4 +1,5 @@ import { AuthCredentialsSchema } from "core/authentication/types"; +import { validateInputs } from "core/validation/inputs"; import { Request, Response } from "express"; import { catalog } from "integrations/catalog"; import { z } from "zod"; @@ -43,8 +44,6 @@ export async function handleAction(req: Request, res: Response) { return; } - console.log("body", req.body); - const bodyResult = bodySchema.safeParse(req.body); if (!bodyResult.success) { @@ -57,10 +56,25 @@ export async function handleAction(req: Request, res: Response) { return; } + const inputValidationResult = await validateInputs( + matchingAction.spec.input, + bodyResult.data + ); + if (!inputValidationResult.success) { + res.status(400).send( + JSON.stringify({ + success: false, + error: inputValidationResult.error, + }) + ); + return; + } + try { const data = await matchingAction.action(bodyResult.data); res.send(JSON.stringify(data)); } catch (e: any) { + console.error(e); res .status(500) .send(JSON.stringify({ success: false, errors: e.toString() })); diff --git a/apps/integrations/src/core/request/errors.ts b/apps/integrations/src/core/request/errors.ts index ae04d0e57..948677336 100644 --- a/apps/integrations/src/core/request/errors.ts +++ b/apps/integrations/src/core/request/errors.ts @@ -7,13 +7,19 @@ export type RequestError = | ExtraParametersError | InsufficientScopesError | MissingResponseSpec - | ResponseBodyInvalid; + | ResponseBodyInvalid + | BodyMissing + | MissingCredentialsError; export interface RequestBodyInvalid { type: "request_body_invalid"; errors: any[]; } +export interface BodyMissing { + type: "missing_body"; +} + export interface ParameterMissing { type: "missing_parameter"; parameter: { @@ -27,7 +33,7 @@ export interface ParametersInvalid { name: string; value: any; }; - errors: Array<{ name: string; errors: JSONSchemaError[] }>; + errors: JSONSchemaError[]; } export interface ExtraParametersError { diff --git a/apps/integrations/src/core/request/requestEndpoint.ts b/apps/integrations/src/core/request/requestEndpoint.ts index eb0e66f8e..038baf2e6 100644 --- a/apps/integrations/src/core/request/requestEndpoint.ts +++ b/apps/integrations/src/core/request/requestEndpoint.ts @@ -18,6 +18,12 @@ export async function requestEndpoint( let path = endpointSpec.path; // validate the request body + if (body == null && request.body?.schema != null) { + throw { + type: "missing_body", + }; + } + const requestValid = await validate(body, request.body?.schema); if (!requestValid.success) { throw { diff --git a/apps/integrations/src/core/validation/inputs.ts b/apps/integrations/src/core/validation/inputs.ts new file mode 100644 index 000000000..092cb50d4 --- /dev/null +++ b/apps/integrations/src/core/validation/inputs.ts @@ -0,0 +1,109 @@ +import { InputSpec } from "core/action/types"; +import { checkRequiredScopes } from "core/authentication/credentials"; +import { RequestError } from "core/request/errors"; +import { RequestData, RequestSpec } from "core/request/types"; +import { validate } from "core/schemas/validate"; + +type ValidationResult = + | { + success: true; + } + | { + success: false; + error: RequestError; + }; + +export async function validateInputs( + inputSpec: InputSpec, + { parameters, body, credentials }: RequestData +): Promise { + if (inputSpec.security) { + if (credentials === undefined) { + return { + success: false, + error: { + type: "missing_credentials", + }, + }; + } + const requiredScopes = inputSpec.security[credentials.name] ?? []; + const result = checkRequiredScopes(requiredScopes, credentials); + + if (!result.success) { + return { + success: false, + error: { + type: "insufficient_scopes", + missingScopes: result.missingScopes, + }, + }; + } + } + + // validate the request body exists it it should + if (body == null && inputSpec.body != null) { + return { + success: false, + error: { + type: "missing_body", + }, + }; + } + + //validate the request body against the schema + const requestValid = await validate(body, inputSpec.body); + if (!requestValid.success) { + return { + success: false, + error: { + type: "request_body_invalid", + errors: requestValid.errors, + }, + }; + } + + //validate the parameters + if (inputSpec.parameters != null) { + for (const parameter of inputSpec.parameters) { + const { name, required } = parameter; + + // if the parameter is missing + if (parameters === undefined || parameters[name] == null) { + if (required) { + return { + success: false, + error: { + type: "missing_parameter", + parameter: { + name, + }, + }, + }; + } else { + continue; + } + } + + const element = parameters[name]; + //validate the parameter against the schema + const valid = await validate(element, parameter.schema); + if (!valid.success) { + return { + success: false, + error: { + type: "parameter_invalid", + parameter: { + name, + value: element, + }, + errors: valid.errors, + }, + }; + } + } + } + + return { + success: true, + }; +} From c01bc156226a6378a75f3b93fc28e3919ccc15e5 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 22:05:39 +0000 Subject: [PATCH 014/133] Allow metadata to be passed to the integrations API --- apps/integrations/src/api/action/index.ts | 9 ++++++++- apps/integrations/src/core/action/types.ts | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/integrations/src/api/action/index.ts b/apps/integrations/src/api/action/index.ts index 303a6819f..52599933c 100644 --- a/apps/integrations/src/api/action/index.ts +++ b/apps/integrations/src/api/action/index.ts @@ -8,6 +8,7 @@ const bodySchema = z.object({ parameters: z.record(z.string(), z.any()).optional(), credentials: AuthCredentialsSchema.optional(), body: z.any().optional(), + metadata: z.record(z.string(), z.any()).optional(), }); export async function handleAction(req: Request, res: Response) { @@ -70,8 +71,14 @@ export async function handleAction(req: Request, res: Response) { return; } + const { credentials, parameters, body, metadata } = bodyResult.data; + try { - const data = await matchingAction.action(bodyResult.data); + const data = await matchingAction.action( + { credentials, parameters, body }, + undefined, + metadata + ); res.send(JSON.stringify(data)); } catch (e: any) { console.error(e); diff --git a/apps/integrations/src/core/action/types.ts b/apps/integrations/src/core/action/types.ts index a610ef12c..4cd4b0ec1 100644 --- a/apps/integrations/src/core/action/types.ts +++ b/apps/integrations/src/core/action/types.ts @@ -12,7 +12,7 @@ export type OutputSpec = { responses: EndpointSpec["responses"]; }; -export type Metadata = Record; +export type Metadata = Record; export type Action = { name: string; From 4f7a8f6ae07e2899971373f8bf050952ccc28610 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 22:05:57 +0000 Subject: [PATCH 015/133] Created a VS Code workspace --- .vscode/trigger.code-workspace | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .vscode/trigger.code-workspace diff --git a/.vscode/trigger.code-workspace b/.vscode/trigger.code-workspace new file mode 100644 index 000000000..89f839cf1 --- /dev/null +++ b/.vscode/trigger.code-workspace @@ -0,0 +1,19 @@ +{ + "folders": [ + { + "name": "trigger.dev", + "path": "../" + }, + { + "name": "Webapp", + "path": "../apps/webapp" + }, + { + "name": "Integrations", + "path": "../apps/integrations" + } + ], + "settings": { + "vitest.commandLine": "pnpm exec vitest" + } +} From 5949c98748527d2a3ee4e75cbf9e355bea0b2e0b Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 22:40:44 +0000 Subject: [PATCH 016/133] Created Postgres schema with cache table and PostgresCacheService --- apps/integrations/package.json | 2 + .../20230213221827_init/migration.sql | 20 +++++++ .../migration.sql | 5 ++ .../20230213223405_optional_ttl/migration.sql | 2 + .../prisma/migrations/migration_lock.toml | 3 + apps/integrations/prisma/schema.prisma | 22 +++++++ apps/integrations/src/cache/db.server.ts | 58 +++++++++++++++++++ apps/integrations/src/cache/postgresCache.ts | 53 +++++++++++++++++ pnpm-lock.yaml | 4 ++ 9 files changed, 169 insertions(+) create mode 100644 apps/integrations/prisma/migrations/20230213221827_init/migration.sql create mode 100644 apps/integrations/prisma/migrations/20230213222130_non_unique_key/migration.sql create mode 100644 apps/integrations/prisma/migrations/20230213223405_optional_ttl/migration.sql create mode 100644 apps/integrations/prisma/migrations/migration_lock.toml create mode 100644 apps/integrations/prisma/schema.prisma create mode 100644 apps/integrations/src/cache/db.server.ts create mode 100644 apps/integrations/src/cache/postgresCache.ts diff --git a/apps/integrations/package.json b/apps/integrations/package.json index e5698c845..edebb06ba 100644 --- a/apps/integrations/package.json +++ b/apps/integrations/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@cfworker/json-schema": "^1.12.5", + "@prisma/client": "^4.3.0", "@trigger.dev/sdk": "^0.2.13", "express": "^4.18.1", "express-async-errors": "^3.1.1", @@ -40,6 +41,7 @@ "eslint-plugin-n": "^15.6.1", "eslint-plugin-promise": "^6.1.1", "nodemon": "^2.0.19", + "prisma": "^4.3.0", "rimraf": "^4.1.2", "tiny-invariant": "^1.2.0", "ts-morph": "^17.0.1", diff --git a/apps/integrations/prisma/migrations/20230213221827_init/migration.sql b/apps/integrations/prisma/migrations/20230213221827_init/migration.sql new file mode 100644 index 000000000..57251351d --- /dev/null +++ b/apps/integrations/prisma/migrations/20230213221827_init/migration.sql @@ -0,0 +1,20 @@ +-- CreateTable +CREATE TABLE "Cache" ( + "id" TEXT NOT NULL, + "namespace" TEXT NOT NULL, + "key" TEXT NOT NULL, + "value" TEXT NOT NULL, + "expiresAt" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Cache_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Cache_key_key" ON "Cache"("key"); + +-- CreateIndex +CREATE INDEX "Cache_namespace_key_idx" ON "Cache"("namespace", "key"); + +-- CreateIndex +CREATE UNIQUE INDEX "Cache_namespace_key_key" ON "Cache"("namespace", "key"); diff --git a/apps/integrations/prisma/migrations/20230213222130_non_unique_key/migration.sql b/apps/integrations/prisma/migrations/20230213222130_non_unique_key/migration.sql new file mode 100644 index 000000000..0d4918ff1 --- /dev/null +++ b/apps/integrations/prisma/migrations/20230213222130_non_unique_key/migration.sql @@ -0,0 +1,5 @@ +-- DropIndex +DROP INDEX "Cache_key_key"; + +-- DropIndex +DROP INDEX "Cache_namespace_key_idx"; diff --git a/apps/integrations/prisma/migrations/20230213223405_optional_ttl/migration.sql b/apps/integrations/prisma/migrations/20230213223405_optional_ttl/migration.sql new file mode 100644 index 000000000..666856258 --- /dev/null +++ b/apps/integrations/prisma/migrations/20230213223405_optional_ttl/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Cache" ALTER COLUMN "expiresAt" DROP NOT NULL; diff --git a/apps/integrations/prisma/migrations/migration_lock.toml b/apps/integrations/prisma/migrations/migration_lock.toml new file mode 100644 index 000000000..fbffa92c2 --- /dev/null +++ b/apps/integrations/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/apps/integrations/prisma/schema.prisma b/apps/integrations/prisma/schema.prisma new file mode 100644 index 000000000..e67c296c8 --- /dev/null +++ b/apps/integrations/prisma/schema.prisma @@ -0,0 +1,22 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" + output = "../node_modules/.prisma/client" + binaryTargets = ["native", "debian-openssl-1.1.x"] + previewFeatures = ["orderByNulls"] +} + +model Cache { + id String @id @default(cuid()) + namespace String + key String + value String + expiresAt DateTime? + createdAt DateTime @default(now()) + + @@unique([namespace, key]) +} \ No newline at end of file diff --git a/apps/integrations/src/cache/db.server.ts b/apps/integrations/src/cache/db.server.ts new file mode 100644 index 000000000..ff4ae4a64 --- /dev/null +++ b/apps/integrations/src/cache/db.server.ts @@ -0,0 +1,58 @@ +import { PrismaClient, Prisma } from ".prisma/client"; +import invariant from "tiny-invariant"; + +export { Prisma }; + +let prisma: PrismaClient; + +declare global { + // eslint-disable-next-line no-var + var __db__: PrismaClient; +} + +// this is needed because in development we don't want to restart +// the server with every change, but we want to make sure we don't +// create a new connection to the DB with every change either. +// in production we'll have a single connection to the DB. +if (process.env.NODE_ENV === "production") { + prisma = getClient(); +} else { + if (!global.__db__) { + global.__db__ = getClient(); + } + prisma = global.__db__; +} + +function getClient() { + const { DATABASE_URL } = process.env; + invariant(typeof DATABASE_URL === "string", "DATABASE_URL env var not set"); + + // Remove the username:password in the url and print that to the console + const urlWithoutCredentials = new URL(DATABASE_URL); + urlWithoutCredentials.password = ""; + + console.log( + `1. 🔌 setting up prisma client to ${urlWithoutCredentials.toString()}` + ); + + const client = new PrismaClient({ + datasources: { + db: { + url: DATABASE_URL, + }, + }, + log: ["warn", "error"], + }); + + console.log(`2.0 🔌 prisma client connecting`); + + // connect eagerly + client.$connect(); + + console.log(`3.0 🔌 prisma client connected`); + + return client; +} + +export { prisma }; +export type { PrismaClient } from ".prisma/client"; diff --git a/apps/integrations/src/cache/postgresCache.ts b/apps/integrations/src/cache/postgresCache.ts new file mode 100644 index 000000000..8bb596dce --- /dev/null +++ b/apps/integrations/src/cache/postgresCache.ts @@ -0,0 +1,53 @@ +import type { Prisma, Cache } from ".prisma/client"; +import { prisma } from "./db.server"; +import { CacheService } from "core/cache/types"; + +export class PostgresCacheService implements CacheService { + constructor(private readonly namespace: string) {} + + async get(key: string) { + const cachedRow = await prisma.cache.findFirst({ + where: { + namespace: this.namespace, + key, + OR: [ + { expiresAt: null }, + { + expiresAt: { + gt: new Date(), + }, + }, + ], + }, + }); + + if (cachedRow) { + return cachedRow.value; + } + + return null; + } + + async set(key: string, value: string, ttl?: number): Promise { + const expiresAt = ttl ? new Date(Date.now() + ttl * 1000) : null; + + await prisma.cache.upsert({ + where: { + namespace_key: { + namespace: this.namespace, + key, + }, + }, + update: { + value, + expiresAt, + }, + create: { + namespace: this.namespace, + key, + value, + expiresAt, + }, + }); + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6cb808610..b710a7a0c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,7 @@ importers: apps/integrations: specifiers: '@cfworker/json-schema': ^1.12.5 + '@prisma/client': ^4.3.0 '@trigger.dev/sdk': ^0.2.13 '@types/eslint': ^8.4.6 '@types/express': ^4.17.13 @@ -60,6 +61,7 @@ importers: loglevel: ^1.8.1 node-fetch: ^3.3.0 nodemon: ^2.0.19 + prisma: ^4.3.0 rimraf: ^4.1.2 tiny-invariant: ^1.2.0 ts-morph: ^17.0.1 @@ -72,6 +74,7 @@ importers: zod: ^3.20.2 dependencies: '@cfworker/json-schema': 1.12.5 + '@prisma/client': 4.8.1_prisma@4.8.1 '@trigger.dev/sdk': 0.2.13 express: 4.18.2 express-async-errors: 3.1.1_express@4.18.2 @@ -96,6 +99,7 @@ importers: eslint-plugin-n: 15.6.1_eslint@8.34.0 eslint-plugin-promise: 6.1.1_eslint@8.34.0 nodemon: 2.0.20 + prisma: 4.8.1 rimraf: 4.1.2 tiny-invariant: 1.3.1 ts-morph: 17.0.1 From 5c8fc8188a168bd0d9b247d43b3f0e568fa5b5fc Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 22:52:01 +0000 Subject: [PATCH 017/133] =?UTF-8?q?Passing=20the=20cache=20through=20to=20?= =?UTF-8?q?requests,=20it=E2=80=99s=20working.=20Made=20the=20expected=20r?= =?UTF-8?q?equest=20metadata=20specific?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/integrations/src/api/action/index.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/integrations/src/api/action/index.ts b/apps/integrations/src/api/action/index.ts index 52599933c..59f2dedf4 100644 --- a/apps/integrations/src/api/action/index.ts +++ b/apps/integrations/src/api/action/index.ts @@ -1,3 +1,4 @@ +import { PostgresCacheService } from "cache/postgresCache"; import { AuthCredentialsSchema } from "core/authentication/types"; import { validateInputs } from "core/validation/inputs"; import { Request, Response } from "express"; @@ -8,7 +9,11 @@ const bodySchema = z.object({ parameters: z.record(z.string(), z.any()).optional(), credentials: AuthCredentialsSchema.optional(), body: z.any().optional(), - metadata: z.record(z.string(), z.any()).optional(), + metadata: z.object({ + requestId: z.string(), + workflowId: z.string(), + connectionId: z.string(), + }), }); export async function handleAction(req: Request, res: Response) { @@ -72,11 +77,12 @@ export async function handleAction(req: Request, res: Response) { } const { credentials, parameters, body, metadata } = bodyResult.data; + const cache = new PostgresCacheService(metadata.connectionId); try { const data = await matchingAction.action( { credentials, parameters, body }, - undefined, + cache, metadata ); res.send(JSON.stringify(data)); From de5b2ca3d8646e8cd510a37351ee374ffe3a93b7 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 23:02:29 +0000 Subject: [PATCH 018/133] Add metadata to slack post message --- .../src/integrations/slack/actions/actions.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/apps/integrations/src/integrations/slack/actions/actions.ts b/apps/integrations/src/integrations/slack/actions/actions.ts index 26bcc1e6d..758866e9b 100644 --- a/apps/integrations/src/integrations/slack/actions/actions.ts +++ b/apps/integrations/src/integrations/slack/actions/actions.ts @@ -48,9 +48,34 @@ export const chatPostMessage: Action = { }; } + //we add __internal metadata so we can associate messages with workflow runs + let bodyMetadata: { + event_payload?: any; + event_type: string; + } = { + event_type: "post_message", + }; + if (metadata) { + bodyMetadata = { + ...bodyMetadata, + event_payload: { + ...(data.body?.metadata ?? {}), + __internal: metadata, + }, + }; + } else { + bodyMetadata = { + ...bodyMetadata, + event_payload: { + ...(data.body?.metadata ?? {}), + }, + }; + } + const postMessageBody = { ...data.body, channel: channelId, + metadata: metadata ? bodyMetadata : undefined, }; //todo add extra passed in metadata to the metadata property From a5190693c81c4a9765ea89bd39ee170b7275fe08 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 13 Feb 2023 23:08:13 +0000 Subject: [PATCH 019/133] =?UTF-8?q?Use=20=5F=5Ftrigger=20so=20we=20don?= =?UTF-8?q?=E2=80=99t=20have=20to=20change=20the=20webhooks=20and=20introd?= =?UTF-8?q?uce=20incompatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/integrations/src/integrations/slack/actions/actions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/integrations/src/integrations/slack/actions/actions.ts b/apps/integrations/src/integrations/slack/actions/actions.ts index 758866e9b..bb837d42a 100644 --- a/apps/integrations/src/integrations/slack/actions/actions.ts +++ b/apps/integrations/src/integrations/slack/actions/actions.ts @@ -48,7 +48,7 @@ export const chatPostMessage: Action = { }; } - //we add __internal metadata so we can associate messages with workflow runs + //we add __trigger metadata so we can associate messages with workflow runs let bodyMetadata: { event_payload?: any; event_type: string; @@ -60,7 +60,7 @@ export const chatPostMessage: Action = { ...bodyMetadata, event_payload: { ...(data.body?.metadata ?? {}), - __internal: metadata, + __trigger: metadata, }, }; } else { From 1e1da62b32689eea4b8da708c10b897e66abfa7b Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 12:32:21 +0000 Subject: [PATCH 020/133] The API for integrations is now versioned, accepts params and build credentials --- apps/integrations/src/api/action/index.ts | 95 ----------- apps/integrations/src/api/v1/action/index.ts | 155 ++++++++++++++++++ .../integrations/src/core/schemas/validate.ts | 37 +++-- apps/integrations/src/index.ts | 4 +- 4 files changed, 183 insertions(+), 108 deletions(-) delete mode 100644 apps/integrations/src/api/action/index.ts create mode 100644 apps/integrations/src/api/v1/action/index.ts diff --git a/apps/integrations/src/api/action/index.ts b/apps/integrations/src/api/action/index.ts deleted file mode 100644 index 59f2dedf4..000000000 --- a/apps/integrations/src/api/action/index.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { PostgresCacheService } from "cache/postgresCache"; -import { AuthCredentialsSchema } from "core/authentication/types"; -import { validateInputs } from "core/validation/inputs"; -import { Request, Response } from "express"; -import { catalog } from "integrations/catalog"; -import { z } from "zod"; - -const bodySchema = z.object({ - parameters: z.record(z.string(), z.any()).optional(), - credentials: AuthCredentialsSchema.optional(), - body: z.any().optional(), - metadata: z.object({ - requestId: z.string(), - workflowId: z.string(), - connectionId: z.string(), - }), -}); - -export async function handleAction(req: Request, res: Response) { - const { service, action } = req.params; - - const matchingService = Object.values(catalog.services).find( - (s) => s.service === service - ); - - if (!matchingService) { - res.status(404).send( - JSON.stringify({ - success: false, - service, - error: { type: "missing_service", message: "Service not found" }, - }) - ); - return; - } - - const matchingAction = Object.values(matchingService.actions).find( - (a) => a.name === action - ); - - if (!matchingAction) { - res.status(404).send( - JSON.stringify({ - success: false, - service, - action, - error: { type: "missing_action", message: "Action not found" }, - }) - ); - return; - } - - const bodyResult = bodySchema.safeParse(req.body); - - if (!bodyResult.success) { - res.status(400).send( - JSON.stringify({ - success: false, - error: { type: "invalid_body", issues: bodyResult.error.issues }, - }) - ); - return; - } - - const inputValidationResult = await validateInputs( - matchingAction.spec.input, - bodyResult.data - ); - if (!inputValidationResult.success) { - res.status(400).send( - JSON.stringify({ - success: false, - error: inputValidationResult.error, - }) - ); - return; - } - - const { credentials, parameters, body, metadata } = bodyResult.data; - const cache = new PostgresCacheService(metadata.connectionId); - - try { - const data = await matchingAction.action( - { credentials, parameters, body }, - cache, - metadata - ); - res.send(JSON.stringify(data)); - } catch (e: any) { - console.error(e); - res - .status(500) - .send(JSON.stringify({ success: false, errors: e.toString() })); - } -} diff --git a/apps/integrations/src/api/v1/action/index.ts b/apps/integrations/src/api/v1/action/index.ts new file mode 100644 index 000000000..4270b71a0 --- /dev/null +++ b/apps/integrations/src/api/v1/action/index.ts @@ -0,0 +1,155 @@ +import { PostgresCacheService } from "cache/postgresCache"; +import { AuthCredentials } from "core/authentication/types"; +import { validateInputs } from "core/validation/inputs"; +import { Request, Response } from "express"; +import { catalog } from "integrations/catalog"; +import { z } from "zod"; + +const requestBodySchema = z.object({ + credentials: z.object({ accessToken: z.string() }).optional(), + params: z.record(z.string().or(z.number()), z.any()).optional(), + metadata: z.object({ + requestId: z.string(), + workflowId: z.string(), + connectionId: z.string(), + }), +}); + +export async function handleAction(req: Request, res: Response) { + const { service, action } = req.params; + + const matchingService = Object.values(catalog.services).find( + (s) => s.service === service + ); + + if (!matchingService) { + res.status(404).send( + JSON.stringify({ + success: false, + service, + error: { type: "missing_service", message: "Service not found" }, + }) + ); + return; + } + + const matchingAction = Object.values(matchingService.actions).find( + (a) => a.name === action + ); + + if (!matchingAction) { + res.status(404).send( + JSON.stringify({ + success: false, + service, + action, + error: { type: "missing_action", message: "Action not found" }, + }) + ); + return; + } + + const parsedRequestBody = requestBodySchema.safeParse(req.body); + + if (!parsedRequestBody.success) { + res.status(400).send( + JSON.stringify({ + success: false, + error: { type: "invalid_body", issues: parsedRequestBody.error.issues }, + }) + ); + return; + } + + //for v1 of this API we're building the credentials from the action + //this is fine for now but we'll want to use the connection in future to cover complex cases + let credentials: AuthCredentials | undefined = undefined; + if ( + parsedRequestBody.data.credentials && + matchingAction.spec.input.security + ) { + const firstSecurityMethod = Object.entries( + matchingAction.spec.input.security + )[0]; + if (firstSecurityMethod) { + const [name, scopes] = firstSecurityMethod; + //get the full info from the service + const securityMethod = matchingService.authentication[name]; + + switch (securityMethod.type) { + case "oauth2": + credentials = { + type: "oauth2", + name, + accessToken: parsedRequestBody.data.credentials.accessToken, + scopes, + }; + break; + default: + throw new Error(`Not implemented ${securityMethod.type}`); + } + } + } + + //separate the parameters and body by looking at the spec and pulling properties out + let parameters: Record | undefined = undefined; + let body: any = undefined; + + if (parsedRequestBody.data.params) { + matchingAction.spec.input.parameters?.forEach((p) => { + if (!parameters) { + parameters = {}; + } + parameters[p.name] = parsedRequestBody.data.params?.[p.name]; + }); + + const bodyProperties = matchingAction.spec.input.body?.properties; + if (bodyProperties) { + body = {}; + Object.keys(bodyProperties).forEach((name) => { + const value = parsedRequestBody.data.params?.[name]; + if (value !== undefined) { + body[name] = value; + } + }); + } + } + + console.log("parameters", parameters); + console.log("body", body); + + const inputValidationResult = await validateInputs( + matchingAction.spec.input, + { + parameters, + body, + credentials, + } + ); + if (!inputValidationResult.success) { + res.status(400).send( + JSON.stringify({ + success: false, + error: inputValidationResult.error, + }) + ); + return; + } + + const { metadata } = parsedRequestBody.data; + const cache = new PostgresCacheService(metadata.connectionId); + + try { + const data = await matchingAction.action( + { credentials, parameters, body }, + cache, + metadata + ); + res.send(JSON.stringify(data)); + } catch (e: any) { + console.error(e); + res + .status(500) + .send(JSON.stringify({ success: false, errors: e.toString() })); + } +} diff --git a/apps/integrations/src/core/schemas/validate.ts b/apps/integrations/src/core/schemas/validate.ts index 9d7806b1f..8af342a34 100644 --- a/apps/integrations/src/core/schemas/validate.ts +++ b/apps/integrations/src/core/schemas/validate.ts @@ -1,24 +1,39 @@ import { JSONSchema } from "./types"; export async function validate(data: any, schema?: JSONSchema) { - if (!schema) { + try { + if (!schema) { + return { + success: true as const, + }; + } + const Validator = await getValidator(); + const validator = new Validator(schema); + const result = validator.validate(data); + if (!result.valid) { + return { + success: false as const, + errors: result.errors, + }; + } + return { success: true as const, }; - } - const Validator = await getValidator(); - const validator = new Validator(schema); - const result = validator.validate(data); - if (!result.valid) { + } catch (e: any) { + console.error(e); return { success: false as const, - errors: result.errors, + errors: [ + { + keyword: "undefined", + keywordLocation: "undefined", + instanceLocation: "undefined", + error: e.toString(), + }, + ], }; } - - return { - success: true as const, - }; } async function getValidator() { diff --git a/apps/integrations/src/index.ts b/apps/integrations/src/index.ts index 0bd9712d2..44f2f1a84 100644 --- a/apps/integrations/src/index.ts +++ b/apps/integrations/src/index.ts @@ -1,6 +1,6 @@ import express, { Express, Request, Response } from "express"; import dotenv from "dotenv"; -import { handleAction } from "api/action"; +import { handleAction } from "api/v1/action"; dotenv.config(); const app: Express = express(); @@ -12,7 +12,7 @@ app.get("/", (req: Request, res: Response) => { res.send("Trigger.dev integrations service"); }); -app.post("/api/:service/action/:action", handleAction); +app.post("/api/v1/:service/action/:action", handleAction); app.listen(port, () => { console.log(`⚡️[server]: Server is running at http://localhost:${port}`); From 39d02e6d0094053c580b673527cdbb35257bb70f Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 12:33:17 +0000 Subject: [PATCH 021/133] Added the integrations service to the example Warp config --- .warp/triggerdotdev.yaml.example | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.warp/triggerdotdev.yaml.example b/.warp/triggerdotdev.yaml.example index b2bd5aea7..078234dcf 100644 --- a/.warp/triggerdotdev.yaml.example +++ b/.warp/triggerdotdev.yaml.example @@ -31,8 +31,17 @@ windows: panes: - cwd: /Users/eric/code/triggerdotdev/trigger.dev commands: - - exec: pnpm run dev --filter webapp + - exec: pnpm run build --filter webapp + - exec: pnpm run idev --filter webapp - cwd: /Users/eric/code/triggerdotdev/trigger.dev/apps/webapp + - title: integrations + layout: + split_direction: vertical + panes: + - cwd: /Users/eric/code/triggerdotdev/trigger.dev + commands: + - exec: pnpm run dev --filter integrations + - cwd: /Users/eric/code/triggerdotdev/trigger.dev/apps/integrations - title: ngrok layout: split_direction: horizontal From caac573a640cad3e8cc3f31f31ab0d7531bf8955 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 12:35:24 +0000 Subject: [PATCH 022/133] Added version and made response schema optional for SDK requests --- .../app/services/requests/createIntegrationRequest.server.ts | 2 ++ .../migration.sql | 2 ++ apps/webapp/prisma/schema.prisma | 1 + packages/internal-bridge/src/schemas/server.ts | 1 + .../src/messages/schemas/integrationRequests.ts | 1 + packages/trigger-sdk/src/client.ts | 5 +++++ packages/trigger-sdk/src/localStorage.ts | 3 ++- 7 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 apps/webapp/prisma/migrations/20230214101645_integration_request_added_version/migration.sql diff --git a/apps/webapp/app/services/requests/createIntegrationRequest.server.ts b/apps/webapp/app/services/requests/createIntegrationRequest.server.ts index 2b817df0e..ad0c751d0 100644 --- a/apps/webapp/app/services/requests/createIntegrationRequest.server.ts +++ b/apps/webapp/app/services/requests/createIntegrationRequest.server.ts @@ -21,6 +21,7 @@ export class CreateIntegrationRequest { service: string; endpoint: string; params?: any; + version?: string; } ) { const environment = await this.#prismaClient.runtimeEnvironment.findUnique({ @@ -60,6 +61,7 @@ export class CreateIntegrationRequest { context: { service: data.service, endpoint: data.endpoint, + version: data.version, }, status: "PENDING", ts: timestamp, diff --git a/apps/webapp/prisma/migrations/20230214101645_integration_request_added_version/migration.sql b/apps/webapp/prisma/migrations/20230214101645_integration_request_added_version/migration.sql new file mode 100644 index 000000000..a7357907e --- /dev/null +++ b/apps/webapp/prisma/migrations/20230214101645_integration_request_added_version/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "IntegrationRequest" ADD COLUMN "version" TEXT NOT NULL DEFAULT '1'; diff --git a/apps/webapp/prisma/schema.prisma b/apps/webapp/prisma/schema.prisma index 6b820d19f..3e56e489b 100644 --- a/apps/webapp/prisma/schema.prisma +++ b/apps/webapp/prisma/schema.prisma @@ -335,6 +335,7 @@ model IntegrationRequest { params Json endpoint String + version String @default("1") externalService ExternalService @relation(fields: [externalServiceId], references: [id], onDelete: Cascade, onUpdate: Cascade) externalServiceId String diff --git a/packages/internal-bridge/src/schemas/server.ts b/packages/internal-bridge/src/schemas/server.ts index 82904189b..1579cf084 100644 --- a/packages/internal-bridge/src/schemas/server.ts +++ b/packages/internal-bridge/src/schemas/server.ts @@ -27,6 +27,7 @@ export const ServerRPCSchema = { service: z.string(), endpoint: z.string(), params: z.any(), + version: z.string().optional(), }), timestamp: z.string(), }), diff --git a/packages/internal-platform/src/messages/schemas/integrationRequests.ts b/packages/internal-platform/src/messages/schemas/integrationRequests.ts index e5b56ab1f..6cb7166e8 100644 --- a/packages/internal-platform/src/messages/schemas/integrationRequests.ts +++ b/packages/internal-platform/src/messages/schemas/integrationRequests.ts @@ -29,6 +29,7 @@ export const commands = { data: z.object({ key: z.string(), request: z.object({ + version: z.string().optional(), service: z.string(), endpoint: z.string(), params: z.any(), diff --git a/packages/trigger-sdk/src/client.ts b/packages/trigger-sdk/src/client.ts index f4dd9e0bc..8b1030022 100644 --- a/packages/trigger-sdk/src/client.ts +++ b/packages/trigger-sdk/src/client.ts @@ -558,12 +558,17 @@ export class TriggerClient { service: options.service, endpoint: options.endpoint, params: options.params, + version: options.version, }, timestamp: String(highPrecisionTimestamp()), }); const output = await result; + if (!options.response?.schema) { + return output; + } + return options.response.schema.parse(output); }, sendEvent: async (key, event) => { diff --git a/packages/trigger-sdk/src/localStorage.ts b/packages/trigger-sdk/src/localStorage.ts index 8d0707bfd..182beeb84 100644 --- a/packages/trigger-sdk/src/localStorage.ts +++ b/packages/trigger-sdk/src/localStorage.ts @@ -3,10 +3,11 @@ import { z } from "zod"; import { TriggerCustomEvent, TriggerFetch } from "./types"; type PerformRequestOptions = { + version?: string; service: string; params: unknown; endpoint: string; - response: { + response?: { schema: TSchema; }; }; From 011d7d5611f54af8bc2af8ffc3ba18a9064e74be Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 13:43:24 +0000 Subject: [PATCH 023/133] Added retryableStatusCodes to a service --- apps/integrations/src/core/service/types.ts | 2 +- apps/integrations/src/integrations/slack/index.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/integrations/src/core/service/types.ts b/apps/integrations/src/core/service/types.ts index c006e2105..a25a96fdc 100644 --- a/apps/integrations/src/core/service/types.ts +++ b/apps/integrations/src/core/service/types.ts @@ -1,6 +1,5 @@ import { Action } from "core/action/types"; import { IntegrationAuthentication } from "core/authentication/types"; -import { Endpoint } from "core/endpoint/types"; export type Service = { name: string; @@ -8,4 +7,5 @@ export type Service = { version: string; authentication: IntegrationAuthentication; actions: Record; + retryableStatusCodes: number[]; }; diff --git a/apps/integrations/src/integrations/slack/index.ts b/apps/integrations/src/integrations/slack/index.ts index 8649a4f0b..8a81fe8f2 100644 --- a/apps/integrations/src/integrations/slack/index.ts +++ b/apps/integrations/src/integrations/slack/index.ts @@ -8,4 +8,5 @@ export const slack: Service = { version: "1.0.0", authentication, actions, + retryableStatusCodes: [408, 429, 500, 502, 503, 504], }; From 581068362fdf551caadcdfead06d91eedefed322 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 13:44:03 +0000 Subject: [PATCH 024/133] The integration service now returns the response in the format the webapp is expecting --- apps/integrations/src/api/v1/action/index.ts | 115 ++++++++++++++---- apps/webapp/app/env.server.ts | 2 + .../performIntegrationRequest.server.ts | 113 +++++++++++++---- 3 files changed, 183 insertions(+), 47 deletions(-) diff --git a/apps/integrations/src/api/v1/action/index.ts b/apps/integrations/src/api/v1/action/index.ts index 4270b71a0..043f6e80e 100644 --- a/apps/integrations/src/api/v1/action/index.ts +++ b/apps/integrations/src/api/v1/action/index.ts @@ -1,7 +1,10 @@ import { PostgresCacheService } from "cache/postgresCache"; import { AuthCredentials } from "core/authentication/types"; +import { RequestError } from "core/request/errors"; +import { Service } from "core/service/types"; import { validateInputs } from "core/validation/inputs"; import { Request, Response } from "express"; +import { stat } from "fs"; import { catalog } from "integrations/catalog"; import { z } from "zod"; @@ -15,6 +18,17 @@ const requestBodySchema = z.object({ }), }); +type ReturnResponse = { + response: NormalizedResponse; + isRetryable: boolean; + ok: boolean; +}; + +type NormalizedResponse = { + output: NonNullable; + context: any; +}; + export async function handleAction(req: Request, res: Response) { const { service, action } = req.params; @@ -24,11 +38,13 @@ export async function handleAction(req: Request, res: Response) { if (!matchingService) { res.status(404).send( - JSON.stringify({ - success: false, - service, - error: { type: "missing_service", message: "Service not found" }, - }) + JSON.stringify( + error(404, false, { + type: "missing_service", + message: "Service not found", + service, + }) + ) ); return; } @@ -39,12 +55,14 @@ export async function handleAction(req: Request, res: Response) { if (!matchingAction) { res.status(404).send( - JSON.stringify({ - success: false, - service, - action, - error: { type: "missing_action", message: "Action not found" }, - }) + JSON.stringify( + error(404, false, { + type: "missing_action", + message: "Action not found", + service, + action, + }) + ) ); return; } @@ -53,10 +71,15 @@ export async function handleAction(req: Request, res: Response) { if (!parsedRequestBody.success) { res.status(400).send( - JSON.stringify({ - success: false, - error: { type: "invalid_body", issues: parsedRequestBody.error.issues }, - }) + JSON.stringify( + error(400, false, { + type: "invalid_body", + message: "Action not found", + service, + action, + issues: parsedRequestBody.error.issues, + }) + ) ); return; } @@ -127,12 +150,9 @@ export async function handleAction(req: Request, res: Response) { } ); if (!inputValidationResult.success) { - res.status(400).send( - JSON.stringify({ - success: false, - error: inputValidationResult.error, - }) - ); + res + .status(400) + .send(JSON.stringify(error(400, false, inputValidationResult.error))); return; } @@ -145,11 +165,60 @@ export async function handleAction(req: Request, res: Response) { cache, metadata ); - res.send(JSON.stringify(data)); + + //convert into the format for the webapp + const response: ReturnResponse = { + ok: true, + isRetryable: isRetryable(matchingService, data.status), + response: { + output: data.body ?? {}, + context: { + statusCode: data.status, + headers: data.headers, + }, + }, + }; + res.send(JSON.stringify(response)); } catch (e: any) { console.error(e); + + if (e instanceof Error) { + res + .status(500) + .send(JSON.stringify(error(500, false, { error: JSON.stringify(e) }))); + return; + } + + if ("error" in e) { + res.status(500).send(JSON.stringify(error(500, false, e.error))); + return; + } + res .status(500) - .send(JSON.stringify({ success: false, errors: e.toString() })); + .send(JSON.stringify(error(500, false, { error: JSON.stringify(e) }))); } } + +function isRetryable(service: Service, status: number): boolean { + return service.retryableStatusCodes.includes(status); +} + +function error( + status: number, + isRetryable: boolean, + error: Record +): ReturnResponse { + const response: ReturnResponse = { + ok: false, + isRetryable, + response: { + output: error, + context: { + statusCode: status, + headers: {}, + }, + }, + }; + return response; +} diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index 93399e5de..ba27bb4c1 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -49,6 +49,8 @@ const EnvironmentSchema = z.object({ PULSAR_AUDIENCE: z.string().optional(), PULSAR_DEBUG: z.string().optional(), INTERNAL_TRIGGER_API_KEY: z.string().optional(), + INTEGRATIONS_API_KEY: z.string(), + INTEGRATIONS_API_ORIGIN: z.string(), }); export type Environment = z.infer; diff --git a/apps/webapp/app/services/requests/performIntegrationRequest.server.ts b/apps/webapp/app/services/requests/performIntegrationRequest.server.ts index 12a9a3928..fef176b2f 100644 --- a/apps/webapp/app/services/requests/performIntegrationRequest.server.ts +++ b/apps/webapp/app/services/requests/performIntegrationRequest.server.ts @@ -10,6 +10,7 @@ import type { IntegrationRequest } from "~/models/integrationRequest.server"; import { getAccessInfo } from "../accessInfo.server"; import { RedisCacheService } from "../cacheService.server"; import { getIntegrations } from "~/models/integrations.server"; +import { env } from "~/env.server"; type CallResponse = | { @@ -65,7 +66,8 @@ export class PerformIntegrationRequest { accessInfo, integrationRequest, cache, - integrationRequest.externalService.workflowId + integrationRequest.externalService.workflowId, + integrationRequest.externalService.connection.id ); if (performedRequest.ok) { @@ -224,31 +226,94 @@ export class PerformIntegrationRequest { accessInfo: AccessInfo, integrationRequest: IntegrationRequest, cache: CacheService, - workflowId: string + workflowId: string, + connectionId: string ): Promise { - const integrationInfo = getIntegrations(true).find( - (i) => i.metadata.slug === service - ); + switch (integrationRequest.version) { + case "1": { + const integrationInfo = getIntegrations(true).find( + (i) => i.metadata.slug === service + ); - if (!integrationInfo) { - throw new Error(`Unknown service: ${service}`); + if (!integrationInfo) { + throw new Error(`Unknown service: ${service}`); + } + + const { requests } = integrationInfo; + + if (!requests) { + throw new Error(`Service ${service} does not support requests`); + } + + return requests.perform({ + accessInfo, + endpoint: integrationRequest.endpoint, + params: integrationRequest.params, + cache, + metadata: { + requestId: integrationRequest.id, + workflowId: workflowId, + }, + }); + } + case "2": { + let credentials: { accessToken: string } | undefined = undefined; + switch (accessInfo.type) { + case "oauth2": + credentials = { + accessToken: accessInfo.accessToken, + }; + break; + case "api_key": + credentials = { + accessToken: accessInfo.api_key, + }; + } + + try { + const response = await fetch( + `${env.INTEGRATIONS_API_ORIGIN}/api/v1/${service}/action/${integrationRequest.endpoint}`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${env.INTEGRATIONS_API_KEY}`, + }, + body: JSON.stringify({ + credentials, + params: integrationRequest.params, + metadata: { + requestId: integrationRequest.id, + workflowId: workflowId, + connectionId, + }, + }), + } + ); + + const json = await response.json(); + return json; + } catch (e) { + console.error(e); + return { + ok: false, + isRetryable: true, + response: { + output: { + error: { + message: JSON.stringify(e), + }, + }, + context: {}, + }, + }; + } + } + default: { + throw new Error( + `Unknown integration request version: ${integrationRequest.version}` + ); + } } - - const { requests } = integrationInfo; - - if (!requests) { - throw new Error(`Service ${service} does not support requests`); - } - - return requests.perform({ - accessInfo, - endpoint: integrationRequest.endpoint, - params: integrationRequest.params, - cache, - metadata: { - requestId: integrationRequest.id, - workflowId: workflowId, - }, - }); } } From 8a6467f4c8842c0de095f9afb88ad240ee8d1b0f Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 13:57:14 +0000 Subject: [PATCH 025/133] The namespace for the cache includs connection id and workflow id Connections are used across workflows, so there was a chance the same key could have been fighting --- apps/integrations/src/api/v1/action/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/integrations/src/api/v1/action/index.ts b/apps/integrations/src/api/v1/action/index.ts index 043f6e80e..2edb2fe60 100644 --- a/apps/integrations/src/api/v1/action/index.ts +++ b/apps/integrations/src/api/v1/action/index.ts @@ -1,10 +1,8 @@ import { PostgresCacheService } from "cache/postgresCache"; import { AuthCredentials } from "core/authentication/types"; -import { RequestError } from "core/request/errors"; import { Service } from "core/service/types"; import { validateInputs } from "core/validation/inputs"; import { Request, Response } from "express"; -import { stat } from "fs"; import { catalog } from "integrations/catalog"; import { z } from "zod"; @@ -157,7 +155,9 @@ export async function handleAction(req: Request, res: Response) { } const { metadata } = parsedRequestBody.data; - const cache = new PostgresCacheService(metadata.connectionId); + const cache = new PostgresCacheService( + `${metadata.connectionId}-${metadata.workflowId}` + ); try { const data = await matchingAction.action( From fb6953bc1d8c40b7685161f7e2e7f1f0f06cb838 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 13:58:54 +0000 Subject: [PATCH 026/133] =?UTF-8?q?Actually=20we=E2=80=99re=20going=20to?= =?UTF-8?q?=20cache=20using=20connection=20+=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/integrations/src/api/v1/action/index.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/integrations/src/api/v1/action/index.ts b/apps/integrations/src/api/v1/action/index.ts index 2edb2fe60..8cbc5904b 100644 --- a/apps/integrations/src/api/v1/action/index.ts +++ b/apps/integrations/src/api/v1/action/index.ts @@ -155,9 +155,7 @@ export async function handleAction(req: Request, res: Response) { } const { metadata } = parsedRequestBody.data; - const cache = new PostgresCacheService( - `${metadata.connectionId}-${metadata.workflowId}` - ); + const cache = new PostgresCacheService(`${metadata.connectionId}-${service}`); try { const data = await matchingAction.action( From 8f5474072f560121312b708357ba468c8b9922bd Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 14:33:29 +0000 Subject: [PATCH 027/133] Added live flag to service --- apps/integrations/src/core/service/types.ts | 1 + apps/integrations/src/integrations/slack/index.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/integrations/src/core/service/types.ts b/apps/integrations/src/core/service/types.ts index a25a96fdc..2dbc5b8a6 100644 --- a/apps/integrations/src/core/service/types.ts +++ b/apps/integrations/src/core/service/types.ts @@ -5,6 +5,7 @@ export type Service = { name: string; service: string; version: string; + live: boolean; authentication: IntegrationAuthentication; actions: Record; retryableStatusCodes: number[]; diff --git a/apps/integrations/src/integrations/slack/index.ts b/apps/integrations/src/integrations/slack/index.ts index 8a81fe8f2..e0197ae12 100644 --- a/apps/integrations/src/integrations/slack/index.ts +++ b/apps/integrations/src/integrations/slack/index.ts @@ -6,6 +6,7 @@ export const slack: Service = { name: "Slack", service: "slack", version: "1.0.0", + live: false, authentication, actions, retryableStatusCodes: [408, 429, 500, 502, 503, 504], From dfab30c901120cbefab7ad1983fd33cdef84f655 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 14:33:58 +0000 Subject: [PATCH 028/133] Endpoint that returns information about the services --- apps/integrations/src/api/v1/services.ts | 31 ++++++++++++++++++++++++ apps/integrations/src/index.ts | 3 ++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 apps/integrations/src/api/v1/services.ts diff --git a/apps/integrations/src/api/v1/services.ts b/apps/integrations/src/api/v1/services.ts new file mode 100644 index 000000000..4db13b074 --- /dev/null +++ b/apps/integrations/src/api/v1/services.ts @@ -0,0 +1,31 @@ +import { IntegrationAuthentication } from "core/authentication/types"; +import { Service } from "core/service/types"; +import { Request, Response } from "express"; +import { catalog } from "integrations/catalog"; + +export type ServiceMetadata = { + name: string; + service: string; + version: string; + live: boolean; + authentication: IntegrationAuthentication; +}; + +export async function handleServices(req: Request, res: Response) { + const servicesMetadata: Record = {}; + Object.entries(catalog.services).forEach(([key, service]) => { + const metadata = omitExtraInfo(service); + servicesMetadata[key] = metadata; + }); + + res.send( + JSON.stringify({ + services: servicesMetadata, + }) + ); +} + +function omitExtraInfo(service: Service): ServiceMetadata { + const { actions, retryableStatusCodes, ...rest } = service; + return rest; +} diff --git a/apps/integrations/src/index.ts b/apps/integrations/src/index.ts index 44f2f1a84..dfde73f12 100644 --- a/apps/integrations/src/index.ts +++ b/apps/integrations/src/index.ts @@ -1,6 +1,7 @@ import express, { Express, Request, Response } from "express"; import dotenv from "dotenv"; import { handleAction } from "api/v1/action"; +import { handleServices } from "api/v1/services"; dotenv.config(); const app: Express = express(); @@ -11,7 +12,7 @@ app.use(express.json()); app.get("/", (req: Request, res: Response) => { res.send("Trigger.dev integrations service"); }); - +app.get("/api/v1/services", handleServices); app.post("/api/v1/:service/action/:action", handleAction); app.listen(port, () => { From 84bd5a63a2f1709848bee7899e34b8bd4cdd853f Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 14:52:35 +0000 Subject: [PATCH 029/133] Added API key auth type --- .../src/core/authentication/types.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/integrations/src/core/authentication/types.ts b/apps/integrations/src/core/authentication/types.ts index b21866ad7..18dfc1844 100644 --- a/apps/integrations/src/core/authentication/types.ts +++ b/apps/integrations/src/core/authentication/types.ts @@ -5,16 +5,29 @@ export type IntegrationAuthentication = Record< AuthenticationDefinition >; -type AuthenticationDefinition = OAuth2; +type AuthenticationDefinition = OAuth2Authentication | APIKeyAuthentication; -interface OAuth2 { +type OAuth2Authentication = { type: "oauth2"; placement: AuthenticationPlacement; authorizationUrl: string; tokenUrl: string; flow: "accessCode" | "implicit" | "password" | "application"; scopes: Record; -} +}; + +type APIKeyAuthentication = { + type: "api_key"; + placement: AuthenticationPlacement; + documentation: string; + additionalFields?: { + key: string; + fieldType: "text"; + name: string; + placeholder?: string; + description: string; + }[]; +}; type AuthenticationPlacement = HeaderAuthentication; From 974033d5d2eaf82d0c4d48f1f0470fe014ec805a Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 14:52:51 +0000 Subject: [PATCH 030/133] =?UTF-8?q?Don=E2=80=99t=20export=20the=20service?= =?UTF-8?q?=20metadata=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/integrations/src/api/v1/services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/integrations/src/api/v1/services.ts b/apps/integrations/src/api/v1/services.ts index 4db13b074..230c98dcd 100644 --- a/apps/integrations/src/api/v1/services.ts +++ b/apps/integrations/src/api/v1/services.ts @@ -3,7 +3,7 @@ import { Service } from "core/service/types"; import { Request, Response } from "express"; import { catalog } from "integrations/catalog"; -export type ServiceMetadata = { +type ServiceMetadata = { name: string; service: string; version: string; From 259e28e13a949f6348c862e78f23c157c40bc18c Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 15:04:27 +0000 Subject: [PATCH 031/133] Removed old todo --- apps/integrations/src/integrations/slack/actions/actions.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/integrations/src/integrations/slack/actions/actions.ts b/apps/integrations/src/integrations/slack/actions/actions.ts index bb837d42a..591177012 100644 --- a/apps/integrations/src/integrations/slack/actions/actions.ts +++ b/apps/integrations/src/integrations/slack/actions/actions.ts @@ -78,9 +78,6 @@ export const chatPostMessage: Action = { metadata: metadata ? bodyMetadata : undefined, }; - //todo add extra passed in metadata to the metadata property - // - const postResponse = await endpoints.chatPostMessage.request({ parameters: data.parameters, body: postMessageBody, From 8039f326a974a28fb05bb07cc027365b9fc3ef29 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 15:04:45 +0000 Subject: [PATCH 032/133] =?UTF-8?q?Created=20an=20IntegrationsClient=20tha?= =?UTF-8?q?t=E2=80=99s=20used=20to=20communicate=20with=20the=20integratio?= =?UTF-8?q?ns=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/services/integrationsClient.server.ts | 99 +++++++++++++++++++ .../performIntegrationRequest.server.ts | 59 ++--------- 2 files changed, 107 insertions(+), 51 deletions(-) create mode 100644 apps/webapp/app/services/integrationsClient.server.ts diff --git a/apps/webapp/app/services/integrationsClient.server.ts b/apps/webapp/app/services/integrationsClient.server.ts new file mode 100644 index 000000000..159b7571d --- /dev/null +++ b/apps/webapp/app/services/integrationsClient.server.ts @@ -0,0 +1,99 @@ +import type { IntegrationRequest } from ".prisma/client"; +import type { + AccessInfo, + PerformedRequestResponse, +} from "@trigger.dev/integration-sdk"; +import { env } from "~/env.server"; + +class IntegrationsClient { + #baseUrl: string; + #apiKey: string; + constructor(apiOrigin: string, apiKey: string) { + this.#baseUrl = `${apiOrigin}/api/v1`; + this.#apiKey = apiKey; + } + + async performRequest({ + service, + accessInfo, + integrationRequest, + workflowId, + connectionId, + }: { + service: string; + accessInfo: AccessInfo; + integrationRequest: IntegrationRequest; + workflowId: string; + connectionId: string; + }): Promise { + let credentials: { accessToken: string } | undefined = undefined; + switch (accessInfo.type) { + case "oauth2": + credentials = { + accessToken: accessInfo.accessToken, + }; + break; + case "api_key": + credentials = { + accessToken: accessInfo.api_key, + }; + } + + try { + const response = await fetch( + `${this.#baseUrl}/${service}/action/${integrationRequest.endpoint}`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${this.#apiKey}`, + }, + body: JSON.stringify({ + credentials, + params: integrationRequest.params, + metadata: { + requestId: integrationRequest.id, + workflowId: workflowId, + connectionId, + }, + }), + } + ); + + const json = await response.json(); + return json; + } catch (e) { + console.error(e); + return { + ok: false, + isRetryable: true, + response: { + output: { + error: { + message: JSON.stringify(e), + }, + }, + context: {}, + }, + }; + } + } + + async getServices() { + const response = await fetch(`${this.#baseUrl}/services`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${this.#apiKey}`, + }, + }); + + const json = await response.json(); + return json; + } +} + +export const integrationsClient = new IntegrationsClient( + env.INTEGRATIONS_API_ORIGIN, + env.INTEGRATIONS_API_KEY +); diff --git a/apps/webapp/app/services/requests/performIntegrationRequest.server.ts b/apps/webapp/app/services/requests/performIntegrationRequest.server.ts index fef176b2f..80453de1b 100644 --- a/apps/webapp/app/services/requests/performIntegrationRequest.server.ts +++ b/apps/webapp/app/services/requests/performIntegrationRequest.server.ts @@ -11,6 +11,7 @@ import { getAccessInfo } from "../accessInfo.server"; import { RedisCacheService } from "../cacheService.server"; import { getIntegrations } from "~/models/integrations.server"; import { env } from "~/env.server"; +import { integrationsClient } from "../integrationsClient.server"; type CallResponse = | { @@ -257,57 +258,13 @@ export class PerformIntegrationRequest { }); } case "2": { - let credentials: { accessToken: string } | undefined = undefined; - switch (accessInfo.type) { - case "oauth2": - credentials = { - accessToken: accessInfo.accessToken, - }; - break; - case "api_key": - credentials = { - accessToken: accessInfo.api_key, - }; - } - - try { - const response = await fetch( - `${env.INTEGRATIONS_API_ORIGIN}/api/v1/${service}/action/${integrationRequest.endpoint}`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${env.INTEGRATIONS_API_KEY}`, - }, - body: JSON.stringify({ - credentials, - params: integrationRequest.params, - metadata: { - requestId: integrationRequest.id, - workflowId: workflowId, - connectionId, - }, - }), - } - ); - - const json = await response.json(); - return json; - } catch (e) { - console.error(e); - return { - ok: false, - isRetryable: true, - response: { - output: { - error: { - message: JSON.stringify(e), - }, - }, - context: {}, - }, - }; - } + integrationsClient.performRequest({ + service, + accessInfo, + integrationRequest, + workflowId, + connectionId, + }); } default: { throw new Error( From d60e9ae93949ae43e08d7835fbe061c9256d100f Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 15:09:00 +0000 Subject: [PATCH 033/133] Renamed IntegrationMetadata to ServiceMetadata --- .../components/integrations/AddApiKeyButton.tsx | 10 +++++----- .../app/components/integrations/ConnectButton.tsx | 6 +++--- .../components/integrations/ConnectOAuthButton.tsx | 4 ++-- .../components/integrations/ConnectionSelector.tsx | 14 +++++++------- .../components/integrations/IntegrationIcon.tsx | 6 +++--- apps/webapp/app/models/integrations.server.ts | 2 ++ .../orgs/$organizationSlug/__org/integrations.tsx | 4 ++-- apps/webapp/app/utils/integrationMetadata.ts | 4 ++-- integrations/github/src/internal.ts | 4 ++-- integrations/resend/src/internal.ts | 4 ++-- integrations/shopify/src/internal.ts | 4 ++-- integrations/slack/src/internal.ts | 4 ++-- integrations/whatsapp/src/internal.ts | 4 ++-- packages/integration-sdk/src/types.ts | 4 ++-- 14 files changed, 38 insertions(+), 36 deletions(-) diff --git a/apps/webapp/app/components/integrations/AddApiKeyButton.tsx b/apps/webapp/app/components/integrations/AddApiKeyButton.tsx index a9365900b..3cb4aa75b 100644 --- a/apps/webapp/app/components/integrations/AddApiKeyButton.tsx +++ b/apps/webapp/app/components/integrations/AddApiKeyButton.tsx @@ -1,7 +1,7 @@ import { InformationCircleIcon } from "@heroicons/react/24/outline"; import type { APIKeyAuthentication, - IntegrationMetadata, + ServiceMetadata, } from "@trigger.dev/integration-sdk"; import { marked } from "marked"; import { Fragment, useEffect, useState } from "react"; @@ -26,7 +26,7 @@ export function AddApiKeyButton({ className, children, }: { - integration: IntegrationMetadata; + integration: ServiceMetadata; authentication: APIKeyAuthentication; organizationId: string; sourceId?: string; @@ -68,8 +68,8 @@ export function AddApiKeyButton({ Add your {integration.name} API keys -
-
+
+
Instructions @@ -99,7 +99,7 @@ export function AddApiKeyButton({ {integration.icon} []; selectedConnectionId?: string; className?: string; @@ -55,9 +55,9 @@ export function ConnectionSelector({ - + {selectedConnection ? ( {selectedConnection.title} ) : ( @@ -68,7 +68,7 @@ export function ConnectionSelector({ @@ -87,7 +87,7 @@ export function ConnectionSelector({ )}`} >
-
+
{connections.map((connection) => { return ( ); } diff --git a/apps/webapp/app/models/integrations.server.ts b/apps/webapp/app/models/integrations.server.ts index f51f20396..e9df5e705 100644 --- a/apps/webapp/app/models/integrations.server.ts +++ b/apps/webapp/app/models/integrations.server.ts @@ -1,6 +1,8 @@ import type { InternalIntegration } from "@trigger.dev/integration-sdk"; import { getIntegrations as getInternalIntegrations } from "integration-catalog"; +//todo get integrations for the service, and merge with the old ones + export function getIntegrations(showAdminOnly: boolean) { return getInternalIntegrations(showAdminOnly); } diff --git a/apps/webapp/app/routes/__app/orgs/$organizationSlug/__org/integrations.tsx b/apps/webapp/app/routes/__app/orgs/$organizationSlug/__org/integrations.tsx index 3dcd8d343..997e35582 100644 --- a/apps/webapp/app/routes/__app/orgs/$organizationSlug/__org/integrations.tsx +++ b/apps/webapp/app/routes/__app/orgs/$organizationSlug/__org/integrations.tsx @@ -1,7 +1,7 @@ import { EnvelopeIcon } from "@heroicons/react/24/outline"; import { PlusCircleIcon } from "@heroicons/react/24/solid"; import type { LoaderArgs } from "@remix-run/server-runtime"; -import type { IntegrationMetadata } from "@trigger.dev/integration-sdk"; +import type { ServiceMetadata } from "@trigger.dev/integration-sdk"; import { typedjson, useTypedLoaderData } from "remix-typedjson"; import invariant from "tiny-invariant"; import { ApiLogoIcon } from "~/components/code/ApiLogoIcon"; @@ -126,7 +126,7 @@ function AddButtonContent({ integration, status, }: { - integration: IntegrationMetadata; + integration: ServiceMetadata; status: Status; }) { return ( diff --git a/apps/webapp/app/utils/integrationMetadata.ts b/apps/webapp/app/utils/integrationMetadata.ts index 83cb7f866..2a9a909dd 100644 --- a/apps/webapp/app/utils/integrationMetadata.ts +++ b/apps/webapp/app/utils/integrationMetadata.ts @@ -1,7 +1,7 @@ -import type { IntegrationMetadata } from "@trigger.dev/integration-sdk"; +import type { ServiceMetadata } from "@trigger.dev/integration-sdk"; export function findIntegrationMetadata( - integrations: Array, + integrations: Array, slug: string ) { return integrations.find((i) => i.slug === slug); diff --git a/integrations/github/src/internal.ts b/integrations/github/src/internal.ts index 5a2e30724..e3de868f1 100644 --- a/integrations/github/src/internal.ts +++ b/integrations/github/src/internal.ts @@ -1,12 +1,12 @@ import type { - IntegrationMetadata, + ServiceMetadata, InternalIntegration, } from "@trigger.dev/integration-sdk"; import { GitHubWebhookIntegration } from "./internal/webhooks"; const webhooks = new GitHubWebhookIntegration(); -const metadata: IntegrationMetadata = { +const metadata: ServiceMetadata = { name: "GitHub", slug: "github", icon: "/integrations/github.png", diff --git a/integrations/resend/src/internal.ts b/integrations/resend/src/internal.ts index fdc9e9c88..fc21d96fa 100644 --- a/integrations/resend/src/internal.ts +++ b/integrations/resend/src/internal.ts @@ -1,12 +1,12 @@ import type { - IntegrationMetadata, + ServiceMetadata, InternalIntegration, } from "@trigger.dev/integration-sdk"; import { ResendRequestIntegration } from "./internal/requests"; const requests = new ResendRequestIntegration(); -const metadata: IntegrationMetadata = { +const metadata: ServiceMetadata = { name: "Resend", slug: "resend", icon: "/integrations/resend.png", diff --git a/integrations/shopify/src/internal.ts b/integrations/shopify/src/internal.ts index 87df8d5a1..5bc8af7e3 100644 --- a/integrations/shopify/src/internal.ts +++ b/integrations/shopify/src/internal.ts @@ -1,12 +1,12 @@ import type { - IntegrationMetadata, + ServiceMetadata, InternalIntegration, } from "@trigger.dev/integration-sdk"; import { ShopifyRequestIntegration } from "./internal/requests"; const requests = new ShopifyRequestIntegration(); -const metadata: IntegrationMetadata = { +const metadata: ServiceMetadata = { name: "Shopify", slug: "shopify", icon: "/integrations/shopify.png", diff --git a/integrations/slack/src/internal.ts b/integrations/slack/src/internal.ts index 31150b439..051213989 100644 --- a/integrations/slack/src/internal.ts +++ b/integrations/slack/src/internal.ts @@ -1,12 +1,12 @@ import type { - IntegrationMetadata, + ServiceMetadata, InternalIntegration, } from "@trigger.dev/integration-sdk"; import { SlackRequestIntegration } from "./internal/requests"; const requests = new SlackRequestIntegration(); -const metadata: IntegrationMetadata = { +const metadata: ServiceMetadata = { name: "Slack", slug: "slack", icon: "/integrations/slack.png", diff --git a/integrations/whatsapp/src/internal.ts b/integrations/whatsapp/src/internal.ts index b1f879d49..2ca9f398f 100644 --- a/integrations/whatsapp/src/internal.ts +++ b/integrations/whatsapp/src/internal.ts @@ -1,5 +1,5 @@ import type { - IntegrationMetadata, + ServiceMetadata, InternalIntegration, } from "@trigger.dev/integration-sdk"; import { WhatsAppWebhookIntegration } from "./internal/webhooks"; @@ -8,7 +8,7 @@ import { WhatsAppRequestIntegration } from "./internal/requests"; const webhooks = new WhatsAppWebhookIntegration(); const requests = new WhatsAppRequestIntegration(); -const metadata: IntegrationMetadata = { +const metadata: ServiceMetadata = { name: "WhatsApp Business", slug: "whatsapp", icon: "/integrations/whatsapp.png", diff --git a/packages/integration-sdk/src/types.ts b/packages/integration-sdk/src/types.ts index 8ab75445c..fd612cebd 100644 --- a/packages/integration-sdk/src/types.ts +++ b/packages/integration-sdk/src/types.ts @@ -109,12 +109,12 @@ export interface CacheService { } export type InternalIntegration = { - metadata: IntegrationMetadata; + metadata: ServiceMetadata; requests?: RequestIntegration; webhooks?: WebhookIntegration; }; -export type IntegrationMetadata = { +export type ServiceMetadata = { name: string; slug: string; icon: string; From e013c6faa9bcb7f28798832570b850edbdb4926b Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 14 Feb 2023 15:09:46 +0000 Subject: [PATCH 034/133] Renamed slug to service --- apps/webapp/app/components/integrations/AddApiKeyButton.tsx | 2 +- .../webapp/app/components/integrations/ConnectOAuthButton.tsx | 2 +- apps/webapp/app/models/integrations.server.ts | 4 ++-- apps/webapp/app/models/workflowRunPresenter.server.ts | 4 ++-- .../app/routes/__app/orgs/$organizationSlug/__org/index.tsx | 2 +- .../__app/orgs/$organizationSlug/__org/integrations.tsx | 2 +- .../__app/orgs/$organizationSlug/workflows/$workflowSlug.tsx | 4 ++-- apps/webapp/app/routes/resources/connection/index.tsx | 2 +- .../app/services/requests/performIntegrationRequest.server.ts | 2 +- apps/webapp/app/utils/integrationMetadata.ts | 2 +- integrations/github/src/internal.ts | 2 +- integrations/resend/src/internal.ts | 2 +- integrations/shopify/src/internal.ts | 2 +- integrations/slack/src/internal.ts | 2 +- integrations/whatsapp/src/internal.ts | 2 +- packages/integration-catalog/src/index.ts | 2 +- packages/integration-sdk/src/types.ts | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) diff --git a/apps/webapp/app/components/integrations/AddApiKeyButton.tsx b/apps/webapp/app/components/integrations/AddApiKeyButton.tsx index 3cb4aa75b..68c213233 100644 --- a/apps/webapp/app/components/integrations/AddApiKeyButton.tsx +++ b/apps/webapp/app/components/integrations/AddApiKeyButton.tsx @@ -86,7 +86,7 @@ export function AddApiKeyButton({ - + {sourceId && ( )} diff --git a/apps/webapp/app/components/integrations/ConnectOAuthButton.tsx b/apps/webapp/app/components/integrations/ConnectOAuthButton.tsx index 0134de2ff..88bc0a550 100644 --- a/apps/webapp/app/components/integrations/ConnectOAuthButton.tsx +++ b/apps/webapp/app/components/integrations/ConnectOAuthButton.tsx @@ -35,7 +35,7 @@ export function ConnectOAuthButton({ > - +