Skip to content

Commit

Permalink
Merge pull request #555 from negue/feature/recipe-configs-use-trigger…
Browse files Browse the repository at this point in the history
…-variables

command block: use trigger variables as argument values
  • Loading branch information
negue committed Jun 6, 2023
2 parents 48ed14e + fba0b13 commit 7adcd46
Show file tree
Hide file tree
Showing 26 changed files with 386 additions and 64 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 2023.1.0

### Shoutout Users by Command Blocks
(insert screenshot here)
You can now shoutout a specific person by adding a Shoutout Command .. or

### Parse Trigger Payload as Command Block argument variables (maybe need to rephrase it)
With the help of a [very powerful json query library: JSONata](https://jsonata.org) it is now possible to parse trigger payloads (twitch message, raid, etc) and use those as variables for Arguments of Command Blocks.
(insert screenshot here)

## 2022.1.1

### New Command Block "Random Command Group"
Expand Down
16 changes: 15 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@
"express-validator": "6.14.2",
"immer": "8.0.4",
"js-yaml": "4.1.0",
"jsonata": "2.0.3",
"jwt-decode": "3.1.2",
"lodash": "4.17.21",
"marked": "4.2.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
[matAutosizeMinRows]="4"
(ngModelChange)="valueChanged.emit(value)">

</textarea>

</textarea>
</mat-form-field>

<mat-form-field *ngSwitchCase="'number'" >
Expand Down
4 changes: 4 additions & 0 deletions projects/contracts/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export interface HasExtendedData {
extended?: Dictionary<unknown>;
}

// TODO split Action into a union of each subtype
// - with that only properties that are used for type X
// - are known in each sub type

export interface Action extends HasId, ActionOverridableProperties, HasExtendedData {
name: string;
previewUrl?: string;
Expand Down
8 changes: 4 additions & 4 deletions projects/recipe-core/src/lib/command-blocks.generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function registerGenericCommandBlocks(
type: "number"
}
],
toScriptCode: (step, context) => `sleep.secondsAsync(${step.payload.seconds});`,
toScriptCode: (codePayload) => `sleep.secondsAsync(${codePayload.commandBlock.argument('seconds')});`,
commandEntryLabelAsync: (queries, payload, parentStep) => {
return Promise.resolve(`wait ${payload.seconds} seconds`);
},
Expand All @@ -33,7 +33,7 @@ export function registerGenericCommandBlocks(
type: "number"
}
],
toScriptCode: (step, context) => `sleep.msAsync(${step.payload.ms});`,
toScriptCode: (codePayload) => `sleep.msAsync(${codePayload.commandBlock.argument('ms')});`,
commandEntryLabelAsync: (queries, payload, parentStep) => {
return Promise.resolve(`wait ${payload.ms}ms`);
},
Expand Down Expand Up @@ -79,12 +79,12 @@ export function registerGenericCommandBlocks(
return Promise.resolve('');
},
awaitCodeHandledInternally: true,
toScriptCode: (step, context, userData) => {
toScriptCode: ({step,userData,context}) => {
const awaitCode = step.awaited ? 'await ' : '';

const functionNames: string[] = [];

const generatedFunctions = generateCodeByStep(step, context, userData).map(g => {
const generatedFunctions = generateCodeByStep({step, context, userData}).map(g => {

const functionName = `randomGroup_${g.subCommand.labelId}`;

Expand Down
12 changes: 6 additions & 6 deletions projects/recipe-core/src/lib/command-blocks.memebox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function registerMemeboxCommandBlocks(
}
}
],
toScriptCode: (step) => {
toScriptCode: ({step}) => {
const actionPayload = step.payload.action as RecipeCommandConfigActionPayload;

const actionOverrides = actionPayload.overrides;
Expand Down Expand Up @@ -128,14 +128,14 @@ export function registerMemeboxCommandBlocks(
entries: []
});
},
toScriptCode: (step, context, userData) => {
toScriptCode: ({step, context, userData}) => {
const actionPayload = step.payload.action as RecipeCommandConfigActionPayload;

const actionOverrides = actionPayload.overrides;

return `${createMemeboxApiVariable(actionPayload)}
.triggerWhile(async (helpers_${step.payload._suffix}) => {
${generateCodeByStep(step, context, userData)[0].generatedScript}
${generateCodeByStep({step, context, userData})[0].generatedScript}
}
${actionOverrides ? ',' + JSON.stringify(actionOverrides) : ''});`;
},
Expand Down Expand Up @@ -165,7 +165,7 @@ export function registerMemeboxCommandBlocks(
return false;
// return step.entryType === 'command' && step.commandBlockType === 'triggerActionWhile';
},
toScriptCode: (step) => {
toScriptCode: ({step}) => {
const helpersName = `helpers_${step.payload._suffix}`;

return `${helpersName}.reset();`
Expand All @@ -186,7 +186,7 @@ export function registerMemeboxCommandBlocks(
}
],
awaitCodeHandledInternally: true,
toScriptCode: (step, context, userData) => {
toScriptCode: ({step, context, userData}) => {
const awaitCode = step.awaited ? 'await ' : '';

const actionsToChooseFrom = listActionsOfActionListPayload(
Expand Down Expand Up @@ -241,7 +241,7 @@ export function registerMemeboxCommandBlocks(
}*/
],
awaitCodeHandledInternally: true,
toScriptCode: (step) => {
toScriptCode: ({step}) => {
const actionPayload = step.payload.action as RecipeCommandConfigActionPayload;
const overrides = actionPayload.overrides;

Expand Down
32 changes: 16 additions & 16 deletions projects/recipe-core/src/lib/command-blocks.obs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ export function registerObsCommandBlocks (
type: "obs:scene"
}
],
toScriptCode: (step) => {
const scenePayload = step.payload.scene as string;

return `obs.switchToScene('${scenePayload}');`;
toScriptCode: ({step, commandBlock}) => {
return `obs.switchToScene(${commandBlock.argument('scene')});`;
},
commandEntryLabelAsync: (queries, payload) => {
const scenePayload = payload.scene as string;
Expand All @@ -50,10 +48,8 @@ export function registerObsCommandBlocks (
}

],
toScriptCode: (step) => {
const scenePayload = step.payload.sourceName as string;

return `obs.setSourceVisibility('${scenePayload}', ${step.payload.visible});`;
toScriptCode: ({step, commandBlock}) => {
return `obs.setSourceVisibility(${commandBlock.argument('scene')}, ${step.payload.visible});`;
},
commandEntryLabelAsync: (queries, payload) => {
const sourceName = payload.sourceName as string;
Expand All @@ -78,10 +74,8 @@ export function registerObsCommandBlocks (
type: "boolean"
}
],
toScriptCode: (step) => {
const scenePayload = step.payload.sourceName as string;

return `obs.setSourceMute('${scenePayload}', ${step.payload.muted});`;
toScriptCode: ({step, commandBlock}) => {
return `obs.setSourceMute(${commandBlock.argument('sourceName')}, ${step.payload.muted});`;
},
commandEntryLabelAsync: (queries, payload) => {
const sourceName = payload.sourceName as string;
Expand All @@ -107,7 +101,7 @@ export function registerObsCommandBlocks (
type: "boolean"
}
],
toScriptCode: (step) => {
toScriptCode: ({step}) => {
const filterPayload = step.payload.filter as RecipeCommandConfigObsSetFilterStatePayload;
const enabled = step.payload.enabled as boolean;

Expand All @@ -131,15 +125,21 @@ export function registerObsCommandBlocks (
{
name: "command",
label: "Command",
type: "text"
type: "text",
flags: {
canUseVariables: false,
}
},
{
name: "obsPayload",
label: "Payload",
type: "textarea"
type: "textarea",
flags: {
canUseVariables: false,
}
}
],
toScriptCode: (step) => {
toScriptCode: ({step}) => {
const obsCommand = step.payload.command as string;
const obsPayload = step.payload.obsPayload as string;

Expand Down
40 changes: 22 additions & 18 deletions projects/recipe-core/src/lib/command-blocks.twitch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ export function registerTwitchCommandBlocks (
{
name: "text",
label: "Message to write",
type: "textarea"
type: "textarea",
flags: {
canUseVariables: true,
}
}
],
toScriptCode: (step) => {
const textToSay = step.payload.text as string;

return `twitch.say('${textToSay}');`;
toScriptCode: ({step, commandBlock}) => {
return `twitch.say(${commandBlock.argument('text')});`;
},
commandEntryLabelAsync: (queries, payload) => {
const textToSay = payload.text as string;
Expand All @@ -43,13 +44,14 @@ export function registerTwitchCommandBlocks (
{
name: "username",
label: "Username to Shoutout",
type: "text"
type: "text",
flags: {
canUseVariables: true,
}
}
],
toScriptCode: (step) => {
const username = step.payload.username as string;

return `twitch.shoutout('${username}');`;
toScriptCode: ({step, commandBlock}) => {
return `twitch.shoutout(${commandBlock.argument('username')});`;
},
commandEntryLabelAsync: (queries, payload) => {
const username = payload.username as string;
Expand All @@ -66,7 +68,10 @@ export function registerTwitchCommandBlocks (
{
name: "text",
label: "Announcement to send",
type: "textarea"
type: "textarea",
flags: {
canUseVariables: true,
}
},
{
name: "color",
Expand All @@ -82,11 +87,10 @@ export function registerTwitchCommandBlocks (
]
}
],
toScriptCode: (step) => {
const textToSay = step.payload.text as string;
toScriptCode: ({step, commandBlock}) => {
const color = step.payload.color as string;

return `twitch.sendAnnouncement('${textToSay}','${color}');`;
return `twitch.sendAnnouncement(${commandBlock.argument('text')},'${color}');`;
},
commandEntryLabelAsync: (queries, payload) => {
const textToSay = payload.text as string;
Expand Down Expand Up @@ -150,8 +154,8 @@ export function registerTwitchCommandBlocks (
]
}
],
toScriptCode: (command) => {
const length = command.payload.length as string;
toScriptCode: ({step}) => {
const length = step.payload.length as string;
return `twitch.startCommercial(${+length});`;
},
commandEntryLabelAsync: (queries, payload) => {
Expand Down Expand Up @@ -206,7 +210,7 @@ export function registerTwitchCommandBlocks (
configArguments: [
...chatSettingsArray
],
toScriptCode: (step) => {
toScriptCode: ({step}) => {
return `twitch.updateChatSettings(${JSON.stringify(step.payload)});`;
},
commandEntryLabelAsync: (queries, payload) => {
Expand All @@ -228,7 +232,7 @@ export function registerTwitchCommandBlocks (
label: 'Mode Active'
}
],
toScriptCode: (step) => {
toScriptCode: ({step}) => {
return `twitch.updateChatSettings(${JSON.stringify(step.payload)});`;
},
commandEntryLabelAsync: (queries, payload) => {
Expand Down
24 changes: 20 additions & 4 deletions projects/recipe-core/src/lib/generateCodeByRecipe.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
GenerateCodeByStepPayload,
generatedCodeBySubCommandBlock,
RecipeContext,
RecipeEntry,
RecipeEntryCommandCall,
RecipeEntryCommandPayload
} from "./recipe.types";
Expand All @@ -14,7 +14,7 @@ import {RecipeCommandRegistry} from "./recipeCommandRegistry";
import {registerGenericCommandBlocks} from "./command-blocks.generic";


function generateCodeByStepAsync (step: RecipeEntry, context: RecipeContext, userData: UserDataState): generatedCodeBySubCommandBlock[] {
function generateCodeByStepAsync ({step, context, userData}: GenerateCodeByStepPayload): generatedCodeBySubCommandBlock[] {
const result: generatedCodeBySubCommandBlock[] = [];

for (const subStepInfo of step.subCommandBlocks) {
Expand All @@ -34,7 +34,23 @@ function generateCodeByStepAsync (step: RecipeEntry, context: RecipeContext, use
scriptCode.push('await ');
}

const createdStepCode = entryDefinition.toScriptCode(subEntry, context, userData);
// todo "Mark Scripts / Recipes to know which source they might be triggered from"
// => inline recipe in twitch triggers which sets the context inside for example trigger variables
// todo think of way to use other commadn block results in the current one
// todo commandBlockData should cache if there is no dynamic data to speed up things

const createdStepCode = entryDefinition.toScriptCode({
step: subEntry,
context,
commandBlock: {
argument(name) {
// todo check of config if name exist
// also check that on the UI during edit
return `await commandBlockData['${subEntry.id}']['${name}']()`
}
},
userData
});

scriptCode.push(createdStepCode.trim());

Expand All @@ -59,7 +75,7 @@ export function generateCodeByRecipe(
): string {
const rootEntry = recipeContext.entries[recipeContext.rootEntry];

return generateCodeByStepAsync(rootEntry, recipeContext, userData)
return generateCodeByStepAsync({step: rootEntry, context: recipeContext, userData})
.map(g => g.generatedScript)
.join('\r\n');
}
Expand Down
Loading

1 comment on commit 7adcd46

@vercel
Copy link

@vercel vercel bot commented on 7adcd46 Jun 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

meme-box – ./

meme-box-git-develop-negu3.vercel.app
meme-box.vercel.app
meme-box-negu3.vercel.app

Please sign in to comment.