answerInlineQuery was successfully sended but no result actually - telegram-bot

I have code for cover inlineQuery:
inline mode was turned on in BotFather
webhooks with InlineQuery correctly recived
result for answerInlineQuery is: { "ok": true, "result": true }
Bot JavaScript code (BJS) written on Bots.Business:
results = [];
item = {
type: "article",
id: "13",
title: "Test item",
input_message_content: { "message_text": "this is text" }
}
results.push(item);
Api.answerInlineQuery({
inline_query_id: request.id,
results: results,
cache_time: 0,
on_result: "/trackResult"
})
/trackResult command (it handle after answerInlineQuery method):
throw inspect(options)
In error log (I just track successfull notice as error):
So: answerInlineQuery was sended but actually no any inline results for user in the Telegram chat.

results = [];
item = {
type: "article",
id: "13",
title: "Test item",
input_message_content: '{ "message_text": "this is text" }'
}
results.push(item);
Api.answerInlineQuery({
inline_query_id: request.id,
results: results,
cache_time: 0,
on_result: "/trackResult"
})
Need pass input_message_content as string

Related

Mimic the ( Show All ) link in datatables.net

I have a situation where I want to get the full (data) from the backend as a CSV file. I have already prepared the backend for that, but normally the front-end state => (filters) is not in contact with the backend unless I send a request, so I managed to solve the problem by mimicking the process of showing all data but by a custom button and a GET request ( not an ajax request ). knowing that I am using serverSide: true in datatables.
I prepared the backend to receive a request like ( Show All ) but I want that link to be sent by custom button ( Export All ) not by the show process itself as by the picture down because showing all data is not practical at all.
This is the code for the custom button
{
text: "Export All",
action: function (e, dt, node, config) {
// get the backend file here
},
},
So, How could I send a request like the same request sent by ( Show All ) by a custom button, I prepared the server to respond by the CSV file. but I need a way to get the same link to send a get request ( not by ajax ) by the same link that Show All sends?
If you are using serverSide: true that should mean you have too much data to use the default (serverSide: false) - because the browser/DataTables cannot handle the volume. For this reason I would say you should also not try to use the browser to generate a full export - it's going to be too much data (otherwise, why did you choose to use serverSide: true?).
Instead, use a server-side export utility - not DataTables.
But if you still want to pursuse this approach, you can build a custom button which downloads the entire data set to the DataTables (in your browser) and then exports that complete data to Excel.
Full Disclosure:
The following approach is inspired by the following DataTables forum post:
Customizing the data from export buttons
The following approach requires you to have a separate REST endpoint which delivers the entire data set as a JSON response (by contrast, the standard response should only be one page of data for the actual table data display and pagination.)
How you set up this endpoint is up to you (in Laravel, in your case).
Step 1: Create a custom button:
I tested with Excel, but you can do CSV, if you prefer.
buttons: [
{
extend: 'excelHtml5', // or 'csvHtml5'
text: 'All Data to Excel', // or CSV if you prefer
exportOptions: {
customizeData: function (d) {
var exportBody = getDataToExport();
d.body.length = 0;
d.body.push.apply(d.body, exportBody);
}
}
}
],
Step 2: The export function, used by the above button:
function GetDataToExport() {
var jsonResult = $.ajax({
url: '[your_GET_EVERYTHING_url_goes_here]',
success: function (result) {},
async: false
});
var exportBody = jsonResult.responseJSON.data;
return exportBody.map(function (el) {
return Object.keys(el).map(function (key) {
return el[key]
});
});
}
In the above code, my assumption is that the JSON response has the standard DataTables object structure - so, something like:
{
"data": [
{
"id": "1",
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$320,800",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": "5421"
},
{
"id": "2",
"name": "Garrett Winters",
"position": "Accountant",
"salary": "$170,750",
"start_date": "2011/07/25",
"office": "Tokyo",
"extn": "8422"
},
{
"id": "3",
"name": "Ashton Cox",
"position": "Junior Technical Author",
"salary": "$86,000",
"start_date": "2009/01/12",
"office": "San Francisco",
"extn": "1562"
}
]
}
So, it's an object, containing a data array.
The DataTables customizeData function is what controls writing this complete JSON to the Excel file.
Overall, your DataTables code will look something like this:
$(document).ready(function() {
$('#example').DataTable( {
serverSide: true,
dom: 'Brftip',
buttons: [
{
extend: 'excelHtml5',
text: 'All Data to Excel',
exportOptions: {
customizeData: function (d) {
var exportBody = GetDataToExport();
d.body.length = 0;
d.body.push.apply(d.body, exportBody);
}
}
}
],
ajax: {
url: "[your_SINGLE_PAGE_url_goes_here]"
},
"columns": [
{ "title": "ID", "data": "id" },
{ "title": "Name", "data": "name" },
{ "title": "Position", "data": "position" },
{ "title": "Salary", "data": "salary" },
{ "title": "Start Date", "data": "start_date" },
{ "title": "Office", "data": "office" },
{ "title": "Extn.", "data": "extn" }
]
} );
} );
function GetDataToExport() {
var jsonResult = $.ajax({
url: '[your_GET_EVERYTHING_url_goes_here]',
success: function (result) {},
async: false
});
var exportBody = jsonResult.responseJSON.data;
return exportBody.map(function (el) {
return Object.keys(el).map(function (key) {
return el[key]
});
});
}
Just to repeat my initial warning: This is probably a bad idea, if you really needed to use serverSide: true because of the volume of data you have.
Use a server-side export tool instead - I'm sure Laravel/PHP has good support for generating Excel files.

How to wait for a certain value in API json response

I am working on Cypress API, trying to get a certain response but the problem is that I need to wait until I get a particular response, different from the previous one.
For example, repeating until "activated: true" and "fileType not inprogress".
This is the initial repsonse,
[
{
"filenameSource": "test",
"fileExt": "mp4",
"uniqueId": "18564Cm_BTo7Q0Sb0xCT",
"fileName": "test.mp4",
"title": "Test Video",
"language": "##",
"validFrom": "2022-10-01T00:00:00.000Z",
"rating": 0,
"aspect": "null",
"duration": -1,
"fps": 0,
"activated": false,
"fileSize": 0,
"importTime": "2022-11-07T12:14:31.813Z",
"fileType": "inprogress"
}
]
I think Request Polling is what you are trying to do
function req(attempts = 0) {
if (attempts === 100) {
throw new Error('Too many attempts')
}
cy.request('GET', ...)
.then(resp => resp.json())
.then(json => {
const data = resp.body
if (data[0].activated) {
return // break out of the recursive loop
}
cy.wait(200)
req(++attempts) // else recurse
})
}
cy.request('POST', ...) // initiate product
req() // wait for activated
cy.request('DELETE', ...) // now delete product
I have managed to resolve it with Cypress recurse function. Here is the link https://www.npmjs.com/package/cypress-recurse.
Thanks!

suitescript 2.0 unable to search inventorydetails subrecord from saved search data

I have created one saved search, and I am fetching data from by suitescript and here is the demo data response which I am getting this result from saved search response
{
"results": [
{
"recordType": "itemreceipt",
"id": "2572118",
"values": {
"trandate": "2021-3-25",
"type": [
{
"value": "ItemRcpt",
"text": "Item Receipt"
}
],
"tranid": "RCV123",
"salesrep": [
{
"value": "16018",
"text": "MXZ"
}
],
"entity": [
{
"value": "16993",
"text": "ABC"
}
],
"memo": "",
"amount": "1218.00",
"location": [
{
"value": "1",
"text": "XYZ"
}
],
"inventoryDetail.inventorynumber": [
{
"value": "10504",
"text": "3566044578"
}
]
}
}
]
}
AND I AM USING BELOW CODE TO MAKE FILTER BY inventoryDetail.inventorynumber FIELD WHICH IT MENTIONED IN SAVED SEARCH RESPONSE DATA AND IT THROWS ERROR "An nlobjSearchFilter contains invalid search criteria: inventoryDetail.issueinventorynumber."
but if I used tranid instead of inventoryDetail.issueinventorynumber then it does not throw the error, why I can not filter by inventoryDetail.inventorynumber I am trying since two days but no luck, please help me guys
/**
* #NApiVersion 2.1
* #NScriptType Restlet
* #NModuleScope Public
*/
/*
------------------------------------------------------------------------------------------
Script Information
------------------------------------------------------------------------------------------
Name:
Saved Search API
ID:
_saved_search_api
*/
var
log,
search,
response = new Object();
define( [ 'N/log', 'N/search' ], main );
function main( logModule, searchModule ) {
log = logModule;
search = searchModule;
return { post: postProcess }
}
function postProcess( request ) {
try {
var searchObj = search.load( { id: 1234 } );//saved search id
// Copy the filters from rs into defaultFilters.
var defaultFilters = searchObj.filters;
// below code works
defaultFilters.push(search.createFilter({
name: "tranid",
operator: search.Operator.IS,
values: ["RCV123"]
}));
// but this code does not works and it throws error "An nlobjSearchFilter contains invalid search criteria: inventoryDetail.issueinventorynumber."
/*defaultFilters.push(search.createFilter({
name: "inventoryDetail.inventorynumber",
operator: search.Operator.IS,
values: ["3566044578"]
}));*/
searchObj.filters = defaultFilters;
searchObj.filters = defaultFilters;
response.results = [];
var resultSet = searchObj.run();
var start = 0;
var results = [];
do {
results = resultSet.getRange( { start: start, end: start + 1000 } );
start += 1000;
response.results = response.results.concat( results ) ;
response.count =results.length;
} while ( results.length );
return response;
} catch( e ) {
log.debug( { 'title': 'error', 'details': e } );
return { 'error': { 'type': e.type, 'name': e.name, 'message': e.message } }
}
}
issueinventorynumber is not a valid search Column on the inventorydetail record. You are probably looking for inventorydetail.inventorynumber. You can reference the Search Columns section for the Inventory Detail within the Records Browser.
Be aware that Search Column names are not always the same as the field ID in the UI, as is the case here. The ID in the UI is issueinventorynumber, while the ID for the Search Column is inventorynumber.
Finally I found the solution
var transactionSearchObj = search.create({
type: "transaction",
filters:
[
["formulatext: {inventorydetail.inventorynumber}","contains","30124578547"]
],
columns:
[
search.createColumn({name: "trandate", label: "Date"}),
search.createColumn({name: "type", label: "Type"}),
search.createColumn({name: "tranid", label: "Document Number"}),
search.createColumn({name: "salesrep", label: "Sales Rep"}),
search.createColumn({name: "memo", label: "Memo"}),
search.createColumn({name: "amount", label: "Amount"}),
search.createColumn({name: "location", label: "Location"}),
search.createColumn({
name: "itemid",
join: "item",
label: "Name"
}),
search.createColumn({
name: "inventorynumber",
join: "inventoryDetail",
label: " Number"
})
]
});
return transactionSearchObj.run().getRange( { start: 0, end: 0 + 1000 } );

How to pass array object parameter from vue website to google appscript to set google spreadsheet column value

First I create a website by vue and I pass parameter to my google appscript
vue function
var appurl = "my google appscript url"
this.$http.get(appurl, {
params: {
settingLink: this.settingLink,
albumLink: this.albumLink,
stepControl: this.stepControl,
nav: this.navSetting,
}
}).then(response => {
console.log(response);
})
and I send parameter to google appscript
my google appscript
function doGet(e) {
var params = e.parameter;
var settingLink = params.settingLink;
var albumLink = params.albumLink;
var stepControl = params.stepControl;
var nav = params.nav;
var SpreadSheet = SpreadsheetApp.openByUrl(settingLink);
var SheetName = SpreadSheet.getSheetByName("gameSetting");
SheetName.getRange("D2").setValue(stepControl);
SheetName.getRange("E2").setValue(albumLink);
SheetName.getRange("F2").setValue(nav[0].style);
SheetName.getRange("G2").setValue(nav[1].style);
SheetName.getRange("H2").setValue(nav[2].style);
}
The parameter albumLink and stepControl are string so I success push it to my spreadsheet (figure 1)
but nav is an array object like (in vue data)
nav=[
{style:"red",content:"test"},
{style:"blue",content:"test"},
{style:"green",content:"test"},
]
How could I let spreadsheet F2 as "red", G2 as "blue", and H2 as "green"
figure 1
enter image description here
By checking the output of JSON.stringify(e), it seems that each property of objects become different parameters and are received as something like the following:
{
"queryString": "settingLink=settingLinkTest&albumLink=albumLinkTest&stepControl=stepControlTest&nav%5B0%5D%5Bstyle%5D=red&nav%5B0%5D%5Bcontent%5D=test&nav%5B1%5D%5Bstyle%5D=blue&nav%5B1%5D%5Bcontent%5D=test&nav%5B2%5D%5Bstyle%5D=green&nav%5B2%5D%5Bcontent%5D=test",
"contextPath": "",
"parameters": {
"nav[1][style]": [
"blue"
],
"nav[1][content]": [
"test"
],
"albumLink": [
"albumLinkTest"
],
"nav[2][style]": [
"green"
],
"settingLink": [
"settingLinkTest"
],
"nav[2][content]": [
"test"
],
"nav[0][style]": [
"red"
],
"stepControl": [
"stepControlTest"
],
"nav[0][content]": [
"test"
]
},
"contentLength": -1,
"parameter": {
"nav[2][content]": "test",
"nav[1][content]": "test",
"albumLink": "albumLinkTest",
"settingLink": "settingLinkTest",
"nav[0][style]": "red",
"stepControl": "stepControlTest",
"nav[0][content]": "test",
"nav[1][style]": "blue",
"nav[2][style]": "green"
}
}
Since the index of a particular nav and its properties become names of parameters, you can get their values by changing your doGet() to:
SheetName.getRange("F2").setValue(params["nav[0][style]"]);
SheetName.getRange("G2").setValue(params["nav[1][style]"]);
SheetName.getRange("H2").setValue(params["nav[2][style]"]);
Alternatively, as suggested in the comments of the question, you can stringify the nav object when sending it:
this.$http.get(appurl, {
params: {
settingLink: settingLink,
albumLink: albumLink,
stepControl: stepControl,
nav: JSON.stringify(nav)
}
}).then(response => {
console.log(response);
})
And then parsing when you receive it to use as you intended:
var nav = JSON.parse(params.nav);
SheetName.getRange("F2").setValue(nav[0].style);
SheetName.getRange("G2").setValue(nav[1].style);
SheetName.getRange("H2").setValue(nav[2].style);

Paging and grouping in dynamic grid

I am using dynamic grid using this plugin.
I want to make paging in it,
I tried like,
Ext.define('....', {
extend: 'Ext.data.Store',
pageSize: 10,
proxy: {
type: 'rest',
url: me.url,
reader: {
type: 'dynamicReader',
totalProperty: 'totalCount'
}
}
});
me.bbar = Ext.create('Ext.PagingToolbar', {
store: me.store,
displayInfo: true,
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No topics to display"
});
In DynamicGrid.js totalProperty is not working. Am I setting the property properly there?
Then I am also trying to make grouping in the same plugin.
I have a combobox with some fields and want to select grouping field from it dynamically. When I select a field in combo box, it sends that data to grid's groupField property.
I have that combo box value selected in controller like,
var groupData = Ext.ComponentQuery.query('#groupid')[0].getValue();
I am sending it to grid like,
Ext.define('Group', {
singleton: true,
param: groupData
});
I am getting that for grid property (in DynamicGrid.js) like,
groupField: [Group.param]
But this automatically selects first field for groupField property before even selecting anything in combo box and makes grouping, selecting other fields in combo box also doesn't work, it always has first field for grouping.
What is going wrong? Please help.
I did grouping successfully by adding the following code in listener,
me.store.group(Group.param);
Still having issues with totalProperty, can someone help me to make it work?
I think I am making a mistake, now actual JSON response is,
[{
"userId": 123,
"name": "Ed Spencer",
"email": "ed#sencha.com"
}]
So the code for getting data and manipulating works fine like,
readRecords: function(data) {
if (data.length > 0) {
var item = data[0];
var fields = new Array();
var columns = new Array();
var p;
for (p in item) {
if (p && p != undefined) {
fields.push({name: p, type: 'floatOrString'});
columns.push({text: p, dataIndex: p});
}
}
data.metaData = { fields: fields, columns: columns };
}
return this.callParent([data]);
}
But for sending other metaData properties, from the docs I should probably have the following JSON response,
{
"count": 1,
"ok": true,
"msg": "Users found",
"users": [{
"userId": 123,
"name": "Ed Spencer",
"email": "ed#sencha.com"
}],
"metaData": {
"root": "users",
"idProperty": 'userId',
"totalProperty": 'count',
"successProperty": 'ok',
"messageProperty": 'msg'
}
}
So how do I point root in the readReords function so that it knows data is in root?
Thereby I will have other metaData properties also passed.
Please help!