From 68c170ec7afe0e1c2b387fccfdf7e825209a6150 Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sat, 2 Sep 2023 11:17:24 +0900 Subject: [PATCH 01/11] =?UTF-8?q?github=20action=20=E3=81=AE=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=20on=20=E3=81=A7=E3=83=88=E3=83=AA=E3=82=AC?= =?UTF-8?q?=E3=83=BC=E3=82=92=E5=AE=9A=E7=BE=A9=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/workflow.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/workflow.ts b/src/workflow.ts index c61a935..49ecc5f 100644 --- a/src/workflow.ts +++ b/src/workflow.ts @@ -7,6 +7,7 @@ export interface Workflow { version: `${number}.${number}.${number}`; name: string; steps: WorkflowStep[]; + on: WorkflowTriggerMap; } export interface WorkflowStep { @@ -19,6 +20,21 @@ export interface WorkflowStep { exitFlow: boolean | undefined; } +export const WorkflowEvent = { + WorkflowDispatch: 'workflow_dispatch', + Text: 'text', + Select: 'select', + YesNo: 'yesno', + Task: 'task', +} as const; +export type WorkflowEventType = (typeof WorkflowEvent)[keyof typeof WorkflowEvent]; + +export type WorkflowTrigger = Record; + +export type WorkflowTriggerMap = Partial<{ [e in WorkflowEventType]: WorkflowTrigger }>; + +export type WorkflowEventWith = Record; + export const DefaultAction = { Text: 'daab:message:text', Select: 'daab:message:select', From ee287b183edc354f87981cb947a1fd53372d76ca Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sat, 2 Sep 2023 11:21:55 +0900 Subject: [PATCH 02/11] =?UTF-8?q?github=20actions=20=E3=81=AE=20on=20?= =?UTF-8?q?=E3=81=A8=E5=90=8C=E3=81=98=E3=82=88=E3=81=86=E3=81=AA=20yaml?= =?UTF-8?q?=20=E3=82=92=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=82=81=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine.ts | 22 +++++++++++++++++++--- src/triggers.ts | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/triggers.ts diff --git a/src/engine.ts b/src/engine.ts index 37190c5..0deb129 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -9,6 +9,7 @@ import path from 'path'; import * as uuid from 'uuid'; import yaml from 'js-yaml'; import { Action, CustomAction, MessageAction } from './actions'; +import { parseTrigger } from './triggers'; import { DirectUser, DirectTalk, @@ -47,7 +48,7 @@ export class Workflows { const docs = new Map(); filenames.forEach((fn) => { - const w = yaml.load(fs.readFileSync(fn, 'utf8')); + const w = this.parse(yaml.load(fs.readFileSync(fn, 'utf8'))); if (this.validate(w)) { docs.set(w.name, w); } else { @@ -57,8 +58,23 @@ export class Workflows { return new Workflows(docs, repository); } - static validate(obj: any): obj is Workflow { - return typeof obj === 'object' && obj.version && obj.name && Array.isArray(obj.steps); + static parse(w: any): Workflow { + if (w) { + w.on = parseTrigger(w.on); + } + return w; + } + + static validate(obj: Workflow): boolean { + return ( + typeof obj === 'object' && + typeof obj.version === 'number' && + !!obj.version && + typeof obj.name === 'string' && + !!obj.name && + Array.isArray(obj.steps) && + typeof obj.on === 'object' + ); } getNames(): string[] { diff --git a/src/triggers.ts b/src/triggers.ts new file mode 100644 index 0000000..c59010b --- /dev/null +++ b/src/triggers.ts @@ -0,0 +1,19 @@ +import { + WorkflowEvent, + WorkflowTriggerMap, +} from './workflow'; + +export function parseTrigger(on: any): WorkflowTriggerMap { + if (Array.isArray(on)) { + return on.reduce((obj, o) => ({ ...obj, ...parseTrigger(o) }), {}); + } else if (typeof on === 'object') { + return on; + } else if (typeof on === 'string') { + return { [on]: {} }; + } else if (on === undefined) { + return { [WorkflowEvent.WorkflowDispatch]: {} }; // default + } else { + return {}; // error + } +} + From 909e2a3354c4d5242dc6b9210f7798b0ec5d56d2 Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sat, 2 Sep 2023 11:28:50 +0900 Subject: [PATCH 03/11] =?UTF-8?q?/list=20=E3=81=A7=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=82=8B=E3=83=AF=E3=83=BC=E3=82=AF=E3=83=95?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=81=AF=20on=20=E3=81=AA=E3=81=97=E3=81=A8?= =?UTF-8?q?=20workflow=5Fdispatch=20=E3=81=AB=E9=99=90=E5=AE=9A=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/commands.ts | 2 +- src/engine.ts | 12 +++++++++++- src/triggers.ts | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index 22f4755..99f64f0 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -42,7 +42,7 @@ export class Commands { session.selecting = true; res.send({ question: 'ワークフローを選択してください。', - options: workflows.getNames(), + options: workflows.getSelectableNames(), }); } } diff --git a/src/engine.ts b/src/engine.ts index 0deb129..943c025 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -9,7 +9,7 @@ import path from 'path'; import * as uuid from 'uuid'; import yaml from 'js-yaml'; import { Action, CustomAction, MessageAction } from './actions'; -import { parseTrigger } from './triggers'; +import { parseTrigger, isTriggerFired } from './triggers'; import { DirectUser, DirectTalk, @@ -81,6 +81,16 @@ export class Workflows { return Array.from(this.docs.keys()).sort(); } + getSelectableNames(): string[] { + return this.filterByEvent(WorkflowEvent.WorkflowDispatch).map((workflow) => workflow.name); + } + + filterByEvent(type: WorkflowEventType, e?: WorkflowEventWith): Workflow[] { + return this.getNames() + .map((name) => this.findByName(name)!) + .filter((workflow) => isTriggerFired(type, workflow.on[type], e)); + } + findByName(name: string): Workflow | undefined { return this.docs.get(name); } diff --git a/src/triggers.ts b/src/triggers.ts index c59010b..d25cc5c 100644 --- a/src/triggers.ts +++ b/src/triggers.ts @@ -1,5 +1,8 @@ import { WorkflowEvent, + WorkflowEventType, + WorkflowEventWith, + WorkflowTrigger, WorkflowTriggerMap, } from './workflow'; @@ -17,3 +20,16 @@ export function parseTrigger(on: any): WorkflowTriggerMap { } } +export function isTriggerFired( + type: WorkflowEventType, + trigger: WorkflowTrigger | undefined, + e: WorkflowEventWith | undefined +): boolean { + if (!trigger) { + return false; + } + if (Object.keys(trigger).length == 0) { + return true; + } + return false; +} From bec0d28af3e8c9b4a5a0192df2f75e35a46bd173 Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sat, 2 Sep 2023 11:33:26 +0900 Subject: [PATCH 04/11] =?UTF-8?q?on:=20text=20=E3=81=A7=E3=83=86=E3=82=AD?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=A4=E3=83=99=E3=83=B3=E3=83=88=E3=81=AB?= =?UTF-8?q?=E5=8F=8D=E5=BF=9C=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine.ts | 26 ++++++++++++++++++++++++++ src/index.ts | 17 ++++++++++++++--- src/triggers.ts | 15 +++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/engine.ts b/src/engine.ts index 943c025..1ff23f3 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -29,6 +29,9 @@ import { DefaultActionWith, isCustomAction, getCustomActionName, + WorkflowEvent, + WorkflowEventType, + WorkflowEventWith, } from './workflow'; import { Repository } from './repository'; @@ -102,6 +105,16 @@ export class Workflows { } return undefined; } + + createWorkflowContextByEvent( + type: WorkflowEventType, + e?: WorkflowEventWith + ): WorkflowContext | undefined { + const workflow = this.filterByEvent(type, e); + if (workflow.length) { + return WorkflowContext.create(workflow[0], this.repository); + } + } } // * NOTE: Hubot の Listener 処理が Promise に対応していないため,daab-session を使わずに別途設けることになった @@ -174,6 +187,7 @@ export class WorkflowContext { private valid = true; private stepIndex = 0; private data: WorkflowStepData = {}; + private readonly firstStep = { id: 'on' } as WorkflowStep; private readonly actors = new Set(); private constructor( @@ -231,7 +245,14 @@ export class WorkflowContext { this.data = {}; } + private resetByEvent(type: WorkflowEventType) { + this.stepIndex = -1; + this.data = {}; + this.firstStep.action = `daab:message:${type.split('_')[0]}`; + } + private get currentStep() { + if (this.stepIndex === -1) return this.firstStep; return this.workflow.steps[this.stepIndex]; } private get isLastStep() { @@ -338,6 +359,11 @@ export class WorkflowContext { } } + async triggerWorkflow(type: WorkflowEventType) { + this.resetByEvent(type); + this.activate(); + } + private async exitWorkflow() { this.reset(); this.deactivate(); diff --git a/src/index.ts b/src/index.ts index 1daf436..9de0c0d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ import { import { Repository } from './repository'; import { UserContext, UserSession, Workflows } from './engine'; import { Commands } from './commands'; +import { WorkflowEvent, WorkflowEventType } from './workflow'; const _middlewares = (repository: Repository) => @@ -43,13 +44,23 @@ export function workflow(dirPath: string) { return repository.findUserContextByUserId(userId); } - async function findCurrentWorkflowContext(res: Response) { + async function findCurrentWorkflowContext( + res: Response, + type: WorkflowEventType + ) { const uc = await findUser(res); // console.debug('found uc:', uc); const wc = await repository.findWorkflowContext(uc?.getCurrentWorkflowContextId()); // console.debug('found wc:', wc); + if (wc) { return wc; } + const newContext = workflows.createWorkflowContextByEvent(type, res); + if (newContext) { + await newContext.triggerWorkflow(type); + return newContext; + } + } async function startWorkflow(res: ResponseWithJson, workflows: Workflows) { const selectedName = res.json.options[res.json.response!]; @@ -84,8 +95,8 @@ export function workflow(dirPath: string) { if (command) { command.run(res, session); } else { - const context = await findCurrentWorkflowContext(res); - if (context && context.isActive) { + const context = await findCurrentWorkflowContext(res, WorkflowEvent.Text); + if (context && context.isActive()) { await context.handleText(res); } } diff --git a/src/triggers.ts b/src/triggers.ts index d25cc5c..52ef0bb 100644 --- a/src/triggers.ts +++ b/src/triggers.ts @@ -1,3 +1,7 @@ +import { + Response, + TextMessage, +} from 'lisb-hubot'; import { WorkflowEvent, WorkflowEventType, @@ -31,5 +35,16 @@ export function isTriggerFired( if (Object.keys(trigger).length == 0) { return true; } + switch (type) { + case 'text': { + const res = e as Response; + if (typeof trigger.match === 'string' && res.message.text.match(trigger.match)) { + return true; + } + break; + } + default: + break; + } return false; } From b62d843684472991edc4bca04176821c5bbf1326 Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sat, 2 Sep 2023 11:36:47 +0900 Subject: [PATCH 05/11] =?UTF-8?q?on:note=5Fcreated=20=E3=81=AA=E3=81=A9?= =?UTF-8?q?=E3=81=A7=E3=83=8E=E3=83=BC=E3=83=88=E3=82=A4=E3=83=99=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=81=AB=E5=8F=8D=E5=BF=9C=E3=81=99=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine.ts | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 49 ++++++++++++++++++++++++++++++++++++-------- src/triggers.ts | 20 ++++++++++++++++++ src/workflow.ts | 4 ++++ 4 files changed, 119 insertions(+), 8 deletions(-) diff --git a/src/engine.ts b/src/engine.ts index 1ff23f3..5448dcf 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -20,6 +20,9 @@ import { TaskWithResponse, TextMessage, YesNoWithResponse, + NoteCreated, + NoteUpdated, + NoteDeleted, } from './daab'; import { DefaultAction, @@ -448,4 +451,55 @@ export class WorkflowContext { await this.runNextAction(res); } + + async handleNoteCreated(res: ResponseWithJson) { + const current = this.currentStep; + if (current.action != DefaultAction.Note) { + return; + } + + if (current.id) { + this.data[current.id] = { + responder: res.message.user, + ...res.json, + response: { note: res.json }, + }; + } + + await this.runNextAction(res); + } + + async handleNoteUpdated(res: ResponseWithJson) { + const current = this.currentStep; + if (current.action != DefaultAction.Note) { + return; + } + + if (current.id) { + this.data[current.id] = { + responder: res.message.user, + ...res.json, + response: { note: res.json }, + }; + } + + await this.runNextAction(res); + } + + async handleNoteDeleted(res: ResponseWithJson) { + const current = this.currentStep; + if (current.action != DefaultAction.Note) { + return; + } + + if (current.id) { + this.data[current.id] = { + responder: res.message.user, + ...res.json, + response: { note: res.json }, + }; + } + + await this.runNextAction(res); + } } diff --git a/src/index.ts b/src/index.ts index 9de0c0d..908925f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -53,8 +53,8 @@ export function workflow(dirPath: string) { const wc = await repository.findWorkflowContext(uc?.getCurrentWorkflowContextId()); // console.debug('found wc:', wc); if (wc) { - return wc; - } + return wc; + } const newContext = workflows.createWorkflowContextByEvent(type, res); if (newContext) { await newContext.triggerWorkflow(type); @@ -107,8 +107,8 @@ export function workflow(dirPath: string) { 'select', middlewares(async (res, session) => { // console.debug('select'); - const context = await findCurrentWorkflowContext(res); - if (context && context.isActive) { + const context = await findCurrentWorkflowContext(res, WorkflowEvent.Select); + if (context && context.isActive()) { await context.handleSelect(res); } else { if (session.selecting) { @@ -123,8 +123,8 @@ export function workflow(dirPath: string) { 'task', middlewares(async (res, session) => { // console.debug('task'); - const context = await findCurrentWorkflowContext(res); - if (context && context.isActive) { + const context = await findCurrentWorkflowContext(res, WorkflowEvent.Task); + if (context && context.isActive()) { await context.handleTask(res); } }) @@ -134,12 +134,45 @@ export function workflow(dirPath: string) { 'yesno', middlewares(async (res, session) => { // console.debug('yesno'); - const context = await findCurrentWorkflowContext(res); - if (context && context.isActive) { + const context = await findCurrentWorkflowContext(res, WorkflowEvent.YesNo); + if (context && context.isActive()) { await context.handleYesNo(res); } }) ); + + robot.respond( + 'note_created', + middlewares(async (res, session) => { + // console.debug('note_created'); + const context = await findCurrentWorkflowContext(res, WorkflowEvent.NoteCreated); + if (context && context.isActive()) { + await context.handleNoteCreated(res); + } + }) + ); + + robot.respond( + 'note_updated', + middlewares(async (res, session) => { + // console.debug('note_updated'); + const context = await findCurrentWorkflowContext(res, WorkflowEvent.NoteUpdated); + if (context && context.isActive()) { + await context.handleNoteUpdated(res); + } + }) + ); + + robot.respond( + 'note_deleted', + middlewares(async (res, session) => { + // console.debug('note_deleted'); + const context = await findCurrentWorkflowContext(res, WorkflowEvent.NoteDeleted); + if (context && context.isActive()) { + await context.handleNoteDeleted(res); + } + }) + ); }; return handlers; diff --git a/src/triggers.ts b/src/triggers.ts index 52ef0bb..502519e 100644 --- a/src/triggers.ts +++ b/src/triggers.ts @@ -1,5 +1,9 @@ import { + NoteCreated, + NoteDeleted, + NoteUpdated, Response, + ResponseWithJson, TextMessage, } from 'lisb-hubot'; import { @@ -43,6 +47,22 @@ export function isTriggerFired( } break; } + case 'note_created': + case 'note_updated': + case 'note_deleted': { + const res = e as ResponseWithJson; + const note = res.json; + if (typeof trigger.title === 'string' && note.title.match(trigger.title)) { + return true; + } + if ( + typeof trigger.has_attachments === 'boolean' && + trigger.has_attachments == note.has_attachments + ) { + return true; + } + break; + } default: break; } diff --git a/src/workflow.ts b/src/workflow.ts index 49ecc5f..ef6cea8 100644 --- a/src/workflow.ts +++ b/src/workflow.ts @@ -26,6 +26,9 @@ export const WorkflowEvent = { Select: 'select', YesNo: 'yesno', Task: 'task', + NoteCreated: 'note_created', + NoteUpdated: 'note_updated', + NoteDeleted: 'note_deleted', } as const; export type WorkflowEventType = (typeof WorkflowEvent)[keyof typeof WorkflowEvent]; @@ -40,6 +43,7 @@ export const DefaultAction = { Select: 'daab:message:select', YesNo: 'daab:message:yesno', Task: 'daab:message:task', + Note: 'daab:message:note', } as const; export type DefaultActionType = typeof DefaultAction[keyof typeof DefaultAction]; From 752caa0262244c25e9cb9e04800dabb7382069ab Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sat, 2 Sep 2023 11:48:50 +0900 Subject: [PATCH 06/11] =?UTF-8?q?on:join=20=E3=81=A7=E5=8F=82=E5=8A=A0?= =?UTF-8?q?=E3=82=A4=E3=83=99=E3=83=B3=E3=83=88=E3=81=AB=E5=8F=8D=E5=BF=9C?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine.ts | 32 ++++++++++++++++++++++++++++++++ src/index.ts | 20 ++++++++++++++++++++ src/workflow.ts | 2 ++ 3 files changed, 54 insertions(+) diff --git a/src/engine.ts b/src/engine.ts index 5448dcf..e61dfdc 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -23,6 +23,8 @@ import { NoteCreated, NoteUpdated, NoteDeleted, + JoinMessage, + LeaveMessage, } from './daab'; import { DefaultAction, @@ -502,4 +504,34 @@ export class WorkflowContext { await this.runNextAction(res); } + + async handleJoin(res: Response) { + const current = this.currentStep; + if (current.action != 'daab:message:join') { + return; + } + + if (current.id) { + this.data[current.id] = { + responder: res.message.user, + }; + } + + await this.runNextAction(res); + } + + async handleLeave(res: Response) { + const current = this.currentStep; + if (current.action != 'daab:message:leave') { + return; + } + + if (current.id) { + this.data[current.id] = { + responder: res.message.user, + }; + } + + await this.runNextAction(res); + } } diff --git a/src/index.ts b/src/index.ts index 908925f..5ada126 100644 --- a/src/index.ts +++ b/src/index.ts @@ -173,6 +173,26 @@ export function workflow(dirPath: string) { } }) ); + + robot.join( + middlewares(async (res, session) => { + // console.debug('join'); + const context = await findCurrentWorkflowContext(res, WorkflowEvent.Join); + if (context && context.isActive()) { + await context.handleJoin(res); + } + }) + ); + + robot.leave( + middlewares(async (res, session) => { + // console.debug('leave'); + const context = await findCurrentWorkflowContext(res, WorkflowEvent.Leave); + if (context && context.isActive()) { + await context.handleLeave(res); + } + }) + ); }; return handlers; diff --git a/src/workflow.ts b/src/workflow.ts index ef6cea8..a82fec4 100644 --- a/src/workflow.ts +++ b/src/workflow.ts @@ -26,6 +26,8 @@ export const WorkflowEvent = { Select: 'select', YesNo: 'yesno', Task: 'task', + Join: 'join', + Leave: 'leave', NoteCreated: 'note_created', NoteUpdated: 'note_updated', NoteDeleted: 'note_deleted', From b09b9017d66966042625df9ab11ac96c813b8288 Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sat, 2 Sep 2023 11:49:43 +0900 Subject: [PATCH 07/11] =?UTF-8?q?=E3=82=B5=E3=83=B3=E3=83=97=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/workflows/join.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 example/workflows/join.yml diff --git a/example/workflows/join.yml b/example/workflows/join.yml new file mode 100644 index 0000000..f82d1a8 --- /dev/null +++ b/example/workflows/join.yml @@ -0,0 +1,15 @@ +version: 1 + +name: Join test + +on: + - workflow_dispatch + - join + - text: + match: hello + +steps: + - name: send text + action: daab:message:text + with: + text: はじめまして From b98edc936e140696500ca620ad44dd5cb51af52f Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sun, 10 Sep 2023 22:55:29 +0900 Subject: [PATCH 08/11] =?UTF-8?q?=E8=A4=87=E6=95=B0=E3=81=AE=E3=83=88?= =?UTF-8?q?=E3=83=AA=E3=82=AC=E3=83=BC=E3=82=92=E3=82=AA=E3=83=96=E3=82=B8?= =?UTF-8?q?=E3=82=A7=E3=82=AF=E3=83=88=E5=BD=A2=E5=BC=8F=E3=81=A7=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E3=81=A7=E3=81=8D=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F?= =?UTF-8?q?=E3=81=AE=E3=81=A7=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/triggers.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/triggers.ts b/src/triggers.ts index 502519e..af62087 100644 --- a/src/triggers.ts +++ b/src/triggers.ts @@ -18,6 +18,13 @@ export function parseTrigger(on: any): WorkflowTriggerMap { if (Array.isArray(on)) { return on.reduce((obj, o) => ({ ...obj, ...parseTrigger(o) }), {}); } else if (typeof on === 'object') { + Object.keys(on).forEach((k) => { + if (on[k] === null || on[k] === true) { + on[k] = {}; // fix to {} + } else if (typeof on[k] !== 'object') { + delete on[k]; // invalid + } + }); return on; } else if (typeof on === 'string') { return { [on]: {} }; From 0321889cd76b3cb640dd9f14fa169d083c2e61de Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Mon, 11 Sep 2023 06:23:00 +0900 Subject: [PATCH 09/11] =?UTF-8?q?join=20=E3=81=AE=E3=81=A8=E3=81=8D?= =?UTF-8?q?=E3=81=AF=E3=83=9C=E3=83=83=E3=83=88=E3=81=AEuserId=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=82=8B=E3=81=AE=E3=81=A7=E3=80=81=E7=9B=B8=E6=89=8B?= =?UTF-8?q?=E3=81=AEuserId=20=E3=81=AB=E5=A4=89=E6=8F=9B=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/engine.ts b/src/engine.ts index e61dfdc..c73fb4b 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -283,7 +283,14 @@ export class WorkflowContext { private getUserId(res: Response, step: WorkflowStep) { const args = step.with as { to?: string }; // ! FIXME - return this.findUserId(res, args.to)?.id ?? res.message.user.id; + // FIXME + const obj = (res.robot as any).direct.api.dataStore.me.id; + const botId = `_${obj.high}_${obj.low}`; + let userId = res.message.user.id; + if (userId == botId) { + userId = res.message.roomUsers.find((user: any) => user.id !== botId)?.id; + } + return this.findUserId(res, args.to)?.id ?? userId; } private async findOrCreateUserContext(userId: string) { From cee086540f4cfaea4b924ab2669b3329f19efba9 Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Mon, 11 Sep 2023 09:10:45 +0900 Subject: [PATCH 10/11] =?UTF-8?q?=E3=83=88=E3=83=BC=E3=82=AF=E3=81=8B?= =?UTF-8?q?=E3=82=89=E9=80=80=E5=87=BA=E3=81=97=E3=81=9F=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AB=E3=83=AF=E3=83=BC=E3=82=AF=E3=83=95=E3=83=AD=E3=83=BC?= =?UTF-8?q?=E3=82=92=E5=81=9C=E6=AD=A2=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine.ts | 4 ++++ src/index.ts | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/engine.ts b/src/engine.ts index c73fb4b..9a3c18d 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -394,6 +394,10 @@ export class WorkflowContext { await this.repository.destroy(this); } + async cancelWorkflow() { + return this.exitWorkflow(); + } + async handleSelect(res: ResponseWithJson) { const current = this.currentStep; if (current.action != DefaultAction.Select) { diff --git a/src/index.ts b/src/index.ts index 5ada126..ea3b1c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -191,6 +191,9 @@ export function workflow(dirPath: string) { if (context && context.isActive()) { await context.handleLeave(res); } + if (context) { + await context.cancelWorkflow(); + } }) ); }; From ec91b7929fa3182c30841e0718ab8b01fd7e9a37 Mon Sep 17 00:00:00 2001 From: masataka takeuchi Date: Sat, 18 Nov 2023 23:35:37 +0900 Subject: [PATCH 11/11] =?UTF-8?q?=E3=82=BB=E3=83=AC=E3=82=AF=E3=83=88?= =?UTF-8?q?=E3=82=B9=E3=82=BF=E3=83=B3=E3=83=97=E3=81=AB=E5=8F=8D=E5=BF=9C?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/triggers.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/triggers.ts b/src/triggers.ts index af62087..a47c282 100644 --- a/src/triggers.ts +++ b/src/triggers.ts @@ -4,6 +4,7 @@ import { NoteUpdated, Response, ResponseWithJson, + SelectWithResponse, TextMessage, } from 'lisb-hubot'; import { @@ -54,6 +55,26 @@ export function isTriggerFired( } break; } + case 'select': { + const res = e as ResponseWithJson; + if ( + typeof trigger.question?.match === 'string' && + res.json.question.match(trigger.question.match) + ) { + return true; + } + if (typeof trigger.response === 'number' && res.json.response === trigger.response) { + return true; + } + if ( + typeof trigger.response?.match === 'string' && + typeof res.json.response === 'number' && + res.json.options[res.json.response].match(trigger.response.match) + ) { + return true; + } + break; + } case 'note_created': case 'note_updated': case 'note_deleted': {