diff --git a/packages/basic.gblib/services/KeywordsExpressions.ts b/packages/basic.gblib/services/KeywordsExpressions.ts index e7211b0c..314928d0 100644 --- a/packages/basic.gblib/services/KeywordsExpressions.ts +++ b/packages/basic.gblib/services/KeywordsExpressions.ts @@ -326,7 +326,7 @@ export class KeywordsExpressions { return `hrOn = ${$3}`; } ]; - + keywords[i++] = [ /^\s*(.*)\=\s*(REWRITE)(\s*)(.*)/gim, ($0, $1, $2, $3, $4) => { @@ -335,6 +335,14 @@ export class KeywordsExpressions { } ]; + keywords[i++] = [ + /^\s*(.*)\=\s*(AUTO SAVE)(\s*)(.*)/gim, + ($0, $1, $2, $3, $4) => { + const params = this.getParams($4, ['handle']); + return `await sys.autoSave ({pid: pid, ${params}})`; + } + ]; + keywords[i++] = [ /^\s*hear (\w+\$*) as (\w+( \w+)*.xlsx)/gim, diff --git a/packages/basic.gblib/services/SystemKeywords.ts b/packages/basic.gblib/services/SystemKeywords.ts index f1a04c49..c7a6ed3e 100644 --- a/packages/basic.gblib/services/SystemKeywords.ts +++ b/packages/basic.gblib/services/SystemKeywords.ts @@ -60,6 +60,7 @@ import { GBConversationalService } from '../../core.gbapp/services/GBConversatio import { WebAutomationServices } from './WebAutomationServices.js'; import { KeywordsExpressions } from './KeywordsExpressions.js'; import { ChatServices } from '../../gpt.gblib/services/ChatServices.js'; +import mime from 'mime-types'; /** * @fileoverview General Bots server core. @@ -1874,9 +1875,8 @@ export class SystemKeywords { GBLog.info(`Twitter Automation: ${text}.`); } - /** - * HEAR description + * HEAR description * text = REWRITE description * SAVE "logs.xlsx", username, text */ @@ -1889,10 +1889,10 @@ export class SystemKeywords { } /** - * + * * qrcode = PAY "10000", "Name", 100 * SEND FILE qrcode - * + * */ public async pay({ pid, orderId, customerName, ammount }) { const { min, user } = await DialogKeywords.getProcessInfo(pid); @@ -1940,16 +1940,56 @@ export class SystemKeywords { throw new Error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); - + // Prepare an image on cache and return the GBFILE information. - + const buf = Buffer.from(data.Payment.QrCodeBase64Image, 'base64'); const localName = Path.join('work', gbaiName, 'cache', `qr${GBAdminService.getRndReadableIdentifier()}.png`); Fs.writeFileSync(localName, buf, { encoding: null }); const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); - + GBLog.info(`GBPay: ${data.MerchantOrderId} OK: ${url}.`); - return { localName: localName, url: url, data: buf, text: data.Payment.QrCodeString }; + return { + name: Path.basename(localName), + localName: localName, + url: url, + data: buf, + text: data.Payment.QrCodeString + }; + } + + /** + * HEAR logo AS FILE + * file = AUTO SAVE logo + * TALK "Your " + file.name + " file is saved." + */ + public async autoSave({ pid, handle }) { + const { min } = await DialogKeywords.getProcessInfo(pid); + this.internalAutoSave({ min, handle }); + } + + public async internalAutoSave({ min, handle }) { + const file = GBServer.globals.files[handle]; + GBLog.info(`BASIC: Auto saving '${file.filename}' (SAVE file).`); + let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); + const path = DialogKeywords.getGBAIPath(min.botId, `gbdrive`); + try { + const contentType = mime.lookup(file.url ? file.url : file.name); + const kind = await getContentTypeFolder(contentType); + await client.api(`${baseUrl}/drive/root:/${path}/${kind}/${file.name}:/content`).put(file.data); + } catch (error) { + if (error.code === 'itemNotFound') { + GBLog.info(`BASIC: BASIC source file not found: ${file}.`); + } + throw error; + } + } +} +function getContentTypeFolder(contentType: any) { + // TODO: DS .jpog ->'image/jpg' -> IMages + // #359 + if (contentType === 'image/jpg') { + return 'Images'; } } diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index 27d9fac8..e97d402c 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -99,8 +99,8 @@ import { createKoaHttpServer } from '../../basic.gblib/index.js'; import { DebuggerService } from '../../basic.gblib/services/DebuggerService.js'; import { ImageProcessingServices } from '../../basic.gblib/services/ImageProcessingServices.js'; import { ScheduleServices } from '../../basic.gblib/services/ScheduleServices.js'; -import mime from 'mime'; -import { ChatServices } from '../../gpt.gblib/services/ChatServices.js'; +import mime from 'mime-types'; + /** * Minimal service layer for a bot and encapsulation of BOT Framework calls. */ @@ -1282,17 +1282,40 @@ export class GBMinService { // Prepare Promises to download each attachment and then execute each Promise. if (step.context.activity.attachments + && step.context.activity.attachments[0] && step.context.activity.attachments[0].contentType != 'text/html') { const promises = step.context.activity.attachments.map( GBMinService.downloadAttachmentAndWrite.bind({ min, user, params }) ); const successfulSaves = await Promise.all(promises); - async function replyForReceivedAttachments(localAttachmentData) { - if (localAttachmentData) { + async function replyForReceivedAttachments(attachmentData) { + if (attachmentData) { + // Because the TurnContext was bound to this function,the bot can call // `TurnContext.sendActivity` via `this.sendActivity`; await this.sendActivity(`Upload OK.`); + + // In case of not having HEAR activated before, it is + // a upload with no Dialog, so run Auto Save to .gbdrive. + + if (!min.cbMap[userId]) + { + const t = new SystemKeywords(); + GBLog.info(`BASIC (${min.botId}): Upload done for ${attachmentData.fileName}.`); + const handle = WebAutomationServices.cyrb53(min.botId + attachmentData.fileName); + let data = Fs.readFileSync(attachmentData.localPath); + + const gbfile = { + filename: attachmentData.localPath, + data: data, + name: Path.basename(attachmentData.fileName) + }; + + GBServer.globals.files[handle] = gbfile; + await t.internalAutoSave({min: min, handle:handle }); + } + } else { await this.sendActivity('Error uploading file. Please,start again.'); } @@ -1320,6 +1343,14 @@ export class GBMinService { } min.cbMap[userId].promise = results[0]; } + else + { + // Uploads file to .gbdrive associated folder. + + + } + + } }