@novu/framework 2.0.0-canary.4 → 2.0.0-canary.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/handler-kv_Ed8ly.d.ts +4421 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +447 -118
- package/dist/servers/express.d.ts +1 -1
- package/dist/servers/express.js +16 -16
- package/dist/servers/h3.d.ts +1 -1
- package/dist/servers/h3.js +17 -17
- package/dist/servers/lambda.d.ts +1 -1
- package/dist/servers/lambda.js +15 -15
- package/dist/servers/next.d.ts +1 -1
- package/dist/servers/next.js +15 -15
- package/dist/servers/nuxt.d.ts +1 -1
- package/dist/servers/nuxt.js +17 -17
- package/dist/servers/remix.d.ts +1 -1
- package/dist/servers/remix.js +16 -16
- package/dist/servers/sveltekit.d.ts +1 -1
- package/dist/servers/sveltekit.js +16 -16
- package/package.json +1 -2
- package/dist/handler-RA4Feq8s.d.ts +0 -3912
package/dist/index.js
CHANGED
|
@@ -2,130 +2,459 @@
|
|
|
2
2
|
|
|
3
3
|
var jsonSchemaFaker = require('json-schema-faker');
|
|
4
4
|
var liquidjs = require('liquidjs');
|
|
5
|
-
var
|
|
5
|
+
var Ne = require('ora');
|
|
6
6
|
require('cross-fetch');
|
|
7
|
-
var
|
|
7
|
+
var F = require('chalk');
|
|
8
8
|
var shared = require('@novu/shared');
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
9
|
+
var ze = require('sanitize-html');
|
|
10
|
+
var It = require('ajv');
|
|
11
|
+
var Pt = require('ajv-formats');
|
|
12
12
|
var zodToJsonSchema = require('zod-to-json-schema');
|
|
13
13
|
var crypto = require('crypto');
|
|
14
14
|
|
|
15
15
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
16
|
|
|
17
|
-
var
|
|
18
|
-
var
|
|
19
|
-
var
|
|
20
|
-
var
|
|
21
|
-
var
|
|
17
|
+
var Ne__default = /*#__PURE__*/_interopDefault(Ne);
|
|
18
|
+
var F__default = /*#__PURE__*/_interopDefault(F);
|
|
19
|
+
var ze__default = /*#__PURE__*/_interopDefault(ze);
|
|
20
|
+
var It__default = /*#__PURE__*/_interopDefault(It);
|
|
21
|
+
var Pt__default = /*#__PURE__*/_interopDefault(Pt);
|
|
22
22
|
|
|
23
|
-
var V=(i=>(i.TRIGGER="trigger",i.EXECUTE="execute",i.PREVIEW="preview",i))(V||{}),X=(i=>(i.DISCOVER="discover",i.HEALTH_CHECK="health-check",i.CODE="code",i))(X||{});var st=(t=>(t.SYNC="/v1/bridge/sync",t.DIFF="/v1/bridge/diff",t))(st||{}),Me=5,Ce=1500;var at=(s=>(s.EVERY_SECOND="* * * * * *",s.EVERY_5_SECONDS="*/5 * * * * *",s.EVERY_10_SECONDS="*/10 * * * * *",s.EVERY_30_SECONDS="*/30 * * * * *",s.EVERY_MINUTE="*/1 * * * *",s.EVERY_5_MINUTES="0 */5 * * * *",s.EVERY_10_MINUTES="0 */10 * * * *",s.EVERY_30_MINUTES="0 */30 * * * *",s.EVERY_HOUR="0 0-23/1 * * *",s.EVERY_2_HOURS="0 0-23/2 * * *",s.EVERY_3_HOURS="0 0-23/3 * * *",s.EVERY_4_HOURS="0 0-23/4 * * *",s.EVERY_5_HOURS="0 0-23/5 * * *",s.EVERY_6_HOURS="0 0-23/6 * * *",s.EVERY_7_HOURS="0 0-23/7 * * *",s.EVERY_8_HOURS="0 0-23/8 * * *",s.EVERY_9_HOURS="0 0-23/9 * * *",s.EVERY_10_HOURS="0 0-23/10 * * *",s.EVERY_11_HOURS="0 0-23/11 * * *",s.EVERY_12_HOURS="0 0-23/12 * * *",s.EVERY_DAY_AT_1AM="0 01 * * *",s.EVERY_DAY_AT_2AM="0 02 * * *",s.EVERY_DAY_AT_3AM="0 03 * * *",s.EVERY_DAY_AT_4AM="0 04 * * *",s.EVERY_DAY_AT_5AM="0 05 * * *",s.EVERY_DAY_AT_6AM="0 06 * * *",s.EVERY_DAY_AT_7AM="0 07 * * *",s.EVERY_DAY_AT_8AM="0 08 * * *",s.EVERY_DAY_AT_9AM="0 09 * * *",s.EVERY_DAY_AT_10AM="0 10 * * *",s.EVERY_DAY_AT_11AM="0 11 * * *",s.EVERY_DAY_AT_NOON="0 12 * * *",s.EVERY_DAY_AT_1PM="0 13 * * *",s.EVERY_DAY_AT_2PM="0 14 * * *",s.EVERY_DAY_AT_3PM="0 15 * * *",s.EVERY_DAY_AT_4PM="0 16 * * *",s.EVERY_DAY_AT_5PM="0 17 * * *",s.EVERY_DAY_AT_6PM="0 18 * * *",s.EVERY_DAY_AT_7PM="0 19 * * *",s.EVERY_DAY_AT_8PM="0 20 * * *",s.EVERY_DAY_AT_9PM="0 21 * * *",s.EVERY_DAY_AT_10PM="0 22 * * *",s.EVERY_DAY_AT_11PM="0 23 * * *",s.EVERY_DAY_AT_MIDNIGHT="0 0 * * *",s.EVERY_WEEK="0 0 * * 0",s.EVERY_WEEKDAY="0 0 * * 1-5",s.EVERY_WEEKEND="0 0 * * 6,0",s.EVERY_1ST_DAY_OF_MONTH_AT_MIDNIGHT="0 0 1 * *",s.EVERY_1ST_DAY_OF_MONTH_AT_NOON="0 12 1 * *",s.EVERY_2ND_HOUR="0 */2 * * *",s.EVERY_2ND_HOUR_FROM_1AM_THROUGH_11PM="0 1-23/2 * * *",s.EVERY_2ND_MONTH="0 0 1 */2 *",s.EVERY_QUARTER="0 0 1 */3 *",s.EVERY_6_MONTHS="0 0 1 */6 *",s.EVERY_YEAR="0 0 1 0 *",s.EVERY_30_MINUTES_BETWEEN_9AM_AND_5PM="0 */30 9-17 * * *",s.EVERY_30_MINUTES_BETWEEN_9AM_AND_6PM="0 */30 9-18 * * *",s.EVERY_30_MINUTES_BETWEEN_10AM_AND_7PM="0 */30 10-19 * * *",s.MONDAY_TO_FRIDAY_AT_1AM="0 0 01 * * 1-5",s.MONDAY_TO_FRIDAY_AT_2AM="0 0 02 * * 1-5",s.MONDAY_TO_FRIDAY_AT_3AM="0 0 03 * * 1-5",s.MONDAY_TO_FRIDAY_AT_4AM="0 0 04 * * 1-5",s.MONDAY_TO_FRIDAY_AT_5AM="0 0 05 * * 1-5",s.MONDAY_TO_FRIDAY_AT_6AM="0 0 06 * * 1-5",s.MONDAY_TO_FRIDAY_AT_7AM="0 0 07 * * 1-5",s.MONDAY_TO_FRIDAY_AT_8AM="0 0 08 * * 1-5",s.MONDAY_TO_FRIDAY_AT_9AM="0 0 09 * * 1-5",s.MONDAY_TO_FRIDAY_AT_09_30AM="0 30 09 * * 1-5",s.MONDAY_TO_FRIDAY_AT_10AM="0 0 10 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11AM="0 0 11 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11_30AM="0 30 11 * * 1-5",s.MONDAY_TO_FRIDAY_AT_12PM="0 0 12 * * 1-5",s.MONDAY_TO_FRIDAY_AT_1PM="0 0 13 * * 1-5",s.MONDAY_TO_FRIDAY_AT_2PM="0 0 14 * * 1-5",s.MONDAY_TO_FRIDAY_AT_3PM="0 0 15 * * 1-5",s.MONDAY_TO_FRIDAY_AT_4PM="0 0 16 * * 1-5",s.MONDAY_TO_FRIDAY_AT_5PM="0 0 17 * * 1-5",s.MONDAY_TO_FRIDAY_AT_6PM="0 0 18 * * 1-5",s.MONDAY_TO_FRIDAY_AT_7PM="0 0 19 * * 1-5",s.MONDAY_TO_FRIDAY_AT_8PM="0 0 20 * * 1-5",s.MONDAY_TO_FRIDAY_AT_9PM="0 0 21 * * 1-5",s.MONDAY_TO_FRIDAY_AT_10PM="0 0 22 * * 1-5",s.MONDAY_TO_FRIDAY_AT_11PM="0 0 23 * * 1-5",s))(at||{});var k=(m=>(m.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",m.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",m.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",m.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",m.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",m.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",m.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",m.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",m.STEP_NOT_FOUND_ERROR="StepNotFoundError",m.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",m.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",m.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",m.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",m.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",m.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",m.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",m.INVALID_ACTION_ERROR="InvalidActionError",m.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",m.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",m.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",m.SIGNATURE_INVALID_ERROR="SignatureInvalidError",m.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",m.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",m.BRIDGE_ERROR="BridgeError",m.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",m.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",m))(k||{});var ve=(f=>(f.NOVU_SIGNATURE="novu-signature",f.NOVU_ANONYMOUS="novu-anonymous",f.NOVU_SIGNATURE_DEPRECATED="x-novu-signature",f.NOVU_ANONYMOUS_DEPRECATED="x-novu-anonymous",f.NOVU_FRAMEWORK_SDK="novu-framework-sdk",f.NOVU_FRAMEWORK_SERVER="novu-framework-server",f.NOVU_FRAMEWORK_VERSION="novu-framework-version",f.USER_AGENT="user-agent",f.CONTENT_TYPE="content-type",f.ACCESS_CONTROL_ALLOW_ORIGIN="access-control-allow-origin",f.ACCESS_CONTROL_ALLOW_METHODS="access-control-allow-methods",f.ACCESS_CONTROL_ALLOW_HEADERS="access-control-allow-headers",f.ACCESS_CONTROL_MAX_AGE="access-control-max-age",f))(ve||{});var z=(i=>(i.POST="POST",i.GET="GET",i.OPTIONS="OPTIONS",i))(z||{});var je=(n=>(n.WORKFLOW_ID="workflowId",n.STEP_ID="stepId",n.ACTION="action",n.SOURCE="source",n))(je||{});var J=(o=>(o[o.CONTINUE=100]="CONTINUE",o[o.SWITCHING_PROTOCOLS=101]="SWITCHING_PROTOCOLS",o[o.PROCESSING=102]="PROCESSING",o[o.EARLYHINTS=103]="EARLYHINTS",o[o.OK=200]="OK",o[o.CREATED=201]="CREATED",o[o.ACCEPTED=202]="ACCEPTED",o[o.NON_AUTHORITATIVE_INFORMATION=203]="NON_AUTHORITATIVE_INFORMATION",o[o.NO_CONTENT=204]="NO_CONTENT",o[o.RESET_CONTENT=205]="RESET_CONTENT",o[o.PARTIAL_CONTENT=206]="PARTIAL_CONTENT",o[o.AMBIGUOUS=300]="AMBIGUOUS",o[o.MOVED_PERMANENTLY=301]="MOVED_PERMANENTLY",o[o.FOUND=302]="FOUND",o[o.SEE_OTHER=303]="SEE_OTHER",o[o.NOT_MODIFIED=304]="NOT_MODIFIED",o[o.TEMPORARY_REDIRECT=307]="TEMPORARY_REDIRECT",o[o.PERMANENT_REDIRECT=308]="PERMANENT_REDIRECT",o[o.BAD_REQUEST=400]="BAD_REQUEST",o[o.UNAUTHORIZED=401]="UNAUTHORIZED",o[o.PAYMENT_REQUIRED=402]="PAYMENT_REQUIRED",o[o.FORBIDDEN=403]="FORBIDDEN",o[o.NOT_FOUND=404]="NOT_FOUND",o[o.METHOD_NOT_ALLOWED=405]="METHOD_NOT_ALLOWED",o[o.NOT_ACCEPTABLE=406]="NOT_ACCEPTABLE",o[o.PROXY_AUTHENTICATION_REQUIRED=407]="PROXY_AUTHENTICATION_REQUIRED",o[o.REQUEST_TIMEOUT=408]="REQUEST_TIMEOUT",o[o.CONFLICT=409]="CONFLICT",o[o.GONE=410]="GONE",o[o.LENGTH_REQUIRED=411]="LENGTH_REQUIRED",o[o.PRECONDITION_FAILED=412]="PRECONDITION_FAILED",o[o.PAYLOAD_TOO_LARGE=413]="PAYLOAD_TOO_LARGE",o[o.URI_TOO_LONG=414]="URI_TOO_LONG",o[o.UNSUPPORTED_MEDIA_TYPE=415]="UNSUPPORTED_MEDIA_TYPE",o[o.REQUESTED_RANGE_NOT_SATISFIABLE=416]="REQUESTED_RANGE_NOT_SATISFIABLE",o[o.EXPECTATION_FAILED=417]="EXPECTATION_FAILED",o[o.I_AM_A_TEAPOT=418]="I_AM_A_TEAPOT",o[o.MISDIRECTED=421]="MISDIRECTED",o[o.UNPROCESSABLE_ENTITY=422]="UNPROCESSABLE_ENTITY",o[o.FAILED_DEPENDENCY=424]="FAILED_DEPENDENCY",o[o.PRECONDITION_REQUIRED=428]="PRECONDITION_REQUIRED",o[o.TOO_MANY_REQUESTS=429]="TOO_MANY_REQUESTS",o[o.INTERNAL_SERVER_ERROR=500]="INTERNAL_SERVER_ERROR",o[o.NOT_IMPLEMENTED=501]="NOT_IMPLEMENTED",o[o.BAD_GATEWAY=502]="BAD_GATEWAY",o[o.SERVICE_UNAVAILABLE=503]="SERVICE_UNAVAILABLE",o[o.GATEWAY_TIMEOUT=504]="GATEWAY_TIMEOUT",o[o.HTTP_VERSION_NOT_SUPPORTED=505]="HTTP_VERSION_NOT_SUPPORTED",o))(J||{}),ei=[500];var Q=(i=>(i.WORKFLOW="workflow",i.PROVIDER="provider",i.STEP="step",i))(Q||{});var P=(a=>(a.EMAIL="email",a.SMS="sms",a.PUSH="push",a.CHAT="chat",a.IN_APP="in_app",a))(P||{}),lt=(i=>(i.DIGEST="digest",i.DELAY="delay",i.CUSTOM="custom",i))(lt||{});var $e="2.0.0-canary.4";var L=$e,Z="2024-06-26";var R=class extends Error{data},H=class extends R{statusCode=404},x=class extends R{statusCode=400},v=class extends R{statusCode=401},C=class extends R{statusCode=500},ee=class extends R{statusCode=409};var te=class extends x{code="ExecutionStateCorruptError";constructor(e,t){super(`Workflow with id: \`${e}\` has a corrupt state. Step with id: \`${t}\` does not exist. Please provide the missing state.`),this.data={workflowId:e,stepId:t};}},q=class extends x{code="ExecutionEventPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct event payload.`),this.data=t;}},ie=class extends x{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},oe=class extends x{code="ExecutionStateControlInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid \`controls\`. Please provide the correct step controls.`),this.data=i;}},ne=class extends x{code="ExecutionStateOutputInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid output. Please provide the correct step output.`),this.data=i;}},re=class extends x{code="ExecutionStateResultInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid result. Please provide the correct step result.`),this.data=i;}},se=class extends x{code="ExecutionProviderOutputInvalidError";constructor(e,t,i,n){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` and provider with id: \`${i}\` has invalid output. Please provide the correct provider output.`),this.data=n;}},ae=class extends x{code="WorkflowPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct payload.`),this.data=t;}},le=class extends R{statusCode;data;code;constructor(e,t,i){super(),this.data={message:i},this.statusCode=e,this.code=t;}};var Ue=async()=>{if(process.env.NOVU_BRIDGE_ORIGIN)return `${process.env.NOVU_BRIDGE_ORIGIN}/api/novu`;if(process.env.NEXT_PUBLIC_VERCEL_ENV==="preview"&&process.env.NEXT_PUBLIC_VERCEL_URL)return `https://${process.env.NEXT_PUBLIC_VERCEL_URL}/api/novu`;try{if(process.env.NODE_ENV==="development"){let e=await(await fetch("http://localhost:2022/.well-known/novu")).json();return `${e.tunnelOrigin}${e.route}`}}catch(r){console.error(r);}return ""};var u={info:r=>j__default.default.blue(r),warning:r=>j__default.default.yellow(r),error:r=>j__default.default.red(r),success:r=>j__default.default.green(r),underline:r=>j__default.default.underline(r),bold:r=>j__default.default.bold(r)},_={SUCCESS:u.success("\u2714"),ERROR:u.error("\u2717"),WARNING:u.warning("\u26A0"),INFO:u.info("\u2139"),ARROW:u.bold("\u2192"),MOCK:u.info("\u25CB"),HYDRATED:u.bold(u.info("\u2192")),STEP:u.info("\u03C3"),ACTION:u.info("\u03B1"),DURATION:u.info("\u0394"),PROVIDER:u.info("\u2699"),OUTPUT:u.info("\u21E2"),INPUT:u.info("\u21E0"),WORKFLOW:u.info("\u03C9"),STATE:u.info("\u03C3"),EXECUTE:u.info("\u03B5"),PREVIEW:u.info("\u03C1")};var Oe=r=>Object.values(r).map(e=>`\`${e}\``).join(", "),ce=r=>r.replaceAll(/(\w)(\w*)/g,(e,t,i)=>t.toUpperCase()+i.toLowerCase()).replaceAll(/[\s-]+/g,"");var pe=(r,e="https://api.novu.co")=>{let t=process.env.NOVU_API_URL||e;return {post:async(i,n)=>{let a=await fetch(t+"/v1"+i,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${r}`},body:JSON.stringify(n)}),c=await a.json();if(a.ok)return c;throw shared.checkIsResponseError(c)?new le(c.statusCode,c.error,c.message):new $("Error processing API request to Novu Cloud from Bridge application.")},delete:async i=>(await fetch(t+"/v1"+i,{method:"DELETE",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${r}`}})).json()}};var dt={allowedTags:Fe__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Ye=r=>{if(!r)return r;let e=new RegExp("^<!DOCTYPE .*?>"),t=r.match(e),i=Fe__default.default(r,dt);return t?t[0]+i:i},de=r=>Object.keys(r).reduce((e,t)=>{let i=r[t];return typeof i=="string"?e[t]=Ye(i):Array.isArray(i)?e[t]=i.map(n=>typeof n=="string"?Ye(n):typeof n=="object"?de(n):n):typeof i=="object"&&i!==null?e[t]=de(i):e[t]=i,e},{});var he=class extends R{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${Oe(z)}`},W=class extends x{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${Oe(t)}`);}},ue=class extends x{code="MissingSecretKeyError";constructor(){super("Missing secret key. Set the `NOVU_SECRET_KEY` environment variable or pass `secretKey` to the client options.");}};var $=class extends C{code="BridgeError";message="Something went wrong. Please try again later."};var U=class extends ee{constructor(e,t){super(`${ce(e)} with id: \`${t}\` already exists. Please use a different id.`);}},O=class extends H{constructor(e,t){super(`${ce(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},Y=class extends C{constructor(e,t){super(`Failed to execute ${ce(e)} with id: \`${t}\`. Please try again later.`);}};var me=class extends O{code="ProviderNotFoundError";constructor(e){super("provider",e);}},fe=class extends Y{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var ye=class extends v{code="SignatureMismatchError";constructor(){super("Signature does not match the expected signature. Please ensure the signature provided in the `novu-signature` header is correct and try again.");}},ge=class extends v{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},_e=class extends v{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},be=class extends v{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},we=class extends v{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var Te=class extends O{code="StepNotFoundError";constructor(e){super("step",e);}},xe=class extends U{code="StepAlreadyExistsError";constructor(e){super("step",e);}};var B=class extends O{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},ke=class extends U{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var Re=class{ajv;compiledSchemas;constructor(){this.ajv=new ht__default.default({useDefaults:!0,removeAdditional:"all"}),ut__default.default(this.ajv),this.compiledSchemas=new Map;}isSchema(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.oneOf}async validate(e,t){let i=this.compiledSchemas.get(t);return i||(i=this.ajv.compile(t),this.compiledSchemas.set(t,i)),i(e)?{success:!0,data:e}:{success:!1,errors:i.errors.map(a=>({path:a.instancePath,message:a.message}))}}transformToJsonSchema(e){return e}};var Se=class{isSchema(e){return e.safeParseAsync!==void 0}async validate(e,t){let i=t.safeParse(e);return i.success?{success:!0,data:i.data}:{success:!1,errors:i.error.errors.map(n=>({path:`/${n.path.join("/")}`,message:n.message}))}}transformToJsonSchema(e){try{return zodToJsonSchema.zodToJsonSchema(e)}catch(t){throw t?.message?.includes("Cannot find module")&&console.error("Tried to use a zod schema in @novu/framework without `zod-to-json-schema` installed. Please install it by running `npm install zod-to-json-schema`."),t}}};var Ve=[new Se,new Re],Ee=async(r,e)=>{for(let t of Ve)if(t.isSchema(r))return t.validate(e,r);throw new Error("Invalid schema")},b=r=>{for(let e of Ve)if(e.isSchema(r))return e.transformToJsonSchema(r);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function yt(){return ["development",void 0].includes(process.env.NODE_ENV)}var G=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=L;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!yt()};return t.secretKey=e?.secretKey||process.env.NOVU_SECRET_KEY||process.env.NOVU_API_KEY,e?.strictAuthentication!==void 0?t.strictAuthentication=e.strictAuthentication:process.env.NOVU_STRICT_AUTHENTICATION_ENABLED!==void 0&&(t.strictAuthentication=process.env.NOVU_STRICT_AUTHENTICATION_ENABLED==="true"),t}addWorkflows(e){for(let t of e){if(this.discoveredWorkflows.some(i=>i.workflowId===t.definition.workflowId))throw new ke(t.definition.workflowId);this.discoveredWorkflows.push(t.definition);}}healthCheck(){let e=this.discoveredWorkflows.length,t=this.discoveredWorkflows.reduce((i,n)=>i+n.steps.length,0);return {status:"ok",sdkVersion:L,frameworkVersion:Z,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(i=>i.workflowId===e);if(t)return t;throw new B(e)}getStep(e,t){let n=this.getWorkflow(e).steps.find(a=>a.stepId===t);if(n)return n;throw new Te(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(b(e))}async validate(e,t,i,n,a,c,p){let h=await Ee(t,e);if(h.success)return h.data;switch(i){case"event":this.throwInvalidEvent(n,a,h.errors);case"step":this.throwInvalidStep(c,n,a,h.errors);case"provider":this.throwInvalidProvider(c,p,n,a,h.errors);default:throw new Error(`Invalid component: '${i}'`)}}throwInvalidProvider(e,t,i,n,a){if(!e)throw new Error("stepId is required");if(!t)throw new Error("providerId is required");switch(i){case"output":throw new se(n,e,t,a);default:throw new Error(`Invalid payload type: '${i}'`)}}throwInvalidStep(e,t,i,n){if(!e)throw new Error("stepId is required");switch(t){case"output":throw new ne(i,e,n);case"result":throw new re(i,e,n);case"controls":throw new oe(i,e,n);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,i){switch(e){case"controls":throw new ie(t,i);case"payload":throw new q(t,i);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(i,n,a)=>{let c=this.getStep(e.workflowId,i),p=gt(e),h=await this.createStepControls(c,p),y=e.action==="preview";if(!y&&await this.shouldSkip(a?.skip,h))return t({options:{skip:!0}}),{};let w=this.previewStep.bind(this),E=this.executeStep.bind(this),f=await(y?w:E)(e,{...c,providers:c.providers.map(M=>{let F=a?.providers?.[M.type];if(!F)throw new me(M.type);return {...M,resolve:F}}),resolve:n});return Object.values(P).includes(c.type)&&(f={...f,outputs:de(f.outputs)}),i===e.stepId&&t(f),f.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let n=`${{execute:"Executing",preview:"Previewing"}[e.action]} workflowId:`;console.log(`
|
|
24
|
-
${
|
|
25
|
-
${
|
|
26
|
-
`);}async executeProviders(e,t,i){return t.providers.reduce(async(n,a)=>{let c=await n,p=this.previewProvider.bind(this),
|
|
27
|
-
${c.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let i=Ae__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let n=await this.createStepControls(t,e),a=await this.compileControls(n,e),c=await t.resolve(a),p=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),h=await this.executeProviders(e,t,p);return i.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:p,providers:h}}catch(n){throw i.stopAndPersist({prefixText:"",symbol:_.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),n}}else {let i=Ae__default.default({indent:1}).start(`Hydrating stepId: \`${t.stepId}\``);try{let n=e.state.find(a=>a.stepId===t.stepId);if(n){let a=await this.validate(n.outputs,t.results.unknownSchema,"step","result",e.workflowId,t.stepId);return i.stopAndPersist({symbol:_.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:a,providers:await this.executeProviders(e,t,a)}}else throw new te(e.workflowId,t.stepId)}catch(n){throw i.stopAndPersist({symbol:_.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),n}}}async compileControls(e,t){let i=this.templateEngine.parse(JSON.stringify(e)),n=await this.templateEngine.render(i,{...t.payload||t.data,subscriber:t.subscriber});return JSON.parse(n)}async createStepControls(e,t){let i=t.controls||t.inputs;return await this.validate(i,e.controls.unknownSchema,"step","controls",t.workflowId,e.stepId)}async previewStep(e,t){let i=Ae__default.default({indent:1}).start(`Previewing stepId: \`${t.stepId}\``);try{if(e.stepId===t.stepId){let n=await this.createStepControls(t,e),a=await this.compileControls(n,e),c=await t.resolve(a),p=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return i.stopAndPersist({symbol:_.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:p,providers:await this.executeProviders(e,t,p)}}else {let n=this.mock(t.results.schema);return i.stopAndPersist({symbol:_.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:n,providers:await this.executeProviders(e,t,n)}}}catch(n){throw i.stopAndPersist({symbol:_.ERROR,text:`Failed to preview stepId: \`${t.stepId}\``}),n}}getStepCode(e,t){return {code:this.getStep(e,t).resolve.toString()}}getWorkflowCode(e){return {code:this.getWorkflow(e).execute.toString()}}getCode(e,t){let i;if(e)t?i=this.getStepCode(e,t):i=this.getWorkflowCode(e);else throw new B(e);return i}};function gt(r){return JSON.parse(JSON.stringify(r))}var Pe=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new G,this.client.addWorkflows(e.workflows),this.http=pe(this.client.secretKey),this.frameworkName=e.frameworkName,this.hmacEnabled=this.client.strictAuthentication;}createHandler(){return async(...e)=>{let t=await this.handler(...e),i=await this.handleAction({actions:t});return t.transformResponse(i)}}getStaticHeaders(){let e=`novu-framework:v${this.client.version}`;return {"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST","access-control-allow-headers":"*","access-control-max-age":"604800","novu-framework-version":Z,"novu-framework-sdk":L,"novu-framework-server":this.frameworkName,"user-agent":e}}createResponse(e,t){return {status:e,body:JSON.stringify(t),headers:{...this.getStaticHeaders()}}}createError(e){return {status:e.statusCode,body:JSON.stringify({message:e.message,data:e.data,code:e.code}),headers:this.getStaticHeaders()}}async handleAction({actions:e}){let t=await e.url(),i=await e.method(),n=t.searchParams.get("action")||"",a=t.searchParams.get("workflowId")||"",c=t.searchParams.get("stepId")||"",p=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",h={};try{i==="POST"&&(h=await e.body());}catch{}try{n!=="health-check"&&this.validateHmac(h,p);let y=this.getPostActionMap(h,a,c,n),w=this.getGetActionMap(a,c);if(i==="POST")return await this.handlePostAction(n,y);if(i==="GET")return await this.handleGetAction(n,w);if(i==="OPTIONS")return this.createResponse(200,{})}catch(y){return this.handleError(y)}return this.createError(new he(i))}getPostActionMap(e,t,i,n){return {trigger:this.triggerAction({workflowId:t,...e}),execute:async()=>{let a=await this.client.executeWorkflow({...e,workflowId:t,stepId:i,action:n});return this.createResponse(200,a)},preview:async()=>{let a=await this.client.executeWorkflow({...e,workflowId:t,stepId:i,action:n});return this.createResponse(200,a)}}}triggerAction(e){return async()=>{let t={name:e.workflowId,to:e.to,payload:e?.payload||{},transactionId:e.transactionId,overrides:e.overrides||{},...e.actor&&{actor:e.actor},...e.tenant&&{tenant:e.tenant},...e.bridgeUrl&&{bridgeUrl:e.bridgeUrl},...e.controls&&{controls:e.controls}},i=await this.http.post("/events/trigger",t);return this.createResponse(200,i)}}getGetActionMap(e,t){return {discover:async()=>{let i=await this.client.discover();return this.createResponse(200,i)},"health-check":async()=>{let i=await this.client.healthCheck();return this.createResponse(200,i)},code:async()=>{let i=await this.client.getCode(e,t);return this.createResponse(200,i)}}}async handlePostAction(e,t){if(Object.values(V).includes(e)){let i=t[e];return i()}else throw new W(e,V)}async handleGetAction(e,t){if(Object.values(X).includes(e)){let i=t[e];return i()}else throw new W(e,X)}isBridgeError(e){return Object.values(k).includes(e?.code)}isPlatformError(e){return e?.statusCode>=400&&e?.statusCode<500}handleError(e){return this.isBridgeError(e)?(e.statusCode===500&&console.error(e),this.createError(e)):this.isPlatformError(e)?this.createError(e):(console.error(e),this.createError(new $))}validateHmac(e,t){if(!this.hmacEnabled)return;if(!t)throw new ge;if(!this.client.secretKey)throw new we;let[i,n]=t.split(",");if(!i||!n)throw new _e;let[a,c]=i.split("="),[p,h]=n.split("=");if(Number(a)<Date.now()-1500)throw new be;if(!(this.hashHmac(this.client.secretKey,`${c}.${JSON.stringify(e)}`)===h))throw new ye}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var l={output:{type:"object",properties:{},required:[],additionalProperties:!0}};var bt={type:"object",properties:{webhookUrl:{type:"string",format:"uri"},text:{type:"string"},blocks:{type:"array",items:{type:"object",properties:{type:{enum:["image","context","actions","divider","section","input","file","header","video","rich_text"]}},required:["type"],additionalProperties:!0,allOf:[{if:{properties:{type:{const:"image"}}},then:{$ref:"#/definitions/ImageBlock"}},{if:{properties:{type:{const:"context"}}},then:{$ref:"#/definitions/ContextBlock"}},{if:{properties:{type:{const:"actions"}}},then:{$ref:"#/definitions/ActionsBlock"}},{if:{properties:{type:{const:"divider"}}},then:{$ref:"#/definitions/DividerBlock"}},{if:{properties:{type:{const:"section"}}},then:{$ref:"#/definitions/SectionBlock"}},{if:{properties:{type:{const:"Input"}}},then:{$ref:"#/definitions/InputBlock"}},{if:{properties:{type:{const:"Video"}}},then:{$ref:"#/definitions/VideoBlock"}},{if:{properties:{type:{const:"rich_text"}}},then:{$ref:"#/definitions/RichTextBlock"}}]}}},definitions:{KnownBlock:{oneOf:[{$ref:"#/definitions/ImageBlock"},{$ref:"#/definitions/ContextBlock"},{$ref:"#/definitions/ActionsBlock"},{$ref:"#/definitions/DividerBlock"},{$ref:"#/definitions/SectionBlock"},{$ref:"#/definitions/InputBlock"},{$ref:"#/definitions/FileBlock"},{$ref:"#/definitions/HeaderBlock"},{$ref:"#/definitions/VideoBlock"},{$ref:"#/definitions/RichTextBlock"}]},ImageBlock:{type:"object",properties:{type:{type:"string",const:"image",description:"The type of block. For an image block, `type` is always `image`."},block_id:{type:"string"},image_url:{type:"string",description:"The URL of the image to be displayed. Maximum length for this field is 3000 characters."},alt_text:{type:"string",description:`A plain-text summary of the image. This should not contain any markup.
|
|
28
|
-
Maximum length for this field is 2000 characters.`},title:{$ref:"#/definitions/PlainTextElement",description:`An optional title for the image in the form of a {@link PlainTextElement } object.
|
|
29
|
-
Maximum length for the text in this field is 2000 characters.`}},required:["alt_text","image_url","type"],additionalProperties:!0,description:"Displays an image. A simple image block, designed to make those cat photos really pop."},PlainTextElement:{type:"object",properties:{type:{type:"string",const:"plain_text",description:"The formatting to use for this text object."},text:{type:"string",description:"The text for the block. The minimum length is 1 and maximum length is 3000 characters."},emoji:{type:"boolean",description:"Indicates whether emojis in a text field should be escaped into the colon emoji format."}},required:["type","text"],additionalProperties:!0,description:"Defines an object containing some text."},ContextBlock:{type:"object",properties:{type:{type:"string",const:"context",description:"The type of block. For a context block, `type` is always `context`."},block_id:{type:"string"},elements:{type:"array",items:{anyOf:[{$ref:"#/definitions/ImageElement"},{$ref:"#/definitions/PlainTextElement"},{$ref:"#/definitions/MrkdwnElement"}]},description:`An array of {@link ImageElement }, {@link PlainTextElement } or {@link MrkdwnElement } objects.
|
|
30
|
-
Maximum number of items is 10.`}},required:["elements","type"],additionalProperties:!0,description:"Displays contextual info, which can include both images and text."},ImageElement:{type:"object",properties:{type:{type:"string",const:"image",description:"The type of element. In this case `type` is always `image`."},image_url:{type:"string",description:"The URL of the image to be displayed."},alt_text:{type:"string",description:"A plain-text summary of the image. This should not contain any markup."}},required:["type","image_url","alt_text"],additionalProperties:!0,description:"Displays an image as part of a larger block of content. Use this `image` block if you want a block with\nonly an image in it."},MrkdwnElement:{type:"object",properties:{type:{type:"string",const:"mrkdwn",description:"The formatting to use for this text object."},text:{type:"string",description:`The text for the block. This field accepts any of the standard text formatting markup.
|
|
31
|
-
The minimum length is 1 and maximum length is 3000 characters.`},verbatim:{type:"boolean",description:"When set to `false` (as is default) URLs will be auto-converted into links, conversation names will\nbe converted to links, and certain mentions will be {@link https://api.slack.com/reference/surfaces/formatting#automatic-parsing automatically parsed}.\nUsing a value of `true` will skip any preprocessing of this nature, although you can still include\n{@link https://api.slack.com/reference/surfaces/formatting#advanced manual parsing strings}."}},required:["type","text"],additionalProperties:!0,description:"Defines an object containing some text."},ActionsBlock:{type:"object",properties:{type:{type:"string",const:"actions",description:"The type of block. For an actions block, `type` is always `actions`."},block_id:{type:"string",description:"A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated.\nYou can use this `block_id` when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}.\nMaximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of\na message. If a message is updated, use a new `block_id`."},elements:{type:"array",items:{anyOf:[{$ref:"#/definitions/Button"},{$ref:"#/definitions/Checkboxes"},{$ref:"#/definitions/Datepicker"},{$ref:"#/definitions/DateTimepicker"},{$ref:"#/definitions/MultiSelect"},{$ref:"#/definitions/Overflow"},{$ref:"#/definitions/RadioButtons"},{$ref:"#/definitions/Select"},{$ref:"#/definitions/Timepicker"},{$ref:"#/definitions/WorkflowButton"},{$ref:"#/definitions/RichTextInput"}]},description:`An array of {@link InteractiveElements } objects.
|
|
32
|
-
There is a maximum of 25 elements in each action block.`}},required:["elements","type"],additionalProperties:!0,description:"Holds multiple interactive elements."},Button:{type:"object",properties:{confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
33
|
-
with.`},type:{type:"string",const:"button",description:"The type of element. In this case `type` is always `button`."},action_id:{type:"string"},text:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } that defines the button's text. `text` may truncate with ~30 characters.\nMaximum length for the text in this field is 75 characters."},value:{type:"string",description:`The value to send along with the {@link https://api.slack.com/interactivity/handling#payloads interaction payload}.
|
|
34
|
-
Maximum length for this field is 2000 characters.`},url:{type:"string",description:"A URL to load in the user's browser when the button is clicked. Maximum length for this field is 3000\ncharacters. If you're using `url`, you'll still receive an {@link https://api.slack.com/interactivity/handling#payloads interaction payload}\nand will need to send an {@link https://api.slack.com/interactivity/handling#acknowledgment_response acknowledgement response}."},style:{type:"string",enum:["danger","primary"],description:"Decorates buttons with alternative visual color schemes. Use this option with restraint.\n`primary` gives buttons a green outline and text, ideal for affirmation or confirmation actions. `primary` should\nonly be used for one button within a set.\n`danger` gives buttons a red outline and text, and should be used when the action is destructive. Use `danger` even\nmore sparingly than primary.\nIf you don't include this field, the default button style will be used."},accessibility_label:{type:"string",description:"A label for longer descriptive text about a button element. This label will be read out by screen\nreaders instead of the button `text` object. Maximum length for this field is 75 characters."}},required:["text","type"],additionalProperties:!0,description:"Allows users a direct path to performing basic actions."},Actionable:{type:"object",additionalProperties:!0,properties:{type:{type:"string"},action_id:{type:"string"}},required:["type"]},Action:{type:"object",properties:{type:{type:"string"},action_id:{type:"string"}},required:["type"],additionalProperties:!0},Confirmable:{type:"object",properties:{confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
35
|
-
with.`}},additionalProperties:!0},ConfirmationDialog:{type:"object",additionalProperties:!0,properties:{title:{$ref:"#/definitions/PlainTextElement",description:`A {@link PlainTextElement } text object that defines the dialog's title.
|
|
36
|
-
Maximum length for this field is 100 characters.`},text:{anyOf:[{$ref:"#/definitions/PlainTextElement"},{$ref:"#/definitions/MrkdwnElement"}],description:"A {@link PlainTextElement } text object that defines the explanatory text that appears in the confirm\ndialog. Maximum length for the `text` in this field is 300 characters."},confirm:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } text object to define the text of the button that confirms the action.\nMaximum length for the `text` in this field is 30 characters."},deny:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } text object to define the text of the button that cancels the action.\nMaximum length for the `text` in this field is 30 characters."},style:{type:"string",enum:["primary","danger"],description:"Defines the color scheme applied to the `confirm` button. A value of `danger` will display the button\nwith a red background on desktop, or red text on mobile. A value of `primary` will display the button with a green\nbackground on desktop, or blue text on mobile. If this field is not provided, the default value will be `primary`."}},required:["text"],description:"Defines a dialog that adds a confirmation step to interactive elements."},Confirm:{type:"object",properties:{title:{$ref:"#/definitions/PlainTextElement",description:`A {@link PlainTextElement } text object that defines the dialog's title.
|
|
37
|
-
Maximum length for this field is 100 characters.`},text:{anyOf:[{$ref:"#/definitions/PlainTextElement"},{$ref:"#/definitions/MrkdwnElement"}],description:"A {@link PlainTextElement } text object that defines the explanatory text that appears in the confirm\ndialog. Maximum length for the `text` in this field is 300 characters."},confirm:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } text object to define the text of the button that confirms the action.\nMaximum length for the `text` in this field is 30 characters."},deny:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } text object to define the text of the button that cancels the action.\nMaximum length for the `text` in this field is 30 characters."},style:{type:"string",enum:["primary","danger"],description:"Defines the color scheme applied to the `confirm` button. A value of `danger` will display the button\nwith a red background on desktop, or red text on mobile. A value of `primary` will display the button with a green\nbackground on desktop, or blue text on mobile. If this field is not provided, the default value will be `primary`."}},required:["text"],additionalProperties:!0,description:"Defines a dialog that adds a confirmation step to interactive elements."},Checkboxes:{type:"object",properties:{focus_on_load:{type:"boolean"},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
38
|
-
with.`},type:{type:"string",const:"checkboxes",description:"The type of element. In this case `type` is always `checkboxes`."},action_id:{type:"string"},initial_options:{type:"array",items:{$ref:"#/definitions/Option"},description:"An array of {@link Option } objects that exactly matches one or more of the options within `options`.\nThese options will be selected when the checkbox group initially loads."},options:{type:"array",items:{$ref:"#/definitions/Option"},description:"An array of {@link Option } objects. A maximum of 10 options are allowed."}},required:["options","type"],additionalProperties:!0,description:"Allows users to choose multiple items from a list of options."},Focusable:{type:"object",properties:{focus_on_load:{type:"boolean"}},additionalProperties:!0},Option:{anyOf:[{$ref:"#/definitions/MrkdwnOption"},{$ref:"#/definitions/PlainTextOption"}],description:`Defines a single item in a number of item selection elements. An object that represents a single
|
|
39
|
-
selectable item in a select menu, multi-select menu, checkbox group, radio button group, or overflow menu.`},MrkdwnOption:{type:"object",properties:{value:{type:"string",description:`A unique string value that will be passed to your app when this option is chosen.
|
|
40
|
-
Maximum length for this field is 75 characters.`},url:{type:"string",description:`Only available in overflow menus! A URL to load in the user's browser when the option is clicked.
|
|
41
|
-
Maximum length for this field is 3000 characters.`},description:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } that defines a line of descriptive text shown below the `text` field.\nMaximum length for the `text` within this field is 75 characters."},text:{$ref:"#/definitions/MrkdwnElement",description:"A {@link MrkdwnElement } that defines the text shown in the option on the menu. To be used with\nradio buttons and checkboxes. Maximum length for the `text` in this field is 75 characters."}},required:["text"],additionalProperties:!0},PlainTextOption:{type:"object",properties:{value:{type:"string",description:`A unique string value that will be passed to your app when this option is chosen.
|
|
42
|
-
Maximum length for this field is 75 characters.`},url:{type:"string",description:`Only available in overflow menus! A URL to load in the user's browser when the option is clicked.
|
|
43
|
-
Maximum length for this field is 3000 characters.`},description:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } that defines a line of descriptive text shown below the `text` field.\nMaximum length for the `text` within this field is 75 characters."},text:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } that defines the text shown in the option on the menu. To be used with\noverflow, select and multi-select menus. Maximum length for the `text` in this field is 75 characters."}},required:["text"],additionalProperties:!0},Datepicker:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
44
|
-
with.`},type:{type:"string",const:"datepicker",description:"The type of element. In this case `type` is always `datepicker`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_date:{type:"string",description:"The initial date that is selected when the element is loaded.\nThis should be in the format `YYYY-MM-DD`."}},required:["type"],additionalProperties:!0,description:"Allows users to select a date from a calendar style UI."},Placeholdable:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."}},additionalProperties:!0},DateTimepicker:{type:"object",properties:{focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
45
|
-
with.`},type:{type:"string",const:"datetimepicker",description:"The type of element. In this case `type` is always `datetimepicker`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_date_time:{type:"number"}},required:["type"],additionalProperties:!0,description:`Allows users to select both a date and a time of day, formatted as a Unix timestamp. On desktop
|
|
46
|
-
clients, this time picker will take the form of a dropdown list and the date picker will take the form of a dropdown
|
|
47
|
-
calendar. Both options will have free-text entry for precise choices. On mobile clients, the time picker and date
|
|
48
|
-
picker will use native UIs.`},MultiSelect:{anyOf:[{$ref:"#/definitions/MultiUsersSelect"},{$ref:"#/definitions/MultiStaticSelect"},{$ref:"#/definitions/MultiConversationsSelect"},{$ref:"#/definitions/MultiChannelsSelect"},{$ref:"#/definitions/MultiExternalSelect"}],description:`Allows users to select multiple items from a list of options.
|
|
49
|
-
Just like regular {@link Select }, multi-select menus also include type-ahead functionality, where a user can type a
|
|
50
|
-
part or all of an option string to filter the list.
|
|
51
|
-
There are different types of multi-select menu that depend on different data sources for their lists of options:
|
|
52
|
-
{@link MultiStaticSelect }, {@link MultiExternalSelect }, {@link MultiUsersSelect }, {@link MultiConversationsSelect },
|
|
53
|
-
{@link MultiChannelsSelect }.`},MultiUsersSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
54
|
-
with.`},type:{type:"string",const:"multi_users_select",description:"The type of element. In this case `type` is always `multi_users_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_users:{type:"array",items:{type:"string"},description:"An array of user IDs of any valid users to be pre-selected when the menu loads."},max_selected_items:{type:"number",description:"Specifies the maximum number of items that can be selected in the menu. Minimum number is `1`."}},required:["type"],additionalProperties:!0,description:`This multi-select menu will populate its options with a list of Slack users visible to the current user
|
|
55
|
-
in the active workspace.`},MultiStaticSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
56
|
-
with.`},type:{type:"string",const:"multi_static_select",description:"The type of element. In this case `type` is always `multi_static_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_options:{type:"array",items:{$ref:"#/definitions/PlainTextOption"},description:"An array of option objects that exactly match one or more of the options within `options` or\n`option_groups`. These options will be selected when the menu initially loads."},options:{type:"array",items:{$ref:"#/definitions/PlainTextOption"},description:"An array of {@link PlainTextOption }. Maximum number of options is 100. If `option_groups` is\nspecified, this field should not be."},option_groups:{type:"array",items:{type:"object",properties:{label:{$ref:"#/definitions/PlainTextElement"},options:{type:"array",items:{$ref:"#/definitions/PlainTextOption"}}},required:["label","options"],additionalProperties:!0},description:"An array of option group objects. Maximum number of option groups is 100. If `options` is specified,\nthis field should not be."},max_selected_items:{type:"number",description:"Specifies the maximum number of items that can be selected in the menu. Minimum number is 1."}},required:["type"],additionalProperties:!0,description:`This is the simplest form of select menu, with a static list of options passed in when defining the
|
|
57
|
-
element.`},MultiConversationsSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
58
|
-
with.`},type:{type:"string",const:"multi_conversations_select",description:"The type of element. In this case `type` is always `conversations_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_conversations:{type:"array",items:{type:"string"},description:"An array of one or more IDs of any valid conversations to be pre-selected when the menu loads. If\n`default_to_current_conversation` is also supplied, `initial_conversation` will be ignored."},max_selected_items:{type:"number",description:"Specifies the maximum number of items that can be selected in the menu. Minimum number is 1."},default_to_current_conversation:{type:"boolean",description:"Pre-populates the select menu with the conversation that the user was viewing when they opened the\nmodal, if available. Default is `false`."},filter:{type:"object",properties:{include:{type:"array",items:{type:"string",enum:["im","mpim","private","public"]}},exclude_external_shared_channels:{type:"boolean"},exclude_bot_users:{type:"boolean"}},additionalProperties:!0,description:"A filter object that reduces the list of available conversations using the specified criteria."}},required:["type"],additionalProperties:!0,description:`This multi-select menu will populate its options with a list of public and private channels, DMs, and
|
|
59
|
-
MPIMs visible to the current user in the active workspace.`},MultiChannelsSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
60
|
-
with.`},type:{type:"string",const:"multi_channels_select",description:"The type of element. In this case `type` is always `multi_channels_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_channels:{type:"array",items:{type:"string"},description:"An array of one or more IDs of any valid public channel to be pre-selected when the menu loads."},max_selected_items:{type:"number",description:"Specifies the maximum number of items that can be selected in the menu. Minimum number is 1."}},required:["type"],additionalProperties:!0,description:`This multi-select menu will populate its options with a list of public channels visible to the current
|
|
61
|
-
user in the active workspace.`},MultiExternalSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
62
|
-
with.`},type:{type:"string",const:"multi_external_select",description:"The type of element. In this case `type` is always `multi_external_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_options:{type:"array",items:{$ref:"#/definitions/PlainTextOption"},description:"An array of options to be selected when the menu initially loads."},min_query_length:{type:"number",description:"When the typeahead field is used, a request will be sent on every character change. If you prefer\nfewer requests or more fully ideated queries, use the `min_query_length` attribute to tell Slack the fewest number\nof typed characters required before dispatch. The default value is `3`."},max_selected_items:{type:"number",description:"Specifies the maximum number of items that can be selected in the menu. Minimum number is 1."}},required:["type"],additionalProperties:!0,description:"This menu will load its options from an external data source, allowing for a dynamic list of options."},Overflow:{type:"object",properties:{confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
63
|
-
with.`},type:{type:"string",const:"overflow",description:"The type of element. In this case `type` is always `number_input`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},options:{type:"array",items:{$ref:"#/definitions/PlainTextOption"},description:"An array of up to 5 {@link PlainTextOption } to display in the menu."}},required:["options","type"],additionalProperties:!0,description:`Allows users to press a button to view a list of options.
|
|
64
|
-
Unlike the select menu, there is no typeahead field, and the button always appears with an ellipsis ("\u2026") rather
|
|
65
|
-
than customizable text. As such, it is usually used if you want a more compact layout than a select menu, or to
|
|
66
|
-
supply a list of less visually important actions after a row of buttons. You can also specify simple URL links as
|
|
67
|
-
overflow menu options, instead of actions.`},RadioButtons:{type:"object",properties:{focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
68
|
-
with.`},type:{type:"string",const:"radio_buttons",description:"The type of element. In this case `type` is always `radio_buttons`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_option:{$ref:"#/definitions/Option",description:"An {@link Option } object that exactly matches one of the options within `options`. This option will\nbe selected when the radio button group initially loads."},options:{type:"array",items:{$ref:"#/definitions/Option"},description:"An array of {@link Option } objects. A maximum of 10 options are allowed."}},required:["options","type"],additionalProperties:!0,description:"Allows users to choose one item from a list of possible options."},Select:{anyOf:[{$ref:"#/definitions/UsersSelect"},{$ref:"#/definitions/StaticSelect"},{$ref:"#/definitions/ConversationsSelect"},{$ref:"#/definitions/ChannelsSelect"},{$ref:"#/definitions/ExternalSelect"}],description:`Allows users to choose an option from a drop down menu.
|
|
69
|
-
The select menu also includes type-ahead functionality, where a user can type a part or all of an option string to
|
|
70
|
-
filter the list. There are different types of select menu elements that depend on different data sources for their
|
|
71
|
-
lists of options: {@link StaticSelect }, {@link ExternalSelect }, {@link UsersSelect }, {@link ConversationsSelect },
|
|
72
|
-
{@link ChannelsSelect }.`},UsersSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
73
|
-
with.`},type:{type:"string",const:"users_select",description:"The type of element. In this case `type` is always `users_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_user:{type:"string",description:"The user ID of any valid user to be pre-selected when the menu loads."}},required:["type"],additionalProperties:!0,description:`This select menu will populate its options with a list of Slack users visible to the current user in the
|
|
74
|
-
active workspace.`},StaticSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
75
|
-
with.`},type:{type:"string",const:"static_select",description:"The type of element. In this case `type` is always `static_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_option:{$ref:"#/definitions/PlainTextOption",description:"A single option that exactly matches one of the options within `options` or `option_groups`.\nThis option will be selected when the menu initially loads."},options:{type:"array",items:{$ref:"#/definitions/PlainTextOption"},description:"An array of {@link PlainTextOption }. Maximum number of options is 100. If `option_groups` is\nspecified, this field should not be."},option_groups:{type:"array",items:{type:"object",properties:{label:{$ref:"#/definitions/PlainTextElement"},options:{type:"array",items:{$ref:"#/definitions/PlainTextOption"}}},required:["label","options"],additionalProperties:!0},description:"An array of option group objects. Maximum number of option groups is 100. If `options` is specified,\nthis field should not be."}},required:["type"],additionalProperties:!0,description:`This is the simplest form of select menu, with a static list of options passed in when defining the
|
|
76
|
-
element.`},ConversationsSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
77
|
-
with.`},type:{type:"string",const:"conversations_select",description:"The type of element. In this case `type` is always `conversations_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_conversation:{type:"string",description:"The ID of any valid conversation to be pre-selected when the menu loads. If\n`default_to_current_conversation` is also supplied, `initial_conversation` will take precedence."},response_url_enabled:{type:"boolean",description:"When set to `true`, the {@link https://api.slack.com/reference/interaction-payloads/views#view_submission `view_submission` payload}\nfrom the menu's parent view will contain a `response_url`. This `response_url` can be used for\n{@link https://api.slack.com/interactivity/handling#message_responses message responses}. The target conversation\nfor the message will be determined by the value of this select menu."},default_to_current_conversation:{type:"boolean",description:"Pre-populates the select menu with the conversation that the user was viewing when they opened the\nmodal, if available. Default is `false`."},filter:{type:"object",properties:{include:{type:"array",items:{type:"string",enum:["im","mpim","private","public"]}},exclude_external_shared_channels:{type:"boolean"},exclude_bot_users:{type:"boolean"}},additionalProperties:!0,description:"A filter object that reduces the list of available conversations using the specified criteria."}},required:["type"],additionalProperties:!0,description:`This select menu will populate its options with a list of public and private channels, DMs, and MPIMs
|
|
78
|
-
visible to the current user in the active workspace.`},ChannelsSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
79
|
-
with.`},type:{type:"string",const:"channels_select",description:"The type of element. In this case `type` is always `channels_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_channel:{type:"string",description:"The ID of any valid public channel to be pre-selected when the menu loads."},response_url_enabled:{type:"boolean",description:"When set to `true`, the {@link https://api.slack.com/reference/interaction-payloads/views#view_submission `view_submission` payload}\nfrom the menu's parent view will contain a `response_url`. This `response_url` can be used for\n{@link https://api.slack.com/interactivity/handling#message_responses message responses}. The target channel\nfor the message will be determined by the value of this select menu."}},required:["type"],additionalProperties:!0,description:`This select menu will populate its options with a list of public channels visible to the current user
|
|
80
|
-
in the active workspace.`},ExternalSelect:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
81
|
-
with.`},type:{type:"string",const:"external_select",description:"The type of element. In this case `type` is always `external_select`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_option:{$ref:"#/definitions/PlainTextOption",description:"A single option to be selected when the menu initially loads."},min_query_length:{type:"number",description:"When the typeahead field is used, a request will be sent on every character change. If you prefer\nfewer requests or more fully ideated queries, use the `min_query_length` attribute to tell Slack the fewest number\nof typed characters required before dispatch. The default value is `3`."}},required:["type"],additionalProperties:!0,description:`This select menu will load its options from an external data source, allowing for a dynamic list of
|
|
82
|
-
options.`},Timepicker:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
83
|
-
with.`},type:{type:"string",const:"timepicker",description:"The type of element. In this case `type` is always `timepicker`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_time:{type:"string",description:"The initial time that is selected when the element is loaded. This should be in the format `HH:mm`,\nwhere `HH` is the 24-hour format of an hour (00 to 23) and `mm` is minutes with leading zeros (00 to 59),\nfor example 22:25 for 10:25pm."},timezone:{type:"string",description:`A string in the IANA format, e.g. "America/Chicago". The timezone is displayed to end users as hint
|
|
84
|
-
text underneath the time picker. It is also passed to the app upon certain interactions, such as view_submission.`}},required:["type"],additionalProperties:!0,description:`Allows users to choose a time from a rich dropdown UI. On desktop clients, this time picker will take
|
|
85
|
-
the form of a dropdown list with free-text entry for precise choices. On mobile clients, the time picker will use
|
|
86
|
-
native time picker UIs.`},WorkflowButton:{type:"object",properties:{confirm:{$ref:"#/definitions/ConfirmationDialog",description:`A {@link Confirm } object that defines an optional confirmation dialog after the element is interacted
|
|
87
|
-
with.`},type:{type:"string",const:"workflow_button",description:"The type of element. In this case `type` is always `workflow_button`."},text:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } that defines the button's text. `text` may truncate with ~30 characters.\nMaximum length for the `text` in this field is 75 characters."},workflow:{type:"object",properties:{trigger:{type:"object",properties:{url:{type:"string",description:"The trigger URL of the {@link https://api.slack.com/automation/triggers/link#workflow_buttons link trigger}"},customizable_input_parameters:{type:"array",items:{type:"object",properties:{name:{type:"string",description:`Name of the customizable input, which should be the name of a workflow input parameter for the
|
|
88
|
-
matching workflow of the link trigger.`},value:{type:"string",description:`The value of the customizable input parameter. The type of the value is expected to match the
|
|
89
|
-
specified type for the matching workflow input parameter.`}},required:["name","value"],additionalProperties:!0},description:`List of customizable input parameters and their values. Should match input parameters specified on
|
|
90
|
-
the provided trigger.`}},required:["url"],additionalProperties:!0,description:"Properties of the {@link https://api.slack.com/automation/triggers/link#workflow_buttons link trigger}that will be invoked via this button."}},required:["trigger"],additionalProperties:!0,description:"A workflow object that contains details about the workflow that will run when the button is clicked."},style:{type:"string",enum:["danger","primary"],description:"Decorates buttons with alternative visual color schemes. Use this option with restraint.\n`primary` gives buttons a green outline and text, ideal for affirmation or confirmation actions. `primary` should\nonly be used for one button within a set.\n`danger` gives buttons a red outline and text, and should be used when the action is destructive. Use `danger` even\nmore sparingly than primary.\nIf you don't include this field, the default button style will be used."},accessibility_label:{type:"string",description:"A label for longer descriptive text about a button element. This label will be read out by screen\nreaders instead of the button `text` object. Maximum length for this field is 75 characters."}},required:["type","text","workflow"],additionalProperties:!0,description:"Allows users to run a {@link https://api.slack.com/automation/triggers/link#workflow_buttons link trigger} with customizable inputs."},RichTextInput:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},dispatch_action_config:{$ref:"#/definitions/DispatchActionConfig"},type:{type:"string",const:"rich_text_input",description:"The type of element. In this case `type` is always `rich_text_input`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_value:{$ref:"#/definitions/RichTextBlock",description:"Initial contents of the input when it is loaded."}},required:["type"],additionalProperties:!0,description:`A rich text input creates a composer/WYSIWYG editor for entering formatted text, offering nearly the
|
|
91
|
-
same experience you have writing messages in Slack.`},Dispatchable:{type:"object",properties:{dispatch_action_config:{$ref:"#/definitions/DispatchActionConfig"}},additionalProperties:!0},DispatchActionConfig:{type:"object",properties:{trigger_actions_on:{type:"array",items:{type:"string",enum:["on_enter_pressed","on_character_entered"]},description:"An array of interaction types that you would like to receive a\n{@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` payload} for. Should be\none or both of:\n`on_enter_pressed` \u2014 payload is dispatched when user presses the enter key while the input is in focus. Hint\ntext will appear underneath the input explaining to the user to press enter to submit.\n`on_character_entered` \u2014 payload is dispatched when a character is entered (or removed) in the input."}},additionalProperties:!0,description:"Defines when a {@link PlainTextElement } will return a {@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` interaction payload}."},RichTextBlock:{type:"object",properties:{type:{type:"string",const:"rich_text",description:"The type of block. For a rich text block, `type` is always `rich_text`."},block_id:{type:"string",description:"A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated.\nYou can use this `block_id` when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}.\nMaximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of\na message. If a message is updated, use a new `block_id`."},elements:{type:"array",items:{anyOf:[{$ref:"#/definitions/RichTextSection"},{$ref:"#/definitions/RichTextList"},{$ref:"#/definitions/RichTextQuote"},{$ref:"#/definitions/RichTextPreformatted"}]}}},required:["elements","type"],additionalProperties:!0},RichTextSection:{type:"object",properties:{type:{type:"string",const:"rich_text_section",description:"The type of element. In this case `type` is always `rich_text_section`."},elements:{type:"array",items:{$ref:"#/definitions/RichTextElement"}}},required:["type","elements"],additionalProperties:!0,description:"A section block within a rich text field."},RichTextElement:{anyOf:[{$ref:"#/definitions/RichTextBroadcastMention"},{$ref:"#/definitions/RichTextColor"},{$ref:"#/definitions/RichTextChannelMention"},{$ref:"#/definitions/RichTextDate"},{$ref:"#/definitions/RichTextEmoji"},{$ref:"#/definitions/RichTextLink"},{$ref:"#/definitions/RichTextTeamMention"},{$ref:"#/definitions/RichTextText"},{$ref:"#/definitions/RichTextUserMention"},{$ref:"#/definitions/RichTextUsergroupMention"}],description:"Union of rich text sub-elements for use within rich text blocks."},RichTextBroadcastMention:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0},type:{type:"string",const:"broadcast",description:"The type of element. In this case `type` is always `broadcast`."},range:{type:"string",enum:["here","channel","everyone"],description:"The range of the broadcast; can be one of `here`, `channel` and `everyone`."}},required:["type","range"],additionalProperties:!0,description:"A broadcast mention element for use in a rich text message."},RichTextStyleable:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0}},additionalProperties:!0,description:"For use styling Rich Text message sub-elements."},RichTextColor:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0},type:{type:"string",const:"color",description:"The type of element. In this case `type` is always `color`."},value:{type:"string",description:"The hex value for the color."}},required:["type","value"],additionalProperties:!0,description:"A hex color element for use in a rich text message."},RichTextChannelMention:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0},type:{type:"string",const:"channel",description:"The type of element. In this case `type` is always `channel`."},channel_id:{type:"string",description:"The encoded channel ID, e.g. C1234ABCD."}},required:["type","channel_id"],additionalProperties:!0,description:"A channel mention element for use in a rich text message."},RichTextDate:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0},type:{type:"string",const:"date",description:"The type of element. In this case `type` is always `date`."},timestamp:{type:"number",description:"A UNIX timestamp for the date to be displayed in seconds."},format:{type:"string",description:"A template string containing curly-brace-enclosed tokens to substitute your provided `timestamp`\nin a particularly-formatted way. For example: `Posted at {date_long}`. The available date formatting tokens are:\n- `{day_divider_pretty}`: Shows `today`, `yesterday` or `tomorrow` if applicable. Otherwise, if the date is in\ncurrent year, uses the `{date_long}` format without the year. Otherwise, falls back to using the `{date_long}`\nformat.\n- `{date_num}`: Shows date as YYYY-MM-DD.\n- `{date_slash}`: Shows date as DD/MM/YYYY (subject to locale preferences).\n- `{date_long}`: Shows date as a long-form sentence including day-of-week, e.g. `Monday, December 23rd, 2013`.\n- `{date_long_full}`: Shows date as a long-form sentence without day-of-week, e.g. `August 9, 2020`.\n- `{date_long_pretty}`: Shows `yesterday`, `today` or `tomorrow`, otherwise uses the `{date_long}` format.\n- `{date}`: Same as `{date_long_full}` but without the year.\n- `{date_pretty}`: Shows `today`, `yesterday` or `tomorrow` if applicable, otherwise uses the `{date}` format.\n- `{date_short}`: Shows date using short month names without day-of-week, e.g. `Aug 9, 2020`.\n- `{date_short_pretty}`: Shows `today`, `yesterday` or `tomorrow` if applicable, otherwise uses the `{date_short}`\nformat.\n- `{time}`: Depending on user preferences, shows just the time-of-day portion of the timestamp using either 12 or\n24 hour clock formats, e.g. `2:34 PM` or `14:34`.\n- `{time_secs}`: Depending on user preferences, shows just the time-of-day portion of the timestamp using either 12\nor 24 hour clock formats, including seconds, e.g. `2:34:56 PM` or `14:34:56`.\n- `{ago}`: A human-readable period of time, e.g. `3 minutes ago`, `4 hours ago`, `2 days ago`.\nTODO: test/document `{member_local_time}`, `{status_expiration}` and `{calendar_header}`"},url:{type:"string",description:"URL to link the entire `format` string to."},fallback:{type:"string",description:"Text to display in place of the date should parsing, formatting or displaying fails."}},required:["type","timestamp","format"],additionalProperties:!0,description:"A date element for use in a rich text message."},RichTextEmoji:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0},type:{type:"string",const:"emoji",description:"The type of element. In this case `type` is always `emoji`."},name:{type:"string",description:"Name of emoji, without colons or skin tones, e.g. `wave`"},unicode:{type:"string",description:"Lowercase hexadecimal Unicode representation of a standard emoji (not for use with custom emoji)."},url:{type:"string",description:"URL of emoji asset. Only used when sharing custom emoji across workspaces."}},required:["type","name"],additionalProperties:!0,description:"An emoji element for use in a rich text message."},RichTextLink:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0,description:`A limited style object for styling rich text message elements
|
|
92
|
-
(excluding pre-formatted, or code, elements).`},type:{type:"string",const:"link",description:"The type of element. In this case `type` is always `link`."},text:{type:"string",description:"The text to link."},unsafe:{type:"boolean",description:"TODO: ?"},url:{type:"string",description:"URL to link to."}},required:["type","url"],additionalProperties:!0,description:"A link element for use in a rich text message."},RichTextTeamMention:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0,description:`A limited style object for styling rich text message elements
|
|
93
|
-
(excluding pre-formatted, or code, elements).`},type:{type:"string",const:"team",description:"The type of element. In this case `type` is always `team`."},team_id:{type:"string",description:"The encoded team ID, e.g. T1234ABCD."}},required:["type","team_id"],additionalProperties:!0,description:"A workspace or team mention element for use in a rich text message."},RichTextText:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0,description:`A limited style object for styling rich text message elements
|
|
94
|
-
(excluding pre-formatted, or code, elements).`},type:{type:"string",const:"text",description:"The type of element. In this case `type` is always `text`."},text:{type:"string",description:"The text to render."}},required:["type","text"],additionalProperties:!0,description:"A generic text element for use in a rich text message."},RichTextUserMention:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0,description:`A limited style object for styling rich text message elements
|
|
95
|
-
(excluding pre-formatted, or code, elements).`},type:{type:"string",const:"user",description:"The type of element. In this case `type` is always `user`."},user_id:{type:"string",description:"The encoded user ID, e.g. U1234ABCD."}},required:["type","user_id"],additionalProperties:!0,description:"A user mention element for use in a rich text message."},RichTextUsergroupMention:{type:"object",properties:{style:{type:"object",properties:{bold:{type:"boolean"},italic:{type:"boolean"},strike:{type:"boolean"},highlight:{type:"boolean"}},additionalProperties:!0,description:`A limited style object for styling rich text message elements
|
|
96
|
-
(excluding pre-formatted, or code, elements).`},type:{type:"string",const:"usergroup",description:"The type of element. In this case `type` is always `usergroup`."},usergroup_id:{type:"string",description:"The encoded usergroup ID, e.g. S1234ABCD."}},required:["type","usergroup_id"],additionalProperties:!0,description:"A usergroup mention element for use in a rich text message."},RichTextList:{type:"object",properties:{type:{type:"string",const:"rich_text_list",description:"The type of element. In this case `type` is always `rich_text_list`."},elements:{type:"array",items:{$ref:"#/definitions/RichTextSection"},description:"An array of {@link RichTextSection } elements comprising each list item."},style:{type:"string",enum:["bullet","ordered"],description:"The type of list. Can be either `bullet` (the list points are all rendered the same way) or `ordered`\n(the list points increase numerically from 1)."},indent:{type:"number",description:"The style of the list points. Can be a number from `0` (default) to `8`. Yields a different character\nor characters rendered as the list points. Also affected by the `style` property."},border:{type:"number",enum:[0,1],description:"Whether to render a quote-block-like border on the inline side of the list. `0` renders no border\nwhile `1` renders a border."}},required:["type","elements","style"],additionalProperties:!0,description:"A list block within a rich text field."},RichTextQuote:{type:"object",properties:{type:{type:"string",const:"rich_text_quote",description:"The type of element. In this case `type` is always `rich_text_quote`."},elements:{type:"array",items:{$ref:"#/definitions/RichTextElement"},description:"An array of {@link RichTextElement } comprising the quote block."}},required:["type","elements"],additionalProperties:!0,description:"A quote block within a rich text field."},RichTextPreformatted:{type:"object",properties:{type:{type:"string",const:"rich_text_preformatted",description:"The type of element. In this case `type` is always `rich_text_preformatted`."},elements:{type:"array",items:{anyOf:[{$ref:"#/definitions/RichTextText"},{$ref:"#/definitions/RichTextLink"}]},description:"An array of either {@link RichTextLink } or {@link RichTextText } comprising the preformatted text."},border:{type:"number",enum:[0,1],description:"Whether to render a quote-block-like border on the inline side of the preformatted text.\n`0` renders no border, while `1` renders a border. Defaults to `0`."}},required:["type","elements"],additionalProperties:!0,description:"A block of preformatted text within a rich text field."},DividerBlock:{type:"object",properties:{type:{type:"string",const:"divider",description:"The type of block. For a divider block, `type` is always `divider`."},block_id:{type:"string",description:"A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated.\nYou can use this `block_id` when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}.\nMaximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of\na message. If a message is updated, use a new `block_id`."}},required:["type"],additionalProperties:!0},SectionBlock:{type:"object",properties:{type:{type:"string",const:"section",description:"The type of block. For a section block, `type` is always `section`."},block_id:{type:"string",description:"A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated.\nYou can use this `block_id` when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}.\nMaximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of\na message. If a message is updated, use a new `block_id`."},text:{anyOf:[{$ref:"#/definitions/PlainTextElement"},{$ref:"#/definitions/MrkdwnElement"}],description:"The text for the block, in the form of a text object. Minimum length for the `text` in this field is\n1 and maximum length is 3000 characters. This field is not required if a valid array of `fields` objects is\nprovided instead."},fields:{type:"array",items:{anyOf:[{$ref:"#/definitions/PlainTextElement"},{$ref:"#/definitions/MrkdwnElement"}]},description:"Required if no `text` is provided. An array of text objects. Any text objects included with `fields`\nwill be rendered in a compact format that allows for 2 columns of side-by-side text. Maximum number of items is 10.\nMaximum length for the text in each item is 2000 characters.\n{@link https://app.slack.com/block-kit-builder/#%7B%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22text%22:%22A%20message%20*with%20some%20bold%20text*%20and%20_some%20italicized%20text_.%22,%22type%22:%22mrkdwn%22%7D,%22fields%22:%5B%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Priority*%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Type*%22%7D,%7B%22type%22:%22plain_text%22,%22text%22:%22High%22%7D,%7B%22type%22:%22plain_text%22,%22text%22:%22String%22%7D%5D%7D%5D%7D Click here for an example}."},accessory:{anyOf:[{$ref:"#/definitions/Button"},{$ref:"#/definitions/Overflow"},{$ref:"#/definitions/Datepicker"},{$ref:"#/definitions/Timepicker"},{$ref:"#/definitions/Select"},{$ref:"#/definitions/MultiSelect"},{$ref:"#/definitions/Actionable"},{$ref:"#/definitions/ImageElement"},{$ref:"#/definitions/RadioButtons"},{$ref:"#/definitions/Checkboxes"}],description:"One of the compatible element objects."}},required:["type"],additionalProperties:!0,description:`Displays text, possibly alongside block elements. A section can be used as a simple text block, in
|
|
97
|
-
combination with text fields, or side-by-side with certain
|
|
98
|
-
{@link https://api.slack.com/reference/messaging/block-elements block elements}.`},InputBlock:{type:"object",properties:{type:{type:"string",const:"input",description:"The type of block. For an input block, `type` is always `input`."},block_id:{type:"string",description:"A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated.\nYou can use this `block_id` when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}.\nMaximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of\na message. If a message is updated, use a new `block_id`."},label:{$ref:"#/definitions/PlainTextElement",description:`A label that appears above an input element in the form of a {@link PlainTextElement } object.
|
|
99
|
-
Maximum length for the text in this field is 2000 characters.`},hint:{$ref:"#/definitions/PlainTextElement",description:"An optional hint that appears below an input element in a lighter grey. It must be a\n{@link PlainTextElement object}. Maximum length for the `text` in this field is 2000 characters."},optional:{type:"boolean",description:"A boolean that indicates whether the input element may be empty when a user submits the modal.\nDefaults to `false`."},element:{anyOf:[{$ref:"#/definitions/Select"},{$ref:"#/definitions/MultiSelect"},{$ref:"#/definitions/Datepicker"},{$ref:"#/definitions/Timepicker"},{$ref:"#/definitions/DateTimepicker"},{$ref:"#/definitions/PlainTextInput"},{$ref:"#/definitions/URLInput"},{$ref:"#/definitions/EmailInput"},{$ref:"#/definitions/NumberInput"},{$ref:"#/definitions/RadioButtons"},{$ref:"#/definitions/Checkboxes"},{$ref:"#/definitions/RichTextInput"}],description:"A block element."},dispatch_action:{type:"boolean",description:"A boolean that indicates whether or not the use of elements in this block should dispatch a\n{@link https://api.slack.com/reference/interaction-payloads/block-actions block_actions payload}. Defaults to `false`."}},required:["element","label","type"],additionalProperties:!0,description:"Collects information from users via block elements."},PlainTextInput:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},dispatch_action_config:{$ref:"#/definitions/DispatchActionConfig"},type:{type:"string",const:"plain_text_input",description:"The type of element. In this case `type` is always `plain_text_input`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_value:{type:"string",description:"The initial value in the plain-text input when it is loaded."},multiline:{type:"boolean",description:"Indicates whether the input will be a single line (`false`) or a larger textarea (`true`).\nDefaults to `false`."},min_length:{type:"number",description:`The minimum length of input that the user must provide. If the user provides less, they will receive
|
|
100
|
-
an error. Maximum value is 3000.`},max_length:{type:"number",description:`The maximum length of input that the user can provide. If the user provides more,
|
|
101
|
-
they will receive an error.`}},required:["type"],additionalProperties:!0,description:"Allows users to enter freeform text data into a single-line or multi-line field."},URLInput:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},dispatch_action_config:{$ref:"#/definitions/DispatchActionConfig"},type:{type:"string",const:"url_text_input",description:"The type of element. In this case `type` is always `url_text_input`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_value:{type:"string",description:"The initial value in the URL input when it is loaded."}},required:["type"],additionalProperties:!0,description:"Allows user to enter a URL into a single-line field."},EmailInput:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},dispatch_action_config:{$ref:"#/definitions/DispatchActionConfig",description:"A {@link DispatchActionConfig } object that determines when during text input the element returns a\n{@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` payload}."},type:{type:"string",const:"email_text_input",description:"The type of element. In this case `type` is always `email_text_input`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},initial_value:{type:"string",description:"The initial value in the email input when it is loaded."}},required:["type"],additionalProperties:!0,description:"Allows user to enter an email into a single-line field."},NumberInput:{type:"object",properties:{placeholder:{$ref:"#/definitions/PlainTextElement",description:"A {@link PlainTextElement } object that defines the placeholder text shown on the element. Maximum\nlength for the `text` field in this object is 150 characters."},focus_on_load:{type:"boolean",description:"Indicates whether the element will be set to auto focus within the\n{@link https://api.slack.com/reference/surfaces/views `view` object}. Only one element can be set to `true`.\nDefaults to `false`."},dispatch_action_config:{$ref:"#/definitions/DispatchActionConfig",description:"A {@link DispatchActionConfig } object that determines when during text input the element returns a\n{@link https://api.slack.com/reference/interaction-payloads/block-actions `block_actions` payload}."},type:{type:"string",const:"number_input",description:"The type of element. In this case `type` is always `number_input`."},action_id:{type:"string",description:": An identifier for this action. You can use this when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}. Should be unique\namong all other `action_id`s in the containing block. Maximum length for this field is 255 characters."},is_decimal_allowed:{type:"boolean",description:"Decimal numbers are allowed if this property is `true`, set the value to `false` otherwise."},initial_value:{type:"string",description:"The initial value in the input when it is loaded."},min_value:{type:"string",description:"The minimum value, cannot be greater than `max_value`."},max_value:{type:"string",description:"The maximum value, cannot be less than `min_value`."}},required:["is_decimal_allowed","type"],additionalProperties:!0,description:"Allows user to enter a number into a single-line field. The number input element accepts both whole and\ndecimal numbers. For example, 0.25, 5.5, and -10 are all valid input values. Decimal numbers are only allowed when\n`is_decimal_allowed` is equal to `true`."},FileBlock:{type:"object",properties:{type:{type:"string",const:"file",description:"The type of block. For a file block, `type` is always `file`."},block_id:{type:"string",description:"A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated.\nYou can use this `block_id` when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}.\nMaximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of\na message. If a message is updated, use a new `block_id`."},source:{type:"string",description:"At the moment, source will always be `remote` for a remote file."},external_id:{type:"string",description:"The external unique ID for this file."}},required:["external_id","source","type"],additionalProperties:!0,description:`Displays a {@link https://api.slack.com/messaging/files/remote remote file}. You can't add this block to
|
|
102
|
-
app surfaces directly, but it will show up when {@link https://api.slack.com/messaging/retrieving retrieving messages}
|
|
103
|
-
that contain remote files. If you want to add remote files to messages,
|
|
104
|
-
{@link https://api.slack.com/messaging/files/remote follow our guide}.`},HeaderBlock:{type:"object",properties:{type:{type:"string",const:"header",description:"The type of block. For a header block, `type` is always `header`."},block_id:{type:"string",description:"A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated.\nYou can use this `block_id` when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}.\nMaximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of\na message. If a message is updated, use a new `block_id`."},text:{$ref:"#/definitions/PlainTextElement",description:`The text for the block, in the form of a {@link PlainTextElement }.
|
|
105
|
-
Maximum length for the text in this field is 150 characters.`}},required:["text","type"],additionalProperties:!0,description:"Displays a larger-sized text block. A `header` is a plain-text block that displays in a larger, bold\nfont. Use it to delineate between different groups of content in your app's surfaces."},VideoBlock:{type:"object",properties:{type:{type:"string",const:"video",description:"The type of block. For a video block, `type` is always `video`."},block_id:{type:"string",description:"A string acting as a unique identifier for a block. If not specified, a `block_id` will be generated.\nYou can use this `block_id` when you receive an interaction payload to\n{@link https://api.slack.com/interactivity/handling#payloads identify the source of the action}.\nMaximum length for this field is 255 characters. `block_id` should be unique for each message and each iteration of\na message. If a message is updated, use a new `block_id`."},video_url:{type:"string",description:`The URL to be embedded. Must match any existing
|
|
106
|
-
{@link https://api.slack.com/reference/messaging/link-unfurling#configuring_domains unfurl domains} within the app
|
|
107
|
-
and point to a HTTPS URL.`},thumbnail_url:{type:"string",description:"The thumbnail image URL."},alt_text:{type:"string",description:"A tooltip for the video. Required for accessibility."},title:{$ref:"#/definitions/PlainTextElement",description:"Video title as a {@link PlainTextElement } object. `text` within must be less than 200 characters."},title_url:{type:"string",description:`Hyperlink for the title text. Must correspond to the non-embeddable URL for the video.
|
|
108
|
-
Must go to an HTTPS URL.`},author_name:{type:"string",description:"Author name to be displayed. Must be less than 50 characters."},provider_name:{type:"string",description:"The originating application or domain of the video, e.g. YouTube."},provider_icon_url:{type:"string",description:"Icon for the video provider, e.g. YouTube icon."},description:{$ref:"#/definitions/PlainTextElement",description:"Description for video using a {@link PlainTextElement } object."}},required:["alt_text","thumbnail_url","title","type","video_url"],additionalProperties:!0,description:"Displays an embedded video player. A video block is designed to embed videos in all app surfaces (e.g.\nlink unfurls, messages, modals, App Home) \u2014 anywhere you can put blocks! To use the video block within your app, you\nmust have the {@link https://api.slack.com/scopes/links.embed:write `links.embed:write` scope}."}},additionalProperties:!0},Le={output:bt};var qe={[shared.ChatProviderIdEnum.Slack]:Le,[shared.ChatProviderIdEnum.Discord]:l,[shared.ChatProviderIdEnum.GetStream]:l,[shared.ChatProviderIdEnum.GrafanaOnCall]:l,[shared.ChatProviderIdEnum.Mattermost]:l,[shared.ChatProviderIdEnum.MsTeams]:l,[shared.ChatProviderIdEnum.RocketChat]:l,[shared.ChatProviderIdEnum.Ryver]:l,[shared.ChatProviderIdEnum.WhatsAppBusiness]:l,[shared.ChatProviderIdEnum.Zulip]:l};var wt={type:"object",properties:{},required:[],additionalProperties:!1},We={output:wt};var Be={[shared.EmailProviderIdEnum.SendGrid]:l,[shared.EmailProviderIdEnum.EmailJS]:l,[shared.EmailProviderIdEnum.Mailgun]:l,[shared.EmailProviderIdEnum.Mailjet]:l,[shared.EmailProviderIdEnum.Mandrill]:l,[shared.EmailProviderIdEnum.CustomSMTP]:l,[shared.EmailProviderIdEnum.Postmark]:l,[shared.EmailProviderIdEnum.Sendinblue]:l,[shared.EmailProviderIdEnum.SES]:l,[shared.EmailProviderIdEnum.NetCore]:l,[shared.EmailProviderIdEnum.Infobip]:l,[shared.EmailProviderIdEnum.Resend]:l,[shared.EmailProviderIdEnum.Plunk]:l,[shared.EmailProviderIdEnum.MailerSend]:l,[shared.EmailProviderIdEnum.Mailtrap]:l,[shared.EmailProviderIdEnum.Clickatell]:l,[shared.EmailProviderIdEnum.Outlook365]:l,[shared.EmailProviderIdEnum.Novu]:We,[shared.EmailProviderIdEnum.SparkPost]:l,[shared.EmailProviderIdEnum.EmailWebhook]:l,[shared.EmailProviderIdEnum.Braze]:l};var Tt={type:"object",properties:{},required:[],additionalProperties:!1},Ge={output:Tt};var Ke={[shared.InAppProviderIdEnum.Novu]:Ge};var Xe={[shared.PushProviderIdEnum.FCM]:l,[shared.PushProviderIdEnum.APNS]:l,[shared.PushProviderIdEnum.EXPO]:l,[shared.PushProviderIdEnum.OneSignal]:l,[shared.PushProviderIdEnum.PushWebhook]:l,[shared.PushProviderIdEnum.PusherBeams]:l,[shared.PushProviderIdEnum.Pushpad]:l};var kt={type:"object",properties:{},required:[],additionalProperties:!1},ze={output:kt};var Je={[shared.SmsProviderIdEnum.Twilio]:l,[shared.SmsProviderIdEnum.Termii]:l,[shared.SmsProviderIdEnum.Telnyx]:l,[shared.SmsProviderIdEnum.SNS]:l,[shared.SmsProviderIdEnum.Sms77]:l,[shared.SmsProviderIdEnum.SmsCentral]:l,[shared.SmsProviderIdEnum.Simpletexting]:l,[shared.SmsProviderIdEnum.Sendchamp]:l,[shared.SmsProviderIdEnum.RingCentral]:l,[shared.SmsProviderIdEnum.Plivo]:l,[shared.SmsProviderIdEnum.Nexmo]:l,[shared.SmsProviderIdEnum.Mobishastra]:l,[shared.SmsProviderIdEnum.MessageBird]:l,[shared.SmsProviderIdEnum.Maqsam]:l,[shared.SmsProviderIdEnum.Kannel]:l,[shared.SmsProviderIdEnum.ISendSms]:l,[shared.SmsProviderIdEnum.Infobip]:l,[shared.SmsProviderIdEnum.Gupshup]:l,[shared.SmsProviderIdEnum.GenericSms]:l,[shared.SmsProviderIdEnum.FortySixElks]:l,[shared.SmsProviderIdEnum.Firetext]:l,[shared.SmsProviderIdEnum.Clickatell]:l,[shared.SmsProviderIdEnum.BurstSms]:l,[shared.SmsProviderIdEnum.BrevoSms]:l,[shared.SmsProviderIdEnum.Bandwidth]:l,[shared.SmsProviderIdEnum.AzureSms]:l,[shared.SmsProviderIdEnum.AfricasTalking]:l,[shared.SmsProviderIdEnum.Novu]:ze,[shared.SmsProviderIdEnum.BulkSms]:l,[shared.SmsProviderIdEnum.Clicksend]:l,[shared.SmsProviderIdEnum.EazySms]:l};var Qe={chat:qe,sms:Je,email:Be,push:Xe,in_app:Ke};var Rt={type:"object",properties:{type:{enum:["regular"],default:"regular"},amount:{type:"number"},unit:{type:"string",enum:["seconds","minutes","hours","days","weeks","months"]}},required:["amount","unit"],additionalProperties:!1},St={type:"object",properties:{duration:{type:"number"}},required:["duration"],additionalProperties:!1},De={output:Rt,result:St};var Et={type:"object",properties:{amount:{type:"number"},unit:{type:"string",enum:["seconds","minutes","hours","days","weeks","months"]},digestKey:{type:"string"},lookBackWindow:{type:"object",properties:{amount:{type:"number"},unit:{type:"string",enum:["seconds","minutes","hours","days","weeks","months"]}},required:["amount","unit"],additionalProperties:!1}},required:["amount","unit"],additionalProperties:!1},At={type:"object",properties:{cron:{type:"string"},digestKey:{type:"string"}},required:["cron"],additionalProperties:!1},vt={oneOf:[Et,At]},Ot={type:"object",properties:{events:{type:"array",items:{type:"object",properties:{id:{type:"string"},time:{type:"string"},payload:{type:"object"}},required:["id","time","payload"],additionalProperties:!1}}},required:["events"],additionalProperties:!1},Ne={output:vt,result:Ot};var It={type:"object",properties:{body:{type:"string"}},required:["body"],additionalProperties:!1},Pt={type:"object",properties:{},required:[],additionalProperties:!1},Ze={output:It,result:Pt};var Dt={type:"object",properties:{subject:{type:"string"},body:{type:"string"}},required:["subject","body"],additionalProperties:!1},Nt={type:"object",properties:{},required:[],additionalProperties:!1},He={output:Dt,result:Nt};var Mt={type:"object",properties:{body:{type:"string"}},required:["body"],additionalProperties:!1},Ct={type:"object",properties:{seen:{type:"boolean"},read:{type:"boolean"},lastSeenDate:{type:"string",format:"date-time",nullable:!0},lastReadDate:{type:"string",format:"date-time",nullable:!0}},required:["seen","read","lastSeenDate","lastReadDate"],additionalProperties:!1},et={output:Mt,result:Ct};var jt={type:"object",properties:{subject:{type:"string"},body:{type:"string"}},required:["subject","body"],additionalProperties:!1},$t={type:"object",properties:{},required:[],additionalProperties:!1},tt={output:jt,result:$t};var Ut={type:"object",properties:{body:{type:"string"}},required:["body"],additionalProperties:!1},Yt={type:"object",properties:{},required:[],additionalProperties:!1},it={output:Ut,result:Yt};var S={chat:Ze,sms:it,push:tt,email:He,in_app:et};var T={type:"object",properties:{},required:[],additionalProperties:!1};function tr(r,e,t){let i=t||{},n=pe(process.env.NOVU_SECRET_KEY),a=async p=>{if(!process.env.NOVU_SECRET_KEY)throw new ue;p.payload;if(i.payloadSchema){let f=await Ee(i.payloadSchema,p.payload);if(f.success===!1)throw new ae(r,f.errors);f.data;}let y=await Ue(),w={name:r,to:p.to,payload:{...p?.payload},...p.transactionId&&{transactionId:p.transactionId},...p.overrides&&{overrides:p.overrides},...p.actor&&{actor:p.actor},...p.tenant&&{tenant:p.tenant},...y&&{bridgeUrl:y}},E=await n.post("/events/trigger",w);return {cancel:async()=>n.delete(`/events/trigger/${E.transactionId}`),data:E}},c={workflowId:r,options:{...i,inputSchema:b(i.controlSchema||i.inputSchema||T),controlSchema:b(i.controlSchema||i.inputSchema||T),payloadSchema:b(i.payloadSchema||T)},steps:[],code:e.toString(),data:{schema:b(i.payloadSchema||T),unknownSchema:i.payloadSchema||T},payload:{schema:b(i.payloadSchema||T),unknownSchema:i.payloadSchema||T},inputs:{schema:b(i.controlSchema||i.inputSchema||T),unknownSchema:i.controlSchema||i.inputSchema||T},controls:{schema:b(i.controlSchema||i.inputSchema||T),unknownSchema:i.controlSchema||i.inputSchema||T},execute:e};return e({payload:{},subscriber:{},environment:{},controls:{},step:{push:N(c,"push",S.push.output,S.push.result),chat:N(c,"chat",S.chat.output,S.chat.result),email:N(c,"email",S.email.output,S.email.result),sms:N(c,"sms",S.sms.output,S.sms.result),inApp:N(c,"in_app",S.in_app.output,S.in_app.result),digest:N(c,"digest",Ne.output,Ne.result),delay:N(c,"delay",De.output,De.result),custom:Vt(c,"custom")}}),Lt(c),{trigger:a,definition:c}}function N(r,e,t,i){return async(n,a,c={})=>{let p=c?.controlSchema||c?.inputSchema||T,h={stepId:n,type:e,inputs:{schema:b(p),unknownSchema:p},controls:{schema:b(p),unknownSchema:p},outputs:{schema:b(t),unknownSchema:t},results:{schema:b(i),unknownSchema:i},resolve:a,code:a.toString(),options:c,providers:[]};ot(r,n,h),Object.values(P).includes(e)&&Object.keys(c.providers||{}).length>0&&Ft(h,e,c.providers||{});}}function ot(r,e,t){if(r.steps.some(i=>i.stepId===e))throw new xe(e);r.steps.push(t);}function Ft(r,e,t){let i=Qe[e];Object.entries(t).forEach(([n,a])=>{let c=i[n];r.providers.push({type:n,code:a.toString(),resolve:a,outputs:{schema:b(c.output),unknownSchema:c.output}});});}function Vt(r,e){return async(t,i,n={})=>{let a=n?.controlSchema||n?.inputSchema||T,c=n?.outputSchema||T;ot(r,t,{stepId:t,type:e,inputs:{schema:b(a),unknownSchema:a},controls:{schema:b(a),unknownSchema:a},outputs:{schema:b(c),unknownSchema:c},results:{schema:b(c),unknownSchema:c},resolve:i,code:i.toString(),options:n,providers:[]});}}function Lt(r){console.log(`
|
|
109
|
-
${u.bold(u.underline("Discovered workflowId:"))} '${r.workflowId}'`),r.steps.forEach((e,t)=>{let i=t===r.steps.length-1?"\u2514":"\u251C";console.log(`${i} ${_.STEP} Discovered stepId: '${e.stepId}' Type: '${e.type}'`),e.providers.forEach((n,a)=>{let c=a===e.providers.length-1?"\u2514":"\u251C";console.log(` ${c} ${_.PROVIDER} Discovered provider: '${n.type}'`);});});}var qt=(y=>(y.PENDING="pending",y.QUEUED="queued",y.RUNNING="running",y.COMPLETED="completed",y.FAILED="failed",y.DELAYED="delayed",y.CANCELED="canceled",y.MERGED="merged",y.SKIPPED="skipped",y))(qt||{});
|
|
23
|
+
var G=(i=>(i.TRIGGER="trigger",i.EXECUTE="execute",i.PREVIEW="preview",i))(G||{}),J=(i=>(i.DISCOVER="discover",i.HEALTH_CHECK="health-check",i.CODE="code",i))(J||{});var At=(t=>(t.SYNC="/v1/bridge/sync",t.DIFF="/v1/bridge/diff",t))(At||{}),Ye=5,Ve=1500;var Rt=(r=>(r.EVERY_SECOND="* * * * * *",r.EVERY_5_SECONDS="*/5 * * * * *",r.EVERY_10_SECONDS="*/10 * * * * *",r.EVERY_30_SECONDS="*/30 * * * * *",r.EVERY_MINUTE="*/1 * * * *",r.EVERY_5_MINUTES="0 */5 * * * *",r.EVERY_10_MINUTES="0 */10 * * * *",r.EVERY_30_MINUTES="0 */30 * * * *",r.EVERY_HOUR="0 0-23/1 * * *",r.EVERY_2_HOURS="0 0-23/2 * * *",r.EVERY_3_HOURS="0 0-23/3 * * *",r.EVERY_4_HOURS="0 0-23/4 * * *",r.EVERY_5_HOURS="0 0-23/5 * * *",r.EVERY_6_HOURS="0 0-23/6 * * *",r.EVERY_7_HOURS="0 0-23/7 * * *",r.EVERY_8_HOURS="0 0-23/8 * * *",r.EVERY_9_HOURS="0 0-23/9 * * *",r.EVERY_10_HOURS="0 0-23/10 * * *",r.EVERY_11_HOURS="0 0-23/11 * * *",r.EVERY_12_HOURS="0 0-23/12 * * *",r.EVERY_DAY_AT_1AM="0 01 * * *",r.EVERY_DAY_AT_2AM="0 02 * * *",r.EVERY_DAY_AT_3AM="0 03 * * *",r.EVERY_DAY_AT_4AM="0 04 * * *",r.EVERY_DAY_AT_5AM="0 05 * * *",r.EVERY_DAY_AT_6AM="0 06 * * *",r.EVERY_DAY_AT_7AM="0 07 * * *",r.EVERY_DAY_AT_8AM="0 08 * * *",r.EVERY_DAY_AT_9AM="0 09 * * *",r.EVERY_DAY_AT_10AM="0 10 * * *",r.EVERY_DAY_AT_11AM="0 11 * * *",r.EVERY_DAY_AT_NOON="0 12 * * *",r.EVERY_DAY_AT_1PM="0 13 * * *",r.EVERY_DAY_AT_2PM="0 14 * * *",r.EVERY_DAY_AT_3PM="0 15 * * *",r.EVERY_DAY_AT_4PM="0 16 * * *",r.EVERY_DAY_AT_5PM="0 17 * * *",r.EVERY_DAY_AT_6PM="0 18 * * *",r.EVERY_DAY_AT_7PM="0 19 * * *",r.EVERY_DAY_AT_8PM="0 20 * * *",r.EVERY_DAY_AT_9PM="0 21 * * *",r.EVERY_DAY_AT_10PM="0 22 * * *",r.EVERY_DAY_AT_11PM="0 23 * * *",r.EVERY_DAY_AT_MIDNIGHT="0 0 * * *",r.EVERY_WEEK="0 0 * * 0",r.EVERY_WEEKDAY="0 0 * * 1-5",r.EVERY_WEEKEND="0 0 * * 6,0",r.EVERY_1ST_DAY_OF_MONTH_AT_MIDNIGHT="0 0 1 * *",r.EVERY_1ST_DAY_OF_MONTH_AT_NOON="0 12 1 * *",r.EVERY_2ND_HOUR="0 */2 * * *",r.EVERY_2ND_HOUR_FROM_1AM_THROUGH_11PM="0 1-23/2 * * *",r.EVERY_2ND_MONTH="0 0 1 */2 *",r.EVERY_QUARTER="0 0 1 */3 *",r.EVERY_6_MONTHS="0 0 1 */6 *",r.EVERY_YEAR="0 0 1 0 *",r.EVERY_30_MINUTES_BETWEEN_9AM_AND_5PM="0 */30 9-17 * * *",r.EVERY_30_MINUTES_BETWEEN_9AM_AND_6PM="0 */30 9-18 * * *",r.EVERY_30_MINUTES_BETWEEN_10AM_AND_7PM="0 */30 10-19 * * *",r.MONDAY_TO_FRIDAY_AT_1AM="0 0 01 * * 1-5",r.MONDAY_TO_FRIDAY_AT_2AM="0 0 02 * * 1-5",r.MONDAY_TO_FRIDAY_AT_3AM="0 0 03 * * 1-5",r.MONDAY_TO_FRIDAY_AT_4AM="0 0 04 * * 1-5",r.MONDAY_TO_FRIDAY_AT_5AM="0 0 05 * * 1-5",r.MONDAY_TO_FRIDAY_AT_6AM="0 0 06 * * 1-5",r.MONDAY_TO_FRIDAY_AT_7AM="0 0 07 * * 1-5",r.MONDAY_TO_FRIDAY_AT_8AM="0 0 08 * * 1-5",r.MONDAY_TO_FRIDAY_AT_9AM="0 0 09 * * 1-5",r.MONDAY_TO_FRIDAY_AT_09_30AM="0 30 09 * * 1-5",r.MONDAY_TO_FRIDAY_AT_10AM="0 0 10 * * 1-5",r.MONDAY_TO_FRIDAY_AT_11AM="0 0 11 * * 1-5",r.MONDAY_TO_FRIDAY_AT_11_30AM="0 30 11 * * 1-5",r.MONDAY_TO_FRIDAY_AT_12PM="0 0 12 * * 1-5",r.MONDAY_TO_FRIDAY_AT_1PM="0 0 13 * * 1-5",r.MONDAY_TO_FRIDAY_AT_2PM="0 0 14 * * 1-5",r.MONDAY_TO_FRIDAY_AT_3PM="0 0 15 * * 1-5",r.MONDAY_TO_FRIDAY_AT_4PM="0 0 16 * * 1-5",r.MONDAY_TO_FRIDAY_AT_5PM="0 0 17 * * 1-5",r.MONDAY_TO_FRIDAY_AT_6PM="0 0 18 * * 1-5",r.MONDAY_TO_FRIDAY_AT_7PM="0 0 19 * * 1-5",r.MONDAY_TO_FRIDAY_AT_8PM="0 0 20 * * 1-5",r.MONDAY_TO_FRIDAY_AT_9PM="0 0 21 * * 1-5",r.MONDAY_TO_FRIDAY_AT_10PM="0 0 22 * * 1-5",r.MONDAY_TO_FRIDAY_AT_11PM="0 0 23 * * 1-5",r))(Rt||{});var v=(m=>(m.WORKFLOW_NOT_FOUND_ERROR="WorkflowNotFoundError",m.WORKFLOW_ALREADY_EXISTS_ERROR="WorkflowAlreadyExistsError",m.WORKFLOW_EXECUTION_FAILED_ERROR="WorkflowExecutionFailedError",m.EXECUTION_STATE_OUTPUT_INVALID_ERROR="ExecutionStateOutputInvalidError",m.EXECUTION_STATE_RESULT_INVALID_ERROR="ExecutionStateResultInvalidError",m.EXECUTION_PROVIDER_OUTPUT_INVALID_ERROR="ExecutionProviderOutputInvalidError",m.PROVIDER_NOT_FOUND_ERROR="ProviderNotFoundError",m.PROVIDER_EXECUTION_FAILED_ERROR="ProviderExecutionFailedError",m.STEP_NOT_FOUND_ERROR="StepNotFoundError",m.STEP_ALREADY_EXISTS_ERROR="StepAlreadyExistsError",m.STEP_EXECUTION_FAILED_ERROR="StepExecutionFailedError",m.EXECUTION_STATE_CORRUPT_ERROR="ExecutionStateCorruptError",m.EXECUTION_EVENT_PAYLOAD_INVALID_ERROR="ExecutionEventPayloadInvalidError",m.EXECUTION_EVENT_CONTROL_INVALID_ERROR="ExecutionEventControlInvalidError",m.EXECUTION_STATE_CONTROL_INVALID_ERROR="ExecutionStateControlInvalidError",m.METHOD_NOT_ALLOWED_ERROR="MethodNotAllowedError",m.INVALID_ACTION_ERROR="InvalidActionError",m.MISSING_SECRET_KEY_ERROR="MissingSecretKeyError",m.SIGNATURE_MISMATCH_ERROR="SignatureMismatchError",m.SIGNATURE_NOT_FOUND_ERROR="SignatureNotFoundError",m.SIGNATURE_INVALID_ERROR="SignatureInvalidError",m.SIGNATURE_EXPIRED_ERROR="SignatureExpiredError",m.SIGNING_KEY_NOT_FOUND_ERROR="SigningKeyNotFoundError",m.BRIDGE_ERROR="BridgeError",m.SIGNATURE_VERSION_INVALID_ERROR="SignatureVersionInvalidError",m.WORKFLOW_PAYLOAD_INVALID_ERROR="WorkflowPayloadInvalidError",m))(v||{});var Ce=(y=>(y.NOVU_SIGNATURE="novu-signature",y.NOVU_ANONYMOUS="novu-anonymous",y.NOVU_SIGNATURE_DEPRECATED="x-novu-signature",y.NOVU_ANONYMOUS_DEPRECATED="x-novu-anonymous",y.NOVU_FRAMEWORK_SDK="novu-framework-sdk",y.NOVU_FRAMEWORK_SERVER="novu-framework-server",y.NOVU_FRAMEWORK_VERSION="novu-framework-version",y.USER_AGENT="user-agent",y.CONTENT_TYPE="content-type",y.ACCESS_CONTROL_ALLOW_ORIGIN="access-control-allow-origin",y.ACCESS_CONTROL_ALLOW_METHODS="access-control-allow-methods",y.ACCESS_CONTROL_ALLOW_HEADERS="access-control-allow-headers",y.ACCESS_CONTROL_MAX_AGE="access-control-max-age",y))(Ce||{});var Z=(i=>(i.POST="POST",i.GET="GET",i.OPTIONS="OPTIONS",i))(Z||{});var We=(n=>(n.WORKFLOW_ID="workflowId",n.STEP_ID="stepId",n.ACTION="action",n.SOURCE="source",n))(We||{});var Q=(o=>(o[o.CONTINUE=100]="CONTINUE",o[o.SWITCHING_PROTOCOLS=101]="SWITCHING_PROTOCOLS",o[o.PROCESSING=102]="PROCESSING",o[o.EARLYHINTS=103]="EARLYHINTS",o[o.OK=200]="OK",o[o.CREATED=201]="CREATED",o[o.ACCEPTED=202]="ACCEPTED",o[o.NON_AUTHORITATIVE_INFORMATION=203]="NON_AUTHORITATIVE_INFORMATION",o[o.NO_CONTENT=204]="NO_CONTENT",o[o.RESET_CONTENT=205]="RESET_CONTENT",o[o.PARTIAL_CONTENT=206]="PARTIAL_CONTENT",o[o.AMBIGUOUS=300]="AMBIGUOUS",o[o.MOVED_PERMANENTLY=301]="MOVED_PERMANENTLY",o[o.FOUND=302]="FOUND",o[o.SEE_OTHER=303]="SEE_OTHER",o[o.NOT_MODIFIED=304]="NOT_MODIFIED",o[o.TEMPORARY_REDIRECT=307]="TEMPORARY_REDIRECT",o[o.PERMANENT_REDIRECT=308]="PERMANENT_REDIRECT",o[o.BAD_REQUEST=400]="BAD_REQUEST",o[o.UNAUTHORIZED=401]="UNAUTHORIZED",o[o.PAYMENT_REQUIRED=402]="PAYMENT_REQUIRED",o[o.FORBIDDEN=403]="FORBIDDEN",o[o.NOT_FOUND=404]="NOT_FOUND",o[o.METHOD_NOT_ALLOWED=405]="METHOD_NOT_ALLOWED",o[o.NOT_ACCEPTABLE=406]="NOT_ACCEPTABLE",o[o.PROXY_AUTHENTICATION_REQUIRED=407]="PROXY_AUTHENTICATION_REQUIRED",o[o.REQUEST_TIMEOUT=408]="REQUEST_TIMEOUT",o[o.CONFLICT=409]="CONFLICT",o[o.GONE=410]="GONE",o[o.LENGTH_REQUIRED=411]="LENGTH_REQUIRED",o[o.PRECONDITION_FAILED=412]="PRECONDITION_FAILED",o[o.PAYLOAD_TOO_LARGE=413]="PAYLOAD_TOO_LARGE",o[o.URI_TOO_LONG=414]="URI_TOO_LONG",o[o.UNSUPPORTED_MEDIA_TYPE=415]="UNSUPPORTED_MEDIA_TYPE",o[o.REQUESTED_RANGE_NOT_SATISFIABLE=416]="REQUESTED_RANGE_NOT_SATISFIABLE",o[o.EXPECTATION_FAILED=417]="EXPECTATION_FAILED",o[o.I_AM_A_TEAPOT=418]="I_AM_A_TEAPOT",o[o.MISDIRECTED=421]="MISDIRECTED",o[o.UNPROCESSABLE_ENTITY=422]="UNPROCESSABLE_ENTITY",o[o.FAILED_DEPENDENCY=424]="FAILED_DEPENDENCY",o[o.PRECONDITION_REQUIRED=428]="PRECONDITION_REQUIRED",o[o.TOO_MANY_REQUESTS=429]="TOO_MANY_REQUESTS",o[o.INTERNAL_SERVER_ERROR=500]="INTERNAL_SERVER_ERROR",o[o.NOT_IMPLEMENTED=501]="NOT_IMPLEMENTED",o[o.BAD_GATEWAY=502]="BAD_GATEWAY",o[o.SERVICE_UNAVAILABLE=503]="SERVICE_UNAVAILABLE",o[o.GATEWAY_TIMEOUT=504]="GATEWAY_TIMEOUT",o[o.HTTP_VERSION_NOT_SUPPORTED=505]="HTTP_VERSION_NOT_SUPPORTED",o))(Q||{}),_i=[500];var ee=(i=>(i.WORKFLOW="workflow",i.PROVIDER="provider",i.STEP="step",i))(ee||{});var U=(a=>(a.EMAIL="email",a.SMS="sms",a.PUSH="push",a.CHAT="chat",a.IN_APP="in_app",a))(U||{}),Ge=(i=>(i.DIGEST="digest",i.DELAY="delay",i.CUSTOM="custom",i))(Ge||{});var qe="2.0.0-canary.5";var q=qe,te="2024-06-26";var A=class extends Error{data},ie=class extends A{statusCode=404},O=class extends A{statusCode=400},N=class extends A{statusCode=401},L=class extends A{statusCode=500},ne=class extends A{statusCode=409};var oe=class extends O{code="ExecutionStateCorruptError";constructor(e,t){super(`Workflow with id: \`${e}\` has a corrupt state. Step with id: \`${t}\` does not exist. Please provide the missing state.`),this.data={workflowId:e,stepId:t};}},$=class extends O{code="ExecutionEventPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct event payload.`),this.data=t;}},se=class extends O{code="ExecutionEventControlInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`controls\`. Please provide the correct event controls.`),this.data=t;}},re=class extends O{code="ExecutionStateControlInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid \`controls\`. Please provide the correct step controls.`),this.data=i;}},ae=class extends O{code="ExecutionStateOutputInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid output. Please provide the correct step output.`),this.data=i;}},ce=class extends O{code="ExecutionStateResultInvalidError";constructor(e,t,i){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` has invalid result. Please provide the correct step result.`),this.data=i;}},le=class extends O{code="ExecutionProviderOutputInvalidError";constructor(e,t,i,n){super(`Workflow with id: \`${e}\` has an invalid state. Step with id: \`${t}\` and provider with id: \`${i}\` has invalid output. Please provide the correct provider output.`),this.data=n;}},pe=class extends O{code="WorkflowPayloadInvalidError";constructor(e,t){super(`Workflow with id: \`${e}\` has invalid \`payload\`. Please provide the correct payload.`),this.data=t;}},de=class extends A{statusCode;data;code;constructor(e,t,i){super(),this.data={message:i},this.statusCode=e,this.code=t;}};var $e=async()=>{if(process.env.NOVU_BRIDGE_ORIGIN)return `${process.env.NOVU_BRIDGE_ORIGIN}/api/novu`;if(process.env.NEXT_PUBLIC_VERCEL_ENV==="preview"&&process.env.NEXT_PUBLIC_VERCEL_URL)return `https://${process.env.NEXT_PUBLIC_VERCEL_URL}/api/novu`;try{if(process.env.NODE_ENV==="development"){let e=await(await fetch("http://localhost:2022/.well-known/novu")).json();return `${e.tunnelOrigin}${e.route}`}}catch(s){console.error(s);}return ""};var h={info:s=>F__default.default.blue(s),warning:s=>F__default.default.yellow(s),error:s=>F__default.default.red(s),success:s=>F__default.default.green(s),underline:s=>F__default.default.underline(s),bold:s=>F__default.default.bold(s)},b={SUCCESS:h.success("\u2714"),ERROR:h.error("\u2717"),WARNING:h.warning("\u26A0"),INFO:h.info("\u2139"),ARROW:h.bold("\u2192"),MOCK:h.info("\u25CB"),HYDRATED:h.bold(h.info("\u2192")),STEP:h.info("\u03C3"),ACTION:h.info("\u03B1"),DURATION:h.info("\u0394"),PROVIDER:h.info("\u2699"),OUTPUT:h.info("\u21E2"),INPUT:h.info("\u21E0"),WORKFLOW:h.info("\u03C9"),STATE:h.info("\u03C3"),EXECUTE:h.info("\u03B5"),PREVIEW:h.info("\u03C1")};var De=s=>Object.values(s).map(e=>`\`${e}\``).join(", "),ue=s=>s.replaceAll(/(\w)(\w*)/g,(e,t,i)=>t.toUpperCase()+i.toLowerCase()).replaceAll(/[\s-]+/g,"");var he=(s,e="https://api.novu.co")=>{let t=process.env.NOVU_API_URL||e;return {post:async(i,n)=>{let a=await fetch(t+"/v1"+i,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${s}`},body:JSON.stringify(n)}),c=await a.json();if(a.ok)return c;throw shared.checkIsResponseError(c)?new de(c.statusCode,c.error,c.message):new j("Error processing API request to Novu Cloud from Bridge application.")},delete:async i=>(await fetch(t+"/v1"+i,{method:"DELETE",headers:{"Content-Type":"application/json",Authorization:`ApiKey ${s}`}})).json()}};var xt={allowedTags:ze__default.default.defaults.allowedTags.concat(["style","img","html","head","body","link","meta","title"]),allowedAttributes:!1,allowVulnerableTags:!0,parseStyleAttributes:!1,parser:{lowerCaseAttributeNames:!0}},Be=s=>{if(!s)return s;let e=new RegExp("^<!DOCTYPE .*?>"),t=s.match(e),i=ze__default.default(s,xt);return t?t[0]+i:i},me=s=>Object.keys(s).reduce((e,t)=>{let i=s[t];return typeof i=="string"?e[t]=Be(i):Array.isArray(i)?e[t]=i.map(n=>typeof n=="string"?Be(n):typeof n=="object"?me(n):n):typeof i=="object"&&i!==null?e[t]=me(i):e[t]=i,e},{});var ye=class extends A{code="MethodNotAllowedError";statusCode=405;message=`Method not allowed. Please use one of ${De(Z)}`},B=class extends O{code="InvalidActionError";constructor(e,t){super(`Invalid query string: \`action\`=\`${e}\`. Please use one of ${De(t)}`);}},ge=class extends O{code="MissingSecretKeyError";constructor(){super("Missing secret key. Set the `NOVU_SECRET_KEY` environment variable or pass `secretKey` to the client options.");}};var j=class extends L{code="BridgeError";message="Something went wrong. Please try again later."};var Y=class extends ne{constructor(e,t){super(`${ue(e)} with id: \`${t}\` already exists. Please use a different id.`);}},k=class extends ie{constructor(e,t){super(`${ue(e)} with id: \`${t}\` does not exist. Please provide a valid id.`);}},V=class extends L{constructor(e,t){super(`Failed to execute ${ue(e)} with id: \`${t}\`. Please try again later.`);}};var fe=class extends k{code="ProviderNotFoundError";constructor(e){super("provider",e);}},we=class extends V{code="ProviderExecutionFailedError";constructor(e){super("workflow",e);}};var be=class extends N{code="SignatureMismatchError";constructor(){super("Signature does not match the expected signature. Please ensure the signature provided in the `novu-signature` header is correct and try again.");}},Se=class extends N{code="SignatureNotFoundError";constructor(){super("Signature not found. Please provide a signature in the `novu-signature` header");}},Te=class extends N{code="SignatureInvalidError";constructor(){super("Signature is invalid. Please provide a valid signature in the `novu-signature` header");}},Oe=class extends N{code="SignatureExpiredError";constructor(){super(`Signature expired. Please provide a signature with a timestamp no older than ${5} minutes in the \`novu-signature\` header`);}},ve=class extends N{code="SigningKeyNotFoundError";constructor(){super("Signature key not found. Please provide a valid key in the Client constructor `config.secretKey`");}};var Ae=class extends k{code="StepNotFoundError";constructor(e){super("step",e);}},Re=class extends Y{code="StepAlreadyExistsError";constructor(e){super("step",e);}};var z=class extends k{code="WorkflowNotFoundError";constructor(e){super("workflow",e);}},Ee=class extends Y{code="WorkflowAlreadyExistsError";constructor(e){super("workflow",e);}};var _e=s=>typeof structuredClone=="function"?structuredClone(s):JSON.parse(JSON.stringify(s));var xe=class{ajv;compiledSchemas;constructor(){this.ajv=new It__default.default({useDefaults:!0,removeAdditional:"failing"}),Pt__default.default(this.ajv),this.compiledSchemas=new Map;}isSchema(e){return typeof e=="boolean"?!1:e.type==="object"||!!e.anyOf||!!e.allOf||!!e.oneOf}async validate(e,t){let i=this.compiledSchemas.get(t);i||(i=this.ajv.compile(t),this.compiledSchemas.set(t,i));let n=_e(e);return i(n)?{success:!0,data:n}:{success:!1,errors:i.errors.map(c=>({path:c.instancePath,message:c.message}))}}transformToJsonSchema(e){return e}};var Ie=class{isSchema(e){return e.safeParseAsync!==void 0}async validate(e,t){let i=t.safeParse(e);return i.success?{success:!0,data:i.data}:{success:!1,errors:i.error.errors.map(n=>({path:`/${n.path.join("/")}`,message:n.message}))}}transformToJsonSchema(e){try{return zodToJsonSchema.zodToJsonSchema(e)}catch(t){throw t?.message?.includes("Cannot find module")&&console.error("Tried to use a zod schema in @novu/framework without `zod-to-json-schema` installed. Please install it by running `npm install zod-to-json-schema`."),t}}};var Ke=[new Ie,new xe],Pe=async(s,e)=>{for(let t of Ke)if(t.isSchema(s))return t.validate(e,s);throw new Error("Invalid schema")},f=s=>{for(let e of Ke)if(e.isSchema(s))return e.transformToJsonSchema(s);throw new Error("Invalid schema")};jsonSchemaFaker.JSONSchemaFaker.random.shuffle=function(){return ["[placeholder]"]};jsonSchemaFaker.JSONSchemaFaker.option({useDefaultValue:!0,alwaysFakeOptionals:!0});function Ct(){return ["development",void 0].includes(process.env.NODE_ENV)}var K=class{discoveredWorkflows=[];templateEngine=new liquidjs.Liquid;secretKey;version=q;strictAuthentication;constructor(e){let t=this.buildOptions(e);this.secretKey=t.secretKey,this.strictAuthentication=t.strictAuthentication;}buildOptions(e){let t={secretKey:void 0,strictAuthentication:!Ct()};return t.secretKey=e?.secretKey||process.env.NOVU_SECRET_KEY||process.env.NOVU_API_KEY,e?.strictAuthentication!==void 0?t.strictAuthentication=e.strictAuthentication:process.env.NOVU_STRICT_AUTHENTICATION_ENABLED!==void 0&&(t.strictAuthentication=process.env.NOVU_STRICT_AUTHENTICATION_ENABLED==="true"),t}addWorkflows(e){for(let t of e){if(this.discoveredWorkflows.some(i=>i.workflowId===t.definition.workflowId))throw new Ee(t.definition.workflowId);this.discoveredWorkflows.push(t.definition);}}healthCheck(){let e=this.discoveredWorkflows.length,t=this.discoveredWorkflows.reduce((i,n)=>i+n.steps.length,0);return {status:"ok",sdkVersion:q,frameworkVersion:te,discovered:{workflows:e,steps:t}}}getWorkflow(e){let t=this.discoveredWorkflows.find(i=>i.workflowId===e);if(t)return t;throw new z(e)}getStep(e,t){let n=this.getWorkflow(e).steps.find(a=>a.stepId===t);if(n)return n;throw new Ae(t)}getRegisteredWorkflows(){return this.discoveredWorkflows}discover(){return {workflows:this.getRegisteredWorkflows()}}mock(e){return jsonSchemaFaker.JSONSchemaFaker.generate(f(e))}async validate(e,t,i,n,a,c,p){let u=await Pe(t,e);if(u.success)return u.data;switch(i){case"event":this.throwInvalidEvent(n,a,u.errors);case"step":this.throwInvalidStep(c,n,a,u.errors);case"provider":this.throwInvalidProvider(c,p,n,a,u.errors);default:throw new Error(`Invalid component: '${i}'`)}}throwInvalidProvider(e,t,i,n,a){if(!e)throw new Error("stepId is required");if(!t)throw new Error("providerId is required");switch(i){case"output":throw new le(n,e,t,a);default:throw new Error(`Invalid payload type: '${i}'`)}}throwInvalidStep(e,t,i,n){if(!e)throw new Error("stepId is required");switch(t){case"output":throw new ae(i,e,n);case"result":throw new ce(i,e,n);case"controls":throw new re(i,e,n);default:throw new Error(`Invalid payload type: '${t}'`)}}throwInvalidEvent(e,t,i){switch(e){case"controls":throw new se(t,i);case"payload":throw new $(t,i);default:throw new Error(`Invalid payload type: '${e}'`)}}executeStepFactory(e,t){return async(i,n,a)=>{let c=this.getStep(e.workflowId,i),p=_e(e),u=await this.createStepControls(c,p),g=e.action==="preview";if(!g&&await this.shouldSkip(a?.skip,u))return t({options:{skip:!0},outputs:{},providers:{}}),{};let S=this.previewStep.bind(this),_=this.executeStep.bind(this),y=await(g?S:_)(e,{...c,providers:c.providers.map(M=>{let W=a?.providers?.[M.type];if(!W)throw new fe(M.type);return {...M,resolve:W}}),resolve:n});return Object.values(U).includes(c.type)&&(y={...y,outputs:me(y.outputs)}),i===e.stepId&&t({...y,options:{skip:!1}}),y.outputs}}async shouldSkip(e,t){return e?e(t):!1}async executeWorkflow(e){let n=`${{execute:"Executing",preview:"Previewing"}[e.action]} workflowId:`;console.log(`
|
|
24
|
+
${h.bold(h.underline(n))} '${e.workflowId}'`);let a=this.getWorkflow(e.workflowId),c=process.hrtime(),p={outputs:{},providers:{},options:{skip:!1}},u,g=new Promise(I=>{u=I;}),S=I=>{u(),p=I;},_;try{if(e.action==="execute"&&!e.payload&&!e.data)throw new $(e.workflowId,{message:"Event `payload` is required"});let I=await this.createExecutionPayload(e,a),P={...e,payload:I};await Promise.race([g,a.execute({payload:I,environment:{},input:{},controls:{},subscriber:e.subscriber,step:{email:this.executeStepFactory(P,S),sms:this.executeStepFactory(P,S),inApp:this.executeStepFactory(P,S),digest:this.executeStepFactory(P,S),delay:this.executeStepFactory(P,S),push:this.executeStepFactory(P,S),chat:this.executeStepFactory(P,S),custom:this.executeStepFactory(P,S)}})]);}catch(I){_=I;}let X=process.hrtime(c),y=X[0],M=X[1],W=y*1e3+M/1e6,Ot=_?b.ERROR:b.SUCCESS,vt=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action";if(console.log(`${Ot} ${vt} workflowId: \`${e.workflowId}\``),this.prettyPrintExecute(e,W,_),_)throw _;return {outputs:p.outputs,providers:p.providers,options:p.options,metadata:{status:"success",error:!1,duration:W}}}async createExecutionPayload(e,t){let i=e.payload||e.data;if(e.action==="preview"){let a=this.mock(t.payload.schema);i=Object.assign(a,i);}return await this.validate(i,t.payload.unknownSchema,"event","payload",e.workflowId)}prettyPrintExecute(e,t,i){let n=i?b.ERROR:b.SUCCESS,a=e.action==="execute"?"Executed":e.action==="preview"?"Previewed":"Invalid action",c=i?"Failed to execute":a,p=i?h.error:h.success,u=`${n} ${c} workflowId: '${e.workflowId}`;console.log(`
|
|
25
|
+
${h.bold(p(u))}'`),console.log(` \u251C ${b.STEP} stepId: '${e.stepId}'`),console.log(` \u251C ${b.ACTION} action: '${e.action}'`),console.log(` \u2514 ${b.DURATION} duration: '${t.toFixed(2)}ms'
|
|
26
|
+
`);}async executeProviders(e,t,i){return t.providers.reduce(async(n,a)=>{let c=await n,p=this.previewProvider.bind(this),u=this.executeProvider.bind(this),S=await(e.action==="preview"?p:u)(e,t,a,i);return {...c,[a.type]:S}},Promise.resolve({}))}previewProvider(e,t,i,n){return console.log(` ${b.MOCK} Mocked provider: \`${i.type}\``),this.mock(i.outputs.schema)}async executeProvider(e,t,i,n){let a=Ne__default.default({indent:2}).start(`Executing provider: \`${i.type}\``);try{if(e.stepId===t.stepId){let c=await this.createStepControls(t,e),p=await i.resolve({controls:c,outputs:n}),u=await this.validate(p,i.outputs.unknownSchema,"step","output",e.workflowId,t.stepId,i.type);return a.succeed(`Executed provider: \`${i.type}\``),{...u,_passthrough:p._passthrough}}else return a.stopAndPersist({symbol:b.HYDRATED,text:`Hydrated provider: \`${i.type}\``}),{}}catch(c){throw a.stopAndPersist({symbol:b.ERROR,text:`Failed to execute provider: \`${i.type}\``}),new we(`Failed to execute provider: '${i.type}'.
|
|
27
|
+
${c.message}`)}}async executeStep(e,t){if(e.stepId===t.stepId){let i=Ne__default.default({indent:1}).start(`Executing stepId: \`${t.stepId}\``);try{let n=await this.createStepControls(t,e),a=await this.compileControls(n,e),c=await t.resolve(a),p=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId),u=await this.executeProviders(e,t,p);return i.succeed(`Executed stepId: \`${t.stepId}\``),{outputs:p,providers:u}}catch(n){throw i.stopAndPersist({prefixText:"",symbol:b.ERROR,text:`Failed to execute stepId: \`${t.stepId}\``}),n}}else {let i=Ne__default.default({indent:1}).start(`Hydrating stepId: \`${t.stepId}\``);try{let n=e.state.find(a=>a.stepId===t.stepId);if(n){let a=await this.validate(n.outputs,t.results.unknownSchema,"step","result",e.workflowId,t.stepId);return i.stopAndPersist({symbol:b.HYDRATED,text:`Hydrated stepId: \`${t.stepId}\``}),{outputs:a,providers:await this.executeProviders(e,t,a)}}else throw new oe(e.workflowId,t.stepId)}catch(n){throw i.stopAndPersist({symbol:b.ERROR,text:`Failed to hydrate stepId: \`${t.stepId}\``}),n}}}async compileControls(e,t){let i=this.templateEngine.parse(JSON.stringify(e)),n=await this.templateEngine.render(i,{...t.payload||t.data,subscriber:t.subscriber});return JSON.parse(n)}async createStepControls(e,t){let i=t.controls||t.inputs;return await this.validate(i,e.controls.unknownSchema,"step","controls",t.workflowId,e.stepId)}async previewStep(e,t){let i=Ne__default.default({indent:1}).start(`Previewing stepId: \`${t.stepId}\``);try{if(e.stepId===t.stepId){let n=await this.createStepControls(t,e),a=await this.compileControls(n,e),c=await t.resolve(a),p=await this.validate(c,t.outputs.unknownSchema,"step","output",e.workflowId,t.stepId);return i.stopAndPersist({symbol:b.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:p,providers:await this.executeProviders(e,t,p)}}else {let n=this.mock(t.results.schema);return i.stopAndPersist({symbol:b.MOCK,text:`Mocked stepId: \`${t.stepId}\``}),{outputs:n,providers:await this.executeProviders(e,t,n)}}}catch(n){throw i.stopAndPersist({symbol:b.ERROR,text:`Failed to preview stepId: \`${t.stepId}\``}),n}}getStepCode(e,t){return {code:this.getStep(e,t).resolve.toString()}}getWorkflowCode(e){return {code:this.getWorkflow(e).execute.toString()}}getCode(e,t){let i;if(e)t?i=this.getStepCode(e,t):i=this.getWorkflowCode(e);else throw new z(e);return i}};var Ue=class{frameworkName;handler;client;hmacEnabled;http;constructor(e){this.handler=e.handler,this.client=e.client?e.client:new K,this.client.addWorkflows(e.workflows),this.http=he(this.client.secretKey),this.frameworkName=e.frameworkName,this.hmacEnabled=this.client.strictAuthentication;}createHandler(){return async(...e)=>{let t=await this.handler(...e),i=await this.handleAction({actions:t});return t.transformResponse(i)}}getStaticHeaders(){let e=`novu-framework:v${this.client.version}`;return {"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST","access-control-allow-headers":"*","access-control-max-age":"604800","novu-framework-version":te,"novu-framework-sdk":q,"novu-framework-server":this.frameworkName,"user-agent":e}}createResponse(e,t){return {status:e,body:JSON.stringify(t),headers:{...this.getStaticHeaders()}}}createError(e){return {status:e.statusCode,body:JSON.stringify({message:e.message,data:e.data,code:e.code}),headers:this.getStaticHeaders()}}async handleAction({actions:e}){let t=await e.url(),i=await e.method(),n=t.searchParams.get("action")||"",a=t.searchParams.get("workflowId")||"",c=t.searchParams.get("stepId")||"",p=await e.headers("novu-signature")||await e.headers("x-novu-signature")||"",u={};try{i==="POST"&&(u=await e.body());}catch{}try{n!=="health-check"&&this.validateHmac(u,p);let g=this.getPostActionMap(u,a,c,n),S=this.getGetActionMap(a,c);if(i==="POST")return await this.handlePostAction(n,g);if(i==="GET")return await this.handleGetAction(n,S);if(i==="OPTIONS")return this.createResponse(200,{})}catch(g){return this.handleError(g)}return this.createError(new ye(i))}getPostActionMap(e,t,i,n){return {trigger:this.triggerAction({workflowId:t,...e}),execute:async()=>{let a=await this.client.executeWorkflow({...e,workflowId:t,stepId:i,action:n});return this.createResponse(200,a)},preview:async()=>{let a=await this.client.executeWorkflow({...e,workflowId:t,stepId:i,action:n});return this.createResponse(200,a)}}}triggerAction(e){return async()=>{let t={name:e.workflowId,to:e.to,payload:e?.payload||{},transactionId:e.transactionId,overrides:e.overrides||{},...e.actor&&{actor:e.actor},...e.tenant&&{tenant:e.tenant},...e.bridgeUrl&&{bridgeUrl:e.bridgeUrl},...e.controls&&{controls:e.controls}},i=await this.http.post("/events/trigger",t);return this.createResponse(200,i)}}getGetActionMap(e,t){return {discover:async()=>{let i=await this.client.discover();return this.createResponse(200,i)},"health-check":async()=>{let i=await this.client.healthCheck();return this.createResponse(200,i)},code:async()=>{let i=await this.client.getCode(e,t);return this.createResponse(200,i)}}}async handlePostAction(e,t){if(Object.values(G).includes(e)){let i=t[e];return i()}else throw new B(e,G)}async handleGetAction(e,t){if(Object.values(J).includes(e)){let i=t[e];return i()}else throw new B(e,J)}isBridgeError(e){return Object.values(v).includes(e?.code)}isPlatformError(e){return e?.statusCode>=400&&e?.statusCode<500}handleError(e){return this.isBridgeError(e)?(e.statusCode===500&&console.error(e),this.createError(e)):this.isPlatformError(e)?this.createError(e):(console.error(e),this.createError(new j))}validateHmac(e,t){if(!this.hmacEnabled)return;if(!t)throw new Se;if(!this.client.secretKey)throw new ve;let[i,n]=t.split(",");if(!i||!n)throw new Te;let[a,c]=i.split("="),[p,u]=n.split("=");if(Number(a)<Date.now()-1500)throw new Oe;if(!(this.hashHmac(this.client.secretKey,`${c}.${JSON.stringify(e)}`)===u))throw new be}hashHmac(e,t){return crypto.createHmac("sha256",e).update(t).digest("hex")}};var l={output:{type:"object",properties:{},required:[],additionalProperties:!0}};var Mt={type:"object",properties:{webhookUrl:{type:"string",format:"uri"},text:{type:"string"},blocks:{type:"array",items:{type:"object",properties:{type:{enum:["image","context","actions","divider","section","input","file","header","video","rich_text"]}},required:["type"],additionalProperties:!0}}},additionalProperties:!0},He={output:Mt};var Xe={[shared.ChatProviderIdEnum.Discord]:l,[shared.ChatProviderIdEnum.GetStream]:l,[shared.ChatProviderIdEnum.GrafanaOnCall]:l,[shared.ChatProviderIdEnum.Mattermost]:l,[shared.ChatProviderIdEnum.MsTeams]:l,[shared.ChatProviderIdEnum.RocketChat]:l,[shared.ChatProviderIdEnum.Ryver]:l,[shared.ChatProviderIdEnum.Slack]:He,[shared.ChatProviderIdEnum.WhatsAppBusiness]:l,[shared.ChatProviderIdEnum.Zulip]:l};var Ut={type:"object",properties:{to:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:'Email address of the recipient(s). Example: "Bob bob@host.com". You can use commas to separate multiple recipients (e.g.: "test@example.com,test@example.com" or ["test@example.com", "test@example.com"]).'},from:{type:"string"},subject:{type:"string",description:"Subject of the message."},text:{type:"string",description:"Text version of the message."},html:{type:"string",description:"HTML version of the message."},message:{type:"string",description:"MIME string of the message. Make sure to use multipart/form-data to send this as a file upload."},cc:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Same as To but for carbon copy"},bcc:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Same as To but for blind carbon copy"},ampHtml:{type:"string"},tVersion:{type:"string"},tText:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},oTag:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"Tag string. See Tagging for more information."},oDkim:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Enables/disabled DKIM signatures on per-message basis. Pass yes or no"},oDeliverytime:{type:"string",description:"Desired time of delivery. See Date Format. Note: Messages can be scheduled for a maximum of 3 days in the future."},oDeliverytimeOptimizePeriod:{type:"string"},oTimeZoneLocalize:{type:"string"},oTestmode:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Enables sending in test mode. Pass yes if needed. See Sending in Test Mode"},oTracking:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Toggles tracking on a per-message basis, see Tracking Messages for details. Pass yes or no."},oTrackingClicks:{anyOf:[{type:"string",enum:["yes","no","htmlonly"]},{type:"boolean"}],description:"Toggles clicks tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes, no or htmlonly."},oTrackingOpens:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}],description:"Toggles opens tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes or no."},oRequireTls:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},oSkipVerification:{anyOf:[{type:"string",enum:["yes","no"]},{type:"boolean"}]},recipientVariables:{type:"string"}},required:[],additionalProperties:!0},Je={output:Ut};var C={type:"object",properties:{name:{type:"string"},email:{type:"string"}},description:'JSON object, containing 2 properties: Name and Email address of a previously validated and active sender. Including the Name property in the JSON is optional. This property is not mandatory in case you use TemplateID and you specified a From address for the template. Format : { "Email":"value", "Name":"value" }.',required:["Email"],additionalProperties:!0},Lt={type:"object",properties:{contentType:{type:"string"},filename:{type:"string"},base64Content:{type:"string"}},required:["ContentType","Filename","Base64Content"],additionalProperties:!0},Ft={type:"object",properties:{filename:{type:"string"},contentType:{type:"string"},contentId:{type:"string"},base64Content:{type:"string"}},required:["ContentType","Filename","Base64Content"],additionalProperties:!0},jt={type:"object",properties:{from:C,sender:C,to:{type:"array",items:C},cc:{type:"array",items:C},bcc:{type:"array",items:C},replyTo:C,subject:{type:"string"},textPart:{type:"string",description:"Content of the message, sent in Text and/or HTML format. At least one of these content types needs to be specified. When the HTML part is the only part provided, Mailjet will not generate a Text-part from the HTML version. The property can't be set when you use TemplateID"},htmlPart:{type:"string",description:"Content of the message, sent in Text and/or HTML format. At least one of these content types needs to be specified. When the HTML part is the only part provided, Mailjet will not generate a Text-part from the HTML version. The property can't be set when you use TemplateID"},templateId:{type:"number",description:"an ID for a template that is previously created and stored in Mailjet's system. It is mandatory when From and TextPart and/or HtmlPart are not provided. "},templateLanguage:{type:"boolean"},templateErrorReporting:C,templateErrorDeliver:{type:"boolean"},attachments:{type:"array",items:Lt},inlineAttachments:{type:"array",items:Ft},priority:{type:"number"},customCampaign:{type:"string"},deduplicateCampaign:{type:"boolean"},trackOpens:{type:"string",enum:["account_default","disabled","enabled"]},trackClicks:{type:"string",enum:["account_default","disabled","enabled"]},customId:{type:"string"},eventPayload:{type:"string"},urlTags:{type:"string"},headers:{type:"object",additionalProperties:!0},variables:{type:"object",additionalProperties:!0}},required:[],additionalProperties:!0},Ze={output:jt};var R={type:"object",properties:{address:{type:"string"},name:{type:"string"}},additionalProperties:!0},ke={type:"object",properties:{content:{type:"string"},path:{type:"string"}},additionalProperties:!0},Yt={type:"object",properties:{from:{anyOf:[{type:"string"},R]},sender:{anyOf:[{type:"string"},R]},to:{anyOf:[{type:"string"},R,{type:"array",items:R}]},cc:{anyOf:[{type:"string"},R,{type:"array",items:R}]},bcc:{anyOf:[{type:"string"},R,{type:"array",items:R}]},replyTo:{anyOf:[{type:"string"},R,{type:"array",items:R}]},inReplyTo:{anyOf:[{type:"string"},R]},references:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}]},subject:{type:"string"},text:{anyOf:[{type:"string"},ke]},html:{anyOf:[{type:"string"},ke]},watchHtml:{anyOf:[{type:"string"},ke]},amp:{anyOf:[{type:"string"},{type:"object",properties:{content:{type:"string"},path:{type:"string"},href:{type:"string"},encoding:{type:"string"},contentType:{type:"string"},raw:{anyOf:[{type:"string"},ke]}}}]},icalEvent:{anyOf:[{type:"string"},{type:"object",properties:{content:{type:"string"},path:{type:"string"},method:{type:"string"},filename:{anyOf:[{type:"string"},{type:"boolean"}]},href:{type:"string"},encoding:{type:"string"}}}]},headers:{anyOf:[{type:"object",additionalProperties:!0},{type:"array",items:{type:"object",additionalProperties:!0}}]},list:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}]},attachments:{type:"array",items:{type:"object",properties:{content:{type:"string"},path:{type:"string"}},additionalProperties:!0}}},required:[],additionalProperties:!0},Qe={output:Yt};var Vt={type:"object",properties:{},required:[],additionalProperties:!1},et={output:Vt};var Wt={type:"object",properties:{personalizations:{type:"array",description:"An array of messages and their metadata. Each object within personalizations can be thought of as an envelope - it defines who should receive an individual message and how that message should be handled. See our [Personalizations documentation](https://sendgrid.com/docs/for-developers/sending-email/personalizations/) for examples.",uniqueItems:!1,maxItems:1e3,items:{type:"object",properties:{from:{title:"From Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The 'From' email address used to deliver the message. This address should be a verified sender in your Twilio SendGrid account."},name:{type:"string",description:"A name or title associated with the sending email address."}},required:["email"]},to:{title:"To Email Array",type:"array",items:{type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},cc:{type:"array",description:"An array of recipients who will receive a copy of your email. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name.",maxItems:1e3,items:{title:"CC BCC Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},bcc:{type:"array",description:"An array of recipients who will receive a blind carbon copy of your email. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name.",maxItems:1e3,items:{title:"CC BCC Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The intended recipient's email address."},name:{type:"string",description:"The intended recipient's name."}},required:["email"]}},subject:{type:"string",description:"The subject of your email. See character length requirements according to [RFC 2822](http://stackoverflow.com/questions/1592291/what-is-the-email-subject-length-limit#answer-1592310).",minLength:1},headers:{type:"object",description:"A collection of JSON key/value pairs allowing you to specify handling instructions for your email. You may not overwrite the following headers: `x-sg-id`, `x-sg-eid`, `received`, `dkim-signature`, `Content-Type`, `Content-Transfer-Encoding`, `To`, `From`, `Subject`, `Reply-To`, `CC`, `BCC`"},substitutions:{type:"object",description:'Substitutions allow you to insert data without using Dynamic Transactional Templates. This field should **not** be used in combination with a Dynamic Transactional Template, which can be identified by a `templateId` starting with `d-`. This field is a collection of key/value pairs following the pattern "substitutionTag":"value to substitute". The key/value pairs must be strings. These substitutions will apply to the text and html content of the body of your email, in addition to the `subject` and `reply-to` parameters. The total collective size of your substitutions may not exceed 10,000 bytes per personalization object.',maxProperties:1e4},dynamicTemplateData:{type:"object",description:'Dynamic template data is available using Handlebars syntax in Dynamic Transactional Templates. This field should be used in combination with a Dynamic Transactional Template, which can be identified by a `templateId` starting with `d-`. This field is a collection of key/value pairs following the pattern "variable_name":"value to insert".'},customArgs:{type:"object",description:"Values that are specific to this personalization that will be carried along with the email and its activity data. Substitutions will not be made on custom arguments, so any string that is entered into this parameter will be assumed to be the custom argument that you would like to be used. This field may not exceed 10,000 bytes.",maxProperties:1e4},sendAt:{type:"integer",description:"A unix timestamp allowing you to specify when your email should be delivered. Scheduling delivery more than 72 hours in advance is forbidden."}},required:["to"]}},from:{title:"From Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The 'From' email address used to deliver the message. This address should be a verified sender in your Twilio SendGrid account."},name:{type:"string",description:"A name or title associated with the sending email address."}},required:["email"]},replyTo:{title:"Reply_to Email Object",type:"object",properties:{email:{type:"string",format:"email",description:"The email address where any replies or bounces will be returned."},name:{type:"string",description:"A name or title associated with the `replyTo` email address."}},required:["email"]},replyToList:{type:"array",description:"An array of recipients who will receive replies and/or bounces. Each object in this array must contain the recipient's email address. Each object in the array may optionally contain the recipient's name. You can either choose to use \u201CreplyTo\u201D field or \u201CreplyToList\u201D but not both.",uniqueItems:!0,maxItems:1e3,items:{type:"object",properties:{email:{type:"string",description:"The email address where any replies or bounces will be returned.",format:"email"},name:{type:"string",description:"A name or title associated with the `replyToList` email address."}},required:["email"]}},subject:{type:"string",description:"The global or 'message level' subject of your email. This may be overridden by subject lines set in personalizations.",minLength:1},content:{type:"array",description:"An array where you can specify the content of your email. You can include multiple [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) of content, but you must specify at least one MIME type. To include more than one MIME type, add another object to the array containing the `type` and `value` parameters.",items:{type:"object",properties:{type:{type:"string",description:"The MIME type of the content you are including in your email (e.g., `\u201Ctext/plain\u201D` or `\u201Ctext/html\u201D`).",minLength:1},value:{type:"string",description:"The actual content of the specified MIME type that you are including in your email.",minLength:1}},required:["type","value"]}},attachments:{type:"array",description:"An array of objects where you can specify any attachments you want to include.",items:{type:"object",properties:{content:{type:"string",description:"The Base64 encoded content of the attachment.",minLength:1},type:{type:"string",description:"The MIME type of the content you are attaching (e.g., `\u201Ctext/plain\u201D` or `\u201Ctext/html\u201D`).",minLength:1},filename:{type:"string",description:"The attachment's filename."},disposition:{type:"string",default:"attachment",description:"The attachment's content-disposition, specifying how you would like the attachment to be displayed. For example, `\u201Cinline\u201D` results in the attached file are displayed automatically within the message while `\u201Cattachment\u201D` results in the attached file require some action to be taken before it is displayed, such as opening or downloading the file.",enum:["inline","attachment"]},contentId:{type:"string",description:"The attachment's content ID. This is used when the disposition is set to `\u201Cinline\u201D` and the attachment is an image, allowing the file to be displayed within the body of your email."}},required:["content","filename"]}},templateId:{type:"string",description:"An email template ID. A template that contains a subject and content \u2014 either text or html \u2014 will override any subject and content values specified at the personalizations or message level."},headers:{description:"An object containing key/value pairs of header names and the value to substitute for them. The key/value pairs must be strings. You must ensure these are properly encoded if they contain unicode characters. These headers cannot be one of the reserved headers.",type:"object"},categories:{type:"array",description:"An array of category names for this message. Each category name may not exceed 255 characters. ",uniqueItems:!0,maxItems:10,items:{type:"string",maxLength:255}},customArgs:{description:"Values that are specific to the entire send that will be carried along with the email and its activity data. Key/value pairs must be strings. Substitutions will not be made on custom arguments, so any string that is entered into this parameter will be assumed to be the custom argument that you would like to be used. This parameter is overridden by `customArgs` set at the personalizations level. Total `customArgs` size may not exceed 10,000 bytes.",type:"string"},sendAt:{type:"integer",description:"A unix timestamp allowing you to specify when you want your email to be delivered. This may be overridden by the `sendAt` parameter set at the personalizations level. Delivery cannot be scheduled more than 72 hours in advance. If you have the flexibility, it's better to schedule mail for off-peak times. Most emails are scheduled and sent at the top of the hour or half hour. Scheduling email to avoid peak times \u2014 for example, scheduling at 10:53 \u2014 can result in lower deferral rates due to the reduced traffic during off-peak times."},batchId:{type:"string",description:"An ID representing a batch of emails to be sent at the same time. Including a `batchId` in your request allows you include this email in that batch. It also enables you to cancel or pause the delivery of that batch. For more information, see the [Cancel Scheduled Sends API](https://sendgrid.com/docs/api-reference/)."},asm:{type:"object",description:"An object allowing you to specify how to handle unsubscribes.",properties:{groupId:{type:"integer",description:"The unsubscribe group to associate with this email."},groupsToDisplay:{type:"array",description:"An array containing the unsubscribe groups that you would like to be displayed on the unsubscribe preferences page.",maxItems:25,items:{type:"integer"}}},required:["groupId"]},ipPoolName:{type:"string",description:"The IP Pool that you would like to send this email from.",minLength:2,maxLength:64},mailSettings:{type:"object",description:"A collection of different mail settings that you can use to specify how you would like this email to be handled.",properties:{bypassListManagement:{type:"object",description:"Allows you to bypass all unsubscribe groups and suppressions to ensure that the email is delivered to every single recipient. This should only be used in emergencies when it is absolutely necessary that every recipient receives your email. This filter cannot be combined with any other bypass filters. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassSpamManagement:{type:"object",description:"Allows you to bypass the spam report list to ensure that the email is delivered to recipients. Bounce and unsubscribe lists will still be checked; addresses on these other lists will not receive the message. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassBounceManagement:{type:"object",description:"Allows you to bypass the bounce list to ensure that the email is delivered to recipients. Spam report and unsubscribe lists will still be checked; addresses on these other lists will not receive the message. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},bypassUnsubscribeManagement:{type:"object",description:"Allows you to bypass the global unsubscribe list to ensure that the email is delivered to recipients. Bounce and spam report lists will still be checked; addresses on these other lists will not receive the message. This filter applies only to global unsubscribes and will not bypass group unsubscribes. This filter cannot be combined with the `bypassListManagement` filter. See our [documentation](https://sendgrid.com/docs/ui/sending-email/index-suppressions/#bypass-suppressions) for more about bypass filters.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}},footer:{type:"object",description:"The default footer that you would like included on every email.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},text:{type:"string",description:"The plain text content of your footer."},html:{type:"string",description:"The HTML content of your footer."}}},sandboxMode:{type:"object",description:"Sandbox Mode allows you to send a test email to ensure that your request body is valid and formatted correctly.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."}}}}},trackingSettings:{type:"object",description:"Settings to determine how you would like to track the metrics of how your recipients interact with your email.",properties:{clickTracking:{type:"object",description:"Allows you to track if a recipient clicked a link in your email.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},enableText:{type:"boolean",description:"Indicates if this setting should be included in the `text/plain` portion of your email."}}},openTracking:{type:"object",description:"Allows you to track if the email was opened by including a single pixel image in the body of the content. When the pixel is loaded, Twilio SendGrid can log that the email was opened.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},substitutionTag:{type:"string",description:"Allows you to specify a substitution tag that you can insert in the body of your email at a location that you desire. This tag will be replaced by the open tracking pixel."}}},subscriptionTracking:{type:"object",description:"Allows you to insert a subscription management link at the bottom of the text and HTML bodies of your email. If you would like to specify the location of the link within your email, you may use the `substitutionTag`.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},text:{type:"string",description:"Text to be appended to the email with the subscription tracking link. You may control where the link is by using the tag <% %>"},html:{type:"string",description:"HTML to be appended to the email with the subscription tracking link. You may control where the link is by using the tag <% %>"},substitutionTag:{type:"string",description:"A tag that will be replaced with the unsubscribe URL. for example: `[unsubscribe_url]`. If this parameter is used, it will override both the `text` and `html` parameters. The URL of the link will be placed at the substitution tag\u2019s location with no additional formatting."}}},ganalytics:{type:"object",description:"Allows you to enable tracking provided by Google Analytics.",properties:{enable:{type:"boolean",description:"Indicates if this setting is enabled."},utmSource:{type:"string",description:"Name of the referrer source. (e.g. Google, SomeDomain.com, or Marketing Email)"},utmMedium:{type:"string",description:"Name of the marketing medium. (e.g. Email)"},utmTerm:{type:"string",description:"Used to identify any paid keywords."},utmContent:{type:"string",description:"Used to differentiate your campaign from advertisements."},utmCampaign:{type:"string",description:"The name of the campaign."}}}}}},required:[],additionalProperties:!1},tt={output:Wt};var it={[shared.EmailProviderIdEnum.Braze]:l,[shared.EmailProviderIdEnum.Clickatell]:l,[shared.EmailProviderIdEnum.CustomSMTP]:Qe,[shared.EmailProviderIdEnum.EmailJS]:l,[shared.EmailProviderIdEnum.EmailWebhook]:l,[shared.EmailProviderIdEnum.Infobip]:l,[shared.EmailProviderIdEnum.MailerSend]:l,[shared.EmailProviderIdEnum.Mailgun]:Je,[shared.EmailProviderIdEnum.Mailjet]:Ze,[shared.EmailProviderIdEnum.Mailtrap]:l,[shared.EmailProviderIdEnum.Mandrill]:l,[shared.EmailProviderIdEnum.NetCore]:l,[shared.EmailProviderIdEnum.Novu]:et,[shared.EmailProviderIdEnum.Outlook365]:l,[shared.EmailProviderIdEnum.Plunk]:l,[shared.EmailProviderIdEnum.Postmark]:l,[shared.EmailProviderIdEnum.Resend]:l,[shared.EmailProviderIdEnum.SendGrid]:tt,[shared.EmailProviderIdEnum.Sendinblue]:l,[shared.EmailProviderIdEnum.SES]:l,[shared.EmailProviderIdEnum.SparkPost]:l};var Gt={type:"object",properties:{},required:[],additionalProperties:!1},nt={output:Gt};var ot={[shared.InAppProviderIdEnum.Novu]:nt};var st={anyOf:[{type:"string"},{type:"object",additionalProperties:!0,properties:{name:{type:"string"},volume:{type:"number"},critical:{type:"number"}},required:["name","volume","critical"]}]},$t={type:"object",properties:{topic:{type:"string",description:"The destination topic for the notification."},id:{type:"string",description:"A UUID to identify the notification with APNS. If an id is not supplied, APNS will generate one automatically. If an error occurs the response will contain the id. This property populates the apns-id header."},expiry:{type:"number",description:"A UNIX timestamp when the notification should expire. If the notification cannot be delivered to the device, APNS will retry until it expires. An expiry of 0 indicates that the notification expires immediately, therefore no retries will be attempted."},priority:{type:"number",description:`Provide one of the following values:
|
|
110
28
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
29
|
+
10 - The push notification is sent to the device immediately. (Default)
|
|
30
|
+
The push notification must trigger an alert, sound, or badge on the device. It is an error to use this priority for a push notification that contains only the content-available key.
|
|
31
|
+
|
|
32
|
+
5 - The push message is sent at a time that conserves power on the device receiving it.`},collapseId:{type:"string"},pushType:{type:"string",enum:["background","alert","voip"],description:`The type of the notification. The value of this header is alert or background. Specify alert when the delivery of your notification displays an alert, plays a sound, or badges your app's icon. Specify background for silent notifications that do not interact with the user.
|
|
33
|
+
|
|
34
|
+
The value of this header must accurately reflect the contents of your notification's payload. If there is a mismatch, or if the header is missing on required systems, APNs may delay the delivery of the notification or drop it altogether.`},threadId:{type:"string"},payload:{type:"object",additionalProperties:!0},aps:{type:"object",additionalProperties:!0,properties:{badge:{type:"number"},sound:st,category:{type:"string"},contentAvailable:{type:"number"},launchImage:{type:"number"},mutableContent:{type:"number"},urlArgs:{type:"array",items:{type:"string"}}}},rawPayload:{type:"object",additionalProperties:!0},badge:{type:"number"},sound:st,alert:{anyOf:[{type:"string"},{type:"object",additionalProperties:!0,properties:{title:{type:"string"},body:{type:"string"},subtitle:{type:"string"},titleLocKey:{type:"string"},titleLocArgs:{type:"array",items:{type:"string"}},actionLocKey:{type:"string"},locKey:{type:"string"},locArgs:{type:"array",items:{type:"string"}},launchImage:{type:"string"}},required:["body"]}]},contentAvailable:{type:"boolean"},mutableContent:{type:"boolean"},mdm:{anyOf:[{type:"string"},{type:"object",additionalProperties:!0}]},urlArgs:{type:"array",items:{type:"string"}}},required:[],additionalProperties:!0},rt={output:$t};var Bt={type:"object",properties:{to:{anyOf:[{type:"string"},{type:"array",items:{type:"string"}}],description:"An Expo push token or an array of Expo push tokens specifying the recipient(s) of this message."},data:{type:"object",additionalProperties:!0,description:'A JSON object delivered to your app. It may be up to about 4KiB; the total notification payload sent to Apple and Google must be at most 4KiB or else you will get a "Message Too Big" error.'},title:{type:"string",description:"The title to display in the notification. Often displayed above the notification body."},subtitle:{type:"string",description:"The subtitle to display in the notification below the title."},body:{type:"string",description:"The message to display in the notification."},sound:{anyOf:[{type:"string"},{type:"null"},{type:"object",properties:{name:{anyOf:[{type:"string",enum:["default"]},{type:"null"}]},volume:{type:"number"},critical:{type:"boolean"}},additionalProperties:!0}],description:"Play a sound when the recipient receives this notification. Specify default to play the device's default notification sound, or omit this field to play no sound. Custom sounds are not supported."},ttl:{type:"number",description:"Time to Live: the number of seconds for which the message may be kept around for redelivery if it hasn't been delivered yet. Defaults to undefined to use the respective defaults of each provider (2419200 (4 weeks) for Android/FCM and 0 for iOS/APNs)."},expiration:{type:"number",description:"Timestamp since the Unix epoch specifying when the message expires. Same effect as ttl (ttl takes precedence over expiration)."},priority:{type:"string",enum:["default","normal","high"],description:'The delivery priority of the message. Specify default or omit this field to use the default priority on each platform ("normal" on Android and "high" on iOS).'},badge:{type:"number",description:"Number to display in the badge on the app icon. Specify zero to clear the badge."},channelId:{type:"string",description:"ID of the Notification Channel through which to display this notification. If an ID is specified but the corresponding channel does not exist on the device (that has not yet been created by your app), the notification will not be displayed to the user."},categoryId:{type:"string",description:"ID of the notification category that this notification is associated with."},mutableContent:{type:"boolean",description:"Specifies whether this notification can be intercepted by the client app. In Expo Go, this defaults to true, and if you change that to false, you may experience issues. In standalone and bare apps, this defaults to false."}},required:[],additionalProperties:!0},at={output:Bt};var zt={type:"object",properties:{to:{description:`This parameter specifies the recipient of a message.
|
|
35
|
+
The value must be a registration token, notification key, or topic. Do not set this field when sending to multiple topics. See **condition**.
|
|
36
|
+
`,type:"string"},registrationIds:{description:`This parameter specifies a list of devices (registration tokens, or IDs) receiving a multicast message. It must contain at least 1 and at most 1000 registration tokens.
|
|
37
|
+
Use this parameter only for multicast messaging, not for single recipients. Multicast messages (sending to more than 1 registration tokens) are allowed using HTTP JSON format only.
|
|
38
|
+
`,type:"array",items:{type:"string"}},condition:{description:`This parameter specifies a logical expression of conditions that determine the message target.
|
|
39
|
+
Supported condition: Topic, formatted as yourTopic in topics. This value is case-insensitive.
|
|
40
|
+
Supported operators: &&, ||. Maximum two operators per topic message supported.
|
|
41
|
+
`,type:"string"},notificationKey:{description:`This parameter is deprecated. Instead, use **to** to specify message recipients. For more information on how to send messages to multiple devices using **to**, see [Device Group Messaging](https://firebase.google.com/docs/cloud-messaging/notifications).
|
|
42
|
+
`,type:"string"},collapseKey:{description:'This parameter identifies a group of messages (e.g., with ```"collapseKey": "Updates Available"```) that can be collapsed, so that only the last message gets sent when delivery can be resumed. This is intended to avoid sending too many of the same messages when the device comes back online or becomes active (see **delayWhileIdle**).\nNote that there is no guarantee of the order in which messages get sent.\nNote: A maximum of 4 different collapse keys is allowed at any given time. This means a FCM connection server can simultaneously store 4 different send-to-sync messages per client app. If you exceed this number, there is no guarantee which 4 collapse keys the FCM connection server will keep.\n',type:"string"},priority:{description:`Sets the priority of the message. Valid values are normal and high. On iOS, these correspond to APNs priorities 5 and 10.
|
|
43
|
+
By default, messages are sent with normal priority. Normal priority optimizes the client app's battery consumption and should be used unless immediate delivery is required. For messages with normal priority, the app may receive the message with unspecified delay.
|
|
44
|
+
When a message is sent with high priority, it is sent immediately, and the app can wake a sleeping device and open a network connection to your server.For more information, see [Setting the priority of a message](https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message).
|
|
45
|
+
`,type:"string",enum:["normal","high"]},contentAvailable:{description:"On iOS, use this field to represent **content-available** in the APNS payload. When a notification or message is sent and this is set to ```true```, an inactive client app is awoken. On Android, data messages wake the app by default. On Chrome, currently not supported.\n",type:"boolean"},mutableContent:{description:`Currently for iOS 10+ devices only. On iOS, use this field to represent mutable-content in the APNS payload. When a notification is sent and this is set to true, the content of the notification can be modified before it is displayed, using a [Notification Service app extension](https://developer.apple.com/reference/usernotifications/unnotificationserviceextension). This parameter will be ignored for Android and web.
|
|
46
|
+
`,type:"boolean"},delayWhileIdle:{description:"When this parameter is set to ```true```, it indicates that the message should not be sent until the device becomes active.\nThe default value is ```false```.\n",type:"boolean"},timeToLive:{description:`This parameter specifies how long (in seconds) the message should be kept in FCM storage if the device is offline. The maximum time to live supported is 4 weeks, and the default value is 4 weeks. For more information, see [Setting the lifespan of a message](https://firebase.google.com/docs/cloud-messaging/concept-options#ttl).
|
|
47
|
+
`,type:"number"},restrictedPackageName:{description:`This parameter specifies the package name of the application where the registration tokens must match in order to receive the message.
|
|
48
|
+
`,type:"string"},dryRun:{description:"This parameter, when set to ```true```, allows developers to test a request without actually sending a message.\nThe default value is ```false```.\n",type:"boolean"},data:{description:'This parameter specifies the custom key-value pairs of the message\'s payload.\nFor example, with ```"data":{"score":"3x1"}```:\nOn iOS, if the message is sent via APNS, it represents the custom data fields. If it is sent via FCM connection server, it would be represented as key value dictionary in ```AppDelegate application:didReceiveRemoteNotification:```.\nOn Android, this would result in an intent extra named **score** with the string value **3x1**.\nThe key should not be a reserved word ("from" or any word starting with "google" or "gcm"). Do not use any of the words defined in this table (such as **collapseKey**).\n',type:"object",additionalProperties:{type:"string"}},notification:{description:`Notification payload. For more information about notification message and data message options, see [Payload](https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages).
|
|
49
|
+
`,type:"object",properties:{title:{description:"Indicates notification title. This field is not visible on iOS phones and tablets. Field is required for android.",type:"string"},body:{description:"Indicates notification body text.",type:"string"},icon:{description:"android: Indicates notification icon. Sets value to **myicon** for drawable resource **myicon**.",type:"string"},sound:{description:`Indicates a sound to play when the device receives a notification.
|
|
50
|
+
* iOS: Sound files can be in the main bundle of the client app or in the Library/Sounds folder of the app's data container. See the [iOS Developer Library](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html#//apple_ref/doc/uid/TP40008194-CH103-SW6) for more information).
|
|
51
|
+
* android: Supports default or the filename of a sound resource bundled in the app. Sound files must reside in /res/raw/.
|
|
52
|
+
`,type:"string"},badge:{description:"iOS: Indicates the badge on the client app home icon.",type:"string"},tag:{description:`android: Indicates whether each notification results in a new entry in the notification drawer.
|
|
53
|
+
If not set, each request creates a new notification.
|
|
54
|
+
If set, and a notification with the same tag is already being shown, the new notification replaces the existing one in the notification drawer.
|
|
55
|
+
`,type:"string"},color:{description:"android: Indicates color of the icon, expressed in #rrggbb format",type:"string"},clickAction:{description:`Indicates the action associated with a user click on the notification.
|
|
56
|
+
* iOS: Corresponds to category in the APNs payload.
|
|
57
|
+
* android: When this is set, an activity with a matching intent filter is launched when user clicks the notification.
|
|
58
|
+
`,type:"string"},bodyLocKey:{description:`Indicates the key to the body string for localization.
|
|
59
|
+
* iOS: Corresponds to "loc-key" in the APNs payload.
|
|
60
|
+
* android: Use the key in the app's string resources when populating this value.
|
|
61
|
+
`,type:"string"},bodyLocArgs:{description:`Indicates the string value to replace format specifiers in the body string for localization.
|
|
62
|
+
* iOS: Corresponds to "loc-args" in the APNs payload.
|
|
63
|
+
* android: See [Formatting and Styling](https://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling).
|
|
64
|
+
`,type:"string"},titleLocKey:{description:`Indicates the key to the title string for localization.
|
|
65
|
+
* iOS: Corresponds to "title-loc-key" in the APNs payload.
|
|
66
|
+
* android: Use the key in the app's string resources when populating this value.
|
|
67
|
+
`,type:"string"},titleLocArgs:{description:`Indicates the string value to replace format specifiers in the title string for localization.
|
|
68
|
+
* iOS: Corresponds to "title-loc-args" in the APNs payload.
|
|
69
|
+
* android: See [Formatting strings](https://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling).
|
|
70
|
+
`,type:"string"}}}},required:[],additionalProperties:!0},ct={output:zt};var Kt={allOf:[{allOf:[{anyOf:[{type:"object",properties:{includedSegments:{type:"array",description:`The segment names you want to target. Users in these segments will receive a notification. This targeting parameter is only compatible with excludedSegments.
|
|
71
|
+
Example: ["Active Users", "Inactive Users"]
|
|
72
|
+
`,items:{type:"string"}},excludedSegments:{type:"array",description:`Segment that will be excluded when sending. Users in these segments will not receive a notification, even if they were included in includedSegments. This targeting parameter is only compatible with includedSegments.
|
|
73
|
+
Example: ["Active Users", "Inactive Users"]
|
|
74
|
+
`,items:{type:"string"}}}},{type:"object",properties:{includePlayerIds:{type:"array",description:`Specific playerids to send your notification to. _Does not require API Auth Key.
|
|
75
|
+
Do not combine with other targeting parameters. Not compatible with any other targeting parameters.
|
|
76
|
+
Example: ["1dd608f2-c6a1-11e3-851d-000c2940e62c"]
|
|
77
|
+
Limit of 2,000 entries per REST API call
|
|
78
|
+
`,items:{type:"string"},nullable:!0},includeExternalUserIds:{type:"array",description:`Target specific devices by custom user IDs assigned via API.
|
|
79
|
+
Not compatible with any other targeting parameters
|
|
80
|
+
Example: ["custom-id-assigned-by-api"]
|
|
81
|
+
REQUIRED: REST API Key Authentication
|
|
82
|
+
Limit of 2,000 entries per REST API call.
|
|
83
|
+
Note: If targeting push, email, or sms subscribers with same ids, use with channelForExternalUserIds to indicate you are sending a push or email or sms.
|
|
84
|
+
`,items:{type:"string"},nullable:!0},includeEmailTokens:{type:"array",description:`Recommended for Sending Emails - Target specific email addresses.
|
|
85
|
+
If an email does not correspond to an existing user, a new user will be created.
|
|
86
|
+
Example: nick@catfac.ts
|
|
87
|
+
Limit of 2,000 entries per REST API call
|
|
88
|
+
`,items:{type:"string"}},includePhoneNumbers:{type:"array",description:`Recommended for Sending SMS - Target specific phone numbers. The phone number should be in the E.164 format. Phone number should be an existing subscriber on OneSignal. Refer our docs to learn how to add phone numbers to OneSignal.
|
|
89
|
+
Example phone number: +1999999999
|
|
90
|
+
Limit of 2,000 entries per REST API call
|
|
91
|
+
`,items:{type:"string"}},includeIosTokens:{type:"array",description:`Not Recommended: Please consider using includePlayerIds or includeExternalUserIds instead.
|
|
92
|
+
Target using iOS device tokens.
|
|
93
|
+
Warning: Only works with Production tokens.
|
|
94
|
+
All non-alphanumeric characters must be removed from each token. If a token does not correspond to an existing user, a new user will be created.
|
|
95
|
+
Example: ce777617da7f548fe7a9ab6febb56cf39fba6d38203...
|
|
96
|
+
Limit of 2,000 entries per REST API call
|
|
97
|
+
`,items:{type:"string"}},includeWpWnsUris:{type:"array",description:`Not Recommended: Please consider using includePlayerIds or includeExternalUserIds instead.
|
|
98
|
+
Target using Windows URIs. If a token does not correspond to an existing user, a new user will be created.
|
|
99
|
+
Example: http://s.notify.live.net/u/1/bn1/HmQAAACPaLDr-...
|
|
100
|
+
Limit of 2,000 entries per REST API call
|
|
101
|
+
`,items:{type:"string"}},includeAmazonRegIds:{type:"array",description:`Not Recommended: Please consider using includePlayerIds or includeExternalUserIds instead.
|
|
102
|
+
Target using Amazon ADM registration IDs. If a token does not correspond to an existing user, a new user will be created.
|
|
103
|
+
Example: amzn1.adm-registration.v1.XpvSSUk0Rc3hTVVV...
|
|
104
|
+
Limit of 2,000 entries per REST API call
|
|
105
|
+
`,items:{type:"string"}},includeChromeRegIds:{type:"array",description:`Not Recommended: Please consider using includePlayerIds or includeExternalUserIds instead.
|
|
106
|
+
Target using Chrome App registration IDs. If a token does not correspond to an existing user, a new user will be created.
|
|
107
|
+
Example: APA91bEeiUeSukAAUdnw3O2RB45FWlSpgJ7Ji_...
|
|
108
|
+
Limit of 2,000 entries per REST API call
|
|
109
|
+
`,items:{type:"string"}},includeChromeWebRegIds:{type:"array",description:`Not Recommended: Please consider using includePlayerIds or includeExternalUserIds instead.
|
|
110
|
+
Target using Chrome Web Push registration IDs. If a token does not correspond to an existing user, a new user will be created.
|
|
111
|
+
Example: APA91bEeiUeSukAAUdnw3O2RB45FWlSpgJ7Ji_...
|
|
112
|
+
Limit of 2,000 entries per REST API call
|
|
113
|
+
`,items:{type:"string"}},includeAndroidRegIds:{type:"array",description:`Not Recommended: Please consider using includePlayerIds or includeExternalUserIds instead.
|
|
114
|
+
Target using Android device registration IDs. If a token does not correspond to an existing user, a new user will be created.
|
|
115
|
+
Example: APA91bEeiUeSukAAUdnw3O2RB45FWlSpgJ7Ji_...
|
|
116
|
+
Limit of 2,000 entries per REST API call
|
|
117
|
+
`,items:{type:"string"}},includeAliases:{type:"object",properties:{aliasLabel:{type:"array",items:{type:"string"}}},nullable:!0},targetChannel:{type:"string",enum:["push","email","sms"]}}}]},{type:"object",properties:{id:{type:"string"},value:{type:"integer",readOnly:!0},name:{type:"string",description:`Required for SMS Messages.
|
|
118
|
+
An identifier for tracking message within the OneSignal dashboard or export analytics.
|
|
119
|
+
Not shown to end user.`,writeOnly:!0,nullable:!0},aggregation:{type:"string",enum:["sum","count"],readOnly:!0},isIos:{type:"boolean",description:"Indicates whether to send to all devices registered under your app's Apple iOS platform.",writeOnly:!0,nullable:!0},isAndroid:{type:"boolean",description:"Indicates whether to send to all devices registered under your app's Google Android platform.",writeOnly:!0,nullable:!0},isHuawei:{type:"boolean",description:"Indicates whether to send to all devices registered under your app's Huawei Android platform.",writeOnly:!0,nullable:!0},isAnyWeb:{type:"boolean",description:`Indicates whether to send to all subscribed web browser users, including Chrome, Firefox, and Safari.
|
|
120
|
+
You may use this instead as a combined flag instead of separately enabling isChromeWeb, isFirefox, and isSafari, though the three options are equivalent to this one.
|
|
121
|
+
`,writeOnly:!0,nullable:!0},isChromeWeb:{type:"boolean",writeOnly:!0,nullable:!0,description:"Indicates whether to send to all Google Chrome, Chrome on Android, and Mozilla Firefox users registered under your Chrome & Firefox web push platform."},isFirefox:{type:"boolean",writeOnly:!0,nullable:!0,description:"Indicates whether to send to all Mozilla Firefox desktop users registered under your Firefox web push platform."},isSafari:{type:"boolean",writeOnly:!0,nullable:!0,description:"Does not support iOS Safari. Indicates whether to send to all Apple's Safari desktop users registered under your Safari web push platform. Read more iOS Safari"},isWpWns:{type:"boolean",writeOnly:!0,nullable:!0,description:"Indicates whether to send to all devices registered under your app's Windows platform."},isAdm:{type:"boolean",writeOnly:!0,nullable:!0,description:"Indicates whether to send to all devices registered under your app's Amazon Fire platform."},isChrome:{type:"boolean",writeOnly:!0,nullable:!0,description:`This flag is not used for web push Please see isChromeWeb for sending to web push users. This flag only applies to Google Chrome Apps & Extensions.
|
|
122
|
+
Indicates whether to send to all devices registered under your app's Google Chrome Apps & Extension platform.
|
|
123
|
+
`},channelForExternalUserIds:{type:"string",writeOnly:!0,description:`Indicates if the message type when targeting with includeExternalUserIds for cases where an email, sms, and/or push subscribers have the same external user id.
|
|
124
|
+
Example: Use the string "push" to indicate you are sending a push notification or the string "email"for sending emails or "sms"for sending SMS.
|
|
125
|
+
`},appId:{type:"string",description:`Required: Your OneSignal Application ID, which can be found in Keys & IDs.
|
|
126
|
+
It is a UUID and looks similar to 8250eaf6-1a58-489e-b136-7c74a864b434.
|
|
127
|
+
`,writeOnly:!0},externalId:{type:"string",description:`Correlation and idempotency key.
|
|
128
|
+
A request received with this parameter will first look for another notification with the same externalId. If one exists, a notification will not be sent, and result of the previous operation will instead be returned. Therefore, if you plan on using this feature, it's important to use a good source of randomness to generate the UUID passed here.
|
|
129
|
+
This key is only idempotent for 30 days. After 30 days, the notification could be removed from our system and a notification with the same externalId will be sent again.
|
|
130
|
+
See Idempotent Notification Requests for more details
|
|
131
|
+
writeOnly: true
|
|
132
|
+
`,nullable:!0},contents:{allOf:[{type:"object",properties:{en:{type:"string",description:"Text in English. Will be used as a fallback"},ar:{type:"string",description:"Text in Arabic."},bs:{type:"string",description:"Text in Bosnian."},bg:{type:"string",description:"Text in Bulgarian."},ca:{type:"string",description:"Text in Catalan."},"zh-Hans":{type:"string",description:"Text in Chinese (Simplified)."},"zh-Hant":{type:"string",description:"Text in Chinese (Traditional)."},zh:{type:"string",description:"Alias for zh-Hans."},hr:{type:"string",description:"Text in Croatian."},cs:{type:"string",description:"Text in Czech."},da:{type:"string",description:"Text in Danish."},nl:{type:"string",description:"Text in Dutch."},et:{type:"string",description:"Text in Estonian."},fi:{type:"string",description:"Text in Finnish."},fr:{type:"string",description:"Text in French."},ka:{type:"string",description:"Text in Georgian."},de:{type:"string",description:"Text in German."},el:{type:"string",description:"Text in Greek."},hi:{type:"string",description:"Text in Hindi."},he:{type:"string",description:"Text in Hebrew."},hu:{type:"string",description:"Text in Hungarian."},id:{type:"string",description:"Text in Indonesian."},it:{type:"string",description:"Text in Italian."},ja:{type:"string",description:"Text in Japanese."},ko:{type:"string",description:"Text in Korean."},lv:{type:"string",description:"Text in Latvian."},lt:{type:"string",description:"Text in Lithuanian."},ms:{type:"string",description:"Text in Malay."},nb:{type:"string",description:"Text in Norwegian."},pl:{type:"string",description:"Text in Polish."},fa:{type:"string",description:"Text in Persian."},pt:{type:"string",description:"Text in Portuguese."},pa:{type:"string",description:"Text in Punjabi."},ro:{type:"string",description:"Text in Romanian."},ru:{type:"string",description:"Text in Russian."},sr:{type:"string",description:"Text in Serbian."},sk:{type:"string",description:"Text in Slovak."},es:{type:"string",description:"Text in Spanish."},sv:{type:"string",description:"Text in Swedish."},th:{type:"string",description:"Text in Thai."},tr:{type:"string",description:"Text in Turkish."},uk:{type:"string",description:"Text in Ukrainian."},vi:{type:"string",description:"Text in Vietnamese."}}},{description:`Required unless contentAvailable=true or templateId is set.
|
|
133
|
+
The message's content (excluding the title), a map of language codes to text for each language.
|
|
134
|
+
Each hash must have a language code string for a key, mapped to the localized text you would like users to receive for that language.
|
|
135
|
+
This field supports inline substitutions.
|
|
136
|
+
English must be included in the hash.
|
|
137
|
+
Example: {"en": "English Message", "es": "Spanish Message"}
|
|
138
|
+
`,writeOnly:!0}]},headings:{allOf:[{type:"object",properties:{en:{type:"string",description:"Text in English. Will be used as a fallback"},ar:{type:"string",description:"Text in Arabic."},bs:{type:"string",description:"Text in Bosnian."},bg:{type:"string",description:"Text in Bulgarian."},ca:{type:"string",description:"Text in Catalan."},"zh-Hans":{type:"string",description:"Text in Chinese (Simplified)."},"zh-Hant":{type:"string",description:"Text in Chinese (Traditional)."},zh:{type:"string",description:"Alias for zh-Hans."},hr:{type:"string",description:"Text in Croatian."},cs:{type:"string",description:"Text in Czech."},da:{type:"string",description:"Text in Danish."},nl:{type:"string",description:"Text in Dutch."},et:{type:"string",description:"Text in Estonian."},fi:{type:"string",description:"Text in Finnish."},fr:{type:"string",description:"Text in French."},ka:{type:"string",description:"Text in Georgian."},de:{type:"string",description:"Text in German."},el:{type:"string",description:"Text in Greek."},hi:{type:"string",description:"Text in Hindi."},he:{type:"string",description:"Text in Hebrew."},hu:{type:"string",description:"Text in Hungarian."},id:{type:"string",description:"Text in Indonesian."},it:{type:"string",description:"Text in Italian."},ja:{type:"string",description:"Text in Japanese."},ko:{type:"string",description:"Text in Korean."},lv:{type:"string",description:"Text in Latvian."},lt:{type:"string",description:"Text in Lithuanian."},ms:{type:"string",description:"Text in Malay."},nb:{type:"string",description:"Text in Norwegian."},pl:{type:"string",description:"Text in Polish."},fa:{type:"string",description:"Text in Persian."},pt:{type:"string",description:"Text in Portuguese."},pa:{type:"string",description:"Text in Punjabi."},ro:{type:"string",description:"Text in Romanian."},ru:{type:"string",description:"Text in Russian."},sr:{type:"string",description:"Text in Serbian."},sk:{type:"string",description:"Text in Slovak."},es:{type:"string",description:"Text in Spanish."},sv:{type:"string",description:"Text in Swedish."},th:{type:"string",description:"Text in Thai."},tr:{type:"string",description:"Text in Turkish."},uk:{type:"string",description:"Text in Ukrainian."},vi:{type:"string",description:"Text in Vietnamese."}}},{description:`The message's title, a map of language codes to text for each language. Each hash must have a language code string for a key, mapped to the localized text you would like users to receive for that language.
|
|
139
|
+
This field supports inline substitutions.
|
|
140
|
+
Example: {"en": "English Title", "es": "Spanish Title"}
|
|
141
|
+
`,writeOnly:!0}]},subtitle:{allOf:[{type:"object",properties:{en:{type:"string",description:"Text in English. Will be used as a fallback"},ar:{type:"string",description:"Text in Arabic."},bs:{type:"string",description:"Text in Bosnian."},bg:{type:"string",description:"Text in Bulgarian."},ca:{type:"string",description:"Text in Catalan."},"zh-Hans":{type:"string",description:"Text in Chinese (Simplified)."},"zh-Hant":{type:"string",description:"Text in Chinese (Traditional)."},zh:{type:"string",description:"Alias for zh-Hans."},hr:{type:"string",description:"Text in Croatian."},cs:{type:"string",description:"Text in Czech."},da:{type:"string",description:"Text in Danish."},nl:{type:"string",description:"Text in Dutch."},et:{type:"string",description:"Text in Estonian."},fi:{type:"string",description:"Text in Finnish."},fr:{type:"string",description:"Text in French."},ka:{type:"string",description:"Text in Georgian."},de:{type:"string",description:"Text in German."},el:{type:"string",description:"Text in Greek."},hi:{type:"string",description:"Text in Hindi."},he:{type:"string",description:"Text in Hebrew."},hu:{type:"string",description:"Text in Hungarian."},id:{type:"string",description:"Text in Indonesian."},it:{type:"string",description:"Text in Italian."},ja:{type:"string",description:"Text in Japanese."},ko:{type:"string",description:"Text in Korean."},lv:{type:"string",description:"Text in Latvian."},lt:{type:"string",description:"Text in Lithuanian."},ms:{type:"string",description:"Text in Malay."},nb:{type:"string",description:"Text in Norwegian."},pl:{type:"string",description:"Text in Polish."},fa:{type:"string",description:"Text in Persian."},pt:{type:"string",description:"Text in Portuguese."},pa:{type:"string",description:"Text in Punjabi."},ro:{type:"string",description:"Text in Romanian."},ru:{type:"string",description:"Text in Russian."},sr:{type:"string",description:"Text in Serbian."},sk:{type:"string",description:"Text in Slovak."},es:{type:"string",description:"Text in Spanish."},sv:{type:"string",description:"Text in Swedish."},th:{type:"string",description:"Text in Thai."},tr:{type:"string",description:"Text in Turkish."},uk:{type:"string",description:"Text in Ukrainian."},vi:{type:"string",description:"Text in Vietnamese."}}},{description:`The message's subtitle, a map of language codes to text for each language. Each hash must have a language code string for a key, mapped to the localized text you would like users to receive for that language.
|
|
142
|
+
This field supports inline substitutions.
|
|
143
|
+
Example: {"en": "English Subtitle", "es": "Spanish Subtitle"}
|
|
144
|
+
`,writeOnly:!0}]},data:{type:"object",description:`Channel: Push Notifications
|
|
145
|
+
Platform: Huawei
|
|
146
|
+
A custom map of data that is passed back to your app. Same as using Additional Data within the dashboard. Can use up to 2048 bytes of data.
|
|
147
|
+
Example: {"abc": 123, "foo": "bar", "event_performed": true, "amount": 12.1}
|
|
148
|
+
`,writeOnly:!0,nullable:!0},huaweiMsgType:{type:"string",description:`Channel: Push Notifications
|
|
149
|
+
Platform: Huawei
|
|
150
|
+
Use "data" or "message" depending on the type of notification you are sending. More details in Data & Background Notifications.
|
|
151
|
+
`,writeOnly:!0,nullable:!0},url:{type:"string",description:`Channel: Push Notifications
|
|
152
|
+
Platform: All
|
|
153
|
+
The URL to open in the browser when a user clicks on the notification.
|
|
154
|
+
Note: iOS needs https or updated NSAppTransportSecurity in plist
|
|
155
|
+
This field supports inline substitutions.
|
|
156
|
+
Omit if including webUrl or appUrl
|
|
157
|
+
Example: https://onesignal.com
|
|
158
|
+
`,writeOnly:!0,nullable:!0},webUrl:{type:"string",description:`Channel: Push Notifications
|
|
159
|
+
Platform: All Browsers
|
|
160
|
+
Same as url but only sent to web push platforms.
|
|
161
|
+
Including Chrome, Firefox, Safari, Opera, etc.
|
|
162
|
+
Example: https://onesignal.com
|
|
163
|
+
`,writeOnly:!0,nullable:!0},appUrl:{type:"string",description:`Channel: Push Notifications
|
|
164
|
+
Platform: All Browsers
|
|
165
|
+
Same as url but only sent to web push platforms.
|
|
166
|
+
Including iOS, Android, macOS, Windows, ChromeApps, etc.
|
|
167
|
+
Example: https://onesignal.com
|
|
168
|
+
`,writeOnly:!0,nullable:!0},iosAttachments:{type:"object",description:`Channel: Push Notifications
|
|
169
|
+
Platform: iOS 10+
|
|
170
|
+
Adds media attachments to notifications. Set as JSON object, key as a media id of your choice and the value as a valid local filename or URL. User must press and hold on the notification to view.
|
|
171
|
+
Do not set mutableContent to download attachments. The OneSignal SDK does this automatically
|
|
172
|
+
Example: {"id1": "https://domain.com/image.jpg"}
|
|
173
|
+
`,writeOnly:!0,nullable:!0},templateId:{type:"string",description:`Channel: Push Notifications
|
|
174
|
+
Platform: All
|
|
175
|
+
Use a template you setup on our dashboard. The templateId is the UUID found in the URL when viewing a template on our dashboard.
|
|
176
|
+
Example: be4a8044-bbd6-11e4-a581-000c2940e62c
|
|
177
|
+
`,writeOnly:!0,nullable:!0},contentAvailable:{type:"boolean",description:`Channel: Push Notifications
|
|
178
|
+
Platform: iOS
|
|
179
|
+
Sending true wakes your app from background to run custom native code (Apple interprets this as content-available=1). Note: Not applicable if the app is in the "force-quit" state (i.e app was swiped away). Omit the contents field to prevent displaying a visible notification.
|
|
180
|
+
`,writeOnly:!0,nullable:!0},mutableContent:{type:"boolean",description:`Channel: Push Notifications
|
|
181
|
+
Platform: iOS 10+
|
|
182
|
+
Always defaults to true and cannot be turned off. Allows tracking of notification receives and changing of the notification content in your app before it is displayed. Triggers didReceive(_:withContentHandler:) on your UNNotificationServiceExtension.
|
|
183
|
+
`,writeOnly:!0},targetContentIdentifier:{type:"string",description:`Channel: Push Notifications
|
|
184
|
+
Platform: iOS 13+
|
|
185
|
+
Use to target a specific experience in your App Clip, or to target your notification to a specific window in a multi-scene App.
|
|
186
|
+
`,writeOnly:!0,nullable:!0},bigPicture:{type:"string",description:`Channel: Push Notifications
|
|
187
|
+
Platform: Android
|
|
188
|
+
Picture to display in the expanded view. Can be a drawable resource name or a URL.
|
|
189
|
+
`,writeOnly:!0,nullable:!0},huaweiBigPicture:{type:"string",description:`Channel: Push Notifications
|
|
190
|
+
Platform: Huawei
|
|
191
|
+
Picture to display in the expanded view. Can be a drawable resource name or a URL.
|
|
192
|
+
`,writeOnly:!0,nullable:!0},admBigPicture:{type:"string",description:`Channel: Push Notifications
|
|
193
|
+
Platform: Amazon
|
|
194
|
+
Picture to display in the expanded view. Can be a drawable resource name or a URL.
|
|
195
|
+
`,writeOnly:!0,nullable:!0},chromeBigPicture:{type:"string",description:`Channel: Push Notifications
|
|
196
|
+
Platform: ChromeApp
|
|
197
|
+
Large picture to display below the notification text. Must be a local URL.
|
|
198
|
+
`,writeOnly:!0,nullable:!0},chromeWebImage:{type:"string",description:`Channel: Push Notifications
|
|
199
|
+
Platform: Chrome 56+
|
|
200
|
+
Sets the web push notification's large image to be shown below the notification's title and text. Please see Web Push Notification Icons.
|
|
201
|
+
`,writeOnly:!0,nullable:!0},buttons:{type:"array",items:{type:"object",properties:{id:{type:"string"},text:{type:"string"},icon:{type:"string"}},required:["id"]},description:`Channel: Push Notifications
|
|
202
|
+
Platform: iOS 8.0+, Android 4.1+, and derivatives like Amazon Buttons to add to the notification. Icon only works for Android.
|
|
203
|
+
Buttons show in reverse order of array position i.e. Last item in array shows as first button on device.
|
|
204
|
+
Example: [{"id": "id2", "text": "second button", "icon": "ic_menu_share"}, {"id": "id1", "text": "first button", "icon": "ic_menu_send"}]
|
|
205
|
+
`,writeOnly:!0,nullable:!0},webButtons:{type:"array",items:{type:"object",properties:{id:{type:"string"},text:{type:"string"},icon:{type:"string"}},required:["id"]},description:`Channel: Push Notifications
|
|
206
|
+
Platform: Chrome 48+
|
|
207
|
+
Add action buttons to the notification. The id field is required.
|
|
208
|
+
Example: [{"id": "like-button", "text": "Like", "icon": "http://i.imgur.com/N8SN8ZS.png", "url": "https://yoursite.com"}, {"id": "read-more-button", "text": "Read more", "icon": "http://i.imgur.com/MIxJp1L.png", "url": "https://yoursite.com"}]
|
|
209
|
+
`,writeOnly:!0,nullable:!0},iosCategory:{type:"string",description:`Channel: Push Notifications
|
|
210
|
+
Platform: iOS
|
|
211
|
+
Category APS payload, use with registerUserNotificationSettings:categories in your Objective-C / Swift code.
|
|
212
|
+
Example: calendar category which contains actions like accept and decline
|
|
213
|
+
iOS 10+ This will trigger your UNNotificationContentExtension whose ID matches this category.
|
|
214
|
+
`,writeOnly:!0,nullable:!0},androidChannelId:{type:"string",description:`Channel: Push Notifications
|
|
215
|
+
Platform: Android
|
|
216
|
+
The Android Oreo Notification Category to send the notification under. See the Category documentation on creating one and getting it's id.
|
|
217
|
+
`,writeOnly:!0},huaweiChannelId:{type:"string",description:`Channel: Push Notifications
|
|
218
|
+
Platform: Huawei
|
|
219
|
+
The Android Oreo Notification Category to send the notification under. See the Category documentation on creating one and getting it's id.
|
|
220
|
+
`,writeOnly:!0,nullable:!0},existingAndroidChannelId:{type:"string",description:`Channel: Push Notifications
|
|
221
|
+
Platform: Android
|
|
222
|
+
Use this if you have client side Android Oreo Channels you have already defined in your app with code.
|
|
223
|
+
`,writeOnly:!0},huaweiExistingChannelId:{type:"string",description:`Channel: Push Notifications
|
|
224
|
+
Platform: Huawei
|
|
225
|
+
Use this if you have client side Android Oreo Channels you have already defined in your app with code.
|
|
226
|
+
`,writeOnly:!0,nullable:!0},androidBackgroundLayout:{type:"object",description:`Channel: Push Notifications
|
|
227
|
+
Platform: Android
|
|
228
|
+
Allowing setting a background image for the notification. This is a JSON object containing the following keys. See our Background Image documentation for image sizes.
|
|
229
|
+
`,properties:{image:{type:"string",description:"Asset file, android resource name, or URL to remote image."},headingsColor:{type:"string",description:'Title text color ARGB Hex format. Example(Blue) "FF0000FF".'},contentsColor:{type:"string",description:'Body text color ARGB Hex format. Example(Red) "FFFF0000".'}},writeOnly:!0},smallIcon:{type:"string",description:`Channel: Push Notifications
|
|
230
|
+
Platform: Android
|
|
231
|
+
Icon shown in the status bar and on the top left of the notification.
|
|
232
|
+
If not set a bell icon will be used or ic_stat_onesignal_default if you have set this resource name.
|
|
233
|
+
See: How to create small icons
|
|
234
|
+
`,writeOnly:!0,nullable:!0},huaweiSmallIcon:{type:"string",description:`Channel: Push Notifications
|
|
235
|
+
Platform: Huawei
|
|
236
|
+
Icon shown in the status bar and on the top left of the notification.
|
|
237
|
+
Use an Android resource path (E.g. /drawable/smallIcon).
|
|
238
|
+
Defaults to your app icon if not set.
|
|
239
|
+
`,writeOnly:!0,nullable:!0},largeIcon:{type:"string",description:`Channel: Push Notifications
|
|
240
|
+
Platform: Android
|
|
241
|
+
Can be a drawable resource name or a URL.
|
|
242
|
+
See: How to create large icons
|
|
243
|
+
`,writeOnly:!0,nullable:!0},huaweiLargeIcon:{type:"string",description:`Channel: Push Notifications
|
|
244
|
+
Platform: Huawei
|
|
245
|
+
Can be a drawable resource name or a URL.
|
|
246
|
+
See: How to create large icons
|
|
247
|
+
`,writeOnly:!0,nullable:!0},admSmallIcon:{type:"string",description:`Channel: Push Notifications
|
|
248
|
+
Platform: Amazon
|
|
249
|
+
If not set a bell icon will be used or ic_stat_onesignal_default if you have set this resource name.
|
|
250
|
+
See: How to create small icons
|
|
251
|
+
`,writeOnly:!0,nullable:!0},admLargeIcon:{type:"string",description:`Channel: Push Notifications
|
|
252
|
+
Platform: Amazon
|
|
253
|
+
If blank the smallIcon is used. Can be a drawable resource name or a URL.
|
|
254
|
+
See: How to create large icons
|
|
255
|
+
`,writeOnly:!0,nullable:!0},chromeWebIcon:{type:"string",description:`Channel: Push Notifications
|
|
256
|
+
Platform: Chrome
|
|
257
|
+
Sets the web push notification's icon. An image URL linking to a valid image. Common image types are supported; GIF will not animate. We recommend 256x256 (at least 80x80) to display well on high DPI devices. Firefox will also use this icon, unless you specify firefoxIcon.
|
|
258
|
+
`,nullable:!0},chromeWebBadge:{type:"string",description:`Channel: Push Notifications
|
|
259
|
+
Platform: Chrome
|
|
260
|
+
Sets the web push notification icon for Android devices in the notification shade. Please see Web Push Notification Badge.
|
|
261
|
+
`,writeOnly:!0,nullable:!0},firefoxIcon:{type:"string",description:`Channel: Push Notifications
|
|
262
|
+
Platform: Firefox
|
|
263
|
+
Not recommended Few people need to set Firefox-specific icons. We recommend setting chromeWebIcon instead, which Firefox will also use.
|
|
264
|
+
Sets the web push notification's icon for Firefox. An image URL linking to a valid image. Common image types are supported; GIF will not animate. We recommend 256x256 (at least 80x80) to display well on high DPI devices.
|
|
265
|
+
`,writeOnly:!0,nullable:!0},chromeIcon:{type:"string",description:`Channel: Push Notifications
|
|
266
|
+
Platform: ChromeApp
|
|
267
|
+
This flag is not used for web push For web push, please see chromeWebIcon instead.
|
|
268
|
+
The local URL to an icon to use. If blank, the app icon will be used.
|
|
269
|
+
`,writeOnly:!0,nullable:!0},iosSound:{type:"string",description:`Channel: Push Notifications
|
|
270
|
+
Platform: iOS
|
|
271
|
+
Sound file that is included in your app to play instead of the default device notification sound. Pass nil to disable vibration and sound for the notification.
|
|
272
|
+
Example: "notification.wav"
|
|
273
|
+
`,writeOnly:!0,nullable:!0},androidSound:{type:"string",description:`Channel: Push Notifications
|
|
274
|
+
Platform: Android
|
|
275
|
+
⚠️Deprecated, this field doesn't work on Android 8 (Oreo) and newer devices!
|
|
276
|
+
Please use Notification Categories / Channels noted above instead to support ALL versions of Android.
|
|
277
|
+
Sound file that is included in your app to play instead of the default device notification sound. Pass nil to disable sound for the notification.
|
|
278
|
+
NOTE: Leave off file extension for Android.
|
|
279
|
+
Example: "notification"
|
|
280
|
+
`,writeOnly:!0,nullable:!0},huaweiSound:{type:"string",description:`Channel: Push Notifications
|
|
281
|
+
Platform: Huawei
|
|
282
|
+
⚠️Deprecated, this field ONLY works on EMUI 5 (Android 7 based) and older devices.
|
|
283
|
+
Please also set Notification Categories / Channels noted above to support EMUI 8 (Android 8 based) devices.
|
|
284
|
+
Sound file that is included in your app to play instead of the default device notification sound. NOTE: Leave off file extension for and include the full path.
|
|
285
|
+
|
|
286
|
+
Example: "/res/raw/notification"
|
|
287
|
+
`,writeOnly:!0,nullable:!0},admSound:{type:"string",description:`Channel: Push Notifications
|
|
288
|
+
Platform: Amazon
|
|
289
|
+
⚠️Deprecated, this field doesn't work on Android 8 (Oreo) and newer devices!
|
|
290
|
+
Please use Notification Categories / Channels noted above instead to support ALL versions of Android.
|
|
291
|
+
Sound file that is included in your app to play instead of the default device notification sound. Pass nil to disable sound for the notification.
|
|
292
|
+
NOTE: Leave off file extension for Android.
|
|
293
|
+
Example: "notification"
|
|
294
|
+
`,writeOnly:!0,nullable:!0},wpWnsSound:{type:"string",description:`Channel: Push Notifications
|
|
295
|
+
Platform: Windows
|
|
296
|
+
Sound file that is included in your app to play instead of the default device notification sound.
|
|
297
|
+
Example: "notification.wav"
|
|
298
|
+
`,writeOnly:!0,nullable:!0},androidLedColor:{type:"string",description:`Channel: Push Notifications
|
|
299
|
+
Platform: Android
|
|
300
|
+
⚠️Deprecated, this field doesn't work on Android 8 (Oreo) and newer devices!
|
|
301
|
+
Please use Notification Categories / Channels noted above instead to support ALL versions of Android.
|
|
302
|
+
Sets the devices LED notification light if the device has one. ARGB Hex format.
|
|
303
|
+
Example(Blue): "FF0000FF"
|
|
304
|
+
`,writeOnly:!0,nullable:!0},huaweiLedColor:{type:"string",description:`Channel: Push Notifications
|
|
305
|
+
Platform: Huawei
|
|
306
|
+
⚠️Deprecated, this field ONLY works on EMUI 5 (Android 7 based) and older devices.
|
|
307
|
+
Please also set Notification Categories / Channels noted above to support EMUI 8 (Android 8 based) devices.
|
|
308
|
+
Sets the devices LED notification light if the device has one. RGB Hex format.
|
|
309
|
+
Example(Blue): "0000FF"
|
|
310
|
+
`,writeOnly:!0,nullable:!0},androidAccentColor:{type:"string",description:`Channel: Push Notifications
|
|
311
|
+
Platform: Android
|
|
312
|
+
Sets the background color of the notification circle to the left of the notification text. Only applies to apps targeting Android API level 21+ on Android 5.0+ devices.
|
|
313
|
+
Example(Red): "FFFF0000"
|
|
314
|
+
`,writeOnly:!0,nullable:!0},huaweiAccentColor:{type:"string",description:`Channel: Push Notifications
|
|
315
|
+
Platform: Huawei
|
|
316
|
+
Accent Color used on Action Buttons and Group overflow count.
|
|
317
|
+
Uses RGB Hex value (E.g. #9900FF).
|
|
318
|
+
Defaults to device's theme color if not set.
|
|
319
|
+
`,writeOnly:!0,nullable:!0},androidVisibility:{type:"integer",description:`Channel: Push Notifications
|
|
320
|
+
Platform: Android 5.0_
|
|
321
|
+
⚠️Deprecated, this field doesn't work on Android 8 (Oreo) and newer devices!
|
|
322
|
+
Please use Notification Categories / Channels noted above instead to support ALL versions of Android.
|
|
323
|
+
1 = Public (default) (Shows the full message on the lock screen unless the user has disabled all notifications from showing on the lock screen. Please consider the user and mark private if the contents are.)
|
|
324
|
+
0 = Private (Hides message contents on lock screen if the user set "Hide sensitive notification content" in the system settings)
|
|
325
|
+
-1 = Secret (Notification does not show on the lock screen at all)
|
|
326
|
+
`,writeOnly:!0,nullable:!0},huaweiVisibility:{type:"integer",nullable:!0,description:`Channel: Push Notifications
|
|
327
|
+
Platform: Huawei
|
|
328
|
+
⚠️Deprecated, this field ONLY works on EMUI 5 (Android 7 based) and older devices.
|
|
329
|
+
Please also set Notification Categories / Channels noted above to support EMUI 8 (Android 8 based) devices.
|
|
330
|
+
1 = Public (default) (Shows the full message on the lock screen unless the user has disabled all notifications from showing on the lock screen. Please consider the user and mark private if the contents are.)
|
|
331
|
+
0 = Private (Hides message contents on lock screen if the user set "Hide sensitive notification content" in the system settings)
|
|
332
|
+
-1 = Secret (Notification does not show on the lock screen at all)
|
|
333
|
+
`,writeOnly:!0},iosBadgeType:{type:"string",description:"Channel: Push Notifications\nPlatform: iOS\nDescribes whether to set or increase/decrease your app's iOS badge count by the iosBadgeCount specified count. Can specify None, SetTo, or Increase.\n`None` leaves the count unaffected.\n`SetTo` directly sets the badge count to the number specified in iosBadgeCount.\n`Increase` adds the number specified in iosBadgeCount to the total. Use a negative number to decrease the badge count.\n",writeOnly:!0,nullable:!0},iosBadgeCount:{type:"integer",nullable:!0,description:`Channel: Push Notifications
|
|
334
|
+
Platform: iOS
|
|
335
|
+
Used with iosBadgeType, describes the value to set or amount to increase/decrease your app's iOS badge count by.
|
|
336
|
+
You can use a negative number to decrease the badge count when used with an iosBadgeType of Increase.
|
|
337
|
+
`,writeOnly:!0},collapseId:{type:"string",description:`Channel: Push Notifications
|
|
338
|
+
Platform: iOS 10+, Android
|
|
339
|
+
Only one notification with the same id will be shown on the device. Use the same id to update an existing notification instead of showing a new one. Limit of 64 characters.
|
|
340
|
+
`,writeOnly:!0},webPushTopic:{type:"string",description:`Channel: Push Notifications
|
|
341
|
+
Platform: All Browsers
|
|
342
|
+
Display multiple notifications at once with different topics.
|
|
343
|
+
`,nullable:!0},apnsAlert:{type:"object",description:`Channel: Push Notifications
|
|
344
|
+
Platform: iOS 10+
|
|
345
|
+
iOS can localize push notification messages on the client using special parameters such as loc-key. When using the Create Notification endpoint, you must include these parameters inside of a field called apnsAlert. Please see Apple's guide on localizing push notifications to learn more.
|
|
346
|
+
`,writeOnly:!0,nullable:!0},delayedOption:{type:"string",description:`Channel: All
|
|
347
|
+
Possible values are:
|
|
348
|
+
timezone (Deliver at a specific time-of-day in each users own timezone)
|
|
349
|
+
last-active Same as Intelligent Delivery . (Deliver at the same time of day as each user last used your app).
|
|
350
|
+
If sendAfter is used, this takes effect after the sendAfter time has elapsed.
|
|
351
|
+
`,writeOnly:!0,nullable:!0},deliveryTimeOfDay:{type:"string",description:`Channel: All
|
|
352
|
+
Use with delayedOption=timezone.
|
|
353
|
+
Examples: "9:00AM"
|
|
354
|
+
"21:45"
|
|
355
|
+
"9:45:30"
|
|
356
|
+
`,writeOnly:!0,nullable:!0},ttl:{type:"integer",nullable:!0,description:`Channel: Push Notifications
|
|
357
|
+
Platform: iOS, Android, Chrome, Firefox, Safari, ChromeWeb
|
|
358
|
+
Time To Live - In seconds. The notification will be expired if the device does not come back online within this time. The default is 259,200 seconds (3 days).
|
|
359
|
+
Max value to set is 2419200 seconds (28 days).
|
|
360
|
+
`,writeOnly:!0},priority:{type:"integer",nullable:!0,description:`Channel: Push Notifications
|
|
361
|
+
Platform: Android, Chrome, ChromeWeb
|
|
362
|
+
Delivery priority through the push server (example GCM/FCM). Pass 10 for high priority or any other integer for normal priority. Defaults to normal priority for Android and high for iOS. For Android 6.0+ devices setting priority to high will wake the device out of doze mode.
|
|
363
|
+
`,writeOnly:!0},apnsPushTypeOverride:{type:"string",description:`Channel: Push Notifications
|
|
364
|
+
Platform: iOS
|
|
365
|
+
valid values: voip
|
|
366
|
+
Set the value to voip for sending VoIP Notifications
|
|
367
|
+
This field maps to the APNS header apns-push-type.
|
|
368
|
+
Note: alert and background are automatically set by OneSignal
|
|
369
|
+
`,writeOnly:!0},throttleRatePerMinute:{type:"string",description:`Channel: All
|
|
370
|
+
Apps with throttling enabled:
|
|
371
|
+
- the parameter value will be used to override the default application throttling value set from the dashboard settings.
|
|
372
|
+
- parameter value 0 indicates not to apply throttling to the notification.
|
|
373
|
+
- if the parameter is not passed then the default app throttling value will be applied to the notification.
|
|
374
|
+
Apps with throttling disabled:
|
|
375
|
+
- this parameter can be used to throttle delivery for the notification even though throttling is not enabled at the application level.
|
|
376
|
+
Refer to throttling for more details.
|
|
377
|
+
`,writeOnly:!0,nullable:!0},androidGroup:{type:"string",description:`Channel: Push Notifications
|
|
378
|
+
Platform: Android
|
|
379
|
+
Notifications with the same group will be stacked together using Android's Notification Grouping feature.
|
|
380
|
+
`,writeOnly:!0,nullable:!0},androidGroupMessage:{type:"string",description:`Channel: Push Notifications
|
|
381
|
+
Platform: Android
|
|
382
|
+
Note: This only works for Android 6 and older. Android 7+ allows full expansion of all message.
|
|
383
|
+
Summary message to display when 2+ notifications are stacked together. Default is "# new messages". Include $[notif_count] in your message and it will be replaced with the current number.
|
|
384
|
+
Languages - The value of each key is the message that will be sent to users for that language. "en" (English) is required. The key of each hash is either a a 2 character language code or one of zh-Hans/zh-Hant for Simplified or Traditional Chinese. Read more: supported languages.
|
|
385
|
+
Example: {"en": "You have $[notif_count] new messages"}
|
|
386
|
+
`,writeOnly:!0,nullable:!0},admGroup:{type:"string",description:`Channel: Push Notifications
|
|
387
|
+
Platform: Amazon
|
|
388
|
+
Notifications with the same group will be stacked together using Android's Notification Grouping feature.
|
|
389
|
+
`,writeOnly:!0,nullable:!0},admGroupMessage:{type:"object",description:`Channel: Push Notifications
|
|
390
|
+
Platform: Amazon
|
|
391
|
+
Summary message to display when 2+ notifications are stacked together. Default is "# new messages". Include $[notif_count] in your message and it will be replaced with the current number. "en" (English) is required. The key of each hash is either a a 2 character language code or one of zh-Hans/zh-Hant for Simplified or Traditional Chinese. The value of each key is the message that will be sent to users for that language.
|
|
392
|
+
Example: {"en": "You have $[notif_count] new messages"}
|
|
393
|
+
`,writeOnly:!0,nullable:!0},threadId:{type:"string",description:`Channel: Push Notifications
|
|
394
|
+
Platform: iOS 12+
|
|
395
|
+
This parameter is supported in iOS 12 and above. It allows you to group related notifications together.
|
|
396
|
+
If two notifications have the same thread-id, they will both be added to the same group.
|
|
397
|
+
`,writeOnly:!0,nullable:!0},summaryArg:{type:"string",description:`Channel: Push Notifications
|
|
398
|
+
Platform: iOS 12+
|
|
399
|
+
When using threadId to create grouped notifications in iOS 12+, you can also control the summary. For example, a grouped notification can say "12 more notifications from John Doe".
|
|
400
|
+
The summaryArg lets you set the name of the person/thing the notifications are coming from, and will show up as "X more notifications from summaryArg"
|
|
401
|
+
`,writeOnly:!0},summaryArgCount:{type:"integer",description:`Channel: Push Notifications
|
|
402
|
+
Platform: iOS 12+
|
|
403
|
+
When using threadId, you can also control the count of the number of notifications in the group. For example, if the group already has 12 notifications, and you send a new notification with summaryArgCount = 2, the new total will be 14 and the summary will be "14 more notifications from summaryArg"
|
|
404
|
+
`,writeOnly:!0},emailSubject:{type:"string",description:`Channel: Email
|
|
405
|
+
Required. The subject of the email.
|
|
406
|
+
`,writeOnly:!0,nullable:!0},emailBody:{type:"string",description:`Channel: Email
|
|
407
|
+
Required unless templateId is set.
|
|
408
|
+
HTML suported
|
|
409
|
+
The body of the email you wish to send. Typically, customers include their own HTML templates here. Must include [unsubscribe_url] in an <a> tag somewhere in the email.
|
|
410
|
+
Note: any malformed HTML content will be sent to users. Please double-check your HTML is valid.
|
|
411
|
+
`,writeOnly:!0},emailFromName:{type:"string",description:`Channel: Email
|
|
412
|
+
The name the email is from. If not specified, will default to "from name" set in the OneSignal Dashboard Email Settings.
|
|
413
|
+
`,writeOnly:!0,nullable:!0},emailFromAddress:{type:"string",description:`Channel: Email
|
|
414
|
+
The email address the email is from. If not specified, will default to "from email" set in the OneSignal Dashboard Email Settings.
|
|
415
|
+
`,writeOnly:!0,nullable:!0},emailPreheader:{type:"string",description:`Channel: Email
|
|
416
|
+
The preheader text of the email.
|
|
417
|
+
Preheader is the preview text displayed immediately after an email subject that provides additional context about the email content.
|
|
418
|
+
If not specified, will default to null.
|
|
419
|
+
`,writeOnly:!0,nullable:!0},includeUnsubscribed:{type:"boolean",description:"Channel: Email\nDefault is `false`. This field is used to send transactional notifications. If set to `true`, this notification will also be sent to unsubscribed emails. If a `templateId` is provided, the `includeUnsubscribed` value from the template will be inherited. If you are using a third-party ESP, this field requires the ESP's list of unsubscribed emails to be cleared.",writeOnly:!0},smsFrom:{type:"string",description:`Channel: SMS
|
|
420
|
+
Phone Number used to send SMS. Should be a registered Twilio phone number in E.164 format.
|
|
421
|
+
`,writeOnly:!0,nullable:!0},smsMediaUrls:{type:"array",items:{type:"string"},description:`Channel: SMS
|
|
422
|
+
URLs for the media files to be attached to the SMS content.
|
|
423
|
+
Limit: 10 media urls with a total max. size of 5MBs.
|
|
424
|
+
`,writeOnly:!0,nullable:!0},filters:{type:"array",nullable:!0,items:{type:"object",properties:{field:{type:"string",description:"Name of the field to use as the first operand in the filter expression."},key:{type:"string",description:"If `field` is `tag`, this field is *required* to specify `key` inside the tags."},value:{type:"string",description:"Constant value to use as the second operand in the filter expression. This value is *required* when the relation operator is a binary operator."},relation:{type:"string",description:"Operator of a filter expression.",enum:[">","<","=","!=","exists","not_exists","time_elapsed_gt","time_elapsed_lt"]}},required:["field","relation"]}},customData:{type:"object",description:`Channel: All
|
|
425
|
+
JSON object that can be used as a source of message personalization data for fields that support tag variable substitution.
|
|
426
|
+
Push, SMS: Can accept up to 2048 bytes of valid JSON. Email: Can accept up to 10000 bytes of valid JSON.
|
|
427
|
+
Example: {"order_id": 123, "currency": "USD", "amount": 25}
|
|
428
|
+
`,writeOnly:!0,nullable:!0}}},{required:["appId"]}]},{type:"object",properties:{sendAfter:{type:"string",format:"date-time",description:`Channel: All
|
|
429
|
+
Schedule notification for future delivery. API defaults to UTC -1100
|
|
430
|
+
Examples: All examples are the exact same date & time.
|
|
431
|
+
"Thu Sep 24 2015 14:00:00 GMT-0700 (PDT)"
|
|
432
|
+
"September 24th 2015, 2:00:00 pm UTC-07:00"
|
|
433
|
+
"2015-09-24 14:00:00 GMT-0700"
|
|
434
|
+
"Sept 24 2015 14:00:00 GMT-0700"
|
|
435
|
+
"Thu Sep 24 2015 14:00:00 GMT-0700 (Pacific Daylight Time)"
|
|
436
|
+
Note: SMS currently only supports sendAfter parameter.
|
|
437
|
+
`,writeOnly:!0,nullable:!0}}}],required:[],additionalProperties:!0},lt={output:Kt};var pt={[shared.PushProviderIdEnum.APNS]:rt,[shared.PushProviderIdEnum.EXPO]:at,[shared.PushProviderIdEnum.FCM]:ct,[shared.PushProviderIdEnum.OneSignal]:lt,[shared.PushProviderIdEnum.PusherBeams]:l,[shared.PushProviderIdEnum.Pushpad]:l,[shared.PushProviderIdEnum.PushWebhook]:l};var Ht={type:"object",properties:{},required:[],additionalProperties:!1},dt={output:Ht};var Xt={type:"object",properties:{to:{type:"string",format:"phone-number",description:"The recipient's phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format (for SMS/MMS) or [channel address](https://www.twilio.com/docs/messaging/channels), e.g. `whatsapp:+15552229999`."},statusCallback:{type:"string",format:"uri",description:"The URL of the endpoint to which Twilio sends [Message status callback requests](https://www.twilio.com/docs/sms/api/message-resource#twilios-request-to-the-statuscallback-url). URL must contain a valid hostname and underscores are not allowed. If you include this parameter with the `messagingServiceSid`, Twilio uses this URL instead of the Status Callback URL of the [Messaging Service](https://www.twilio.com/docs/messaging/api/service-resource). "},applicationSid:{type:"string",minLength:34,maxLength:34,pattern:"^AP[0-9a-fA-F]{32}$",description:"The SID of the associated [TwiML Application](https://www.twilio.com/docs/usage/api/applications). [Message status callback requests](https://www.twilio.com/docs/sms/api/message-resource#twilios-request-to-the-statuscallback-url) are sent to the TwiML App's `statusCallback` URL. Note that the `statusCallback` parameter of a request takes priority over the `applicationSid` parameter; if both are included `applicationSid` is ignored."},maxPrice:{type:"number",description:"[OBSOLETE] This parameter will no longer have any effect as of 2024-06-03."},provideFeedback:{type:"boolean",description:"Boolean indicating whether or not you intend to provide delivery confirmation feedback to Twilio (used in conjunction with the [Message Feedback subresource](https://www.twilio.com/docs/sms/api/message-feedback-resource)). Default value is `false`."},attempt:{type:"integer",description:"Total number of attempts made (including this request) to send the message regardless of the provider used"},validityPeriod:{type:"integer",description:"The maximum length in seconds that the Message can remain in Twilio's outgoing message queue. If a queued Message exceeds the `validityPeriod`, the Message is not sent. Accepted values are integers from `1` to `36000`. Default value is `36000`. A `validityPeriod` greater than `5` is recommended. [Learn more about the validity period](https://www.twilio.com/blog/take-more-control-of-outbound-messages-using-validity-period-html)"},forceDelivery:{type:"boolean",description:"Reserved"},contentRetention:{type:"string",enum:["retain","discard"],description:"Determines if the message content can be stored or redacted based on privacy settings"},addressRetention:{type:"string",enum:["retain","obfuscate"],description:"Determines if the address can be stored or obfuscated based on privacy settings"},smartEncoded:{type:"boolean",description:"Whether to detect Unicode characters that have a similar GSM-7 character and replace them. Can be: `true` or `false`."},persistentAction:{type:"array",items:{type:"string"},description:"Rich actions for non-SMS/MMS channels. Used for [sending location in WhatsApp messages](https://www.twilio.com/docs/whatsapp/message-features#location-messages-with-whatsapp)."},shortenUrls:{type:"boolean",description:"For Messaging Services with [Link Shortening configured](https://www.twilio.com/docs/messaging/features/link-shortening) only: A Boolean indicating whether or not Twilio should shorten links in the `body` of the Message. Default value is `false`. If `true`, the `messagingServiceSid` parameter must also be provided."},scheduleType:{type:"string",enum:["fixed"],description:"For Messaging Services only: Include this parameter with a value of `fixed` in conjunction with the `sendAt` parameter in order to [schedule a Message](https://www.twilio.com/docs/messaging/features/message-scheduling)."},sendAt:{type:"string",format:"date-time",description:"The time that Twilio will send the message. Must be in ISO 8601 format."},sendAsMms:{type:"boolean",description:"If set to `true`, Twilio delivers the message as a single MMS message, regardless of the presence of media."},contentVariables:{type:"string",description:"For [Content Editor/API](https://www.twilio.com/docs/content) only: Key-value pairs of [Template variables](https://www.twilio.com/docs/content/using-variables-with-content-api) and their substitution values. `contentSid` parameter must also be provided. If values are not defined in the `contentVariables` parameter, the [Template's default placeholder values](https://www.twilio.com/docs/content/content-api-resources#create-templates) are used."},riskCheck:{type:"string",enum:["enable","disable"],description:"Include this parameter with a value of `disable` to skip any kind of risk check on the respective message request."},from:{type:"string",format:"phone-number",description:"The sender's Twilio phone number (in [E.164](https://en.wikipedia.org/wiki/E.164) format), [alphanumeric sender ID](https://www.twilio.com/docs/sms/quickstart), [Wireless SIM](https://www.twilio.com/docs/iot/wireless/programmable-wireless-send-machine-machine-sms-commands), [short code](https://www.twilio.com/en-us/messaging/channels/sms/short-codes), or [channel address](https://www.twilio.com/docs/messaging/channels) (e.g., `whatsapp:+15554449999`). The value of the `from` parameter must be a sender that is hosted within Twilio and belongs to the Account creating the Message. If you are using `messagingServiceSid`, this parameter can be empty (Twilio assigns a `from` value from the Messaging Service's Sender Pool) or you can provide a specific sender from your Sender Pool."},messagingServiceSid:{type:"string",minLength:34,maxLength:34,pattern:"^MG[0-9a-fA-F]{32}$",description:"The SID of the [Messaging Service](https://www.twilio.com/docs/messaging/services) you want to associate with the Message. When this parameter is provided and the `from` parameter is omitted, Twilio selects the optimal sender from the Messaging Service's Sender Pool. You may also provide a `from` parameter if you want to use a specific Sender from the Sender Pool."},body:{type:"string",description:"The text content of the outgoing message. Can be up to 1,600 characters in length. SMS only: If the `body` contains more than 160 [GSM-7](https://www.twilio.com/docs/glossary/what-is-gsm-7-character-encoding) characters (or 70 [UCS-2](https://www.twilio.com/docs/glossary/what-is-ucs-2-character-encoding) characters), the message is segmented and charged accordingly. For long `body` text, consider using the [sendAsMms parameter](https://www.twilio.com/blog/mms-for-long-text-messages)."},mediaUrl:{type:"array",items:{type:"string",format:"uri"},description:"The URL of media to include in the Message content. `jpeg`, `jpg`, `gif`, and `png` file types are fully supported by Twilio and content is formatted for delivery on destination devices. The media size limit is 5 MB for supported file types (`jpeg`, `jpg`, `png`, `gif`) and 500 KB for [other types](https://www.twilio.com/docs/messaging/guides/accepted-mime-types) of accepted media. To send more than one image in the message, provide multiple `mediaUrl` parameters in the POST request. You can include up to ten `mediaUrl` parameters per message. [International](https://support.twilio.com/hc/en-us/articles/223179808-Sending-and-receiving-MMS-messages) and [carrier](https://support.twilio.com/hc/en-us/articles/223133707-Is-MMS-supported-for-all-carriers-in-US-and-Canada-) limits apply."},contentSid:{type:"string",minLength:34,maxLength:34,pattern:"^HX[0-9a-fA-F]{32}$",description:"For [Content Editor/API](https://www.twilio.com/docs/content) only: The SID of the Content Template to be used with the Message, e.g., `HXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`. If this parameter is not provided, a Content Template is not used. Find the SID in the Console on the Content Editor page. For Content API users, the SID is found in Twilio's response when [creating the Template](https://www.twilio.com/docs/content/content-api-resources#create-templates) or by [fetching your Templates](https://www.twilio.com/docs/content/content-api-resources#fetch-all-content-resources)."}},required:[],additionalProperties:!0},ut={output:Xt};var ht={[shared.SmsProviderIdEnum.AfricasTalking]:l,[shared.SmsProviderIdEnum.AzureSms]:l,[shared.SmsProviderIdEnum.Bandwidth]:l,[shared.SmsProviderIdEnum.BrevoSms]:l,[shared.SmsProviderIdEnum.BulkSms]:l,[shared.SmsProviderIdEnum.BurstSms]:l,[shared.SmsProviderIdEnum.Clickatell]:l,[shared.SmsProviderIdEnum.Clicksend]:l,[shared.SmsProviderIdEnum.EazySms]:l,[shared.SmsProviderIdEnum.Firetext]:l,[shared.SmsProviderIdEnum.FortySixElks]:l,[shared.SmsProviderIdEnum.GenericSms]:l,[shared.SmsProviderIdEnum.Gupshup]:l,[shared.SmsProviderIdEnum.Infobip]:l,[shared.SmsProviderIdEnum.ISendSms]:l,[shared.SmsProviderIdEnum.Kannel]:l,[shared.SmsProviderIdEnum.Maqsam]:l,[shared.SmsProviderIdEnum.MessageBird]:l,[shared.SmsProviderIdEnum.Mobishastra]:l,[shared.SmsProviderIdEnum.Nexmo]:l,[shared.SmsProviderIdEnum.Novu]:dt,[shared.SmsProviderIdEnum.Plivo]:l,[shared.SmsProviderIdEnum.RingCentral]:l,[shared.SmsProviderIdEnum.Sendchamp]:l,[shared.SmsProviderIdEnum.Simpletexting]:l,[shared.SmsProviderIdEnum.Sms77]:l,[shared.SmsProviderIdEnum.SmsCentral]:l,[shared.SmsProviderIdEnum.SNS]:l,[shared.SmsProviderIdEnum.Telnyx]:l,[shared.SmsProviderIdEnum.Termii]:l,[shared.SmsProviderIdEnum.Twilio]:ut};var mt={chat:Xe,sms:ht,email:it,push:pt,in_app:ot};var Jt={type:"object",properties:{type:{enum:["regular"],default:"regular"},amount:{type:"number"},unit:{type:"string",enum:["seconds","minutes","hours","days","weeks","months"]}},required:["amount","unit"],additionalProperties:!1},Zt={type:"object",properties:{duration:{type:"number"}},required:["duration"],additionalProperties:!1},Le={output:Jt,result:Zt};var Qt={type:"object",properties:{amount:{type:"number"},unit:{type:"string",enum:["seconds","minutes","hours","days","weeks","months"]},digestKey:{type:"string"},lookBackWindow:{type:"object",properties:{amount:{type:"number"},unit:{type:"string",enum:["seconds","minutes","hours","days","weeks","months"]}},required:["amount","unit"],additionalProperties:!1}},required:["amount","unit"],additionalProperties:!1},ei={type:"object",properties:{cron:{type:"string"},digestKey:{type:"string"}},required:["cron"],additionalProperties:!1},ti={oneOf:[Qt,ei]},ii={type:"object",properties:{events:{type:"array",items:{type:"object",properties:{id:{type:"string"},time:{type:"string"},payload:{type:"object"}},required:["id","time","payload"],additionalProperties:!1}}},required:["events"],additionalProperties:!1},Fe={output:ti,result:ii};var ni={type:"object",properties:{body:{type:"string"}},required:["body"],additionalProperties:!1},oi={type:"object",properties:{},required:[],additionalProperties:!1},yt={output:ni,result:oi};var si={type:"object",properties:{subject:{type:"string"},body:{type:"string"}},required:["subject","body"],additionalProperties:!1},ri={type:"object",properties:{},required:[],additionalProperties:!1},gt={output:si,result:ri};var ft={type:"object",properties:{label:{type:"string"},url:{type:"string"}},required:["label"],additionalProperties:!1},ai={type:"object",properties:{subject:{type:"string"},body:{type:"string"},avatar:{type:"string",format:"uri"},primaryAction:ft,secondaryAction:ft},required:["body"],additionalProperties:!1},ci={type:"object",properties:{seen:{type:"boolean"},read:{type:"boolean"},lastSeenDate:{type:"string",format:"date-time",nullable:!0},lastReadDate:{type:"string",format:"date-time",nullable:!0}},required:["seen","read","lastSeenDate","lastReadDate"],additionalProperties:!1},wt={output:ai,result:ci};var li={type:"object",properties:{subject:{type:"string"},body:{type:"string"}},required:["subject","body"],additionalProperties:!1},pi={type:"object",properties:{},required:[],additionalProperties:!1},bt={output:li,result:pi};var di={type:"object",properties:{body:{type:"string"}},required:["body"],additionalProperties:!1},ui={type:"object",properties:{},required:[],additionalProperties:!1},St={output:di,result:ui};var E={chat:yt,sms:St,push:bt,email:gt,in_app:wt};var T={type:"object",properties:{},required:[],additionalProperties:!1};function Hs(s,e,t){let i=t||{},n=he(process.env.NOVU_SECRET_KEY),a=async p=>{if(!process.env.NOVU_SECRET_KEY)throw new ge;let u=p.payload;if(i.payloadSchema){let y=await Pe(i.payloadSchema,p.payload);if(y.success===!1)throw new pe(s,y.errors);u=y.data;}let g=await $e(),S={name:s,to:p.to,payload:{...u},...p.transactionId&&{transactionId:p.transactionId},...p.overrides&&{overrides:p.overrides},...p.actor&&{actor:p.actor},...p.tenant&&{tenant:p.tenant},...g&&{bridgeUrl:g}},_=await n.post("/events/trigger",S);return {cancel:async()=>n.delete(`/events/trigger/${_.transactionId}`),data:_}},c={workflowId:s,options:{...i,inputSchema:f(i.controlSchema||i.inputSchema||T),controlSchema:f(i.controlSchema||i.inputSchema||T),payloadSchema:f(i.payloadSchema||T)},steps:[],code:e.toString(),data:{schema:f(i.payloadSchema||T),unknownSchema:i.payloadSchema||T},payload:{schema:f(i.payloadSchema||T),unknownSchema:i.payloadSchema||T},inputs:{schema:f(i.controlSchema||i.inputSchema||T),unknownSchema:i.controlSchema||i.inputSchema||T},controls:{schema:f(i.controlSchema||i.inputSchema||T),unknownSchema:i.controlSchema||i.inputSchema||T},tags:i.tags||[],execute:e};return e({payload:{},subscriber:{},environment:{},controls:{},input:{},step:{push:H(c,"push",E.push.output,E.push.result),chat:H(c,"chat",E.chat.output,E.chat.result),email:H(c,"email",E.email.output,E.email.result),sms:H(c,"sms",E.sms.output,E.sms.result),inApp:H(c,"in_app",E.in_app.output,E.in_app.result),digest:Tt(c,"digest",Fe.output,Fe.result),delay:Tt(c,"delay",Le.output,Le.result),custom:mi(c,"custom")}}),yi(c),{trigger:a,definition:c}}function H(s,e,t,i){return async(n,a,c={})=>{let p=c?.controlSchema||c?.inputSchema||T,u={stepId:n,type:e,inputs:{schema:f(p),unknownSchema:p},controls:{schema:f(p),unknownSchema:p},outputs:{schema:f(t),unknownSchema:t},results:{schema:f(i),unknownSchema:i},resolve:a,code:a.toString(),options:c,providers:[]};return je(s,n,u),Object.keys(c.providers||{}).length>0&&hi(u,e,c.providers||{}),{_ctx:{timestamp:Date.now(),state:{status:"pending",error:!1}}}}}function Tt(s,e,t,i){return async(n,a,c={})=>{let p=c?.controlSchema||c?.inputSchema||T;return je(s,n,{stepId:n,type:e,inputs:{schema:f(p),unknownSchema:p},controls:{schema:f(p),unknownSchema:p},outputs:{schema:f(t),unknownSchema:t},results:{schema:f(i),unknownSchema:i},resolve:a,code:a.toString(),options:c,providers:[]}),{_ctx:{timestamp:Date.now(),state:{status:"pending",error:!1}}}}}function je(s,e,t){if(s.steps.some(i=>i.stepId===e))throw new Re(e);s.steps.push(t);}function hi(s,e,t){let i=mt[e];Object.entries(t).forEach(([n,a])=>{let c=i[n];s.providers.push({type:n,code:a.toString(),resolve:a,outputs:{schema:f(c.output),unknownSchema:c.output}});});}function mi(s,e){return async(t,i,n={})=>{let a=n?.controlSchema||n?.inputSchema||T,c=n?.outputSchema||T;return je(s,t,{stepId:t,type:e,inputs:{schema:f(a),unknownSchema:a},controls:{schema:f(a),unknownSchema:a},outputs:{schema:f(c),unknownSchema:c},results:{schema:f(c),unknownSchema:c},resolve:i,code:i.toString(),options:n,providers:[]}),{_ctx:{timestamp:Date.now(),state:{status:"pending",error:!1}}}}}function yi(s){console.log(`
|
|
438
|
+
${h.bold(h.underline("Discovered workflowId:"))} '${s.workflowId}'`),s.steps.forEach((e,t)=>{let i=t===s.steps.length-1?"\u2514":"\u251C";console.log(`${i} ${b.STEP} Discovered stepId: '${e.stepId}' Type: '${e.type}'`),e.providers.forEach((n,a)=>{let c=a===e.providers.length-1?"\u2514":"\u251C";console.log(` ${c} ${b.PROVIDER} Discovered provider: '${n.type}'`);});});}var gi=(g=>(g.PENDING="pending",g.QUEUED="queued",g.RUNNING="running",g.COMPLETED="completed",g.FAILED="failed",g.DELAYED="delayed",g.CANCELED="canceled",g.MERGED="merged",g.SKIPPED="skipped",g))(gi||{});
|
|
439
|
+
|
|
440
|
+
exports.ActionStepEnum = Ge;
|
|
441
|
+
exports.ChannelStepEnum = U;
|
|
442
|
+
exports.Client = K;
|
|
443
|
+
exports.CronExpression = Rt;
|
|
444
|
+
exports.ErrorCodeEnum = v;
|
|
445
|
+
exports.FRAMEWORK_VERSION = te;
|
|
446
|
+
exports.GetActionEnum = J;
|
|
447
|
+
exports.HttpHeaderKeysEnum = Ce;
|
|
448
|
+
exports.HttpMethodEnum = Z;
|
|
449
|
+
exports.HttpQueryKeysEnum = We;
|
|
450
|
+
exports.HttpStatusEnum = Q;
|
|
451
|
+
exports.JobStatusEnum = gi;
|
|
452
|
+
exports.NovuApiEndpointsEnum = At;
|
|
453
|
+
exports.NovuRequestHandler = Ue;
|
|
454
|
+
exports.PostActionEnum = G;
|
|
455
|
+
exports.RETRYABLE_ERROR_STATUS_CODES = _i;
|
|
456
|
+
exports.ResourceEnum = ee;
|
|
457
|
+
exports.SDK_VERSION = q;
|
|
458
|
+
exports.SIGNATURE_TIMESTAMP_TOLERANCE = Ve;
|
|
459
|
+
exports.SIGNATURE_TIMESTAMP_TOLERANCE_MINUTES = Ye;
|
|
460
|
+
exports.workflow = Hs;
|