telegram bot keyboard with google apps script - google-apps-script

I want to meet new clients in telegram bot with a keyboard buttons
So far I have this code written in Google Apps Script, but in result there is nothing.
function doPost(e) {
var API_TOKEN = 'bla-bla-bla';
var update = JSON.parse(e.postData.contents);
if (update.hasOwnProperty('message')) {
var msg = update.message;
var chatId = msg.chat.id;
if (msg.text == '/start') {
function sendText(chatId, text, keyboard) {
var payload = {
'method': 'sendMessage',
'chat_id': String(chatId),
'text': "Hello",
'parse_mode': 'HTML',
reply_markup: JSON.stringify({
keyboard: [
[
"A",
"B"
],
[
"C",
"D"
]
],
resize_keyboard: true,
one_time_keyboard:true
})
}
var data = {
"method": "post",
"payload": payload
}
UrlFetchApp.fetch('https://api.telegram.org/bot' + API_TOKEN + '/', data);
}
}
}
}
Is this a missing feature or it's me, doing something wrong?

You probably want something like this?
PS: replace it with your chat id
function testKeyboard() {
const chatId = YOURCHATID; // REPLACE THIS
const choices = ['Mozzarella','Gouda cheese','Camembert','Gorgonzola','Cheddar Cheese'];
const text = 'Make your choice';
sendKeyboard(chatId, choices, text);
}
You can do it with this code.
PS: replace token with your bot's token
const token = ''; // REPLACE IT WITH YOUR BOTS TOKEN
const telegramApi = 'https://api.telegram.org/bot' + token;
function sendKeyboard(chatId, choices, text = 'Menu') {
const buttons = transformArrayToKeyboard(choices);
const replyKeyboardMarkup = {keyboard: buttons,
one_time_keyboard: true,
resize_keyboard: true};
const replyMarkup = JSON.stringify(replyKeyboardMarkup);
const url = telegramApi + '/sendMessage?chat_id=' + encodeURIComponent(chatId) + '&text=' + encodeURIComponent(text) + '&disable_web_page_preview=true&reply_markup=' + encodeURIComponent(replyMarkup);
const response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function transformArrayToKeyboard(choices) {
const maxLengthRowKeyboardMenu = 3;
const arr = choices.map(item => ({text: item }));
const result = [];
let index = 0;
while(arr.slice(index).length > 0) {
const newRowValuesForButtons = arr.slice(index,index+maxLengthRowKeyboardMenu);
result.push(newRowValuesForButtons);
index += maxLengthRowKeyboardMenu;
}
return result;
}
// function transformArrayToKeyboard transforms [4,5,6,7,8] to:
// [
// [
// {text: "4" },{text: "5" },{text: "6" }
// ]
// [
// {text: "7" },{text: "8" }
// ]
// ];

Related

Why am I getting "TypeError: Cannot read property 'getRange' of undefined" for line 2 sheet.getRange?

This function was working perfectly until this morning and I can't find the reason for the error... I have edited the first line to include the Spreadsheet and it says it is executing normally now but there is no actual post
function createMeetingMessage(sheet) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var values = ss.getSheetByName("Post") .getRange("B2:D40").getValues(); // Modify this range, if you want to expand it.
var message = values.reduce(function(s, e) {
var SlackIDrow, YearsWorkedrow, Congratsrow, _,
[SlackIDrow, YearsWorkedrow, Congratsrow, _, _, ] = e;
if (SlackIDrow && YearsWorkedrow && Congratsrow) {
s += "> *Human* " +"<"+ SlackIDrow +">"+"\n"
+ "> *Years worked as of today* " + YearsWorkedrow + "\n"
+ Congratsrow + "\n"
+"\n";
}
return s;
}, "> *Today's Workiversaries!*" +"\n");
return message;
}
function triggerSlackWorkaversaryLog(channel, msg) {
var slackWebhook = "https://hooks.slack.com/services/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";
var payload = { "channel": channel, "text": msg, "link_names": 1, "username": "Time to Partyyyyyy", "icon_emoji": ":confetti_ball:" };
var options = { "method": "post", "contentType": "application/json", "muteHttpExceptions": true, "payload": JSON.stringify(payload) };
Logger.log(UrlFetchApp.fetch(slackWebhook, options));
}
function notifySlackChannelofWorkaversaries() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Post");
if (!sheet.getRange("B2").getValue()) return;
var channel = getChannel();
var msg = createMeetingMessage(sheet);
triggerSlackWorkaversaryLog(channel, msg);
}
function isTest() {
return false;
}
function getChannel() {
if(isTest()) {
return "intergration_tests";
} else {
return "intergration_tests";
}
}
If you wish to run that function from the script editor you could do this:
function testCreateMeetingMessage() {
Logger.log(CreateMeetingMessage(SpreadsheetApp.getActive());
}
The problem is not with the function you quote but with the function that calls it. The sheet parameter must be a SpreadsheetApp.Sheet object (rather than a sheet name as text string or something like that.)
You will also get the error you quote if you run the function directly in the script editor.

Delete token from SAPUI5 Multi Input Field with Data Binding

in my SAPUI5 app I am using a Multi Input Field with tokens which are bound to a JSON Model. Newly added entries are saved in the JSON Model. However, when deleting a token by pressing the "x" next to the token text, the token disappears from the multi input field. But when adding a new token the deleted one reappears.
How can I ensure that the deleted entry is also deleted from the JSON Model?
This is my current code for adding the token to the model:
multiInputField.addValidator(function(args){
MessageBox.confirm("Do you really want to add Token\"" + args.text + "\"?", {
onClose: function(oAction) {
if (oAction === MessageBox.Action.OK){
var oToken = new Token({key: args.text, text: args.text});
args.asyncCallback(oToken);
var aFields = sap.ui.getCore().getView().getModel("myModel").getProperty("/Tokens");
var oNewFields= {
Tokens: args.text
};
aFields .push(oNewFields);
sap.ui.getCore().getView().getModel("myModel").setProperty("/Tokens", aFields );
sap.ui.getCore().getView().getModel("myModel").refresh();
} else {
args.asyncCallback(null);
}
},
title: "Add Token"
});
return sap.m.MultiInput.WaitForAsyncValidation;
});
I guess we can use "tokenUpdate" event for this.
For example, given that I have this MultiInput in my view:
<MultiInput width="500px" id="multiInput" suggestionItems="{ path: 'dataModel>/data'}" showValueHelp="true" tokenUpdate="onTokenUpdate">
<core:Item key="{dataModel>key}" text="{dataModel>value}"/>
</MultiInput>
then in my controller I can handle this like :
onTokenUpdate: function(oEvent) {
var sType = oEvent.getParameter("type");
if (sType === "removed") {
var sKey = oEvent.getParameter("removedTokens")[0].getProperty("key");
var oModel = this.getView().getModel("dataModel");
var aData = this.getView().getModel("dataModel").getProperty("/data");
for (var i = 0, len = aData.length; i < len; i++) {
var idx;
console.log(sKey + "-" + aData[i].key);
if (aData[i].key === sKey) {
idx = i;
}
}
aData.splice(idx, 1);
oModel.setProperty("/data", aData);
console.log(oModel);
}
}
And this is my json:
{
"data": [
{
"key": "token1",
"value": "token1"
},
{
"key": "token2",
"value": "token2"
}
]
}

Chrome extension can't find USB printer device

I am building chrome application for POS Terminal printers. The problem that I have is that chrome application for some reason can't find USB device and I am not sure why it is not working. I tried few methods (converted hexadecimal vendor/product ID to decimal, used hexadecimal product/vendor id to connect to USB printer) and all of the reports that device can't be found...
EDIT:
I got this error from device log:
Failed to open device: Operation not supported or unimplemented on this platform
Does someone know where is the problem?
Here is details about printer (DATECS DPP 255):
Manifest:
{
"manifest_version": 2,
"name": "Thermal Printer Extension",
"description": "Thermal Printer Extension for ESC/POS Commands",
"version": "1.0",
"app": {
"background": {
"scripts": ["main.js"]
}
},
"permissions": ["usb", "notifications"],
"optional_permissions": [
{
"usbDevices": [
{
"vendorId": 65520, "productId": 98
}
]
}
],
"externally_connectable": {
"matches": ["http://localhost:3000/*"]
}
}
main.js
chrome.runtime.onMessageExternal.addListener(function (stuff) {
if(stuff){
function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
var port = 0;
var endpoint = 0x01;
// needs to be set in optional permissions for each VID/PID pair
var device = {vendorId: 0xfff0, productId: 0x0062};
// var device = {vendorId: 65520, productId: 98};
String.prototype.toBytes = function() {
var arr = [];
for (var i=0; i < this.length; i++) {
arr.push(this[i].charCodeAt(0));
}
return arr;
}
// setting variables for printing, array for data, and calculations
var alignLeft = [0x01B, 0x061, 0];
var alignCenter = [0x01B, 0x061, 1];
var alignRight = [0x01B, 0x061, 2];
var endPrint = [0x01B, 0x064, 2];
// enter new line
var lineFeed = [0x00A];
var buzz = [07];
var drawLineMiddle = "________________________________________________".toBytes();
var drawLineSmall = "________________________________".toBytes();
var horizontalTab = [0x009];
var cutpaperFull = [0x01D, 0x056, 1];
var cutpaperPartial = [0x01D, 0x056, 0];
function createAnything() {
var anything = alignCenter;
anything = anything.concat("Awesome Chrome Extension".toBytes());
anything = anything.concat(lineFeed);
anything = anything.concat(drawLineMiddle);
anything = anything.concat(stuff.stuffToPrint.toBytes());
anything = anything.concat(lineFeed);
return anything;
}
function createReceipt(devices) {
var data = [];
data = data.concat(createAnything());
data = data.concat(endPrint);
data = data.concat(cutpaperPartial);
var buffer = new Uint8Array(data).buffer;
var transferinfo = {direction: "out", endpoint: endpoint, data: buffer };
chrome.usb.bulkTransfer({handle: devices[0].handle, vendorId: devices[0].vendorId, productId: devices[0].productId}, transferinfo, function(response) {
if (response.resultCode == 0) {
chrome.usb.closeDevice({handle: devices[0].handle, vendorId: devices[0].vendorId, productId: devices[0].productId}, chrome.notifications.create("4", {type: "basic", iconUrl: "icon.png", title: "Success!", message: "Printing receipt..."}, function() {console.log("Success!")}));
} else {
console.log("Error ", response);
}
});
}
var connect = function(callback) {
chrome.permissions.getAll(function(p) {
if (p.permissions.indexOf("usb") >= 0) {
//construct permission object for our device
var obj = { usbDevices: [device] };
//now request the permissions
chrome.permissions.request({ permissions: [obj] }, function(granted) {
if (granted) {
chrome.usb.findDevices(device, function(devices) {
if (devices && devices.length > 0) {
//use the first found device
var foundDevice = devices[0];
//now lets reset the device
chrome.usb.resetDevice(foundDevice, function() {
//perform some error checking to make sure we reset the device
if ( ! chrome.runtime.lastError) {
//now claim the interface using the port we specified
chrome.usb.claimInterface(foundDevice, port, function() {
if ( ! chrome.runtime.lastError) {
callback(devices);
} else {
throw chrome.runtime.lastError.message;
}
});
} else {
throw chrome.runtime.lastError.message;
}
});
} else {
chrome.notifications.create("1", {type: "basic", iconUrl: "icon.png", title: "Error", message: "Device not found!"}, function() {console.warn("Device not found!")});
console.warn("Device not found!");
}
});
} else {
chrome.notifications.create("2", {type: "basic", iconUrl: "icon.png", title: "Error", message: "USB Permission not granted."}, function() {console.warn("USB Permission not granted.")});
console.warn("USB Permission not granted.");
}
});
} else {
chrome.notifications.create("3", {type: "basic", iconUrl: "icon.png", title: "Error", message: "No USB permissions granted."}, function() {console.warn("No USB permissions granted.")});
console.warn("No USB permissions granted.");
}
});
}
connect(createReceipt);
}
});

Google App Script. JSON from BigQuery.Jobs.query response

I want to get JSON string from a response of BigQuery.Jobs.query. Are there any easy ways?
Google App Script
var request = {
query: 'SELECT TOP(word, 300) AS word, COUNT(*) AS word_count ' + 'FROM publicdata:samples.shakespeare WHERE LENGTH(word) > 10;'
};
var queryResults = BigQuery.Jobs.query(request, projectId);
What I want to take a JSON text from queryResults
[
{
"word": "counterfeit",
"word_count": "28"
},
{
"word": "remembrance",
"word_count": "24"
},
{
"word": "countenance",
"word_count": "24"
},
It worked thanks to Henrique Abreu.
var request = {
query: 'SELECT TOP(word, 300) AS word, COUNT(*) AS word_count ' + 'FROM publicdata:samples.shakespeare WHERE LENGTH(word) > 10;'
};
var queryResults = BigQuery.Jobs.query(request, projectId);
Logger.log(parseSimpleResults(queryResults));
[
{
word_count=28,
word=counterfeit
},
{
word_count=24,
word=remembrance
}
]
I have not tested this with more BigQuery query results, but it should work fine for "simple" results.
function parseSimpleResults(results) {
var names = results.schema.fields.map(function(field){ return field.name; });
return results.rows.map(function(row) {
var obj = {};
for( var i = 0, len = names.length; i < len; ++i ) {
obj[names[i]] = row.f[i].v;
}
return obj;
});
}
Just pass your queryResults variable to it and you should get your nice array of objects.
just one of directions for you to explore:
local obj = JSON.parse(queryResults)
return obj.rows[1].f[1].v, obj.rows[1].f[2].v

Node.js + bluebird + JSON. JSON is not valid after modification

Trying to get API data.
I have problem with creating valid JSON after modification.
Data should looks like this: [{"1"},{"2"},{"3"}, ... ,{201},{202},{203}, ...]
but now: [{"1"},{"2"},{"3"}, ...],[{"201"},{"202"},{"203"}, ...]
Where is my mistake?
var Promise = require("bluebird");
var request = require('bluebird').promisifyAll(require('request'));
var fs = Promise.promisifyAll(require('fs'));
var ladders = {"hardcore":"hardcore", "standard":"standard"};
function getJSONsync(urls) {
var ladder = [];
Promise.map(urls, function(url) {
return request
.getAsync(url)
.spread(function (res, body) {
if (res.statusCode != 200) {
throw new Error('Unsuccessful attempt. Code: '+ res.statusCode);
}
return JSON.stringify(ladder.concat(JSON.parse(body).entries), "", 4);
})
.catch(console.error);
},{ concurrency: 10 })
.then(function(arr) {
fs.writeFileAsync('file.json', arr);
})
}
function setUrls(ladderName, offset, limit) {
var arr = [];
while(offset < 15000 ) {
arr.push('http://api.pathofexile.com/ladders/'+ladderName+'?offset='+offset+'&limit='+limit);
offset = offset + 200;
}
return arr;
}
getJSONsync(setUrls(ladders.hardcore, 0, 200));
Thx for help.
Sorry for my Eng.
Finally:
var Promise = require("bluebird");
var request = require('bluebird').promisifyAll(require('request'));
var fs = Promise.promisifyAll(require('fs'));
var ladders = {"hardcore":"hardcore","standard":"standard"};
function getJSONsync(urls) {
Promise.map(urls, function(url) {
return request
.getAsync(url)
.spread(function (res, body) {
if (res.statusCode != 200) {
throw new Error('Unsuccessful attempt. Code: '+ res.statusCode);
}
return JSON.parse(body).entries;
})
.catch(console.error);
},{ concurrency: 10 })
.reduce(function(a, b) { return a.concat(b) })
.then(function(arr) {
fs.writeFileAsync('file.json', JSON.stringify(arr, "", 4));
console.log(arr.length);
})
}
function setUrls(ladder, offset, limit) {
var arr = [];
while(offset < 15000 ) {
arr.push('http://api.pathofexile.com/ladders/'+ladder+'?offset='+offset+'&limit='+limit);
offset = offset + 200;
}
return arr;
}
getJSONsync(setUrls(ladders.hardcore, 0, 200));
Promise.map returns an array, so when you do ladder.concat you return another array, so it becomes [[{"1"}], [{"1", "2"}]
You should just remove concat:
return JSON.stringify(JSON.parse(body).entries, "", 4);
But if you want to use variable ladder you may ladder.push(JSON.stringify(JSON.parse(body).entries, "", 4)) and use it instead of arr returned variable