new(basic.gblib): TABLE keyword #375 fixes.
This commit is contained in:
parent
90e0688cd6
commit
7163c077fe
6 changed files with 199 additions and 149 deletions
|
@ -644,6 +644,19 @@ export class DialogKeywords {
|
|||
await DialogKeywords.setOption({ pid, name, value });
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns current if any continuation token for paginated HTTP requests.
|
||||
*
|
||||
* @example CONTINUATION TOKEN
|
||||
*
|
||||
*/
|
||||
public async getContinuationToken({ pid }) {
|
||||
let { min, user, params, proc } = await DialogKeywords.getProcessInfo(pid);
|
||||
|
||||
return DialogKeywords.getOption({ pid, name: `${proc.executable}-continuationToken` });
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns bot param persisted on storage.
|
||||
*
|
||||
|
|
|
@ -171,19 +171,42 @@ export class GBVMService extends GBService {
|
|||
} else {
|
||||
await this.translateBASIC(mainName, fullFilename, min);
|
||||
}
|
||||
|
||||
|
||||
// Syncronizes Database Objects with the ones returned from "Word".
|
||||
|
||||
const tablesFile = urlJoin(folder, 'tables.json');
|
||||
const tablesFile = urlJoin(folder, `${filename}.tables.json`);
|
||||
if (Fs.existsSync(tablesFile)) {
|
||||
const minBoot = GBServer.globals.minBoot;
|
||||
GBLogEx.info(min, `BASIC: Reading tables and sync storage for ${min.botId}...`);
|
||||
|
||||
const tables = JSON.parse(Fs.readFileSync(tablesFile, 'utf8'));
|
||||
tables.forEach(t => {
|
||||
minBoot.core.sequelize.define(t.name, t.fields);
|
||||
|
||||
const t = JSON.parse(Fs.readFileSync(tablesFile, 'utf8'));
|
||||
|
||||
const getTypeBasedOnCondition = (t) => {
|
||||
switch (t) {
|
||||
case 'string':
|
||||
return { key: 'STRING' };
|
||||
case 'key':
|
||||
return { key: 'STRING' }; // Assuming key is a string data type
|
||||
case 'integer':
|
||||
return { key: 'INTEGER' };
|
||||
case 'double':
|
||||
return { key: 'FLOAT' };
|
||||
case 'date':
|
||||
return { key: 'DATE' };
|
||||
case 'boolean':
|
||||
return { key: 'BOOLEAN' };
|
||||
default:
|
||||
return { key: 'STRING' }; // Default to string if the type is unknown
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(t.fields).forEach(key => {
|
||||
let obj = t.fields[key];
|
||||
obj.type = getTypeBasedOnCondition(obj.type);
|
||||
});
|
||||
|
||||
minBoot.core.sequelize.define(t.name, t.fields);
|
||||
|
||||
await minBoot.core.sequelize.sync();
|
||||
}
|
||||
|
||||
|
@ -194,6 +217,7 @@ export class GBVMService extends GBService {
|
|||
}
|
||||
|
||||
public async translateBASIC(mainName, filename: any, min: GBMinInstance) {
|
||||
|
||||
// Converts General Bots BASIC into regular VBS
|
||||
|
||||
let basicCode: string = Fs.readFileSync(filename, 'utf8');
|
||||
|
@ -218,7 +242,7 @@ export class GBVMService extends GBService {
|
|||
}
|
||||
} while (include);
|
||||
|
||||
let { code, map, metadata, tasks } = await this.convert(mainName, basicCode);
|
||||
let { code, map, metadata, tasks } = await this.convert(filename, mainName, basicCode);
|
||||
|
||||
// Generates function JSON metadata to be used later.
|
||||
|
||||
|
@ -231,7 +255,7 @@ export class GBVMService extends GBService {
|
|||
|
||||
// Execute off-line code tasks
|
||||
|
||||
await this.executeTasks(tasks);
|
||||
await this.executeTasks(min, tasks);
|
||||
|
||||
// Run JS into the GB context.
|
||||
|
||||
|
@ -310,6 +334,15 @@ export class GBVMService extends GBService {
|
|||
const hour = (v) => { return (async () => { return await dk.getHourFromDate({v}) })(); };
|
||||
const base64 = (v) => { return (async () => { return await dk.getCoded({v}) })(); };
|
||||
const tolist = (v) => { return (async () => { return await dk.getToLst({v}) })(); };
|
||||
const uuid = () => {
|
||||
var dt = new Date().getTime();
|
||||
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
||||
var r = (dt + Math.random()*16)%16 | 0;
|
||||
dt = Math.floor(dt/16);
|
||||
return (c=='x' ? r :(r&0x3|0x8)).toString(16);
|
||||
});
|
||||
return uuid;
|
||||
};
|
||||
|
||||
// Setups interprocess communication from .gbdialog run-time to the BotServer API.
|
||||
|
||||
|
@ -338,29 +371,20 @@ export class GBVMService extends GBService {
|
|||
|
||||
}
|
||||
|
||||
private async executeTasks(tasks) {
|
||||
private async executeTasks(min, tasks) {
|
||||
for (let i = 0; i < tasks.length; i++) {
|
||||
const task = tasks[i];
|
||||
|
||||
if (task.kind === 'writeTableDefinition') {
|
||||
|
||||
// Creates an empty object that will receive Sequelize fields.
|
||||
|
||||
let obj = {name: task.name};
|
||||
obj['fields'] = [];
|
||||
|
||||
const fields = task.fields;
|
||||
fields.forEach(f => {
|
||||
let obj = { name: task.name };
|
||||
obj['fields'] = task.fields;
|
||||
const path = DialogKeywords.getGBAIPath(min.botId, `gbdialog`);
|
||||
const tablesFile = `${task.file}.tables.json`;
|
||||
|
||||
let field = {};
|
||||
field[f.name] = f;
|
||||
|
||||
obj['fields'].push(field);
|
||||
|
||||
});
|
||||
|
||||
const jsonFile = `${task.name}.table.json`;
|
||||
Fs.writeFileSync(jsonFile, JSON.stringify(obj));
|
||||
Fs.writeFileSync(tablesFile, JSON.stringify(obj));
|
||||
|
||||
}
|
||||
|
||||
|
@ -454,42 +478,20 @@ export class GBVMService extends GBService {
|
|||
let required = line.indexOf('*') !== -1;
|
||||
line = line.replace('*', '');
|
||||
|
||||
const fieldRegExp = /^\s*(\w+)\s*(\w+)(\((\d+)\))?/gim;
|
||||
const fieldRegExp = /^\s*(\w+)\s*(\w+)(?:\((\d+)\))?/gim;
|
||||
|
||||
let reg = fieldRegExp.exec(line);
|
||||
const t = reg[2];
|
||||
const n = reg[1];
|
||||
|
||||
let obj = {};
|
||||
let field = {allowNull: !required };
|
||||
obj[n] = field;
|
||||
const name = reg[1];
|
||||
|
||||
const getTypeBasedOnCondition = (t) => {
|
||||
switch (t) {
|
||||
case 'string':
|
||||
return DataTypes.STRING;
|
||||
case 'key':
|
||||
return DataTypes.STRING; // Assuming key is a string data type
|
||||
case 'integer':
|
||||
return DataTypes.INTEGER;
|
||||
case 'double':
|
||||
return DataTypes.FLOAT;
|
||||
case 'date':
|
||||
return DataTypes.DATE;
|
||||
case 'boolean':
|
||||
return DataTypes.BOOLEAN;
|
||||
default:
|
||||
return DataTypes.STRING; // Default to string if the type is unknown
|
||||
}
|
||||
};
|
||||
|
||||
field['type'] = getTypeBasedOnCondition(t);
|
||||
|
||||
if (reg[3]){
|
||||
field['size'] = getTypeBasedOnCondition(t);
|
||||
let definition = { allowNull: !required };
|
||||
definition['type'] = t;
|
||||
|
||||
if (reg[3]) {
|
||||
definition['size'] = Number.parseInt(reg[3]);
|
||||
}
|
||||
|
||||
return obj;
|
||||
return { name, definition };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -498,7 +500,7 @@ export class GBVMService extends GBService {
|
|||
*
|
||||
* @param code General Bots BASIC
|
||||
*/
|
||||
public async convert(mainName: string, code: string) {
|
||||
public async convert(filename: string, mainName: string, code: string) {
|
||||
|
||||
// Start and End of VB2TS tags of processing.
|
||||
|
||||
|
@ -511,9 +513,10 @@ export class GBVMService extends GBService {
|
|||
let description;
|
||||
let table = null; // Used for TABLE keyword.
|
||||
const tasks = [];
|
||||
let fields = [];
|
||||
let fields = {};
|
||||
|
||||
for (let i = 1; i <= lines.length; i++) {
|
||||
|
||||
let line = lines[i - 1];
|
||||
|
||||
// Remove lines before statments.
|
||||
|
@ -541,27 +544,12 @@ export class GBVMService extends GBService {
|
|||
emmit = false;
|
||||
}
|
||||
|
||||
// Inside BEGIN/END table pair containing FIELDS.
|
||||
|
||||
if (table) {
|
||||
const field = this.parseField(line);
|
||||
fields.push(field);
|
||||
}
|
||||
|
||||
const tableKeyword = /^\s*TABLE\s*\"(.*)\"/gim;
|
||||
let tableReg = tableKeyword.exec(line);
|
||||
if (tableReg) {
|
||||
table = tableReg[1];
|
||||
emmit = false;
|
||||
}
|
||||
|
||||
const endTableKeyword = /^\s*END TABLE"/gim;
|
||||
const endTableKeyword = /^\s*END TABLE\s*/gim;
|
||||
let endTableReg = endTableKeyword.exec(line);
|
||||
if (endTableReg) {
|
||||
|
||||
if (endTableReg && table) {
|
||||
|
||||
tasks.push({
|
||||
kind: 'writeTableDefinition', name: table, fields: fields
|
||||
kind: 'writeTableDefinition', file: filename, name: table, fields: fields
|
||||
});
|
||||
|
||||
fields = [];
|
||||
|
@ -569,16 +557,27 @@ export class GBVMService extends GBService {
|
|||
emmit = false;
|
||||
}
|
||||
|
||||
// Inside BEGIN/END table pair containing FIELDS.
|
||||
|
||||
if (emmit) {
|
||||
|
||||
// Add additional lines returned from replacement.
|
||||
|
||||
let add = line.split(/\r\n|\r|\n/).length;
|
||||
current = current + (add ? add : 0);
|
||||
map[i] = current;
|
||||
lines[i - 1] = line;
|
||||
if (table && line.trim() !== '') {
|
||||
const field = await this.parseField(line);
|
||||
fields[field.name] = field.definition;
|
||||
emmit = false;
|
||||
}
|
||||
|
||||
const tableKeyword = /^\s*TABLE\s*(.*)/gim;
|
||||
let tableReg = tableKeyword.exec(line);
|
||||
if (tableReg && !table) {
|
||||
table = tableReg[1];
|
||||
emmit = false;
|
||||
}
|
||||
|
||||
// Add additional lines returned from replacement.
|
||||
|
||||
let add = emmit ? line.split(/\r\n|\r|\n/).length : 0;
|
||||
current = current + (add ? add : 0);
|
||||
map[i] = current;
|
||||
lines[i - 1] = emmit ? line : '';
|
||||
}
|
||||
|
||||
code = `${lines.join('\n')}\n`;
|
||||
|
@ -617,7 +616,7 @@ export class GBVMService extends GBService {
|
|||
variables['aadToken'] = await (min.adminService as any)['acquireElevatedToken'](min.instance.instanceId, false);
|
||||
|
||||
// Adds all .gbot params as variables.
|
||||
|
||||
|
||||
const gbotConfig = JSON.parse(min.instance.params);
|
||||
let keys = Object.keys(gbotConfig);
|
||||
for (let j = 0; j < keys.length; j++) {
|
||||
|
@ -650,7 +649,7 @@ export class GBVMService extends GBService {
|
|||
|
||||
let code = min.sandBoxMap[text];
|
||||
const channel = step ? step.context.activity.channelId : 'web';
|
||||
const pid = GBVMService.createProcessInfo(user, min, channel);
|
||||
const pid = GBVMService.createProcessInfo(user, min, channel, text);
|
||||
const dk = new DialogKeywords();
|
||||
const sys = new SystemKeywords();
|
||||
await dk.setFilter({ pid: pid, value: null });
|
||||
|
@ -723,14 +722,15 @@ export class GBVMService extends GBService {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static createProcessInfo(user: GuaribasUser, min: GBMinInstance, channel: any) {
|
||||
public static createProcessInfo(user: GuaribasUser, min: GBMinInstance, channel: any, executable: string) {
|
||||
const pid = GBAdminService.getNumberIdentifier();
|
||||
GBServer.globals.processes[pid] = {
|
||||
pid: pid,
|
||||
userId: user ? user.userId : 0,
|
||||
instanceId: min.instance.instanceId,
|
||||
channel: channel,
|
||||
roles: 'everyone'
|
||||
roles: 'everyone',
|
||||
executable: executable
|
||||
};
|
||||
return pid;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ export class KeywordsExpressions {
|
|||
const convertConditions = input => {
|
||||
var result = input.replace(/ +and +/gim, ' && ');
|
||||
result = result.replace(/ +or +/gim, ' || ');
|
||||
result = result.replace(/ +not +/gim, ' !');
|
||||
result = result.replace(/ +<> +/gim, ' !== ');
|
||||
result = result.replace(/ += +/gim, ' === ');
|
||||
return result;
|
||||
|
@ -319,8 +320,14 @@ export class KeywordsExpressions {
|
|||
return `${$1} = await dk.getConfig ({pid: pid, name: ${$2}})`;
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
keywords[i++] = [
|
||||
/\s*CONTINUATION TOKEN\s*/gim,
|
||||
() => {
|
||||
return `await dk.getContinuationToken ({pid: pid})`;
|
||||
}
|
||||
];
|
||||
|
||||
keywords[i++] = [
|
||||
/^\s*(set hear on)(\s*)(.*)/gim,
|
||||
($0, $1, $2, $3) => {
|
||||
|
@ -340,14 +347,15 @@ export class KeywordsExpressions {
|
|||
__next = true;
|
||||
__calls = 0;
|
||||
__index = 0;
|
||||
__data = ${$2};
|
||||
|
||||
__url = $2.links?.next?.uri;
|
||||
__seekToken = $2.links?.self?.headers["MS-ContinuationToken"]
|
||||
__totalCount = $2["totalCount"];
|
||||
__url = __data.links?.next?.uri;
|
||||
__seekToken = __data.links?.self?.headers["MS-ContinuationToken"]
|
||||
__totalCount = __data["totalCount"];
|
||||
|
||||
while (__next)
|
||||
{
|
||||
let $1 = $2[__index];
|
||||
let ${$1} = __data[__index];
|
||||
`;
|
||||
}
|
||||
];
|
||||
|
@ -357,37 +365,37 @@ export class KeywordsExpressions {
|
|||
($0, $1, $2) => {
|
||||
|
||||
return `
|
||||
|
||||
// TRUE if all items are processed.
|
||||
|
||||
if (__index >= __totalCount) {
|
||||
|
||||
// Check if HTTP call limit has reached.
|
||||
|
||||
if (__calls < __totalCalls) {
|
||||
|
||||
// Perform GET request using the constructed URL
|
||||
|
||||
$2 = await sys.get ({pid: pid, file: __url, addressOrHeaders: headers, httpUsername, httpPs});
|
||||
|
||||
// Update current variable handlers.
|
||||
// TRUE if all items are processed.
|
||||
|
||||
if (__index >= __totalCount) {
|
||||
|
||||
// Check if HTTP call limit has reached.
|
||||
|
||||
if (__calls < __totalCalls) {
|
||||
|
||||
// Perform GET request using the constructed URL
|
||||
|
||||
__data = await sys.get ({pid: pid, file: __url, addressOrHeaders: headers, httpUsername, httpPs});
|
||||
|
||||
// Update current variable handlers.
|
||||
|
||||
__url = __data.links?.next?.uri;
|
||||
__seekToken = __data.links?.self?.headers["MS-ContinuationToken"]
|
||||
__totalCount = __data["totalCount"];
|
||||
|
||||
index = 0;
|
||||
__calls++;
|
||||
|
||||
} else {
|
||||
|
||||
next = false;
|
||||
|
||||
}
|
||||
|
||||
__url = $2.links?.next?.uri;
|
||||
__seekToken = $2.links?.self?.headers["MS-ContinuationToken"]
|
||||
__totalCount = $2["totalCount"];
|
||||
|
||||
index = 0;
|
||||
__calls++;
|
||||
|
||||
} else {
|
||||
|
||||
next = false;
|
||||
|
||||
}
|
||||
|
||||
index = index + 1;
|
||||
}
|
||||
`;
|
||||
index = index + 1;
|
||||
}
|
||||
}`;
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -690,7 +698,7 @@ export class KeywordsExpressions {
|
|||
keywords[i++] = [
|
||||
/^\s*(set page mode)(\s*)(.*)/gim,
|
||||
($0, $1, $2, $3) => {
|
||||
return `await dk.setPageMode ({pid: pid, ${$3}})`;
|
||||
return `await dk.setPageMode ({pid: pid, value: ${$3}})`;
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -704,7 +712,7 @@ export class KeywordsExpressions {
|
|||
keywords[i++] = [
|
||||
/^\s*set header\s*(.*)\s*as\s*(.*)/gim,
|
||||
($0, $1, $2) => {
|
||||
return `headers[${$1}]=${$2})`;
|
||||
return `headers[${$1.trim()}] = ${$2}`;
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -845,14 +853,14 @@ export class KeywordsExpressions {
|
|||
];
|
||||
|
||||
keywords[i++] = [
|
||||
/^\s*(\bexit\b)\s*/gim,
|
||||
/^\sEXIT\s*$/gim,
|
||||
() => {
|
||||
return `return;`;
|
||||
}
|
||||
];
|
||||
|
||||
keywords[i++] = [
|
||||
/^\s*(\bEND\b)\s*/gim,
|
||||
/^\s*END\s*$/gim,
|
||||
() => {
|
||||
return `return;`;
|
||||
}
|
||||
|
@ -1072,10 +1080,29 @@ export class KeywordsExpressions {
|
|||
($0, $1, $2, $3, $4) => {
|
||||
$3 = $3.replace(/\'/g, '');
|
||||
$3 = $3.replace(/\"/g, '');
|
||||
$4 = $4.substr(2);
|
||||
const fields = $4.split(',');
|
||||
let fields = $3.split(',');
|
||||
const table = fields[0].trim();
|
||||
fields.shift();
|
||||
|
||||
return `await sys.saveToStorage({pid: pid, file: "${$3}", args: [${$4}]}, fields)`;
|
||||
const fieldsAsText = fields.join(',');
|
||||
|
||||
let fieldsNamesOnly = [];
|
||||
let index = 0;
|
||||
|
||||
|
||||
fields.forEach(field => {
|
||||
|
||||
// Extracts only the last part of the variable like 'column'
|
||||
// from 'row.column'.
|
||||
|
||||
const fieldRegExp = /(?:.*\.)(.*)/gim;
|
||||
let name = fieldRegExp.exec(field)[1]
|
||||
|
||||
fieldsNamesOnly.push (name);
|
||||
});
|
||||
let fieldsNames = fieldsNamesOnly.join(',');
|
||||
|
||||
return `await sys.saveToStorage({pid: pid, table: "${table}", fields: [${fieldsAsText}], fieldsNames: [${fieldsNames}] })`;
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -656,24 +656,18 @@ export class SystemKeywords {
|
|||
*/
|
||||
public async saveToStorage({ pid, table, fields, fieldsNames }) {
|
||||
|
||||
const fieldRegExp = /(?:.*\.)(.*)/gim;
|
||||
GBLog.info(`BASIC: Saving '${table}' (SAVE). Values: ${fields.join(',')}.`);
|
||||
const minBoot = GBServer.globals.minBoot as any;
|
||||
const definition = minBoot.core.sequelize.models[table];
|
||||
|
||||
|
||||
let data = {};
|
||||
let index = 0;
|
||||
|
||||
fields.forEach(field => {
|
||||
|
||||
// Extracts only the last part of the variable like 'column'
|
||||
// from 'row.column'.
|
||||
|
||||
let name = fieldsNames[index];
|
||||
name = fieldRegExp.exec(name)[2];
|
||||
|
||||
data[name] = field;
|
||||
fieldsNames.forEach(field => {
|
||||
data[fieldsNames] = fields[index++];
|
||||
});
|
||||
|
||||
|
||||
return await definition.create(data);
|
||||
}
|
||||
|
||||
|
@ -1509,7 +1503,7 @@ export class SystemKeywords {
|
|||
public generatePassword(pid) {
|
||||
return GBAdminService.getRndPassword();
|
||||
}
|
||||
|
||||
static aa;
|
||||
/**
|
||||
* Calls any REST API by using GET HTTP method.
|
||||
*
|
||||
|
@ -1519,11 +1513,12 @@ export class SystemKeywords {
|
|||
public async getByHttp({ pid, url, headers, username, ps, qs }) {
|
||||
let options = {};
|
||||
|
||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||
const { min, user, params, proc } = await DialogKeywords.getProcessInfo(pid);
|
||||
GBLogEx.info(min, `GET: ${url}`);
|
||||
|
||||
const pageMode = await DialogKeywords.getOption({ pid, name: 'pageMode' });
|
||||
let continuationToken = await DialogKeywords.getOption({ pid, name: 'continuationToken' });
|
||||
let continuationToken = await
|
||||
DialogKeywords.getOption({ pid, name: `${proc.executable}-continuationToken` });
|
||||
|
||||
if (pageMode === "auto" && continuationToken) {
|
||||
headers = headers ? headers : {};
|
||||
|
@ -1775,7 +1770,17 @@ export class SystemKeywords {
|
|||
}
|
||||
};
|
||||
|
||||
const result = await fetch(url, options);
|
||||
|
||||
let result;
|
||||
if (!SystemKeywords.aa){
|
||||
SystemKeywords.aa = 1;
|
||||
return r1;
|
||||
} else {
|
||||
SystemKeywords.aa = null;
|
||||
return r2;
|
||||
}
|
||||
|
||||
//const result = await fetch(url, options);
|
||||
|
||||
try {
|
||||
|
||||
|
@ -1783,7 +1788,7 @@ export class SystemKeywords {
|
|||
// Token expired.
|
||||
|
||||
GBLog.info(`Expired Token for ${url}.`);
|
||||
await DialogKeywords.setOption({ pid, name: 'continuationToken', value: null });
|
||||
await DialogKeywords.setOption({ pid, name: `${proc.executable}-continuationToken`, value: null });
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -76,11 +76,14 @@ export class GBLogEx {
|
|||
* Finds and update user agent information to a next available person.
|
||||
*/
|
||||
public static async log(instance: IGBInstance, kind: string, message: string): Promise<GuaribasLog> {
|
||||
message = message ? message.substring(0, 1023) : null;
|
||||
return await GuaribasLog.create(<GuaribasLog>{
|
||||
instanceId: instance ? instance.instanceId : 1,
|
||||
message: message,
|
||||
kind: kind
|
||||
});
|
||||
if (process.env.LOG_ON_STORAGE) {
|
||||
message = message ? message.substring(0, 1023) : null;
|
||||
|
||||
return await GuaribasLog.create(<GuaribasLog>{
|
||||
instanceId: instance ? instance.instanceId : 1,
|
||||
message: message,
|
||||
kind: kind
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1031,8 +1031,10 @@ export class GBMinService {
|
|||
return;
|
||||
}
|
||||
} else if (context.activity.type === 'message') {
|
||||
|
||||
// Processes messages activities.
|
||||
const pid = GBVMService.createProcessInfo(user, min, step.context.activity.channelId);
|
||||
|
||||
const pid = GBVMService.createProcessInfo(user, min, step.context.activity.channelId, null);
|
||||
step.context.activity['pid'] = pid;
|
||||
|
||||
await this.processMessageActivity(context, min, step, pid);
|
||||
|
|
Loading…
Add table
Reference in a new issue